Skip to content

Instantly share code, notes, and snippets.

@Ronserruya
Created April 13, 2020 09:51
Show Gist options
  • Select an option

  • Save Ronserruya/75cd899307393fc1825b9c5cdb038187 to your computer and use it in GitHub Desktop.

Select an option

Save Ronserruya/75cd899307393fc1825b9c5cdb038187 to your computer and use it in GitHub Desktop.
Access starlette response in middleware
class JsonResponseMiddleware(BaseHTTPMiddleware):
# BaseHTTPMiddleware returns a streaming response that can't be consumed in the middleware
# Instead we consume it here and create a JsonResponse that can be consumed multiple times
async def call_next(self, request: Request) -> Response:
loop = asyncio.get_event_loop()
queue = asyncio.Queue() # type: asyncio.Queue
scope = request.scope
receive = request.receive
send = queue.put
async def coro() -> None:
try:
await self.app(scope, receive, send)
finally:
await queue.put(None)
task = loop.create_task(coro())
message = await queue.get()
if message is None:
task.result()
raise RuntimeError("No response returned.")
assert message["type"] == "http.response.start"
body = (await queue.get())['body'].decode()
task.result()
response = JSONResponse(
status_code=message["status"], content=json.loads(body)
)
response.raw_headers = message["headers"]
return response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment