Production-oriented unified runtime for FastAPI + Streamlit
Project description
FluxLit
FastAPI and Streamlit on one public port. FluxLit gives you one FluxLit app object, a Uvicorn-powered ASGI gateway, and a managed Streamlit sidecar so your API and UI deploy together without hand-rolling a reverse proxy.
- UI: served from the app root on the URL Uvicorn prints, typically
http://127.0.0.1:8000. - API: mounted under
/apiby default, with OpenAPI at/api/docs. - Routing:
/api/*goes to FastAPI; everything else, including Streamlit WebSockets, is proxied to Streamlit.
Docs: fluxlit.readthedocs.io · Security: SECURITY.md · Roadmap: ROADMAP.md · Changelog: CHANGELOG.md (release 0.11.0)
Install
Python 3.10+.
pip install fluxlit
Optional JWT / OIDC / BFF helpers: pip install "fluxlit[auth]" — see Auth recipes.
For local development on FluxLit itself, clone the repository and run pip install -e ".[dev]".
Quick Start
fluxlit new my-app && cd my-app # optional
app.py:
from typing import Any
from fluxlit import FluxLit
from fluxlit.client import ApiClient
app = FluxLit(title="Admin Portal")
@app.api.get("/users")
def users():
return [{"name": "Ada"}]
@app.page("/")
def home(st: Any, client: ApiClient) -> None:
st.title("Dashboard")
st.write(client.get("/users").json())
Optional typed-page patterns (0.9+): Depends, parse_query_params, PageMeta, manifests — see Streamlit pages: typing and examples/roadmap_09/. 0.10 adds async Depends when an asyncio loop is already running, an opt-in allowlist that merges extra browser header names onto the gateway → Streamlit HTTP hop (see Security for baseline vs allowlist behavior), and a cookbook of copy-paste recipes.
fluxlit dev # default target app:app; or fluxlit dev your.module:app
Open the URL Uvicorn prints. The default gateway is http://127.0.0.1:8000; try GET /api/users or visit /api/docs.
In Streamlit, use paths like client.get("/users"), not "/api/users". Secured routes need a client with credentials — Auth recipes.
What Ships
- One app object:
FluxLitexposes.apifor FastAPI and@app.page(...)for Streamlit pages (optional 0.9+ typing:Depends,Annotated, query/session models,PageMeta,fluxlit pages manifest; 0.10 improves asyncDependsunder Streamlit’s execution model and optional gateway header allowlist merging on the HTTP hop to Streamlit — see Configuration and Security). - Gateway runtime:
fluxlit devandfluxlit runstart Uvicorn plus a managed Streamlit subprocess. - Operational defaults: health/readiness probes, request IDs, optional JSON logs, configurable gateway timeouts, body limits, concurrency, and graceful shutdown.
- Quality gate: package tests enforce 100% line coverage for
src/fluxlitin CI; a single internal import guard in the test helpers uses# pragma: no coverfor an unreachable defensive branch. - Deployment paths:
fluxlit build, Docker Compose, Kubernetes manifests, proxy smoke tests (nginx, Traefik, Caddy strip-prefix, full-path, root, HTTPS, and/apps/my-app), and production TLS/proxy guidance. - Optional auth: JWT validation, OIDC/BFF helpers, Streamlit-safe API clients, and security docs via
fluxlit[auth]. - Testing and diagnostics:
FluxLitTestClient,streamlit_main_path(), AppTest recipes (includingapptest_select_page/apptest_assert_no_errorsfor multipage and query params), URL-session test-mode defaults, optional?page=deep links beforest.navigationwith multipage apps, and expandedfluxlit doctordiagnostics (readiness route, WebSocket expectations, gateway timeouts, async deps, optional header-forwarding hints).
Start with the Quick start, then see Architecture, CLI, Configuration, Deployment, and the Cookbook.
Configuration
Precedence: CLI → environment (FLUXLIT_*, .env) → fluxlit.toml / [tool.fluxlit] → defaults.
# fluxlit.toml (optional)
target = "app:app"
gateway_host = "127.0.0.1"
gateway_port = 8000
Variable reference: Configuration.
Gateway → Streamlit (optional env): tune upstream HTTP timeouts, max proxied request body (returns 413 when exceeded), concurrent upstream HTTP cap, httpx connection limits, WebSocket open/ping/close timeouts, and optional frame size — see the Gateway proxy rows in Configuration. FLUXLIT_GATEWAY_FORWARD_CLIENT_HEADERS_TO_STREAMLIT (JSON list, default empty) merges additional header names from the raw browser request onto the HTTP hop; the baseline proxy already forwards most non–hop-by-hop client headers (see Security). FLUXLIT_UVICORN_GRACEFUL_SHUTDOWN_TIMEOUT_S maps to Uvicorn’s graceful drain window when set (fluxlit dev / fluxlit run).
Logs: enable structured gateway lines with FLUXLIT_ENABLE_GATEWAY_ACCESS_LOG=1; for one JSON object per line in log aggregators, use fluxlit.logging.JsonLogFormatter (examples in Observability). Avoid logging secrets—see Secrets.
TLS / edge: behind a real proxy, tighten FLUXLIT_FORWARDED_ALLOW_IPS, validate X-Forwarded-Proto, and read Production TLS before enabling strict HSTS or CSP elsewhere.
Production References
- Deployment: containers, probes, scaling, Kubernetes graceful shutdown, and a reverse-proxy compatibility matrix (nginx, Traefik, Caddy).
- Cookbook: copy-paste patterns (headers, multipage, tests, pins).
- Observability: request correlation, JSON logs, Prometheus metrics, SLO notes, and runbooks.
- Security architecture, Production TLS, and Secrets: auth boundaries, proxy trust, key rotation, and log hygiene.
- Support matrix: Python and dependency versions tested in CI, pinning guidance (
uv/pip-tools/ constraints), and upgrade notes forFluxLitTestClientand StreamlitAppTest. examples/kubernetes/,examples/docker_compose/,examples/path_prefixed_proxy/,examples/multipage_apptest/,examples/roadmap_09/(typed Streamlit pages), andexamples/fullstack_demo/: reference deployment and application patterns. Runnable nginx, Traefik, and Caddy + FluxLit smoke stacks (including/apps/my-app) live underdocker/proxy-deployment/.
Project Layout
my_app/
├── app.py
├── fluxlit.toml
├── .env # not committed
└── pkg/pages/ # optional: discover_pages(...)
Contributors
pip install -e ".[dev]"
python -m ruff format && python -m ruff check
python -m mypy src/fluxlit
ty check
python -m pytest -n auto --cov=fluxlit --cov-report=term-missing --cov-fail-under=100
Status
FluxLit is in the 0.x line and actively hardening toward production use. Current releases include the unified gateway, page discovery, typed ApiClient, optional Streamlit page typing (Depends, query models, PageMeta, manifests), 0.10-era async Depends handling when an event loop is already active, default-empty allowlist merge for extra gateway → Streamlit HTTP headers (see Security for wire vs allowlist semantics), health/readiness probes, auth helpers, URL session utilities, AppTest-friendly navigation and query-param helpers, expanded fluxlit doctor signals, gateway limits, structured logging helpers, Prometheus metrics, CI security audit/SBOM generation, Docker/Kubernetes examples, path-prefixed reverse-proxy documentation and multi-engine smoke coverage, deployment runbooks, a cookbook, and a 100% package line-coverage gate for src/fluxlit in CI.
See the changelog, support matrix, and roadmap for release status and remaining work.
MIT — see 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 fluxlit-0.11.0.tar.gz.
File metadata
- Download URL: fluxlit-0.11.0.tar.gz
- Upload date:
- Size: 220.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97d6faa7caf473d367787ea7a6d1339482152eb97daac2a6a062cf6e1e57f5f5
|
|
| MD5 |
2531aed10d4f5b7f11d061d7ab6279d5
|
|
| BLAKE2b-256 |
a199204ef7562976aa74694acb47c6a681c104ba91afdffc3fa626a28563be3c
|
File details
Details for the file fluxlit-0.11.0-py3-none-any.whl.
File metadata
- Download URL: fluxlit-0.11.0-py3-none-any.whl
- Upload date:
- Size: 135.7 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 |
e1c3dec4a64b201bfacb8b15dcead82d2bde45632893749ea657fa03f55666e0
|
|
| MD5 |
51052086f78bf2792084b6eb428f30d2
|
|
| BLAKE2b-256 |
9aa5cb4a0f8c7e435618be74d03828b7dac3b313a9ea5a65c8f5ca48dcc83c51
|