Skip to main content

ui-foundation-backend

The auth and security layer shared by the FastAPI + SQLModel backends of apps built on ui-foundation: the half of every app's backend that apps never change on purpose. Import package foundation_backend. Released with @tristan2828/ui-foundation, under the same version number, from the same commit.

What's in it

Module What it is
config The settings it reads from the environment (database, cookies and sessions, sign-in limits, TOTP, error reporting, AI chats' OAuth, scheduled jobs, Web Push, the seeded account), database_connect_args() and normalize_database_url()
db The async engine and the get_session dependency
models User, Session, LoginFailure, RecoveryCode, PendingLogin, OAuthClient, OAuthCode, OAuthGrant, and since 4.35 McpAuditEntry, JobRunRecord (table names users, sessions, …). PushSubscription and Reminder still import from here, but live in push_models and reminders_models (4.37, #247), on SQLModel.metadata only once used
schemas CamelModel, Page, the sign-in and error-envelope schemas, JobOut/JobRunOut and the push schemas
security, totp, login_limits, rate_window Password and token hashing, the TOTP step, failed sign-in limits, an in-memory rate window
errors, error_reporting, openapi_responses Error bodies pinned to the contract, report_error, the shared responses= fragments
deploy_checks, spa What APP_ENV=production refuses to start with; the SPA mount with its client-route fallback
routers.auth router (login, the TOTP step, logout, me) and register_router (POST /auth/register), with get_current_user
routers.environment, routers.client_errors, routers.oauth GET /environment, POST /client-errors, AI chats' OAuth sign-in (off unless MCP_ENABLED)
mcp, mcp_tools, routers.mcp AI chats' tools (4.35, #230): McpEntity and ListArgs for an app's entities, register_entities (checked by check_entities), the tools generated from them, and /mcp itself (off unless MCP_ENABLED). Every write is a row in mcp_audit_log
jobs, routers.jobs Scheduled jobs (4.35): register_job, start_jobs/stop_jobs for the app's lifespan, one run at a time across processes, GET /jobs and POST /jobs/{name}/run
push, reminders, routers.push Web Push and reminders (4.35): send_push, config_problem(), the send-reminders job (reminders.register(), or register(model=...) on the app's own table, 4.37), /push/*. Needs the push extra (cryptography)
scripts.set_password, scripts.enable_totp, scripts.disable_totp Run as python -m foundation_backend.scripts.<name> <email> from the app's backend/
scripts.generate_vapid_keys, scripts.send_test_push, scripts.check_jobs_live A VAPID key pair; one test notification to a user's devices; the jobs runner against a live Postgres (check-backend-postgres.sh runs it)
scripts.check_deps python -m foundation_backend.scripts.check_deps from backend/: every requirement in pyproject.toml is in ../deps-allowlist.json's python list and pinned with == (4.34, #236). The app's scripts/verify.sh runs it
testing.signed_in session_cookie, to sign a test client in for real
migrations/ Reference copies of the Alembic revisions that create these tables; never run from here (migrations/README.md)

An app keeps everything else: its entities, models, routers and migrations, its McpEntity list (app/mcp_entities.py), the jobs it registers by name, and its main.py, which includes the package's routers and starts its jobs.

How an app uses it

backend/pyproject.toml pins it to the release the app is on, the same version as its @tristan2828/ui-foundation:

dependencies = [
  "ui-foundation-backend==4.35.0",
  ...
]

The app's own modules re-export it, so from app.models import User keeps working (the template's app/config.py, db.py, models.py, schemas.py, openapi_responses.py, security.py, errors.py, spa.py do this), and its main.py includes the routers it offers:

from foundation_backend.routers import auth, client_errors, environment, oauth

app.include_router(auth.router, prefix="/api")
app.include_router(auth.register_router, prefix="/api")  # only if people make their own accounts
app.include_router(client_errors.router, prefix="/api")
app.include_router(environment.router, prefix="/api")
app.include_router(oauth.router)  # only with AI chats (MCP)

register_router is separate on purpose. An app where accounts are made by whoever runs it leaves it out, with /auth/register out of its openapi.yaml (the path is x-optional) and LoginRoute registerPath={null}. Including router alone serves sign-in with no way to make an account through the API.

DATABASE_URL can be a connection string as a provider or a compose file gives it: postgres:// and postgresql:// become postgresql+asyncpg://, libpq's sslmode and channel_binding are dropped from the query (asyncpg reads neither), and sslmode (require, verify-ca, verify-full) sets DATABASE_SSL's default. An explicit DATABASE_SSL wins; with neither, SSL is off. So the scripts run as python -m foundation_backend.scripts.<name> against any of those URLs, with no wrapper of the app's own.

A setting the package reads is changed at runtime (a test's monkeypatch) on foundation_backend.config or on the module that imported it, never on the app's re-export, which is a copy.

Upgrading: bump the pin with the npm package, run the migrations the changelog names for that release, then npm run verify:backend (docs/consuming.md).

In this repo

template/backend/ depends on ui-foundation-backend unpinned. Install both editable in one pip call, so the dependency resolves to this folder and never to PyPI:

cd template/backend
python -m venv .venv
.venv/Scripts/python -m pip install -e ../../packages/backend-foundation -e ".[dev]"   # .venv/bin/python elsewhere

template/backend/scripts/dev.sh and the cloud session hook do this. Installing template/backend on its own would pull the published version (or fail before the first release), and its tests would run against code that isn't this commit's.

npm run verify:backend (repo root) runs this package's gate, scripts/verify.sh (mypy strict, then pytest over SQLite against tests/minimal_app.py, an app made of the package alone), then the template's. On its own: cd packages/backend-foundation && pytest.

Releasing

.github/workflows/release.yml builds it (build-py, with the release's version written into pyproject.toml) and publishes it to PyPI by trusted publishing (publish-py), beside the npm package, before tagging. The committed version in pyproject.toml is a floor, like packages/ui-foundation/package.json's; keep the two the same.

Metadata

Release files for ui-foundation-backend 4.39.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ui-foundation-backend 4.39.0
File Size Uploaded Provenance Actions
ui_foundation_backend-4.39.0.tar.gz 98.2 kB With provenance Details for ui_foundation_backend-4.39.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ui-foundation-backend 4.39.0
File Interpreter ABI Platform Actions
ui_foundation_backend-4.39.0-py3-none-any.whl Python 3 none any Details for ui_foundation_backend-4.39.0-py3-none-any.whl

Total release size: 192.1 kB

Release files / ui_foundation_backend-4.39.0.tar.gz

Download URL ui_foundation_backend-4.39.0.tar.gz
Size 98.2 kB
Tags Source
SHA-256 checksum
How to use checksums
9ec9c0220c56809b02bf76746a11fba609f41135016b6c64c91cceece1fcbb8c
BLAKE2b-256 checksum
How to use checksums
552558fc4f5c5532cdf275b86f2e47ffdbba881602f5cafc15a8722bb9d68e9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / ui_foundation_backend-4.39.0-py3-none-any.whl

Download URL ui_foundation_backend-4.39.0-py3-none-any.whl
Size 93.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f951bb7aeaede7090ed7335f8ab0c8897cf72a388b07d2a83eaa267895ce3fe
BLAKE2b-256 checksum
How to use checksums
7a45607805e1bb08d8387d60e9c253c85e7ed2952101f4ed2a0907d5f90089a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for ui-foundation-backend 4.39.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ui_foundation_backend-4.39.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page