st.App
ASGI-compatible Streamlit application.
Warning
This feature is experimental and may change or be removed in future versions without warning. Use at your own risk.
Warning
Hosting multiple App instances with different script_path values in the same process is not supported. The first App constructed in a process pins the script-level config directory (via the process-global config._main_script_path), and subsequent App instances will resolve relative script_path values against that first directory rather than the current working directory.
This class provides a way to configure and run Streamlit applications with custom routes, middleware, lifespan hooks, and exception handlers.
| Class description[source] | |
|---|---|
st.App(script_path, *, secrets=None, lifespan=None, routes=None, middleware=None, on_script_error=None, exception_handlers=None, debug=False) | |
| Methods | |
lifespan() | Get a lifespan context manager for mounting on external ASGI frameworks. |
| Attributes | |
script_path (str | Path) | Path to the main Streamlit script. Can be absolute or relative. Relative paths are resolved based on context: when started via streamlit run, they resolve relative to the main script; when started directly via uvicorn or another ASGI server, they resolve relative to the current working directory. |
secrets (Mapping[str, SecretsValue] | None) | A dictionary of secrets to make available via st.secrets. Supported value types are: str, int, float, bool, and nested dict. When provided, these secrets are shallow-merged with file-based secrets (programmatic secrets override file-based secrets at the top level). Unsupported types raise TypeError at construction. |
lifespan (Callable[[App], AbstractAsyncContextManager[dict[str, Any] | None]] | None) | Async context manager for startup/shutdown logic. The context manager receives the App instance and can yield a dictionary of state that will be accessible via app.state. |
routes (Sequence[BaseRoute] | None) | Additional routes to mount alongside Streamlit. User routes are checked against reserved Streamlit routes and will raise ValueError if they conflict. |
middleware (Sequence[Middleware] | None) | Middleware stack to apply to all requests. User middleware runs before Streamlit's internal middleware. |
on_script_error (Callable[[Exception], bool | None] | None) | Callback invoked when an uncaught exception occurs during script execution. The callback receives the exception and can optionally return True to suppress the default exception display in the UI, allowing custom error UI to be shown instead. Returns False or None to show the exception normally. Useful for integrating with error monitoring services like Sentry. The handler is invoked for:
The handler is NOT invoked for:
|
exception_handlers (Mapping[Any, ExceptionHandler] | None) | A mapping of either integer status codes, or exception class types onto callables which handle the exceptions. Exception handler callables should be of the form handler(request, exc) -> response and may be either standard functions, or async functions. This is only for exception handling on the network layer. Use on_script_error for customized handling of uncaught exceptions from the app script. |
debug (bool) | Enable debug mode for the underlying Starlette application. |
Application state, populated by lifespan context manager. | |
Examples
Basic usage:
from streamlit.web.server.starlette import App app = App("main.py")With lifespan hooks:
from contextlib import asynccontextmanager from streamlit.web.server.starlette import App @asynccontextmanager async def lifespan(app): print("Starting up...") yield {"model": "loaded"} print("Shutting down...") app = App("main.py", lifespan=lifespan)With custom routes:
from starlette.routing import Route from starlette.responses import JSONResponse from streamlit.web.server.starlette import App async def health(request): return JSONResponse({"status": "ok"}) app = App("main.py", routes=[Route("/health", health)])With programmatic secrets:
import os from streamlit.web.server.starlette import App app = App( "main.py", secrets={ "database": { "host": os.environ["DB_HOST"], "password": os.environ["DB_PASSWORD"], } }, )With error monitoring (Sentry):
import sentry_sdk from streamlit.web.server.starlette import App sentry_sdk.init(dsn="...") def log_to_sentry(exc): sentry_sdk.capture_exception(exc) return None # Show default exception display app = App("main.py", on_script_error=log_to_sentry)With custom error UI:
import streamlit as st from streamlit.web.server.starlette import App def custom_error_handler(exc): st.error("Something went wrong!") return True # Suppress default exception display app = App("main.py", on_script_error=custom_error_handler)
Still have questions?
Our forums are full of helpful information and Streamlit experts.