Skip to main content

Extending the FastAPI App

Parlant exposes its functionality through a FastAPI application. While the built-in API covers most use cases, you may need to add custom endpoints, middleware, or other extensions for your specific deployment.

The configure_api Hook​

The Server class accepts a configure_api parameter: an async function that receives the FastAPI app instance. This hook is called after Parlant's built-in routes and middleware are configured, giving you full access to extend the application.

from fastapi import FastAPI

async def configure_api(app: FastAPI) -> None:
# Add your customizations here
pass

async with p.Server(configure_api=configure_api) as server:
await server.serve()

Adding Custom Endpoints​

You can add custom routes directly to the FastAPI app:

from fastapi import FastAPI

async def configure_api(app: FastAPI) -> None:
@app.get("/custom/health")
async def custom_health_check() -> dict[str, object]:
return {"status": "healthy", "custom": True}

@app.post("/custom/webhook")
async def handle_webhook(payload: dict[str, object]) -> dict[str, object]:
# Process incoming webhook
return {"received": True}

This is useful for:

  • Custom health checks with application-specific logic
  • Webhook endpoints for external integrations
  • Internal debugging or admin endpoints
  • Metrics endpoints for custom monitoring

Adding Middleware​

You can add HTTP middleware to intercept and modify requests and responses:

from fastapi import FastAPI, Request, Response
from typing import Callable, Awaitable

async def configure_api(app: FastAPI) -> None:
@app.middleware("http")
async def custom_middleware(
request: Request,
call_next: Callable[[Request], Awaitable[Response]]
) -> Response:
# Pre-processing
print(f"Request: {request.method} {request.url.path}")

response = await call_next(request)

# Post-processing
response.headers["X-Custom-Header"] = "my-value"
return response

Common middleware use cases:

  • Request logging and timing
  • Adding custom headers
  • Request validation or transformation
  • Custom authentication layers

Customizing CORS​

CORS (Cross-Origin Resource Sharing) middleware is ideally something you'd configure through the AuthorizationPolicy class.

Both the built-in DevelopmentAuthorizationPolicy and ProductionAuthorizationPolicy allow all origins by default, but you can customize this by overriding your policy's configure_app method.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

class CustomAuthorizationPolicy(p.ProductionAuthorizationPolicy):
async def configure_app(self, app: FastAPI) -> FastAPI:
# Add restrictive CORS for production
app.add_middleware(
CORSMiddleware,
allow_origins=[
"https://your-app.com",
"https://admin.your-app.com",
],
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Authorization", "Content-Type"],
)
return app

Then register your custom policy:

async def configure_container(container: p.Container) -> p.Container:
container[p.AuthorizationPolicy] = CustomAuthorizationPolicy()
return container

async with p.Server(configure_container=configure_container) as server:
await server.serve()

Note that the configure_app method runs before the configure_api hook, so any middleware you add there will be applied first. This is the recommended approach for CORS configuration since it integrates with Parlant's authorization system.

github Need help extending the API?