Skip to content

API Reference

This page contains the API reference documentation for the RouteLit FastAPI adapter.

RouteLitFastAPIAdapter

routelit_fastapi.adapter.RouteLitFastAPIAdapter(routelit, *, static_path=None, template_path=get_default_template_path(), run_mode='prod', local_frontend_server=None, local_components_server=None, cookie_config=None)

A FastAPI adapter for the RouteLit framework, enabling seamless integration of RouteLit's reactive UI components with FastAPI web applications.

Initialize the RouteLitFastAPIAdapter. - When run_mode="prod", no need to specify local_frontend_server and local_components_server. - When run_mode="dev_client", you need to specify local_frontend_server. - When run_mode="dev_components", you need to specify local_components_server.

Parameters:

Name Type Description Default
routelit RouteLit

The RouteLit instance.

required
static_path Optional[str]

The path to the static js/css assets are.

None
template_path str

The path to the index.html template file. Default is in routelit package, so no need to specify.

get_default_template_path()
run_mode RunMode

The run mode. Example: "prod", "dev_client", "dev_components".

'prod'
local_frontend_server Optional[str]

The local vite frontend server. Example: "http://localhost:5173".

None
local_components_server Optional[str]

The local vite components server. Example: "http://localhost:5174".

None
cookie_config Optional[dict[str, Any] | bool]

The cookie configuration. Default is production cookie config. Set to False to skip cookies config (e.g. for dev or testing).

None
Source code in src/routelit_fastapi/adapter.py
def __init__(
    self,
    routelit: RouteLit,
    *,
    static_path: str | None = None,
    template_path: str = get_default_template_path(),
    run_mode: RunMode = "prod",
    local_frontend_server: str | None = None,
    local_components_server: str | None = None,
    cookie_config: CookieConfig | bool | None = None,
):
    """
    Initialize the RouteLitFastAPIAdapter.
    - When run_mode="prod", no need to specify local_frontend_server and local_components_server.
    - When run_mode="dev_client", you need to specify local_frontend_server.
    - When run_mode="dev_components", you need to specify local_components_server.

    Args:
        routelit (RouteLit): The RouteLit instance.
        static_path (Optional[str]): The path to the static js/css assets are.
        template_path (str): The path to the index.html template file. Default is in routelit package, so no need to specify.
        run_mode (RunMode): The run mode. Example: "prod", "dev_client", "dev_components".
        local_frontend_server (Optional[str]): The local vite frontend server. Example: "http://localhost:5173".
        local_components_server (Optional[str]): The local vite components server. Example: "http://localhost:5174".
        cookie_config (Optional[dict[str, Any] | bool]): The cookie configuration. Default is production cookie config. Set to `False` to skip cookies config (e.g. for dev or testing).
    """
    self.routelit = routelit
    self.static_path = static_path or get_default_static_path()
    self.template_path = template_path
    self.run_mode = run_mode
    self.local_frontend_server = local_frontend_server
    self.local_components_server = local_components_server
    self.cookie_config: CookieConfig = (
        {**production_cookie_config, **(cookie_config or {})}
        if run_mode == "prod" and cookie_config is not False
        else {}
    )
    self.templates: Jinja2Templates | None = None
    self.app: FastAPI | None = None

configure(app)

Configure the FastAPI application to use the RouteLitFastAPIAdapter.

Parameters:

Name Type Description Default
app FastAPI

The FastAPI application to configure.

required

Returns:

Type Description
RouteLitFastAPIAdapter

The RouteLitFastAPIAdapter instance.

Source code in src/routelit_fastapi/adapter.py
def configure(self, app: FastAPI) -> "RouteLitFastAPIAdapter":
    """
    Configure the FastAPI application to use the RouteLitFastAPIAdapter.

    Args:
        app: The FastAPI application to configure.

    Returns:
        The RouteLitFastAPIAdapter instance.
    """
    # Store the FastAPI app for later use in route decorators
    self.app = app

    # Configure static files FIRST (specific routes)
    for static_path in self.routelit.get_builder_class().get_client_resource_paths():
        self.configure_static_assets(app, static_path)

    # Mount routelit static files SECOND (general route)
    app.mount(
        "/routelit",
        StaticFiles(directory=self.static_path, check_dir=False),
    )

    # Configure Jinja2 templates
    self.templates = Jinja2Templates(directory=self.template_path)

    return self

