Liberty Next — connector-driven low-code framework (SQL + API connectors, React admin UI, AI tool-use assistant, dependency-aware deployment packaging)
Project description
Liberty Next
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 → <tab>.
Quick links
- 📚 Documentation — https://docs.nomana-it.fr/liberty/getting-started/
- 💻 Source — https://github.com/fblettner/liberty-next
- 🐳 Docker image — https://github.com/fblettner/liberty-next/pkgs/container/liberty-next
- 🚀 Deployment configs (Compose + Swarm + helper scripts) —
release/ - 🐛 Issues — https://github.com/fblettner/liberty-next/issues
- 📦 Releases — https://github.com/fblettner/liberty-next/releases
Install
Full guide: https://docs.nomana-it.fr/liberty/getting-started/
Three routes — pick what fits.
Docker Compose (recommended)
Customer hosts only need the release/ directory — sparse-checkout pulls just that:
# 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).
Upgrade later with release/upgrade.sh — it pulls the newest
image (or --tag X.Y.Z), recreates the stack, waits for health, and reports the
framework + apps version change (also journaled in Settings → History → Upgrades).
The full deployment guide (TLS wiring, backups, upgrades, swarm, common ops) lives
in 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):
# 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):
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 http://localhost:8000.
Adding the licensed apps to a pipx install
For Docker, release/install-apps.sh handles everything.
For a pipx install, do it manually:
# 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)
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 # 1100+ 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 → <tab>:
| 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 withLIBERTY_MASTER_KEY). Without a key the framework runs in restricted mode — those connectors aren't loaded. Headless installs can pre-seed the encrypted value withliberty-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.
Upgrade history & release notes
Every config save is versioned (content-addressed snapshots on the persistent config
volume), and version changes of the software itself are journaled too. On startup
the running container compares its installed version against the last one it recorded
and writes an install / upgrade entry — independently for the framework
(liberty-next) and the licensed apps (liberty-apps). So after a docker compose pull (or release/upgrade.sh) you get a dated "7.0.38 → 7.0.39"
trail, with the apps bundle tracked separately from the framework.
- Settings → History — three toggles: Files (per-TOML version history with diff + restore), Screens (screen+dependency bundles), and Upgrades (the version timeline; selecting an entry renders that version's release notes inline, with a Framework / Apps badge).
- Settings → Release notes — the full changelog, EN + FR (FR falls back to EN), with a per-version table of contents and a Framework / Apps switch.
Release notes ship inside each wheel as RELEASE.md / RELEASE.fr.md and are served
by GET /admin/release-notes; the version timeline is GET /admin/upgrades (both
superuser-gated). The release workflow guarantees each released version has a
## <version> — <date> section (it inserts a stub + warns when one is missing), so the
Upgrades detail is never empty.
Releasing
One GitHub Actions workflow, 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. Ensures liberty/RELEASE.md has a "## <version>" section
(inserts a dated stub + warns if missing), then commits the
bumped pyproject.toml + RELEASE.md back to main ([skip ci])
4. Builds + pushes multi-arch Docker to ghcr.io as <version> + :latest
5. Publishes sdist + wheel to PyPI
6. Tags v<version> + 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): bumpversion = "7.1.0"inpyproject.tomlin 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)
-
Branch protection on
main(recommended): https://github.com/fblettner/liberty-next/settings/branches → add a rule formain→ require pull request before merging. This forces the develop → main flow. -
PyPI token: https://pypi.org/manage/account/token/ → create a token (account-scoped first time; scope to
liberty-nextafter the first release). Add it as a repo secret: https://github.com/fblettner/liberty-next/settings/secrets/actions → Name:PYPI_API_TOKEN, Value:pypi-…. -
Docker image visibility: after the first push to ghcr.io, the image lands private. Make it public at https://github.com/fblettner?tab=packages → 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
https://github.com/fblettner/liberty-next/actions/workflows/release.yml →
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.tomlto the next version and push again. - Tag push fails with "refusing to allow a GitHub App to create or update workflow …
without
workflowspermission" — this happens only on the release right after a.github/workflows/*file changed: theGITHUB_TOKENthe bot uses can't push a ref that carries a workflow-file change, so the final tag step is rejected (the Docker + PyPI steps already ran — the version is published, just untagged). Fix: push the tag yourself (you have the scope the bot lacks), e.g.git tag -a v<version> origin/main -m "Release v<version>" && git push origin v<version>, then draft the GitHub release from that tag. Pushing the tag does not re-trigger the workflow (it triggers onpush: branches: [main], not tags), and it breaks the cycle so the next release tags normally. To automate even this case, use a PAT withworkflowscope for the bump/tag push steps instead ofGITHUB_TOKEN.
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
· RELEASE.md · RELEASE.fr.md (changelog shipped in the wheel)
· {cli,admin_cli,connectors_cli,migrate_cli,crypto_cli,license_cli}.py
· connectors/{config,base,db,sql,api,registry,dictionary,introspect}.py
· versioning/ config + upgrade-history store (.versions/index.db)
· 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, upgrade.sh)
tests/ 1100+ tests
docs/ PLAN.md · DEPLOYMENT.md · NOMAFLOW-UI.md · PHASE13.md
Links
- Docs (getting started, config reference, walkthroughs): https://docs.nomana-it.fr/liberty/getting-started/
- GitHub: https://github.com/fblettner/liberty-next
- PyPI: https://pypi.org/project/liberty-next/
- Docker image: https://github.com/fblettner/liberty-next/pkgs/container/liberty-next
- Deployment configs:
release/(light + full Docker Compose layouts) - API reference:
https://<your-install>/redoc - CLI reference:
liberty-next --help(alsoliberty-admin,liberty-license,liberty-crypto) - Working with Claude Code? See
CLAUDE.md - Full plan + design decisions:
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liberty_next-7.0.44.tar.gz.
File metadata
- Download URL: liberty_next-7.0.44.tar.gz
- Upload date:
- Size: 893.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f679c9efe54de89f1a5d87e3cc537e477121854f7f066e99fefb4f13dedbfdc3
|
|
| MD5 |
57fea7c720d06b96f7e2fdfea2a2ffb0
|
|
| BLAKE2b-256 |
a01ab2c097f24dd9cc2bd8bd7cccd343dc1bf91641bacd2388fef398028724f0
|
File details
Details for the file liberty_next-7.0.44-py3-none-any.whl.
File metadata
- Download URL: liberty_next-7.0.44-py3-none-any.whl
- Upload date:
- Size: 674.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b66978913e5d0914f40854bf5d52bfe096b3b7cbfc8925369c787906f0f1f121
|
|
| MD5 |
de159a91b6ce7129b7b9cd0e9eadbcc4
|
|
| BLAKE2b-256 |
d440abdd96c06c6ccaf8bf8c9c8774687ad9b265b0097b9947b12b99094434da
|