Skip to main content

Use AstraBox from a Python application

Most applications run AstraBox as a separate service and use its HTTP API. A Python application that must share the same process can instead load AstraBox as an ASGI application with create_app(). Specialized Python workers can use the service layer directly when they intentionally own every lifecycle step they need.

Both options use the same Agents, Sessions, streaming responses, Deployments, credentials, and sandbox lifecycle. In-process use does not move the Agent program into the host application: the Agent program still runs in an OpenSandbox sandbox and remains available after the developer's computer disconnects.

Integration options

HTTP serviceASGI application in the host process
Works withAny language or frameworkPython and an ASGI server
DeploymentAstraBox is deployed and scaled independentlyAstraBox and the host application are deployed together
Failure and dependency isolationSeparate process and Python environmentShared process, dependencies, event loop, and failures
AccessHTTP, SSE, WebSocket, and remote MCPThe same routes through the ASGI application
ExtensionsInstalled AstraBox extension packagesInstalled extensions plus an outer ASGI wrapper when needed
UpgradeUpgrade AstraBox independentlyTest and upgrade the combined application

Use the HTTP service when the application only needs to create or use Agents. Use the ASGI application when one Python process or direct ASGI composition is a deliberate requirement.

Run AstraBox as an HTTP service

Start the application on loopback:

astrabox serve --host 127.0.0.1 --port 8088

The AstraBox process initializes storage, runs migrations, starts background recovery and scheduled work, reports readiness, drains active work, and closes connections during shutdown. The calling application only needs to authenticate and use the published API.

See HTTP API, API authentication, and Event Stream for the application-facing interface. See Deploy AstraBox when the service will be available outside one trusted host.

Load the ASGI application

create_app() returns the FastAPI application used by astrabox serve:

from astrabox.api.app import create_app

astrabox_app = create_app()

Set AstraBox environment variables before calling create_app(). Creating the object registers routes and middleware but does not connect to the database or sandbox service. Those operations begin when the application lifespan starts.

An ASGI server can run the factory directly:

uvicorn astrabox.api.app:create_app --factory --host 127.0.0.1 --port 8088

This shares the launch mechanism, not the process, with another application. For one combined process, mount AstraBox at the root of a parent FastAPI app and enter the AstraBox lifespan from the parent's lifespan:

from contextlib import asynccontextmanager

from fastapi import FastAPI

from astrabox.api.app import create_app

astrabox_app = create_app()


@asynccontextmanager
async def lifespan(_: FastAPI):
async with astrabox_app.router.lifespan_context(astrabox_app):
yield


app = FastAPI(lifespan=lifespan)


@app.get("/host-health")
async def host_health() -> dict[str, str]:
return {"status": "ok"}


# Register host routes first. AstraBox handles every remaining root path.
app.mount("/", astrabox_app)

FastAPI runs lifespan events only for the main application, not automatically for a mounted subapplication. Enter the AstraBox lifespan exactly once as shown above; otherwise migrations, recovery, scheduled work, and shutdown do not run.

Keep AstraBox at the origin root

The AstraBox console uses root-relative asset, API, authentication, and console routes such as /assets, /api, and /manage. Mounting the application at a path such as /astrabox is therefore not supported.

The parent application can register its own routes before the root mount. If both applications need independent root routes or browser interfaces, give AstraBox its own hostname or route a separate virtual host to the ASGI application. Path-prefix hosting is not supported for the bundled console.

What the lifespan starts

The AstraBox lifespan owns the complete service lifecycle:

  • loads installed extensions and Provider implementations;
  • prepares the database and runs pending migrations;
  • starts Deployment scheduling and runtime recovery;
  • enters installed lifespan hooks after core startup;
  • changes /readyz to not ready before shutdown;
  • drains active work and closes runtime connections.

Required extensions, database preparation, migrations, and Deployment scheduling must initialize successfully. Runtime recovery startup errors are logged without aborting boot; the first API request can retry that initialization. The host must not accept requests until the lifespan has entered successfully.

Call AstraBox services without HTTP

A Python worker that does not need the console or HTTP routes can initialize the provider composition, storage, migrations, and runtime recovery explicitly:

from astrabox.bootstrap import bootstrap
from astrabox.persistence.migrations import run_pending_migrations
from astrabox.persistence.repository import backend
from astrabox.core.service.orchestrator.service_registry import (
get_platform_service,
run_lifecycle_shutdown,
run_lifecycle_startup,
)

bootstrap()
await backend.create_all()
await run_pending_migrations()
await run_lifecycle_startup()

platform = get_platform_service()

try:
# Call the required platform service with an explicit user context.
...
finally:
await run_lifecycle_shutdown(reason="host_shutdown")

bootstrap() is idempotent. It loads built-in and installed Providers, selects the configured sandbox service, and rejects incompatible deployment settings. It does not prepare storage, run migrations, start Deployment scheduling, enter application lifespan hooks, or arrange shutdown.

The example starts the recovery lifecycle used by AstraBox services, but it is not a substitute for the full application lifespan. Use create_app() when the host needs scheduled Deployments, app extensions, readiness and draining, the console, or any HTTP surface. Direct service calls must still pass an explicit user identity so normal authorization remains in effect.

Extend the application

An installed Python package can add behavior through entry points:

Entry-point groupCapability
astrabox.api.routersAdd FastAPI routes after core API routes and before the console fallback
astrabox.web.middlewaresAdd middleware inside AstraBox's trusted-host and identity checks
astrabox.lifespan_hooksStart and stop extension services with the AstraBox lifespan
astrabox.service_factoriesReplace a supported service implementation
astrabox.providers.*Add implementations for an AstraBox Provider interface

Application router, middleware, and lifespan entry points load in name order. Duplicate names, incompatible interface versions, invalid targets, and startup errors stop the application instead of silently skipping the extension. Lifespan hooks exit in reverse order.

Middleware installed through an AstraBox entry point runs after the trusted-host and identity checks. Middleware that must wrap the complete application belongs on the parent ASGI app.

See Architecture for the available Provider interfaces. The adapter-specific guides cover Agent programs and messaging platforms.

Process and security requirements

  • Run one AstraBox application per Python process. Provider registries, selected defaults, services, and background workers are process-wide.
  • Use one long-lived event loop. Database clients and background tasks are bound to the loop that enters the lifespan.
  • Enter and exit the AstraBox lifespan once. The parent owns process signals; the AstraBox lifespan owns its service shutdown.
  • Configure AstraBox authentication and authorization normally. Sharing a process does not grant the host application's users access to AstraBox resources.
  • Keep ASTRABOX_ALLOWED_HOSTS, TLS, callback addresses, model access, and sandbox networking consistent with the hostname used for the embedded app.
  • If the host requires a different event-loop policy, configure the ASGI server before it starts AstraBox. uvicorn[standard] may otherwise select uvloop.

Before release, exercise startup, login, one Agent task and its stream, scheduled work when configured, readiness during shutdown, and final process exit using the same ASGI layout used in production.