Skip to content

API Reference

Complete reference documentation for pico-fastapi's public API.

Module: pico_fastapi

Decorators

Decorator Description
@controller Marks a class as a FastAPI controller
@get(path, **kwargs) Defines a GET endpoint
@post(path, **kwargs) Defines a POST endpoint
@put(path, **kwargs) Defines a PUT endpoint
@delete(path, **kwargs) Defines a DELETE endpoint
@patch(path, **kwargs) Defines a PATCH endpoint
@websocket(path, **kwargs) Defines a WebSocket endpoint

Classes

Class Description
FastApiConfigurer Protocol for application configurers
FastApiSettings Configuration dataclass for FastAPI settings
FastApiAppFactory Factory that creates FastAPI instances

Exceptions

Exception Description
PicoFastAPIError Base exception for all pico-fastapi errors
NoControllersFoundError Raised when no controllers are found during startup

Decorator Reference

@controller

Marks a class as a FastAPI controller with automatic route registration.

@controller(
    cls: Type = None,
    *,
    scope: str = "request",
    prefix: str = "",
    tags: list[str] = None,
    dependencies: list = None,
    responses: dict = None,
    **kwargs
)

Parameters:

Parameter Type Default Description
scope str "request" Component scope (request, websocket, singleton)
prefix str "" URL prefix for all routes in this controller
tags list[str] None OpenAPI tags
dependencies list None FastAPI dependencies for all routes
responses dict None Default responses for all routes

Example:

@controller(prefix="/users", tags=["Users"], scope="request")
class UserController:
    def __init__(self, service: UserService):
        self.service = service

    @get("/")
    async def list_users(self):
        return self.service.list_all()

@get, @post, @put, @delete, @patch

Define HTTP method endpoints on controller methods.

@get(path: str, **kwargs)
@post(path: str, **kwargs)
@put(path: str, **kwargs)
@delete(path: str, **kwargs)
@patch(path: str, **kwargs)

Parameters:

Parameter Type Description
path str Route path (required)
**kwargs Any FastAPI route parameters

Common kwargs:

Kwarg Type Description
response_model Type Pydantic model for response
status_code int HTTP status code
tags list[str] OpenAPI tags
summary str OpenAPI summary
description str OpenAPI description
deprecated bool Mark as deprecated
responses dict Additional response documentation

Example:

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

@controller(prefix="/users")
class UserController:
    @get("/", response_model=list[User], tags=["Users"])
    async def list_users(self):
        return [{"id": 1, "name": "Alice"}]

    @post("/", status_code=201, response_model=User)
    async def create_user(self, data: UserCreate):
        return {"id": 1, **data.dict()}

    @delete("/{user_id}", status_code=204)
    async def delete_user(self, user_id: int):
        pass

@websocket

Defines a WebSocket endpoint on a controller method.

@websocket(path: str, **kwargs)

Parameters:

Parameter Type Description
path str WebSocket route path (required)
**kwargs Any FastAPI WebSocket parameters

Example:

from fastapi import WebSocket

@controller(scope="websocket")
class ChatController:
    def __init__(self, manager: ChatManager):
        self.manager = manager

    @websocket("/ws/chat")
    async def chat(self, websocket: WebSocket):
        await self.manager.handle(websocket)

Class Reference

FastApiConfigurer

Protocol for classes that configure the FastAPI application.

from typing import Protocol, runtime_checkable
from fastapi import FastAPI

@runtime_checkable
class FastApiConfigurer(Protocol):
    @property
    def priority(self) -> int:
        return 0

    def configure_app(self, app: FastAPI) -> None:
        ...

Attributes:

Attribute Type Default Description
priority int 0 Middleware ordering (negative = outer, non-negative = inner)

Methods:

Method Description
configure_app(app) Called to configure the FastAPI application

Example:

from pico_ioc import component
from pico_fastapi import FastApiConfigurer

