Skip to main content

Production-oriented unified runtime for FastAPI + Streamlit

Project description

FluxLit (fluxlit)

Production-oriented unified runtime for FastAPI and Streamlit: one public port, one CLI, and a single FluxLit app object for APIs plus UI pages.

Docs in this repo: Product & architecture plan · Development roadmap


Overview

FluxLit targets teams that want FastAPI for HTTP APIs and Streamlit for interactive UIs without wiring separate ports, ad hoc reverse proxies, and brittle dev scripts. The runtime uses a sidecar model: Streamlit runs in a subprocess; a Starlette ASGI gateway fronts both the API and the UI.


Requirements

  • Python 3.10+
  • Dependencies are declared in pyproject.toml (FastAPI, Uvicorn, Streamlit, Typer, httpx, websockets, etc.).

Install

pip install fluxlit

For local development of FluxLit itself:

git clone https://github.com/odosmatthews/fluxlit.git
cd fluxlit
pip install -e ".[dev]"

Quick start

Create a project (optional):

fluxlit new my-app
cd my-app

Define a FluxLit app (e.g. app.py):

from fluxlit import FluxLit

app = FluxLit(title="Admin Portal")

@app.api.get("/users")
def users():
    return [{"name": "Ada"}]

@app.page("/")
def home(st, client):
    st.title("Dashboard")
    st.write(client.get("/users").json())

Run the unified server (default import path app:app):

fluxlit dev app:app
  • Browser: open the URL shown by Uvicorn (default http://127.0.0.1:8000).
  • API: routes are mounted under /api (e.g. GET /api/users).
  • OpenAPI / docs: http://127.0.0.1:8000/api/docs (Swagger) and /api/openapi.json.
  • Health: http://127.0.0.1:8000/api/healthz (hidden from OpenAPI).

From Streamlit code, ApiClient calls the API using a base URL that includes /api (set automatically as FLUXLIT_INTERNAL_API_BASE when using fluxlit dev / fluxlit run). Use paths like client.get("/users"), not client.get("/api/users").


How routing works

Browser
   │
   ▼
┌──────────────────────────────────────┐
│  FluxLit gateway (Uvicorn, one port)  │
├──────────────────────────────────────┤
│  /api/*     → FastAPI (path prefix    │
│               stripped inside the app) │
│  /*         → Streamlit (HTTP + WS    │
│               proxy to subprocess)     │
└──────────────────────────────────────┘

Anything that is not under /api is forwarded to Streamlit (including WebSockets used by Streamlit). Reserve /api for your HTTP API.

Note: the API prefix is configurable via FluxlitSettings.api_mount_path (default /api).


CLI

Command Description
fluxlit dev [target] Development server: Streamlit subprocess + gateway. Default target is app:app.
fluxlit run [target] Same stack without auto-reload.
fluxlit new <name> Scaffold a minimal app.py in a new directory.
python -m fluxlit Equivalent entry to the fluxlit console script.

Options for dev / run include --host, --port, --log-level, --proxy-headers, --forwarded-allow-ips. fluxlit dev also supports --reload (experimental; API gateway reload may not restart Streamlit).


Configuration

FluxlitSettings (src/fluxlit/config.py) loads from environment variables prefixed with FLUXLIT_ and from a .env file if present.

Variable Role
FLUXLIT_TITLE App title (default for FastAPI / UX).
FLUXLIT_GATEWAY_HOST / FLUXLIT_GATEWAY_PORT Defaults for binding (also used in settings; CLI overrides bind for dev/run).
FLUXLIT_ROOT_PATH ASGI root path behind a reverse proxy (passed through to FastAPI).
FLUXLIT_INTERNAL_API_BASE Set by the runtime for Streamlit-side ApiClient (includes /api).

Suggested project layout

my_app/
├── app.py              # FluxLit instance, @app.api routes, @app.page handlers
├── pages/              # Optional: extra Streamlit modules if you extend beyond @app.page
├── services/
├── static/
└── .env                # FLUXLIT_* and secrets (do not commit)

A committed fluxlit.toml (or similar) config file is on the roadmap; today, prefer env / .env and CLI flags.


Package layout (src/fluxlit)

Module Purpose
app FluxLit application object
cli Typer CLI
client ApiClient (httpx) for server-side API calls
config FluxlitSettings
gateway ASGI router + HTTP/WebSocket proxy
runtime Subprocess orchestration, Uvicorn entry
streamlit_main Streamlit entry script (FLUXLIT_APP)
testing FluxLitTestClient (FluxLit-native API + Streamlit test helpers)
api Optional APIRouter helpers
auth Placeholder / future shared auth hooks

Testing

FluxLit uses the same “built-in” testing platforms you likely already know:

  • FastAPI: starlette.testclient.TestClient
  • Streamlit: streamlit.testing.v1.AppTest (version-dependent)

FluxLit also ships a small wrapper: FluxLitTestClient.

from fluxlit import FluxLit, FluxLitTestClient

app = FluxLit(title="Test")
client = FluxLitTestClient(app)

assert client.api_get("/healthz").status_code == 200

For Streamlit, you can run FluxLit’s Streamlit entrypoint via AppTest:

at = client.streamlit(target="my_app:app", extra_sys_path=".")

Development (contributors)

pip install -e ".[dev]"
ruff check src tests && ruff format src tests
python -m pytest
python -m mypy src/fluxlit

Features: today vs planned

Available in current alphas

  • Single public port; managed Streamlit subprocess
  • Gateway: /api → FastAPI; HTTP + WebSocket proxy to Streamlit
  • @app.page + st.navigation integration
  • fluxlit new, dev, run
  • Typed package; Ruff + Mypy + Pytest in-tree

Planned (see roadmap)

  • CI, hardened reload/shutdown, first-class health/metrics
  • Auth (JWT, sessions, proxy headers, OAuth)
  • Docker/Kubernetes examples, doctor / build CLI
  • Richer config file and optional page discovery

Philosophy

FluxLit should stay Pythonic (explicit, typed, easy to reason about), production-minded (proxy-safe, observable, deployable), and honest about Streamlit’s process/WebSocket model until a native ASGI path is proven.


License

MIT — see pyproject.toml metadata.

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

fluxlit-0.1.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

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

fluxlit-0.1.0-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file fluxlit-0.1.0.tar.gz.

File metadata

  • Download URL: fluxlit-0.1.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fluxlit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a8b17a5b237021ea9c821fb469a284291802482fa18ac54f9b218e3cb4409be1
MD5 cecd81e8ffae1e676386984b6c8fba61
BLAKE2b-256 6cc56de166b73f4d79f942ab0bcc07e07a8080a0352251c421500c4a99f58654

See more details on using hashes here.

File details

Details for the file fluxlit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fluxlit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fluxlit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bbb51bf84f98b172c74d78ce3a63d6cc5fd0eeaf1c5ca2c430b4229bd980fe12
MD5 cb2332497880cd3030497ecc3b7ea5c5
BLAKE2b-256 07e43419d90c2efd8e31fcaee5b60543859f20f8441283ac6a66c6da603f21fb

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