configure_static_assets(app, asset_target) classmethod

Configure static assets for a package.

Parameters:

Name Type Description Default
app FastAPI

The FastAPI application.

required
asset_target AssetTarget

The asset target configuration.

required
Source code in src/routelit_fastapi/adapter.py
@classmethod
def configure_static_assets(cls, app: FastAPI, asset_target: AssetTarget) -> None:
    """
    Configure static assets for a package.

    Args:
        app: The FastAPI application.
        asset_target: The asset target configuration.
    """
    package_name, path = asset_target["package_name"], asset_target["path"]
    assets_path = resources.files(package_name).joinpath(path)
    app.mount(
        f"/routelit/{package_name}",
        StaticFiles(directory=str(assets_path), check_dir=False),
    )

response(view_fn, request, inject_builder=None, *args, **kwargs) async

Handle a request and return a response.

Parameters:

Name Type Description Default
view_fn ViewFn

The view function to handle the request.

required
request Request

The FastAPI request.

required
inject_builder Optional[bool]

Whether to inject the builder into the request.

None
*args Any

Additional arguments to pass to the view function.

()
**kwargs Any

Additional keyword arguments to pass to the view function.

{}

Returns:

Type Description
Response

A FastAPI response.

Source code in src/routelit_fastapi/adapter.py
async def response(
    self,
    view_fn: ViewFn,
    request: Request,
    inject_builder: bool | None = None,
    *args: Any,
    **kwargs: Any,
) -> Response:
    """
    Handle a request and return a response.

    Args:
        view_fn (ViewFn): The view function to handle the request.
        request (Request): The FastAPI request.
        inject_builder (Optional[bool]): Whether to inject the builder into the request.
        *args: Additional arguments to pass to the view function.
        **kwargs: Additional keyword arguments to pass to the view function.

    Returns:
        A FastAPI response.
    """
    rl_request = FastAPIRLRequest(request)
    await rl_request.build()

    if rl_request.method == "POST":
        actions = self.routelit.handle_post_request(view_fn, rl_request, inject_builder, *args, **kwargs)
        return JSONResponse(content=actions)
    else:
        return await self._handle_get_request(view_fn, request, **kwargs)

route(path, methods=None)

Decorator to register a route with the adapter and FastAPI.

Parameters:

Name Type Description Default
path str

The URL path for the route.

required
methods list[str] | None

List of HTTP methods to allow.

None

Returns:

Type Description
Callable[[ViewFn], None]

A decorator function.

Example

@adapter.route("/counter") def counter_view(rl: RouteLitBuilder) -> None: rl.markdown("Hello")

Source code in src/routelit_fastapi/adapter.py
def route(self, path: str, methods: list[str] | None = None) -> Callable[[ViewFn], None]:
    """
    Decorator to register a route with the adapter and FastAPI.

    Args:
        path: The URL path for the route.
        methods: List of HTTP methods to allow.

    Returns:
        A decorator function.

    Example:
        @adapter.route("/counter")
        def counter_view(rl: RouteLitBuilder) -> None:
            rl.markdown("Hello")
    """
    if methods is None:
        methods = ["GET", "POST"]

    def decorator(view_fn: ViewFn) -> None:
        if self.app is None:
            raise RuntimeError("Adapter not configured. Call configure() first.")  # noqa: TRY003

        async def endpoint(request: Request) -> Response:
            return await self.response(view_fn, request)

        # Register with FastAPI
        for method in methods:
            if method.upper() == "GET":
                self.app.get(path)(endpoint)
            elif method.upper() == "POST":
                self.app.post(path)(endpoint)
            else:
                # For other methods, use the generic route
                self.app.api_route(path, methods=[method])(endpoint)

    return decorator

stream_response(view_fn, request, inject_builder=None, *args, **kwargs) async