@component
class CORSConfigurer(FastApiConfigurer):
    priority = -100

    def configure_app(self, app: FastAPI) -> None:
        from fastapi.middleware.cors import CORSMiddleware
        app.add_middleware(CORSMiddleware, allow_origins=["*"])

FastApiSettings

Dataclass for FastAPI application settings, automatically loaded from configuration.

@configured(target="self", prefix="fastapi", mapping="tree")
@dataclass
class FastApiSettings:
    title: str = "Pico-FastAPI App"
    version: str = "1.0.0"
    debug: bool = False

Fields:

Field Type Default Description
title str "Pico-FastAPI App" API title (shown in docs)
version str "1.0.0" API version
debug bool False Debug mode

Configuration:

fastapi:
  title: My API
  version: 2.0.0
  debug: true

FastApiAppFactory

Factory class that creates FastAPI application instances.

@factory
class FastApiAppFactory:
    @provides(FastAPI, scope="singleton")
    def create_fastapi_app(self, settings: FastApiSettings) -> FastAPI:
        return FastAPI(**dataclasses.asdict(settings))

The factory is automatically registered and creates the FastAPI app as a singleton.


Exception Reference

PicoFastAPIError

Base exception for all pico-fastapi errors.

class PicoFastAPIError(Exception):
    pass

Usage:

try:
    # pico-fastapi operations
except PicoFastAPIError as e:
    # Handle any pico-fastapi error

NoControllersFoundError

Raised when no controllers are registered during application startup.

class NoControllersFoundError(PicoFastAPIError):
    def __init__(self):
        super().__init__(
            "No controllers were registered. "
            "Ensure your controller modules are scanned."
        )

Cause: No classes decorated with @controller were found.

Solutions:

  1. Add @controller decorator to your controller classes
  2. Include controller modules in init(modules=[...])
  3. Check for import errors in controller modules

Auto-generated API

pico_fastapi

pico-fastapi: FastAPI integration for pico-ioc.

Provides class-based controllers with constructor dependency injection, automatic request/session/websocket scope management, and a pluggable configurer system for middleware ordering.

Public API

Decorators: controller, get, post, put, delete, patch, websocket Protocols: FastApiConfigurer Dataclasses: FastApiSettings Factories: FastApiAppFactory Exceptions: PicoFastAPIError, NoControllersFoundError

FastApiConfigurer

Bases: Protocol

Protocol for pluggable FastAPI configuration hooks.

Implement this protocol to add middleware, mount sub-apps, register error handlers, or perform any other app-level setup. Configurers are discovered automatically by pico-ioc when decorated with @component.

The priority attribute controls ordering relative to PicoScopeMiddleware:

  • priority < 0 -- outer middleware, applied before the scope middleware (e.g. CORS, session).
  • priority >= 0 -- inner middleware, applied after the scope middleware (e.g. auth, business-logic hooks).

Within the same group, lower values execute first.

Attributes:

Name Type Description
priority int

Integer that determines execution order. Defaults to 0.

Example

.. code-block:: python

from pico_ioc import component
from pico_fastapi import FastApiConfigurer
from fastapi import FastAPI

@component
class CORSConfigurer(FastApiConfigurer):
    priority = -100

    def configure_app(self, app: FastAPI) -> None:
        from fastapi.middleware.cors import CORSMiddleware
        app.add_middleware(
            CORSMiddleware,
            allow_origins=["*"],
        )
