Unavailability to set `default` response for OpenAPI doc at `0.79.0`
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the FastAPI documentation, with the integrated search.
- [X] I already searched in Google "How to X in FastAPI" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to FastAPI but to Pydantic.
- [X] I already checked if it is not related to FastAPI but to Swagger UI.
- [X] I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel
class Item(BaseModel):
id: str
value: str
class Message(BaseModel):
message: str
app = FastAPI()
@app.get("/items/{item_id}", response_model=Item, responses={"default": {"model": Message}})
async def read_item(item_id: str):
if item_id == "foo":
return {"id": "foo", "value": "there goes my hero"}
else:
return JSONResponse(status_code=404, content={"message": "Item not found"})
Description
Prior to 0.79.0 I was able to specify the default response for the path. According to the OpenAPI Spec, it should be somehow possible: https://swagger.io/specification/#path-item-object
At 0.79.0 I am receiving this exception:
Traceback (most recent call last):
File "<stdin>", line 19, in <module>
File "/Users/matnowak/.pyenv/versions/3.9.11/envs/radkit3.9/lib/python3.9/site-packages/fastapi/routing.py", line 622, in decorator
self.add_api_route(
File "/Users/matnowak/.pyenv/versions/3.9.11/envs/radkit3.9/lib/python3.9/site-packages/fastapi/routing.py", line 561, in add_api_route
route = route_class(
File "/Users/matnowak/.pyenv/versions/3.9.11/envs/radkit3.9/lib/python3.9/site-packages/fastapi/routing.py", line 418, in __init__
assert is_body_allowed_for_status_code(
File "/Users/matnowak/.pyenv/versions/3.9.11/envs/radkit3.9/lib/python3.9/site-packages/fastapi/utils.py", line 24, in is_body_allowed_for_status_code
current_status_code = int(status_code)
ValueError: invalid literal for int() with base 10: 'default'
invalid literal for int() with base 10: 'default'
How to set the default response in OpenAPI?
Operating System
Linux, Windows, macOS
Operating System Details
No response
FastAPI Version
0.79.0
Python Version
3.9.11
Additional Context
No response
default response_code is 200, you need to specify status code instead of default keyword
@kalmastenitin As you can see in the spec example: https://swagger.io/specification/#path-item-object besides 200 there is the option to specify the default.
If I will rephrase the question here, it will be: how to recreate the same structure as presented in OpenAPI examples from fastapi point of view?
"default" response is a specifier for any status code that doesn't have an entry. It usually is for specifying the schema of error responses
Hi! We are also seeing this issue. We are initializing FastAPI with a default response for unexpected error responses for OpenAPI spec:
FastAPI(..., responses={"default": {"model": UnexpectedErrorResponse}})
After updating to 0.79.0 this breaks with similar exception as above.
See OpenAPI specification for "default" responses: https://swagger.io/docs/specification/describing-responses/#default previously this was possible to define it in FastAPI but it is now broken.
This PR seems the one that broke the OpenAPI default-response definitions: https://github.com/tiangolo/fastapi/pull/5145 cc @tiangolo
@MarkusSintonen Thanks for the answer. I am glad that someone else is also seeing this as a potential bug. I will try to propose a fix for this.
Hi!
We are also facing this issue. We are using default as status code for error responses too.
Also things like 5XX (see Swagger Docs) should be valid values.
Changing the function is_body_allowed_for_status_code could fix this issue. Maybe something like this:
def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
if status_code is None:
return True
if isinstance(status_code, str) and not status_code.isdigit():
# return 'True' as we cannot know if this response is allowed to have a body
return True
current_status_code = int(status_code)
return not (current_status_code < 200 or current_status_code in {204, 304})
I guess that could work. I would opt for a more specific check though, just to be compliant with the OpenAPI spec. Something in the line of:
def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
if status_code is None or status_code=="default":
return True
current_status_code = int(status_code)
return not (current_status_code < 200 or current_status_code in {204, 304})
@JarroVGIT the OpenAPI spec also allows specifiers of 4XX etc, which your code would still raise the same ValueError on. It's not very nice but at least the default use cases are client/server errors and as such we won't see 2XX 3XX often/at all
My pull request does account for that, it checks various values including the xXX values