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.