Handle a request and return a streaming response.

Parameters:

Name Type Description Default
view_fn ViewFn

The view function to handle the request.

required
request Request

The FastAPI request.

required
inject_builder Optional[bool]

Whether to inject the builder into the request.

None
*args Any

Additional arguments to pass to the view function.

()
**kwargs Any

Additional keyword arguments to pass to the view function.

{}

Returns:

Type Description
Response

A FastAPI streaming response.

Source code in src/routelit_fastapi/adapter.py
async def stream_response(
    self,
    view_fn: ViewFn,
    request: Request,
    inject_builder: bool | None = None,
    *args: Any,
    **kwargs: Any,
) -> Response:
    """
    Handle a request and return a streaming response.

    Args:
        view_fn (ViewFn): The view function to handle the request.
        request (Request): The FastAPI request.
        inject_builder (Optional[bool]): Whether to inject the builder into the request.
        *args: Additional arguments to pass to the view function.
        **kwargs: Additional keyword arguments to pass to the view function.

    Returns:
        A FastAPI streaming response.
    """
    rl_request = FastAPIRLRequest(request)
    await rl_request.build()

    if rl_request.method == "POST":
        stream = self.routelit.handle_post_request_stream_jsonl(
            view_fn, rl_request, inject_builder, *args, **kwargs
        )
        return StreamingResponse(
            stream,
            media_type="application/jsonlines",
        )
    else:
        return await self._handle_get_request(view_fn, request, **kwargs)

stream_route(path, methods=None)

Decorator to register a streaming route with the adapter and FastAPI.

Parameters:

Name Type Description Default
path str

The URL path for the route.

required
methods list[str] | None

List of HTTP methods to allow.

None

Returns:

Type Description
Callable[[ViewFn], None]

A decorator function.

Example

@adapter.stream_route("/stream") async def stream_view(rl: RouteLitBuilder) -> None: for i in range(10): rl.text(f"Count: {i}")

Source code in src/routelit_fastapi/adapter.py
def stream_route(self, path: str, methods: list[str] | None = None) -> Callable[[ViewFn], None]:
    """
    Decorator to register a streaming route with the adapter and FastAPI.

    Args:
        path: The URL path for the route.
        methods: List of HTTP methods to allow.

    Returns:
        A decorator function.

    Example:
        @adapter.stream_route("/stream")
        async def stream_view(rl: RouteLitBuilder) -> None:
            for i in range(10):
                rl.text(f"Count: {i}")
    """
    if methods is None:
        methods = ["GET", "POST"]

    def decorator(view_fn: ViewFn) -> None:
        if self.app is None:
            raise RuntimeError("Adapter not configured. Call configure() first.")  # noqa: TRY003

        async def endpoint(request: Request) -> Response:
            return await self.stream_response(view_fn, request)

        # Register with FastAPI
        for method in methods:
            if method.upper() == "GET":
                self.app.get(path)(endpoint)
            elif method.upper() == "POST":
                self.app.post(path)(endpoint)
            else:
                self.app.api_route(path, methods=[method])(endpoint)

    return decorator

handler: python options: members: - init - configure - configure_static_assets - route - stream_route - response - stream_response show_root_heading: true show_source: false heading_level: 3

CookieConfig

routelit_fastapi.adapter.CookieConfig

Bases: TypedDict

Configuration for session cookies.

handler: python options: show_root_heading: true show_source: false heading_level: 3

RunMode

routelit_fastapi.adapter.RunMode = Literal['prod', 'dev_client', 'dev_components'] module-attribute

The run mode for the RouteLitFastAPIAdapter.

  • prod: Production mode.
  • dev_client: Development mode for the client.
  • dev_components: Development mode for the components.

handler: python options: show_root_heading: true show_source: false heading_level: 3

RunModeEnum

routelit_fastapi.adapter.RunModeEnum

Bases: Enum

handler: python options: show_root_heading: true show_source: false heading_level: 3

FastAPIRLRequest

routelit_fastapi.request.FastAPIRLRequest(request)

Bases: RouteLitRequest

Implements the RouteLitRequest interface for FastAPI.

