4

I am using a middleware to print the HTTP request body to avoid print statements in every function. However, there is no response from fastapi when running the client code.

The server is simplified to the code below:

import typing

import uvicorn
from fastapi import FastAPI
from fastapi import Request, Body

app = FastAPI()


@app.middleware('http')
async def debug_request(request: Request, call_next):
    _body = await request.body()
    print(_body)
    #
    response = await call_next(request)
    return response


@app.put("/")
def _(
    _body: typing.Dict
):
    # print(_body)  # this statement is replaced by the middleware
    return {"detail": "ok"}


if __name__ == '__main__':
    uvicorn.run(app, host='localhost', port=8000)

The client code is given below:

import requests

_url = 'http://localhost:8000/'
_json = {
    'row_id': '1'
}
resp = requests.put(_url, json=_json)
if not resp.ok:
    print('http-code: ', resp.status_code)
print('http-response: ', resp.text)
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Hobin C.
  • 671
  • 1
  • 8
  • 17

1 Answers1

5

I don't have a solution for this yet, but, I have spent a fair amount of time stuck in this hanging issue (for critical apps in my org which have multiple custom MDW). This hanging is basically because @app.middleware("http") based middlewares, are in back-end created by inheriting from Starlette's BaseHTTPMiddleware. So this problem also exists for MDWs written by inheriting from BaseHTTPMiddleware explicitly. The reasons for this are quite complex and this is what I have understood so far:

  1. from here (GitHub Starlette Issue) and here (Github FastAPI Issue): I learnt that this method uses StreamingResponse which has some issues
  2. from here (GitHub Starlette Issue): I learnt that one of the reasons for hanging is: awaiting request.json() is allowed only once in request life-cycle in API, and BaseHTTPMiddleware also creates a Request object on its own (which causes hanging issue, since that is another request)

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)

raghavsikaria
  • 867
  • 17
  • 30
  • There is a solution in [issue-comment](https://github.com/tiangolo/fastapi/issues/394#issuecomment-927272627). – Hobin C. Apr 11 '22 at 00:56
  • The solution is not universal and works only if you have 1 custom middleware, and it is placed as the last middleware (as mentioned later in the comments). Plus it failed my use-case where we have multiple mdws in our app. – raghavsikaria Apr 11 '22 at 06:39