Source code in src/pico_fastapi/config.py
@runtime_checkable
class FastApiConfigurer(Protocol):
    """Protocol for pluggable FastAPI configuration hooks.

    Implement this protocol to add middleware, mount sub-apps, register
    error handlers, or perform any other app-level setup.  Configurers are
    discovered automatically by pico-ioc when decorated with ``@component``.

    The ``priority`` attribute controls ordering relative to
    ``PicoScopeMiddleware``:

    - **priority < 0** -- *outer* middleware, applied **before** the scope
      middleware (e.g. CORS, session).
    - **priority >= 0** -- *inner* middleware, applied **after** the scope
      middleware (e.g. auth, business-logic hooks).

    Within the same group, lower values execute first.

    Attributes:
        priority: Integer that determines execution order.  Defaults to ``0``.

    Example:
        .. code-block:: python

            from pico_ioc import component
            from pico_fastapi import FastApiConfigurer
            from fastapi import FastAPI

            @component
            class CORSConfigurer(FastApiConfigurer):
                priority = -100

                def configure_app(self, app: FastAPI) -> None:
                    from fastapi.middleware.cors import CORSMiddleware
                    app.add_middleware(
                        CORSMiddleware,
                        allow_origins=["*"],
                    )
    """

    @property
    def priority(self) -> int:
        return 0

    def configure_app(self, app: FastAPI) -> None:
        """Apply configuration to the FastAPI application.

        Args:
            app: The FastAPI application instance to configure.
        """
        ...

configure_app(app)

Apply configuration to the FastAPI application.

Parameters:

Name Type Description Default
app FastAPI

The FastAPI application instance to configure.

required
Source code in src/pico_fastapi/config.py
def configure_app(self, app: FastAPI) -> None:
    """Apply configuration to the FastAPI application.

    Args:
        app: The FastAPI application instance to configure.
    """
    ...

FastApiSettings dataclass

Type-safe application settings for the FastAPI instance.

Populated automatically from configuration sources (YAML, env, dict) using the fastapi prefix via pico-ioc's @configured decorator. The FastApiAppFactory converts these fields into keyword arguments for the FastAPI() constructor.

Attributes:

Name Type Description
title str

API title shown in the OpenAPI docs.

version str

API version string.

debug bool

Enable FastAPI debug mode.

Example

.. code-block:: yaml

# application.yaml
fastapi:
  title: My API
  version: 2.0.0
  debug: true
Source code in src/pico_fastapi/config.py
@configured(target="self", prefix="fastapi", mapping="tree")
@dataclass
class FastApiSettings:
    """Type-safe application settings for the FastAPI instance.

    Populated automatically from configuration sources (YAML, env, dict)
    using the ``fastapi`` prefix via pico-ioc's ``@configured`` decorator.
    The ``FastApiAppFactory`` converts these fields into keyword arguments
    for the ``FastAPI()`` constructor.

    Attributes:
        title: API title shown in the OpenAPI docs.
        version: API version string.
        debug: Enable FastAPI debug mode.

    Example:
        .. code-block:: yaml

            # application.yaml
            fastapi:
              title: My API
              version: 2.0.0
              debug: true
    """

    title: str = "Pico-FastAPI App"
    version: str = "1.0.0"
    debug: bool = False

NoControllersFoundError

Bases: PicoFastAPIError

Raised when no @controller-decorated classes are found at startup.

This error is raised by register_controllers() when the pico-ioc container does not contain any classes marked with the @controller decorator.

Causes
  • Controller modules were not included in init(modules=[...]).
  • Controller classes are missing the @controller decorator.
  • Import errors prevented controller modules from loading.
Example

.. code-block:: python

try:
    register_controllers(app, container)
except NoControllersFoundError:
    logger.warning("No controllers found; API has no endpoints.")
Source code in src/pico_fastapi/exceptions.py
class NoControllersFoundError(PicoFastAPIError):
    """Raised when no ``@controller``-decorated classes are found at startup.

    This error is raised by ``register_controllers()`` when the pico-ioc
    container does not contain any classes marked with the ``@controller``
    decorator.

    Causes:
        - Controller modules were not included in ``init(modules=[...])``.
        - Controller classes are missing the ``@controller`` decorator.
        - Import errors prevented controller modules from loading.

    Example:
        .. code-block:: python

            try:
                register_controllers(app, container)
            except NoControllersFoundError:
                logger.warning("No controllers found; API has no endpoints.")
    """

    def __init__(self):
        super().__init__("No controllers were registered. Ensure your controller modules are scanned.")

