Hello
The FastAPI SQLCommenterMiddleware currently breaks FastAPI's openapi feature (see the log message at the end).
This is because this route uses a starlette.routing.Route (FastAPI is built on top of Starlette), which does not have the "route" info used in the code.
I think the easiest fix here would be to return child_scope.get("route") instead, so that if we find a matching child_scope but it lacks the info we're looking for the middleware simply returns no route info rather than crash.
Happy to create a merge request if this solution is OK with you.
Possible implementation of a currently failing test:
# in tests/fastapi/test.py
def test_get_docs_does_not_throw(client):
resp = client.get(app.docs_url)
assert resp.status_code == 200
{
"severity": "ERROR",
"name": "uvicorn.error",
"message": "Exception in ASGI application\n",
"module": "httptools_impl",
"process": 1626484,
"processName": "MainProcess",
"pathname": "<..>/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py",
"lineno": 378,
"labels": {
"app_name": "profile_api",
"version": "1.14.0+query_insights.1"
},
"serviceContext": {
"service": "profile_api",
"version": "1.14.0+query_insights.1"
},
"stack_trace": "Traceback (most recent call last):
File \"<..>/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 375, in run_asgi
result = await app(self.scope, self.receive, self.send)
File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__
return await self.app(scope, receive, send)
File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py\", line 82, in __call__
raise exc from None
File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py\", line 78, in __call__
await self.app(scope, inner_receive, inner_send)
File \"<..>/lib/python3.8/site-packages/fastapi/applications.py\", line 269, in __call__
await super().__call__(scope, receive, send)
File \"<..>/lib/python3.8/site-packages/starlette/applications.py\", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File \"<..>/lib/python3.8/site-packages/starlette/middleware/errors.py\", line 184, in __call__
raise exc
File \"<..>/lib/python3.8/site-packages/starlette/middleware/errors.py\", line 162, in __call__
await self.app(scope, receive, _send)
File \"<..>/lib/python3.8/site-packages/opentelemetry/instrumentation/asgi/__init__.py\", line 459, in __call__
await self.app(scope, otel_receive, otel_send)
File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 69, in __call__
info = _get_fastapi_info(fastapi_app, scope)
File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 84, in _get_fastapi_info
route = _get_fastapi_route(fastapi_app, scope)
File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 98, in _get_fastapi_route
return child_scope[\"route\"]
KeyError: 'route'",
"timestamp": "2022-05-27T08:23:55.549322+00:00"
}
Hello
The FastAPI
SQLCommenterMiddlewarecurrently breaks FastAPI's openapi feature (see the log message at the end).This is because this route uses a
starlette.routing.Route(FastAPI is built on top of Starlette), which does not have the"route"info used in the code.I think the easiest fix here would be to return
child_scope.get("route")instead, so that if we find a matchingchild_scopebut it lacks the info we're looking for the middleware simply returns no route info rather than crash.Happy to create a merge request if this solution is OK with you.
Possible implementation of a currently failing test:
{ "severity": "ERROR", "name": "uvicorn.error", "message": "Exception in ASGI application\n", "module": "httptools_impl", "process": 1626484, "processName": "MainProcess", "pathname": "<..>/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", "lineno": 378, "labels": { "app_name": "profile_api", "version": "1.14.0+query_insights.1" }, "serviceContext": { "service": "profile_api", "version": "1.14.0+query_insights.1" }, "stack_trace": "Traceback (most recent call last): File \"<..>/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 375, in run_asgi result = await app(self.scope, self.receive, self.send) File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__ return await self.app(scope, receive, send) File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py\", line 82, in __call__ raise exc from None File \"<..>/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py\", line 78, in __call__ await self.app(scope, inner_receive, inner_send) File \"<..>/lib/python3.8/site-packages/fastapi/applications.py\", line 269, in __call__ await super().__call__(scope, receive, send) File \"<..>/lib/python3.8/site-packages/starlette/applications.py\", line 124, in __call__ await self.middleware_stack(scope, receive, send) File \"<..>/lib/python3.8/site-packages/starlette/middleware/errors.py\", line 184, in __call__ raise exc File \"<..>/lib/python3.8/site-packages/starlette/middleware/errors.py\", line 162, in __call__ await self.app(scope, receive, _send) File \"<..>/lib/python3.8/site-packages/opentelemetry/instrumentation/asgi/__init__.py\", line 459, in __call__ await self.app(scope, otel_receive, otel_send) File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 69, in __call__ info = _get_fastapi_info(fastapi_app, scope) File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 84, in _get_fastapi_info route = _get_fastapi_route(fastapi_app, scope) File \"<..>/lib/python3.8/site-packages/google/cloud/sqlcommenter/fastapi.py\", line 98, in _get_fastapi_route return child_scope[\"route\"] KeyError: 'route'", "timestamp": "2022-05-27T08:23:55.549322+00:00" }