I have this endpoint in my API which calls another endpoint in another API. I'm just returning the received response to the client, but sometimes the client is actually receiving a different status_code
than the one I'm passing in the return
statement.
I'm doing it something like this (using FastAPI):
@router.post("/my_endpoint")
async def my_method():
...
response = requests.post(url=<url_to_the_other_api>, headers=headers, timeout=10)
return response.json()
The client is sometimes receiving an error message but still with status_code
200. I thought I was returning the same received response object, but apparently not.
May someone please explain it?
I thought json()
method or FastAPI could be creating a new response
object and just using the old body. Is that what happens? This behavior is quite unclear to me.
When using return response.json()
you are just returning the content of the response
that you are getting from the request issued using Python requests
to <the_other_api>
. FastAPI, behind the scenes, will then put the JSON data into a JSONResponse
and reuturn it back to the client using a status_code
value of 200
(see this answer for more details).
If you would like to use the status_code
(as well as the media_type
/content-type
) returned in the response from <the_other_api>
, you could then return a custom Response directly.
from fastapi import FastAPI, Response
import requests
app = FastAPI()
@app.get('/')
def root():
# returns 400 Error Not Found Response (for testing purposes)
#r = requests.get(url='http://httpbin.org/NotValidRoute')
# reurns 200 Successful Response
r = requests.get(url='http://httpbin.org/json')
return Response(content=r.content, media_type=r.headers['content-type'], status_code=r.status_code)
I would, however, strongly recommend using the httpx
library instead of requests
(httpx
has very similar syntax to requests
, is easy to use and provides async
support), as demonstrated in this answer, as well as here and here. If you would rather keep using requests
, please make sure to define the endpoint with normal def
(as shown in the exmaple above) not async def
(as shown in your question)—have a look at this answer for more details as to why.