PicoFastAPIError

Bases: Exception

Base exception for all pico-fastapi errors.

Catch this at startup boundaries to handle any pico-fastapi failure without matching individual subclasses.

Example

.. code-block:: python

try:
    app = container.get(FastAPI)
except PicoFastAPIError as exc:
    logger.error("pico-fastapi startup failed: %s", exc)
    raise
Source code in src/pico_fastapi/exceptions.py
class PicoFastAPIError(Exception):
    """Base exception for all pico-fastapi errors.

    Catch this at startup boundaries to handle any pico-fastapi failure
    without matching individual subclasses.

    Example:
        .. code-block:: python

            try:
                app = container.get(FastAPI)
            except PicoFastAPIError as exc:
                logger.error("pico-fastapi startup failed: %s", exc)
                raise
    """

FastApiAppFactory

Factory that creates the FastAPI application as a singleton.

Reads :class:FastApiSettings (populated from configuration sources) and passes its fields as keyword arguments to the FastAPI() constructor. The resulting app is registered in the container with scope="singleton".

Example

.. code-block:: python

from fastapi import FastAPI
from pico_boot import init

container = init(modules=["myapp"])
app = container.get(FastAPI)  # Created by FastApiAppFactory
Source code in src/pico_fastapi/factory.py
@factory
class FastApiAppFactory:
    """Factory that creates the ``FastAPI`` application as a singleton.

    Reads :class:`FastApiSettings` (populated from configuration sources)
    and passes its fields as keyword arguments to the ``FastAPI()``
    constructor.  The resulting app is registered in the container with
    ``scope="singleton"``.

    Example:
        .. code-block:: python

            from fastapi import FastAPI
            from pico_boot import init

            container = init(modules=["myapp"])
            app = container.get(FastAPI)  # Created by FastApiAppFactory
    """

    @provides(FastAPI, scope="singleton")
    def create_fastapi_app(
        self,
        settings: FastApiSettings,
    ) -> FastAPI:
        """Create a FastAPI instance from the provided settings.

        Args:
            settings: Application settings (title, version, debug).

        Returns:
            A configured ``FastAPI`` application instance.
        """
        return FastAPI(**dataclasses.asdict(settings))

create_fastapi_app(settings)

Create a FastAPI instance from the provided settings.

Parameters:

Name Type Description Default
settings FastApiSettings

Application settings (title, version, debug).

required

Returns:

Type Description
FastAPI

A configured FastAPI application instance.

Source code in src/pico_fastapi/factory.py
@provides(FastAPI, scope="singleton")
def create_fastapi_app(
    self,
    settings: FastApiSettings,
) -> FastAPI:
    """Create a FastAPI instance from the provided settings.

    Args:
        settings: Application settings (title, version, debug).

    Returns:
        A configured ``FastAPI`` application instance.
    """
    return FastAPI(**dataclasses.asdict(settings))

controller(cls=None, *, scope='request', **kwargs)

Mark a class as a pico-fastapi controller with DI and auto-routing.

The decorated class is registered as a pico-ioc @component and its methods decorated with @get, @post, etc. are automatically registered as FastAPI routes at startup.

Can be used with or without arguments::

@controller
class A: ...

@controller(prefix="/api", tags=["Items"], scope="request")
class B: ...

Parameters:

Name Type Description Default
cls Optional[Type[Any]]

The class being decorated (passed implicitly when used without parentheses).

None
scope str

pico-ioc scope for the controller instance. Typical values are "request" (default) and "websocket".

'request'
**kwargs Any

Additional metadata forwarded to the APIRouter constructor. Common keys: prefix, tags, dependencies, responses.

{}

Returns:

Type Description
Callable[[Type[Any]], Type[Any]] | Type[Any]

The decorated class (registered as a pico-ioc component), or a

Callable[[Type[Any]], Type[Any]] | Type[Any]

decorator function if called with arguments.

Example

.. code-block:: python

