FluxLit documentation¶
FastAPI and Streamlit on one public port. FluxLit gives you one app object, one gateway URL, and a managed Streamlit sidecar so your API and UI deploy together.
Install: pip install fluxlit (Python 3.10+) · PyPI · GitHub
Tip
New here? Follow Quick start first. You should have a working app at http://127.0.0.1:8000 in a few minutes.
Choose your path¶
I want to… |
Start here |
|---|---|
Run a minimal API + Streamlit app locally |
|
Understand how requests reach FastAPI vs Streamlit |
|
Configure ports, env vars, proxy paths, or reload behavior |
|
Deploy with containers, Kubernetes, platforms, or a reverse proxy |
Deployment · Platform recipes · Production TLS and edge headers |
Operate the app with logs, metrics, probes, and runbooks |
|
Add JWT, OIDC, or call secured APIs from Streamlit |
|
Survive full page reload without cookies (URL + server store) |
URL session continuity (no cookies) · URL sessions, query tokens, and email links (security) |
Deep links, query params, and invite-style URLs to Streamlit |
|
Test API routes, Streamlit pages, multipage nav, and query params in Pytest |
|
Copy-paste deployment and header patterns |
|
Call the FastAPI app from Streamlit pages ( |
|
FastAPI-style typing, |
|
Fix imports, 503 readiness, WebSockets, or wrong API paths |
Troubleshooting · |
Browse API reference, support policy, or release history |
Ideas to remember¶
Gateway: Uvicorn serves the public URL; Streamlit runs in a child process on an internal port.
Routing:
/api/*goes to FastAPI. Everything else, including/_stcore/...WebSockets, is proxied to Streamlit.From Streamlit, call the API with the injected
clientusing paths like"/users", not"/api/users". The runtime sets the base URL for you. For bearer auth, usewith_bearer()orfor_fluxlit(); see Streamlit → FastAPI: ApiClient patterns and Auth recipes.Secured routes: the default page
clienthas noAuthorizationheader unless you add it per request or usewith_bearer/for_fluxlit.Gateway → Streamlit headers: by default, arbitrary browser headers are not merged onto the internal HTTP hop to Streamlit. Optional 0.10+ allowlists (
FLUXLIT_GATEWAY_FORWARD_CLIENT_HEADERS_TO_STREAMLIT) merge named non-secret headers for correlation; credential and hop-by-hop names are rejected from the allowlist. 0.11+ surfaces those rejected names influxlit configwarnings and afluxlit doctorrow so misconfigurations are obvious. 0.12+ addsfluxlit doctor --strictto fail CI on broad proxy allowlists andpublic_base_urlpath mismatches vs the mount — see Command-line interface. Treat forwarding as high risk and read Security architecture before enabling. Preferset_page_header_context()from trusted FastAPI code for sensitive deployments.Health:
GET /api/healthzchecks the API.GET /api/readyzchecks the Streamlit sidecar when the gateway is managing one.Operations: request IDs, structured logs, Prometheus metrics (with stability notes in Support matrix and Observability), gateway limits, graceful shutdown, Kubernetes guidance, and multi-replica checklists are documented in Observability and Deployment. Unified
FluxLitASGI rejects Uvicorn--workers> 1 at lifespan startup unlessFLUXLIT_ALLOW_UNIFIED_UVICORN_MULTIWORKER=1(unsupported); scale with replicas instead — see Deployment and URL session continuity (no cookies) for session stickiness vs external stores.Tests: use
FluxLitTestClientfor gateway-aware API tests andstreamlit_main_path()/ AppTest for thin Streamlit smoke tests; helpers likeapptest_select_pagehelp exercise multipagest.navigationand query params. See Testing and Deep links and query parameters.
Note
Contributors: the default test command and CI matrix are in Testing. Repository guidelines: Contributing.
User guide
- Quick start
- Architecture
- Configuration
- Command-line interface
- Deployment
- Platform recipes
- Production TLS and edge headers
- Secrets lifecycle
- Observability
- Rate limiting
- Security architecture
- URL session continuity (no cookies)
- URL sessions, query tokens, and email links (security)
- Deep links and query parameters
- Cookbook
- Forward-auth style header for a Streamlit page
- Optional
traceparenton the Streamlit HTTP hop - Multipage + URL session continuity
FluxLitTestClientwithDependsoverrides- Production pins (
uv/pip-tools) - Gateway Prometheus metrics
- Kubernetes-style probes (minimal)
- Fail CI on configuration warnings
- Cap uploads proxied to Streamlit (
413)
- Streamlit → FastAPI:
ApiClientpatterns - Streamlit pages: typing,
Depends, and manifests - Migrating to JWT and OIDC
- Auth recipes
- Friendly API (env-driven, less boilerplate)
- JWT: protect routes (development HS256)
- JWT: production-style RS256 + JWKS
- Scopes and roles
- Streamlit: call the API with a bearer token
- OIDC login + BFF (
auth_codeexchange) - Forward-auth (reverse proxy / SSO)
- API key for automation (header dependency)
- CORS and security headers (settings)
- Secret and key rotation
- Troubleshooting
- First step:
fluxlit doctor - Import and target errors
- Port already in use
- Readiness returns 503
- Payload too large or bad gateway from the proxy
- Streamlit cannot reach the API
- Debug mode (Streamlit ↔ API connectivity)
- Subpath / static assets / WebSockets
- Authentication
- Development reload confusion
- PID file and shutdown
- Getting help
- First step:
- Runbooks
- Testing
- Quick start
- Pytest recipe for apps
- What to test where
- AppTest entrypoint
- Multipage and menu-heavy UIs
- Deep links and query parameters
- FluxLitTestClient: subpaths, docs, query params, and
ApiClient - Markers
- Coverage
- Security audit and SBOM (CI)
- Docker proxy smoke (integration)
- OpenAPI contract
- Chaos and failure injection
- Canonical smoke app
- Soak / load (local)
- Chaos checks (local)
- Upgrade matrix (latest deps)
- E2E
- Type check (
ty) - Readiness
- Fast suite highlights
- Conventions
- Contributing
- Contributing to FluxLit
Reference
- Python API reference
CookieDependsFluxLitPublicUrlsHeaderInMemorySessionStoreNavigationModelPagePageMetaQuerySessionModelSessionStoreapptest_assert_no_errors()apptest_select_page()assert_no_streamlit_exception()ensure_url_session()hydrate_url_session()hydrate_url_session_typed()new_session_id()parse_query_params()persist_url_session()reset_trace_hook()set_trace_hook()streamlit_main_path()trace_span()FluxLitApiClientFluxlitSettingsJsonValueProjectConfigload_project_config()resolve_binding()resolve_target()ProjectConfigload_project_config()resolve_binding()resolve_target()JsonLogFormatterget_request_id()new_request_id()redact_authorization()redact_query_string()reset_request_id()sanitize_headers()set_request_id()GatewayProxyOptionsbuild_gateway()normalize_api_mount_path()normalize_root_mount()split_gateway_paths()probe_streamlit_ready()redact_authorization()redact_query_string()sanitize_headers()asgi_from_fluxlit()create_gateway_app()create_unified_app()default_pidfile_path()find_free_port()internal_api_base_url()load_fluxlit()read_streamlit_upstream_url()resolve_import_target_for_unified()run_unified()shutdown_unified_process()update_streamlit_upstream_file()write_streamlit_upstream_state()FluxLitTestClientapptest_assert_no_errors()apptest_select_page()assert_no_streamlit_exception()streamlit_main_path()reset_trace_hook()set_trace_hook()trace_span()router()GenericOIDCClientGenericOIDCClientConfigInMemoryOIDCBFFTokenStoreJWTAuthConfigJWTBearerOIDCBFFConfigOIDCBFFTokenStoreOIDCProviderRequireRolesRequireScopesStandardClaimsTrustedProxyUserTrustedProxyUserConfigbearer_headers_from_session()exchange_auth_code_from_query()issue_hs256_access_token()pkce_pair()prepare_streamlit_api_client()proxy_user_header()register_oidc_bff_routes()JWTAuthConfigJWTBearerRequireRolesRequireScopesStandardClaimsissue_hs256_access_token()GenericOIDCClientGenericOIDCClientConfigInMemoryOIDCBFFTokenStoreOIDCBFFConfigOIDCBFFTokenStoreOIDCProviderpkce_pair()register_oidc_bff_routes()bearer_headers_from_session()exchange_auth_code_from_query()prepare_streamlit_api_client()InMemorySessionStoreSessionStoreensure_url_session()hydrate_url_session()hydrate_url_session_typed()new_session_id()persist_url_session()match_nav_page()query_params()SecurityHeadersMiddlewarePageFnbuild()config()dev()doctor()main()new()pages_manifest()pages_validate()run_cmd()shutdown()workbench_cmd()
- Changelog
- Changelog
- Unreleased
- 0.13.3 - 2026-05-26
- 0.13.2 - 2026-05-26
- 0.13.1 - 2026-05-14
- 0.13.0 - 2026-05-13
- 0.12.0 - 2026-05-13
- 0.11.0 - 2026-05-12
- 0.10.0 - 2026-05-12
- 0.9.0 - 2026-05-12
- 0.8.1 - 2026-05-12
- 0.8.0 - 2026-05-12
- 0.7.0 - 2026-05-11
- 0.6.1 - 2026-05-11
- 0.6.0 - 2026-05-11
- 0.5.0 - 2026-05-11
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
- Support matrix
- Roadmap
- FluxLit — Development Roadmap
- Path to 1.0 (phased plan)
- Current status (0.13.x)
- Version 0.5 — Production hardening & operations (released)
- Version 0.6 — Production proof points & ecosystem hardening (released)
- Version 0.7 — Testing and diagnostics polish (released)
- Version 0.8 — Configuration visibility and docs (released)
- Version 0.9 — Typed Streamlit pages & developer contracts (released)
- Version 0.3 — Security, identity, and cross-layer trust (released on PyPI)
- Phase 0 — Foundation (complete)
- Phase 1 — Unified runtime MVP (mostly complete)
- Phase 2 — Developer experience
- Phase 2 follow-on — Streamlit survives browser refresh (no cookies)
- Phase 3 — Auth and sessions
- Phase 4 — Production runtime
- Phase 5 — Native ASGI exploration
- Phase 6 — Ecosystem
- Testing strategy
- Success metrics
- Versioning note
- Related documentation