Skip to main content

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

PyPI Python Docker Release Docs

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


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 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.


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): 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): https://github.com/fblettner/liberty-next/settings/branches → add a rule for main → require pull request before merging. This forces the develop → main flow.

  2. PyPI token: https://pypi.org/manage/account/token/ → create a token (account-scoped first time; scope to liberty-next after the first release). Add it as a repo secret: https://github.com/fblettner/liberty-next/settings/secrets/actions → 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 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.toml to the next version and push again.
  • Tag push fails with "refusing to allow a GitHub App to create or update workflow … without workflows permission" — this happens only on the release right after a .github/workflows/* file changed: the GITHUB_TOKEN the 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 on push: branches: [main], not tags), and it breaks the cycle so the next release tags normally. To automate even this case, use a PAT with workflow scope for the bump/tag push steps instead of GITHUB_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


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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

liberty_next-7.0.44.tar.gz (893.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

liberty_next-7.0.44-py3-none-any.whl (674.6 kB view details)

Uploaded Python 3

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

Hashes for liberty_next-7.0.44.tar.gz
Algorithm Hash digest
SHA256 f679c9efe54de89f1a5d87e3cc537e477121854f7f066e99fefb4f13dedbfdc3
MD5 57fea7c720d06b96f7e2fdfea2a2ffb0
BLAKE2b-256 a01ab2c097f24dd9cc2bd8bd7cccd343dc1bf91641bacd2388fef398028724f0

See more details on using hashes here.

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

Hashes for liberty_next-7.0.44-py3-none-any.whl
Algorithm Hash digest
SHA256 b66978913e5d0914f40854bf5d52bfe096b3b7cbfc8925369c787906f0f1f121
MD5 de159a91b6ce7129b7b9cd0e9eadbcc4
BLAKE2b-256 d440abdd96c06c6ccaf8bf8c9c8774687ad9b265b0097b9947b12b99094434da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page