@controller(prefix="/users", tags=["Users"])
class UserController:
    def __init__(self, service: UserService):
        self.service = service

    @get("/")
    async def list_users(self):
        return self.service.list_all()
Source code in src/pico_fastapi/decorators.py
def controller(
    cls: Optional[Type[Any]] = None, *, scope: str = "request", **kwargs: Any
) -> Callable[[Type[Any]], Type[Any]] | Type[Any]:
    """Mark a class as a pico-fastapi controller with DI and auto-routing.

    The decorated class is registered as a pico-ioc ``@component`` and its
    methods decorated with ``@get``, ``@post``, etc. are automatically
    registered as FastAPI routes at startup.

    Can be used with or without arguments::

        @controller
        class A: ...

        @controller(prefix="/api", tags=["Items"], scope="request")
        class B: ...

    Args:
        cls: The class being decorated (passed implicitly when used without
            parentheses).
        scope: pico-ioc scope for the controller instance.  Typical values
            are ``"request"`` (default) and ``"websocket"``.
        **kwargs: Additional metadata forwarded to the ``APIRouter``
            constructor.  Common keys: ``prefix``, ``tags``,
            ``dependencies``, ``responses``.

    Returns:
        The decorated class (registered as a pico-ioc component), or a
        decorator function if called with arguments.

    Example:
        .. code-block:: python

            @controller(prefix="/users", tags=["Users"])
            class UserController:
                def __init__(self, service: UserService):
                    self.service = service

                @get("/")
                async def list_users(self):
                    return self.service.list_all()
    """

    def decorate(c: Type[Any]) -> Type[Any]:
        setattr(c, PICO_CONTROLLER_META, kwargs)
        setattr(c, IS_CONTROLLER_ATTR, True)
        return component(c, scope=scope)

    return decorate if cls is None else decorate(cls)

delete(path, **kwargs)

Define a DELETE endpoint on a controller method.

Parameters:

Name Type Description Default
path str

URL path for the route.

required
**kwargs Any

Additional FastAPI route parameters.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches DELETE route metadata to the method.

Example

.. code-block:: python

@delete("/items/{id}", status_code=204)
async def delete_item(self, id: int):
    pass
