1

I am trying to write a FastAPI middleware to add a header to a response. The contents of the header is based on the value of the response body. This is what I have so far:

from starlette.middleware.base import BaseHTTPMiddleware

class FooMiddleware(BaseHTTPMiddleware):

    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        response.headers["X-Foo"] = Foo(response.content)
        return response

According to the docs, FastAPI returns JSON responses as a default (https://fastapi.tiangolo.com/advanced/custom-response/?h=stream#jsonresponse), and I have done nothing to override that.

The strange thing is that the type of the response object seems to be StreamingResponse (https://fastapi.tiangolo.com/advanced/custom-response/?h=stream#streamingresponse). What is causing that?

Alex
  • 2,270
  • 3
  • 33
  • 65
  • This seems odd, but without the code of the endpoint, it is difficoult to say anything. Do you mind sharing it? – lsabi Oct 23 '22 at 20:16
  • Any response inside of the _middleware_ will be a StreamingResponse: https://github.com/encode/starlette/blob/040d8c86b09f34be49e8c253d97a588973bc7308/starlette/middleware/base.py#L98 - as this is what `call_next` returns. I'm guessing when you get this far any response has been converted to a read that can be awaited. Your middleware shouldn't depend on the _response type_ itself returned from your view. – MatsLindh Oct 23 '22 at 21:28
  • @MatsLindh How would I go about awaiting the (async generator type) `response.body_iterator`? I've tried awaiting it, which is an error. – Alex Oct 23 '22 at 23:19
  • Have you seen https://github.com/encode/starlette/issues/874 (and https://stackoverflow.com/questions/64115628/get-starlette-request-body-in-the-middleware-context - they're generally the same problem) ? – MatsLindh Oct 24 '22 at 06:18
  • See [relate answer](https://stackoverflow.com/a/73464007/17865804) as well. – Chris Oct 24 '22 at 06:20

0 Answers0