Skip to content

artifactr.fastapi

The fastapi extra. See Serving over WebSocket and REST.

The thread protocol over WebSocket, and REST commands and reads, as a FastAPI router.

Include it in an application and give it the host's authentication::

async def resolve_actor(connection: HTTPConnection) -> tuple[str, Actor]:
    user = await authenticate(connection.headers)  # the application's own auth
    return user.tenant_id, UserActor(id=user.id, name=user.name)


app.include_router(
    artifactr_router(workspaces, runner, resolve_actor=resolve_actor), prefix="/v1"
)

Every command, over either transport, goes through artifactr.agent.Runner.execute, so it behaves identically (ADR-0048). See docs/protocol.md for the wire format.

The router

artifactr_router

artifactr_router(
    workspaces: Workspaces,
    runner: Runner[Any],
    *,
    resolve_actor: ResolveActor,
    authorize: Authorize | None = None,
    hello_timeout: float = 10.0,
    outbox_size: int = 1000,
    tracer_provider: TracerProvider | None = None,
    meter_provider: MeterProvider | None = None,
) -> APIRouter

Build the router for the thread protocol, REST commands and reads.

Parameters:

Name Type Description Default
workspaces Workspaces

Opens tenant-scoped workspaces.

required
runner Runner[Any]

Carries out commands, once per command_id, and runs the agent.

required
resolve_actor ResolveActor

Authenticates each request and connection.

required
authorize Authorize | None

Whether an actor may use a workspace; allows everything if omitted.

None
hello_timeout float

Seconds a new connection has to send hello.

10.0
outbox_size int

Frames buffered for a slow connection before it is closed (4429).

1000
tracer_provider TracerProvider | None

Where artifactr.stream spans go. Defaults to the global one.

None
meter_provider MeterProvider | None

Where connection metrics go. Defaults to the global one.

None

Each REST request's span (FastAPI's own, when it is instrumented) and each connection's artifactr.stream span are attributed to the tenant, workspace and actor.

ResolveActor module-attribute

ResolveActor = Callable[
    [HTTPConnection], Awaitable[tuple[TenantId, Actor]]
]

Authenticates a request or connection: returns its tenant and actor, or raises Unauthorized.

Unauthorized

Bases: Exception

Raise from resolve_actor to refuse a request (401) or connection (close 4401).

STATUS_CODES module-attribute

STATUS_CODES: dict[str, int] = {
    "version_conflict": 409,
    "invalid_state": 409,
    "validation_failed": 422,
    "patch_failed": 422,
    "not_found": 404,
    "forbidden": 403,
    "unsupported_protocol": 400,
}

The HTTP status for each rejection type.