Source code in src/pico_fastapi/decorators.py
def delete(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a DELETE endpoint on a controller method.

    Args:
        path: URL path for the route.
        **kwargs: Additional FastAPI route parameters.

    Returns:
        A decorator that attaches DELETE route metadata to the method.

    Example:
        .. code-block:: python

            @delete("/items/{id}", status_code=204)
            async def delete_item(self, id: int):
                pass
    """
    return _create_route_decorator("DELETE", path, **kwargs)

get(path, **kwargs)

Define a GET endpoint on a controller method.

Parameters:

Name Type Description Default
path str

URL path for the route (e.g. "/", "/{id}").

required
**kwargs Any

Additional FastAPI route parameters such as response_model, status_code, tags, summary.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches GET route metadata to the method.

Example

.. code-block:: python

@get("/items", response_model=list[Item])
async def list_items(self):
    return self.service.get_all()
Source code in src/pico_fastapi/decorators.py
def get(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a GET endpoint on a controller method.

    Args:
        path: URL path for the route (e.g. ``"/"``, ``"/{id}"``).
        **kwargs: Additional FastAPI route parameters such as
            ``response_model``, ``status_code``, ``tags``, ``summary``.

    Returns:
        A decorator that attaches GET route metadata to the method.

    Example:
        .. code-block:: python

            @get("/items", response_model=list[Item])
            async def list_items(self):
                return self.service.get_all()
    """
    return _create_route_decorator("GET", path, **kwargs)

patch(path, **kwargs)

Define a PATCH endpoint on a controller method.

Parameters:

Name Type Description Default
path str

URL path for the route.

required
**kwargs Any

Additional FastAPI route parameters.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches PATCH route metadata to the method.

Example

.. code-block:: python

@patch("/items/{id}")
async def patch_item(self, id: int, data: ItemPatch):
    return self.service.patch(id, data)
Source code in src/pico_fastapi/decorators.py
def patch(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a PATCH endpoint on a controller method.

    Args:
        path: URL path for the route.
        **kwargs: Additional FastAPI route parameters.

    Returns:
        A decorator that attaches PATCH route metadata to the method.

    Example:
        .. code-block:: python

            @patch("/items/{id}")
            async def patch_item(self, id: int, data: ItemPatch):
                return self.service.patch(id, data)
    """
    return _create_route_decorator("PATCH", path, **kwargs)

post(path, **kwargs)

Define a POST endpoint on a controller method.

Parameters:

Name Type Description Default
path str

URL path for the route.

required
**kwargs Any

Additional FastAPI route parameters such as response_model, status_code.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches POST route metadata to the method.

Example

.. code-block:: python

@post("/items", status_code=201)
async def create_item(self, data: ItemCreate):
    return self.service.create(data)
Source code in src/pico_fastapi/decorators.py
def post(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a POST endpoint on a controller method.

    Args:
        path: URL path for the route.
        **kwargs: Additional FastAPI route parameters such as
            ``response_model``, ``status_code``.

    Returns:
        A decorator that attaches POST route metadata to the method.

    Example:
        .. code-block:: python

            @post("/items", status_code=201)
            async def create_item(self, data: ItemCreate):
                return self.service.create(data)
    """
    return _create_route_decorator("POST", path, **kwargs)

put(path, **kwargs)

Define a PUT endpoint on a controller method.

Parameters:

Name Type Description Default
path str

URL path for the route.

required
**kwargs Any

Additional FastAPI route parameters.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches PUT route metadata to the method.

Example

.. code-block:: python

@put("/items/{id}")
async def update_item(self, id: int, data: ItemUpdate):
    return self.service.update(id, data)
Source code in src/pico_fastapi/decorators.py
def put(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a PUT endpoint on a controller method.

    Args:
        path: URL path for the route.
        **kwargs: Additional FastAPI route parameters.

    Returns:
        A decorator that attaches PUT route metadata to the method.

    Example:
        .. code-block:: python

            @put("/items/{id}")
            async def update_item(self, id: int, data: ItemUpdate):
                return self.service.update(id, data)
    """
    return _create_route_decorator("PUT", path, **kwargs)

websocket(path, **kwargs)

Define a WebSocket endpoint on a controller method.

The WebSocket parameter is detected by type annotation (ws: WebSocket), not by argument name.

Parameters:

Name Type Description Default
path str

WebSocket route path (e.g. "/ws/chat").

required
**kwargs Any

Additional FastAPI WebSocket route parameters.

{}

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator that attaches WebSocket route metadata to the method.

Example

.. code-block:: python

from fastapi import WebSocket

@controller(scope="websocket")
class ChatController:
    @websocket("/ws/chat")
    async def chat(self, ws: WebSocket):
        await ws.accept()
        data = await ws.receive_text()
        await ws.send_text(f"Echo: {data}")
Source code in src/pico_fastapi/decorators.py
def websocket(path: str, **kwargs: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Define a WebSocket endpoint on a controller method.

    The WebSocket parameter is detected by type annotation
    (``ws: WebSocket``), not by argument name.

    Args:
        path: WebSocket route path (e.g. ``"/ws/chat"``).
        **kwargs: Additional FastAPI WebSocket route parameters.

    Returns:
        A decorator that attaches WebSocket route metadata to the method.

    Example:
        .. code-block:: python

            from fastapi import WebSocket

            @controller(scope="websocket")
            class ChatController:
                @websocket("/ws/chat")
                async def chat(self, ws: WebSocket):
                    await ws.accept()
                    data = await ws.receive_text()
                    await ws.send_text(f"Echo: {data}")
    """
    return _create_route_decorator("WEBSOCKET", path, **kwargs)