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-0012). 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,
    remembered_commands: int = 10000,
) -> 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 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
remembered_commands int

Command ids remembered for deduplication, per process.

10000

ResolveActor module-attribute

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

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

Authorize module-attribute

Decides whether an actor may use a workspace of its tenant.

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.