FastAPI
Add TapPassMiddleware to a FastAPI app. Per-request TapPass sessions are managed automatically. Governance decisions from route handlers are mapped to typed HTTP status codes.
Install
Section titled “Install”pip install 'tappass[fastapi]'Add the middleware
Section titled “Add the middleware”from fastapi import FastAPIfrom tappass.integrations.fastapi import TapPassMiddleware
app = FastAPI()app.add_middleware( TapPassMiddleware, tappass_url="https://tappass.example.com", api_key="tp_...", auto_open_session=False, # default: join caller's session from headers)
# Governance decisions from handlers are mapped to typed HTTP responses:# PolicyBlockError → 403, ApprovalRequired → 428, BreakGlassActive → 503.Decision → HTTP status mapping
Section titled “Decision → HTTP status mapping”| Exception | HTTP status | Notes |
|---|---|---|
PolicyBlockError | 403 | Body includes blocked_by, reason, audit_url |
ApprovalRequired | 428 | Body includes approval_url, resume_token, expires_at |
TrustTierDenied | 403 | Body includes required_tier, actual_tier |
BreakGlassActive | 503 | Body includes level, expires_at |
ToolIntegrityViolation | 422 | Body includes tool_name, violation |
Correlation propagation
Section titled “Correlation propagation”Incoming requests carrying X-TapPass-Session-Id / X-TapPass-Agent-Uuid headers automatically join the existing TapPass session. Outgoing responses carry the same headers so downstream services can continue the correlation chain.
Set auto_open_session=True to open a fresh TapPass session for every request that doesn’t already carry correlation headers.
Using the governed agent in route handlers
Section titled “Using the governed agent in route handlers”from fastapi import FastAPI, Dependsfrom tappass import Agent, current_session
app = FastAPI()# middleware added as above
def get_agent() -> Agent: return Agent("https://tappass.example.com", api_key="tp_...")
@app.post("/chat")def chat(prompt: str, agent: Agent = Depends(get_agent)): response = agent.chat(prompt) session = current_session() return {"content": response.content, "audit_url": session.audit_url if session else None}Migrating from 0.5
Section titled “Migrating from 0.5”The 0.5 manual try/except PolicyBlockError → raise HTTPException pattern is replaced by TapPassMiddleware which handles all GovernanceDecision subclasses and maps them to typed HTTP responses automatically. See the migration guide.