-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
This week I was working in something related with the BaseHTTPMiddleware where due to the StreamingResponse and in some production settings, it can transform your async REST API in a totally sync one. The context is here in this post [1]:
The last link also mentions that what also causes the hanging issue, is that, because of StreamingResponse; the reading of response somehow gets exhausted in the first read, and when it comes to the second read, it keeps on waiting for it indefinitely which causes the hanging. (first and second read here means: in ASGI APPs, messages are sent to-and-from client & APP with various types like http.response.start, http.response.body etc)
To avoid it, one could instead of using the BaseHTTPMiddleware use the pure AGSI:
from starlette.types import ASGIApp, Receive, Send, Message
class LogResponseMDW:
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send):
async def send_wrapper(message: Message):
# This will capture response coming from APP Layer
# You will want to check for message["type"] first
# response body will be in message where the type is
# "http.response.body"
print(f"message: {message}") # log here, after checking the message type
await send(message)
await self.app(scope, receive, send_wrapper)
# you can add this to your app this way:
app.add_middleware(LogResponseMDW)