Usage
  1. Create instance: rl_request = FastAPIRLRequest(request)
  2. Call build(): await rl_request.build()
  3. Use with RouteLit handlers: routelit.handle_post_request(..., rl_request, ...)

The build() method must be called before using the request with RouteLit handlers. It pre-processes all async operations (body parsing, file extraction, ui_event parsing).

Source code in src/routelit_fastapi/request.py
def __init__(self, request: Request):
    self.request = request
    self.__default_session_id = str(uuid.uuid4())
    self._json_data: dict[str, Any] | None = None
    self._form_data: dict[str, Any] | None = None
    self._files: list[IOBase] | None = None
    self._built = False

    # Initialize parent class attributes - will be properly set in build()
    self._ui_event: Any | None = None
    self._fragment_id: str | None = None

fragment_id property

Get the fragment ID from the request.

Note: build() must be called before accessing this property.

ui_event property

Get the UI event from the request.

Note: build() must be called before accessing this property.

build() async

Pre-process all async operations for the request.

This method must be called before using the request with RouteLit handlers. It handles: - JSON body parsing - Multipart form data parsing - File extraction from multipart forms - UI event parsing from the request body

After calling this method, the request is ready to be used with: - routelit.handle_get_request() - routelit.handle_post_request() - routelit.handle_post_request_stream_jsonl()

Source code in src/routelit_fastapi/request.py
async def build(self) -> None:
    """
    Pre-process all async operations for the request.

    This method must be called before using the request with RouteLit handlers.
    It handles:
    - JSON body parsing
    - Multipart form data parsing
    - File extraction from multipart forms
    - UI event parsing from the request body

    After calling this method, the request is ready to be used with:
    - routelit.handle_get_request()
    - routelit.handle_post_request()
    - routelit.handle_post_request_stream_jsonl()
    """
    if self._built:
        return

    self._built = True
    content_type = self.request.headers.get("content-type", "")

    # Parse body based on content type
    if "application/json" in content_type:
        self._json_data = await self.request.json()
    elif "multipart/form-data" in content_type:
        form = await self.request.form()
        self._form_data = dict(form)

        # Extract files from form data
        files: list[IOBase] = []
        for key, value in form.multi_items():
            # Check if value is a file upload (has filename and file attributes)
            if key == "files" and hasattr(value, "filename") and value.filename and hasattr(value, "file"):
                # Store filename on the file object for later access
                file_obj = cast(IOBase, value.file)
                file_obj.filename = value.filename  # type: ignore[attr-defined]
                files.append(file_obj)
        self._files = files if files else None

        # Parse JSON from form data if present
        if "json" in self._form_data and isinstance(self._form_data["json"], str):
            with contextlib.suppress(json.JSONDecodeError, TypeError):
                self._json_data = json.loads(self._form_data["json"])

    # Now that body is parsed, initialize parent class event data
    self._ui_event = self._get_ui_event()
    self._fragment_id = self._get_fragment_id()

get_files()

Get files from request body.

Note: build() must be called before this method.

Source code in src/routelit_fastapi/request.py
def get_files(self) -> list[IOBase] | None:
    """
    Get files from request body.

    Note: build() must be called before this method.
    """
    return self._files

get_json()

Get JSON data from request body.

Note: build() must be called before this method.

Source code in src/routelit_fastapi/request.py
def get_json(self) -> dict[str, Any] | None:
    """
    Get JSON data from request body.

    Note: build() must be called before this method.
    """
    return self._json_data

handler: python options: members: - init - build - get_headers - get_path_params - get_referrer - get_json - get_files - is_json - is_multipart - get_query_param - get_query_param_list - get_session_id - get_pathname - get_host - method - ui_event - fragment_id show_root_heading: true show_source: false heading_level: 3

Exports

The following are exported from the routelit_fastapi package:

from routelit_fastapi import (
    RouteLitFastAPIAdapter,  # Main adapter class
    RunMode,                  # Literal type for run modes
    RunModeEnum,              # Enum for run modes
    CookieConfig,             # TypedDict for cookie configuration
)