fastapi: How to send 204 response?
I tried to send 204 response in delete method
Example handler
@router.delete('/{order_id}/', tags=['smart order'], status_code=204)
async def cancel_smart_order(
session: Session = Depends(get_session),
order_id: UUID = Path(...)
):
order = await session.get(order_id)
if order.status != OrderStatus.open:
raise HTTPException(409, f'Order have status: {order.status}')
order.status = OrderStatus.canceled
await session.commit_only(order)
But got error h11._util.LocalProtocolError: Too much data for declared Content-Length. Seems framefork convert None to null but set content length 0.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 2
- Comments: 27 (6 by maintainers)
Commits related to this issue
- Fix 204 reponse content-length error https://github.com/tiangolo/fastapi/issues/717#issuecomment-583826657 — committed to FigureHook/hook_api by EltonChou 2 years ago
Instead of returning
None, and instead of injecting the response, just return a newly created response. It would look like:The reason you are getting content is because FastAPI uses a
JSONResponseby default (instead of aResponse), which converts the returned valueNoneto"null". By returning aResponsedirectly, you prevent FastAPI from using theJSONResponseand encoding theNone.This is a bug: FastAPI is not conforming to the HTTP RFC: https://tools.ietf.org/html/rfc2616#section-10.2.5
FastAPI should made it difficult to produce an invalid HTTP response, not allowing to create a valid one with a workaround.
Dunno why, but today I ran into the same issue with python3.9. fastapi==0.63.0 and uvicorn==0.13.3, h11==0.12.0 on Debian10:
This helped, just use:
response_class=Responseexample:
Just to mention, I had no issues previously on versions fastapi==0.54.1, uvicorn==0.11.3, h11==0.9.0 (Ubuntu 20.04, python3.8)
the easiest way:
@robmoore and anyone who sees this in the future.
I think the issue you were having is one I also ran into. I was apparently importing this
from starlette.responses import Responseinstead offrom fastapi.responses import ResponseThis solved my issue, anyways.
I think the best way to handle this is @georgealar solution: (aka setting response_class=Response in the decorator)
Hi @dmontagu and @tiangolo
I believe FastAPI can do the right thing here with regards to returning empty body when handler declares its status_code as 204. It’s not a trivial to spot and is a potential time sink. Speaking from the fresh experience - I had a code that did:
It works fine locally, e.g. when browsing localhost with Chrome or FF. Then I deploy to Google Cloud Run and start getting
HTTP 503 Service Unavaialable. Cloud Run is relatively new, so I turn to GCP support and back&forth several hours later I land here to join the club of other devs bit by the same issue.Too bad, what do you think?
The current full fix is as follows:
But even that is not without a quirk - the handler declaration accepts
HTTPStatusenum as is, butResponsedoesn’t resulting in weird HTTP logs likeAgain, too many details to dig into for something I would expect to work out of the box (by high FastAPI standards). Opinions?
@tiangolo I’ve just been reported this bug by mobile devs:
HTTP FAILED: java.net.ProtocolException: HTTP 204 had non-zero Content-Length: 4I believe FastAPI should handle this and set response to
Responseclass ifresponse_codeis set to 204Yep. Just what @dmontagu said ☝️
Not sure why the content-length is wrong; that may be a bug. But if you want to return an actual empty response, just set
response_class=Responsein the route decorator (the default isJSONResponse, which convertsNoneto"null"as you have noticed).@tiangolo It does seem that a lot of lower-level frameworks/tools are explicitly checking for 204s to be empty, and raising errors when they aren’t. The way things are implemented now, it admittedly feels like it would be a little unnatural to automatically modify the response class for just a single value of the return code, but given the extent to which this is special-cased in other tools, maybe it makes sense.
Either way, it probably makes to at least make a note of this behavior in the docs (probably somewhere near this section, which does explicitly discuss the 204 response code: https://fastapi.tiangolo.com/tutorial/response-status-code/#about-http-status-codes).