Description
Aikido Zen v1.2.32 patches starlette.routing.request_response for route discovery (post_response hook), but FastAPI defines its own request_response in fastapi/routing.py (line 97). APIRoute.__init__ uses the FastAPI copy, not Starlette's.
This means pre_response and post_response hooks never fire for FastAPI API endpoints — route discovery, API spec generation, and per-route IP blocking are silently skipped.
Evidence
import aikido_zen
aikido_zen.protect()
import starlette.routing
import fastapi.routing
print(hasattr(starlette.routing.request_response, '__wrapped__')) # True ✅
print(hasattr(fastapi.routing.request_response, '__wrapped__')) # False ❌
Only docs endpoints (/openapi.json, /docs, /redoc) that use starlette.routing.Route directly get the wrapper applied. All @app.get/@app.post endpoints using APIRoute are unpatched.
SYNC_DATA consistently shows current_routes: {} even with active API traffic.
Root Cause
FastAPI's fastapi/routing.py defines its own request_response function (copy of Starlette's with AsyncExitStack additions), rather than importing from starlette.routing. Aikido's @on_import("starlette.routing") hook only patches the Starlette module.
The Fix I Applied (Works in Production)
After protect(), patch FastAPI's copy with the same wrapper:
import fastapi.routing
from aikido_zen.sources.starlette.starlette_routing import _request_response
from aikido_zen.sinks import patch_function
patch_function(fastapi.routing, "request_response", _request_response)
After deploying this to production, all FastAPI endpoints are discovered correctly with auto-generated API specs, query parameter detection, and auth scheme detection. Route discovery, user tracking, and middleware integration all work as expected.
The same approach should be added natively via a @on_import("fastapi.routing", "fastapi") hook.
Environment
- aikido-zen: 1.2.32
- fastapi: 0.135.2
- starlette: 1.0.0
- Python: 3.13
Description
Aikido Zen v1.2.32 patches
starlette.routing.request_responsefor route discovery (post_responsehook), but FastAPI defines its ownrequest_responseinfastapi/routing.py(line 97).APIRoute.__init__uses the FastAPI copy, not Starlette's.This means
pre_responseandpost_responsehooks never fire for FastAPI API endpoints — route discovery, API spec generation, and per-route IP blocking are silently skipped.Evidence
Only docs endpoints (
/openapi.json,/docs,/redoc) that usestarlette.routing.Routedirectly get the wrapper applied. All@app.get/@app.postendpoints usingAPIRouteare unpatched.SYNC_DATA consistently shows
current_routes: {}even with active API traffic.Root Cause
FastAPI's
fastapi/routing.pydefines its ownrequest_responsefunction (copy of Starlette's withAsyncExitStackadditions), rather than importing fromstarlette.routing. Aikido's@on_import("starlette.routing")hook only patches the Starlette module.The Fix I Applied (Works in Production)
After
protect(), patch FastAPI's copy with the same wrapper:After deploying this to production, all FastAPI endpoints are discovered correctly with auto-generated API specs, query parameter detection, and auth scheme detection. Route discovery, user tracking, and middleware integration all work as expected.
The same approach should be added natively via a
@on_import("fastapi.routing", "fastapi")hook.Environment