question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Get response body in Middleware

See original GitHub issue

How do I get the response body from the StreamingResponse object in middleware?

Simple example:

class AccessMiddleware(base.BaseHTTPMiddleware):

    async def dispatch(
        self,
        request: Request,
        handler: base.RequestResponseEndpoint,
    ) -> Response:
        response: StreamingResponse = await handler(request)

        binary = b''
        async for data in response.body_iterator:
            binary += data
        body = binary.decode()
        
        print(body)

        return response  # Here body is empty

Is it possible to copy the response.body_iterator generator?
What is the best way to solve the problem of extracting final data (response body) and further post-processing?

Thanks.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:7

github_iconTop GitHub Comments

7reactions
BC30138commented, Feb 2, 2022

Just because such solution not stated yet, but it’s worked for me:

from typing import Callable, Awaitable

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import StreamingResponse
from starlette.concurrency import iterate_in_threadpool

class LogStatsMiddleware(BaseHTTPMiddleware):
    async def dispatch(  # type: ignore
        self, request: Request, call_next: Callable[[Request], Awaitable[StreamingResponse]],
    ) -> Response:
        response = await call_next(request)
        response_body = [section async for section in response.body_iterator]
        response.body_iterator = iterate_in_threadpool(iter(response_body))
        logging.info(f"response_body={response_body[0].decode()}")
        return response

def init_app(app):
    app.add_middleware(LogStatsMiddleware)

iterate_in_threadpool actually making from iterator object async Iterator

If you look on implementation of starlette.responses.StreamingResponse you’ll see, that this function used exactly for this

1reaction
AmmarAhmadKhancommented, Jun 1, 2022

Just because such solution not stated yet, but it’s worked for me:

from typing import Callable, Awaitable

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import StreamingResponse
from starlette.concurrency import iterate_in_threadpool

class LogStatsMiddleware(BaseHTTPMiddleware):
    async def dispatch(  # type: ignore
        self, request: Request, call_next: Callable[[Request], Awaitable[StreamingResponse]],
    ) -> Response:
        response = await call_next(request)
        response_body = [section async for section in response.body_iterator]
        response.body_iterator = iterate_in_threadpool(iter(response_body))
        logging.info(f"response_body={response_body[0].decode()}")
        return response

def init_app(app):
    app.add_middleware(LogStatsMiddleware)

iterate_in_threadpool actually making from iterator object async Iterator

If you look on implementation of starlette.responses.StreamingResponse you’ll see, that this function used exactly for this

response_body[0].decode() Gives error if we return some fields with value of true or false and says “name true is not defined”. How to get rid of this issue ?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to read ASP.NET Core Response.Body? - Stack Overflow
In the examples below, I'm trying to get the Response.Body value in a custom middleware class. Response.Body is a set only property in...
Read more >
returning-response-body-in-middleware - Next.js
Note: In Next.js v13.0.0 you can now respond to Middleware directly by returning a NextResponse . For more information, see Producing a Response....
Read more >
Request and Response operations in ASP.NET Core
This article explains how to read from the request body and write to the response body. Code for these operations might be required...
Read more >
Getting response headers and body in middleware? : r/golang
I have been trying to find the best way to receive response headers and body when request are made(also request body).
Read more >
Read Request and Response body in ASP.NET Core
Getting started; Create Middleware for Reading the request payload; Enable Middleware in API pipeline; Using ResultFilter. There were a few ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found