https://github.com/fblettner/liberty-next
https://github.com/fblettner/liberty-next
Last synced: 9 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/fblettner/liberty-next
- Owner: fblettner
- Created: 2026-05-14T09:16:05.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-07T20:15:38.000Z (13 days ago)
- Last Synced: 2026-06-07T20:19:17.831Z (13 days ago)
- Language: Python
- Size: 5.23 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Liberty Next
[](https://pypi.org/project/liberty-next/)
[](https://pypi.org/project/liberty-next/)
[](https://github.com/fblettner/liberty-next/pkgs/container/liberty-next)
[](https://github.com/fblettner/liberty-next/actions/workflows/release.yml)
[](https://docs.nomana-it.fr/liberty/getting-started/)
**Connector-driven low-code framework.** Configure SQL queries + HTTP endpoints in
TOML; Liberty derives schemas at query time, serves a React admin UI on the same
port, surfaces an Anthropic tool-use assistant for natural-language access, and
wraps everything in a structured-config builder + dependency-aware deployment
packager.
Declarative `connectors.toml` / `screens.toml` / `dictionary.toml` / `menus.toml` /
`charts.toml` / `dashboards.toml` files drive the runtime โ schemas derived at query
time, no code-gen step, every field round-trippable through the structured editors
at **Settings โ \**.
## Quick links
- ๐ **Documentation** โ
- ๐ป **Source** โ
- ๐ณ **Docker image** โ
- ๐ **Deployment configs** (Compose + Swarm + helper scripts) โ [`release/`](https://github.com/fblettner/liberty-next/tree/main/release)
- ๐ **Issues** โ
- ๐ฆ **Releases** โ
---
## Install
**Full guide:**
Three routes โ pick what fits.
### Docker Compose (recommended)
Customer hosts only need the `release/` directory โ sparse-checkout pulls just that:
```bash
# 1. Sparse-clone โ downloads ONLY release/ (no liberty/, no frontend/, no .git history of source)
git clone --depth 1 --filter=blob:none --sparse https://github.com/fblettner/liberty-next.git
cd liberty-next
git sparse-checkout set release
cd release
# 2. One-shot install (interactive picks light vs full; or use a flag)
./install.sh full
# 3. (Licensed customer) overlay the apps wheel โ see release/README.md
./install-apps.sh /path/to/liberty_apps-X.Y.Z.whl
# Set the license key after install via Settings โ App โ License (encrypted at rest in app.toml).
```
The full deployment guide (TLS wiring, backups, upgrades, swarm, common ops) lives
in [`release/README.md`](release/README.md).
### PyPI
**Recommended โ pipx** (isolates Liberty Next in its own venv; CLI commands stay on
your PATH; no risk of polluting system Python):
```bash
# Install pipx once if you don't have it:
# macOS: brew install pipx && pipx ensurepath
# Linux: sudo apt install pipx && pipx ensurepath
# # or: python3 -m pip install --user pipx && python3 -m pipx ensurepath
# Windows: py -m pip install --user pipx && py -m pipx ensurepath
# Report rendering (markdown โ PDF) uses WeasyPrint โ install the system libs
# it links against. Skip if you don't plan to use the /api/reports endpoints.
# macOS: brew install pango
# Debian/Ubuntu: sudo apt install libpango-1.0-0 libpangoft2-1.0-0 libharfbuzz0b libfontconfig1
pipx install liberty-next
liberty-next # โ API + SPA on http://localhost:8000
```
This gives you every CLI tool the package ships (`liberty-next`, `liberty-admin`,
`liberty-connectors`, `liberty-migrate`, `liberty-license`, `liberty-crypto`) on the PATH,
each one routed through the same isolated venv. Upgrade with `pipx upgrade liberty-next`;
uninstall cleanly with `pipx uninstall liberty-next` (removes the venv + every shim,
leaves nothing behind).
**Plain pip** (only when pipx isn't an option โ make a venv yourself to avoid breaking
system packages):
```bash
python3 -m venv ~/.local/liberty-venv
~/.local/liberty-venv/bin/pip install liberty-next
~/.local/liberty-venv/bin/liberty-next
```
First boot generates an `admin` password and prints it once โ capture it from the
logs, then sign in at .
### Adding the licensed apps to a pipx install
For Docker, [`release/install-apps.sh`](release/install-apps.sh) handles everything.
For a pipx install, do it manually:
```bash
# 1. Inject the apps wheel into the SAME pipx venv as liberty-next
# (delivered to licensed customers as liberty_apps-X.Y.Z-py3-none-any.whl):
pipx inject liberty-next /path/to/liberty_apps-X.Y.Z-py3-none-any.whl
# 2. Persistent secrets โ generate ONCE and put in ~/.bashrc / ~/.zshrc.
# Both must stay stable across restarts (rotating either breaks every encrypted
# secret in app.toml + connectors.toml).
export LIBERTY_JWT_SECRET="$(openssl rand -base64 48 | tr -d '\n=+/')"
export LIBERTY_MASTER_KEY="$(openssl rand -base64 32 | tr -d '\n=+/')"
# 3. Postgres credentials โ used by liberty-admin init-db to seed [pools.default]
# AND by deploy-databases to inherit-and-set the nomasx1 / nomajde role passwords.
# Skip if you only want SQLite for trial (licensed connectors need real pg).
export POSTGRES_PASSWORD="your-postgres-superuser-password"
export POSTGRES_USER=liberty
export POSTGRES_HOST=localhost
export POSTGRES_PORT=5432
export POSTGRES_DB=liberty
# SQLite fallback (no licensed connectors): export LIBERTY_DB_URL=sqlite+aiosqlite:///./liberty.db
# 4. Materialize the wheel's payload into a writable LIBERTY_APPS_DIR
mkdir -p ~/.local/share/liberty-next/apps
liberty-apps install --target ~/.local/share/liberty-next/apps/config
export LIBERTY_APPS_DIR=~/.local/share/liberty-next/apps/config
# 5. Bootstrap the framework DB + admin user
psql -h "$POSTGRES_HOST" -U postgres -c "CREATE ROLE $POSTGRES_USER LOGIN SUPERUSER PASSWORD '$POSTGRES_PASSWORD';"
psql -h "$POSTGRES_HOST" -U postgres -c "CREATE DATABASE $POSTGRES_DB OWNER $POSTGRES_USER;"
liberty-admin init-db # seeds [pools.default] + creates 'admin' user, prints password
# 6. Run the install-time jobs (deploy-databases / init-schema / import-reference)
liberty-admin run-install-jobs
# 7. Start the server
liberty-next # API + SPA on http://localhost:8000
# 8. Sign in as admin, then Settings โ App โ License โ Set
# (encrypted at rest in app.toml with LIBERTY_MASTER_KEY)
```
Upgrade the apps later by injecting a new wheel + re-running `liberty-apps install`
(operator-edited TOMLs are preserved; pass `--force-config` to overwrite). License /
AI api_key / OIDC settings stay in app.toml and survive the upgrade.
### From source (development)
```bash
git clone https://github.com/fblettner/liberty-next.git
cd liberty-next
python3.12 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -v # 920+ tests
./start.sh init-config # seed config/*.toml from the .example files
./start.sh init-db # FIRST RUN: create the auth store + `admin` user (prints password)
./start.sh # build frontend + serve on :8000
./start.sh dev # same, with backend auto-reload
./start.sh frontend # Vite HMR dev server on :5173 (pair with `./start.sh api dev`)
```
---
## What you get
| URL | Purpose |
|---|---|
| `/` | React SPA โ admin UI (sign-in, workspace tabs, Settings, AI assistant) |
| `/docs` | **Swagger UI** โ interactive API explorer |
| `/redoc` | **ReDoc** โ print-friendly API reference (grouped by tag) |
| `/openapi.json` | OpenAPI 3 spec โ generated from FastAPI routes + Pydantic models |
| `/api/*` | Public API surface (auth gates per route) |
| `/admin/*` | Operator-only endpoints โ config CRUD, find-usages, packaging, AI scaffold-apply, โฆ |
| `/info` | Public liveness + counts (connectors / screens / pools) โ Docker `HEALTHCHECK` hits this |
---
## Configuration in 60 seconds
Eight TOML files under `config/` (or wherever `LIBERTY_APPS_DIR` points). Every file
is round-trippable through the structured editors at **Settings โ \**:
| File | What it carries | Editor |
|---|---|---|
| `app.toml` | App-level settings (host / port / log level / AI model / hot-reload) + encrypted secrets (license key, AI api_key, OIDC client_secret) | Settings โ App |
| `connectors.toml` | DB pools + SQL connectors with named queries + API connectors with endpoints | Settings โ Pools, Settings โ Connectors |
| `dictionary.toml` | Shared + per-connector field metadata (labels / types / rules / lookups / sequences) | Settings โ Dictionary |
| `screens.toml` | Screen definitions โ per-app grids + dialog forms + actions + row menus | Settings โ Screens |
| `charts.toml` | Saved chart specs referenceable from screens + dashboards | Settings โ Charts |
| `dashboards.toml` | Widget grids with shared filters | Settings โ Dashboards |
| `menus.toml` | Per-app navigation trees | Settings โ Menus |
| `jobs.toml` | nomaflow ETL pipelines + scheduled jobs (per-step `op_kwargs`, retry, retention) | Nomaflow โ Jobs |
Two secrets stay env-only: `LIBERTY_JWT_SECRET` (signs access / refresh tokens) and
`LIBERTY_MASTER_KEY` (the AES-256-GCM key that decrypts every `ENC:` value in app.toml +
connectors.toml). Everything else โ license key, Anthropic API key, OIDC client secret,
pool / API-connector passwords โ lives encrypted at rest in TOML and is edited through
the UI's masked-secret pattern. `${VAR}` / `${VAR:-default}` env references in TOML are
still expanded at load time for the few values an operator wants to keep externally
managed.
---
## Customer / vendor split
Liberty Next ships as an **open framework**. The customer-facing connectors + screens
+ dictionaries live in a separate apps repo (`liberty-apps`); the licensed ones
(nomasx1 / nomajde / nomaflow) are unlocked by an RS256 JWT set via **Settings โ App โ
License** (encrypted at rest in app.toml with `LIBERTY_MASTER_KEY`). Without a key
the framework runs in **restricted** mode โ those connectors aren't loaded. Headless
installs can pre-seed the encrypted value with `liberty-crypto encrypt`.
The **Settings โ Package** tab packages selected screens / menu items / dashboards
plus their full dependency closure (connectors / queries / DD entries / lookups / โฆ)
into a ZIP for atomic deployment to another install. Each entity carries an
`override = true` flag operators can flip to mark customer customisations โ the
import-package endpoint's `overwrite` strategy preserves flagged entities so vendor
upgrades don't clobber customer forks.
---
## Releasing
One GitHub Actions workflow, [`release.yml`](.github/workflows/release.yml), publishes
every release. **It runs automatically on every push to `main`.** No buttons, no tags,
no manual triggers.
### The flow
```
develop branch โ work happens here, push freely, NOTHING triggers
โ
PR develop โ main, merge
โ
main branch push โ release.yml runs:
1. Reads pyproject.toml's version
2. If that version is already tagged โ auto-bump patch (7.0.1 โ 7.0.2)
Else use as-is (when you manually bumped for a major/minor)
3. Commits the bumped pyproject.toml back to main ([skip ci])
4. Builds + pushes multi-arch Docker to ghcr.io as + :latest
5. Publishes sdist + wheel to PyPI
6. Tags v + creates GitHub release with auto-notes
```
### Version control
- **Bugfix / patch release** (default): just merge to main. Workflow auto-bumps `7.0.1 โ 7.0.2`.
- **Minor release** (`7.0.x โ 7.1.0`): bump `version = "7.1.0"` in `pyproject.toml` in any commit before merging. Workflow honours it.
- **Major release** (`7.x โ 8.0.0`): same โ bump in pyproject.toml.
### Setting up the repo (one-time)
1. **Branch protection on `main`** (recommended):
โ add a rule for
`main` โ require pull request before merging. This forces the develop โ main flow.
2. **PyPI token**: โ create a token
(account-scoped first time; scope to `liberty-next` after the first release).
Add it as a repo secret:
โ
Name: `PYPI_API_TOKEN`, Value: `pypi-โฆ`.
3. **Docker image visibility**: after the first push to ghcr.io, the image lands
private. Make it public at โ
liberty-next โ Package settings โ Change visibility โ Public. (One-time.)
### Manual override
The workflow also has a `workflow_dispatch` trigger if you need to re-publish a
specific version (rebuild after a base-image CVE, etc.). Go to
โ
Run workflow โ optional version input.
### Recovering from a failed publish
- **Pre-publish failure** (build, Docker push) โ fix and re-trigger; nothing is consumed.
- **PyPI publish failure** (the only irreversible step) โ the version is burned. Bump
`pyproject.toml` to the next version and push again.
---
## Stack
Python 3.12 ยท FastAPI ยท SQLAlchemy 2.0 async ยท asyncpg (PostgreSQL) ยท oracledb (Oracle,
thin) ยท APScheduler (nomaflow ETL + cron) ยท Anthropic SDK ยท authlib (OIDC) ยท argon2 ยท
cryptography (AES-256-GCM) ยท React 19 + Vite + TypeScript + emotion ยท
TanStack Table ยท Monaco (SQL editor) ยท Recharts (visualisation).
---
## Repository layout
```
config/ app.toml (committed) ยท {connectors,dictionary,menus,screens,charts,dashboards,auth,jobs}.toml (NOT committed โ per-deployment)
liberty/ main.py ยท config.py ยท crypto.py ยท framework_enums.py ยท theme.py
ยท {cli,admin_cli,connectors_cli,migrate_cli,crypto_cli,license_cli}.py
ยท connectors/{config,base,db,sql,api,registry,dictionary,introspect}.py
ยท licensing/{__init__.py, public.pem}
ยท menus/config.py ยท screens/config.py ยท charts/config.py ยท dashboards/config.py
ยท auth/{authstore,password,tokens,principal,oidc,dependencies,routes,models,db,service}.py
ยท ai/{tools,connector_tools,scaffold_tools,proposal,assistant,routes}.py
ยท jobs/{schema,registry,db,runner,scheduler,wiring,coercion,triggers,models,steps/}
ยท etl/{operations,โฆ}.py โ shared SQL helpers used by nomaflow callables
ยท web/{admin,connectors,menus,screens,charts,dashboards,license,theme,jobs,
access,hot_reload,errors,dependencies,deps,package,package_import,
clone,clone_with_deps,delete_with_deps,rename,export,dictgen,usages}.py
frontend/ Vite + React 19 + TS โ built dist/ served by the backend
src/{api,auth,workspace,types,services,common,pages,components,locales}/*
.github/workflows/ release.yml โ auto-publishes Docker (ghcr.io) + PyPI on every push to main
docker/ entrypoint.sh โ runtime config-init (init-db when POSTGRES_PASSWORD set)
start.sh run/dev helper (serve | dev | api | build | frontend | init-db | init-config | help)
release/ deployment configs (Docker Compose light/full/swarm, install.sh, install-apps.sh)
tests/ 920+ tests
docs/ PLAN.md ยท DEPLOYMENT.md ยท NOMAFLOW-UI.md ยท PHASE13.md
```
---
## Links
- **Docs (getting started, config reference, walkthroughs):**
- **GitHub:**
- **PyPI:**
- **Docker image:**
- **Deployment configs:** [`release/`](release/) (light + full Docker Compose layouts)
- **API reference:** `https:///redoc`
- **CLI reference:** `liberty-next --help` (also `liberty-admin`, `liberty-license`, `liberty-crypto`)
- **Working with Claude Code?** See [`CLAUDE.md`](CLAUDE.md)
- **Full plan + design decisions:** [`docs/PLAN.md`](docs/PLAN.md)
---
## License
Open framework: free. Connectors flagged `licensed = true` in `connectors.toml`
(sold separately, distributed in their own repos) are unlocked by an RS256 JWT
license key, set via **Settings โ App โ License** (encrypted at rest in app.toml with
the install's `LIBERTY_MASTER_KEY`). `nomasx1` and `nomajde` are always-licensed โ
the loader refuses to load them without a covering key regardless of the on-disk
`licensed` flag. Without a key the framework runs in "restricted" mode. Inspect
a key with `liberty-license verify`; status at `GET /api/license`.