fastapi
fastapi copied to clipboard
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'starlette.responses.JSONResponse'> is a valid pydantic field type
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
import logging
from fastapi import APIRouter
from fastapi.responses import JSONResponse
liveness = True
router = APIRouter()
@router.get(
"/livez",
summary="Liveness probe",
description="Returns 200 if the service is alive",
)
async def get_liveness() -> JSONResponse:
logging.debug("GET /livez")
if liveness:
return JSONResponse(status_code=200, content={"status": "ok"})
else:
return JSONResponse(status_code=500, content={"status": "not ok"})
Description
With version 0.88.0, my unit tests run fine, I get no error. With version 0.89.0, I get the following error:
/root/.pyenv/versions/3.8/lib/python3.8/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
???
<frozen importlib._bootstrap>:991: in _find_and_load
???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
???
<frozen importlib._bootstrap>:671: in _load_unlocked
???
/root/.pyenv/versions/3.8/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
exec(co, module.__dict__)
tests/models/conftest.py:7: in <module>
from my_sample_lib.main import app
my_sample_lib/main.py:10: in <module>
from my_sample_lib.health.router import router as health_router
my_sample_lib/health/router.py:24: in <module>
async def get_liveness() -> JSONResponse:
/root/.pyenv/versions/3.8/lib/python3.8/site-packages/fastapi/routing.py:633: in decorator
self.add_api_route(
/root/.pyenv/versions/3.8/lib/python3.8/site-packages/fastapi/routing.py:572: in add_api_route
route = route_class(
/root/.pyenv/versions/3.8/lib/python3.8/site-packages/fastapi/routing.py:400: in __init__
self.response_field = create_response_field(
/root/.pyenv/versions/3.8/lib/python3.8/site-packages/fastapi/utils.py:90: in create_response_field
raise fastapi.exceptions.FastAPIError(
E fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'starlette.responses.JSONResponse'> is a valid pydantic field type
The only way I found to get rid of the error is to remove the type hint, which I don't really want. Also, I tried to follow the guidelines provided in your documentation without success.
Interestingly, the whole thing works fine (with the type hint and fastapi 0.89.0) under Windows 10. Under Ubuntu 22.10, it doesn't work at all (i.e. it provides the above message).
Operating System
Linux
Operating System Details
Under Windows 10, it works like a charm. Under Ubuntu 22.10, it fails with the provided error above.
FastAPI Version
0.89.0
Python Version
3.8.12
Additional Context
It is also failing with python 3.9, and 3.10.
I encountered the same error with response classes
@zadigus You can specify response_model
manually but I'm not sure if that's correct here 🤔
pydantic does not recognize JSONReponse
as being a valid field type, pydantic documentation says to add arbitrary_types_allowed
in the Config
to allow for arbitrary user types: (https://docs.pydantic.dev/usage/model_config/)
whether to allow arbitrary user types for fields (they are validated simply by checking if the value is an instance of the type). If False, RuntimeError will be raised on model declaration (default: False). See an example in Field Types.
The issue happens in fastapi.utils.create_response_field
which calls pydantic.fields.ModelField
(partially), it passes down model_config=pydantic.config.BaseConfig
as a default value.
Perhaps fastapi needs to add a way to pass custom config class when constructing the APIRoute
to be passed down to create_response_field
class MyConfig:
arbitrary_types_allowed = True
pydantic does not recognize
JSONReponse
as being a valid field type, pydantic documentation says to addarbitrary_types_allowed
in theConfig
to allow for arbitrary user types: (https://docs.pydantic.dev/usage/model_config/)whether to allow arbitrary user types for fields (they are validated simply by checking if the value is an instance of the type). If False, RuntimeError will be raised on model declaration (default: False). See an example in Field Types.
The issue happens in
fastapi.utils.create_response_field
which callspydantic.fields.ModelField
(partially), it passes downmodel_config=pydantic.config.BaseConfig
as a default value. Perhaps fastapi needs to add a way to pass custom config class when constructing theAPIRoute
to be passed down tocreate_response_field
class MyConfig: arbitrary_types_allowed = True
I think adding arbitrary_types_allowed=True
would only cause Response
to be interpreted as
content: Any
status_code: int
headers: ...
...
(As in Response.__init__
), and what would be preferred is either fastapi recognizing Response
subclasses or mentioning it in documentation and recommending a workaround (for example passing response_model=None
explicitly)
Same issue here, it is only checking for instances of pydantic.fields.ModelField
, and ignoring instances of starlette.responses.Response
, where comes from JSONResponse
...
It is also failing with python 3.9, and 3.10.
And 3.11
Pretty sure it's a regression in release 0.89, since its only new feature deals with response_model
s: https://github.com/tiangolo/fastapi/pull/1436.
EDIT: Forgot to mention: my code worked with 0.88, but doesn't with 0.89, which is why I'm sure it's the culprit.
Looks like a regression. Try with 0.88 if the issue exist?
Yes, 0.88 works as expected.
Small script to reproduce:
- python 3.11
- FastAPI 0.89
from fastapi import FastAPI, Response
app = FastAPI(debug=True)
@app.get("/plain-text")
def plain_text() -> Response:
return Response(content="bla", media_type="text/plain")
Running this with python main.py
will show this error.
Traceback (most recent call last):
File "../fastapi-regression/main.py", line 7, in <module>
@app.get("/plain-text")
^^^^^^^^^^^^^^^^^^^^^^
File "../fastapi-regression/venv/lib/python3.11/site-packages/fastapi/routing.py", line 633, in decorator
self.add_api_route(
File "../fastapi-regression/venv/lib/python3.11/site-packages/fastapi/routing.py", line 572, in add_api_route
route = route_class(
^^^^^^^^^^^^
File "../fastapi-regression/venv/lib/python3.11/site-packages/fastapi/routing.py", line 400, in __init__
self.response_field = create_response_field(
^^^^^^^^^^^^^^^^^^^^^^
File "../fastapi-regression/venv/lib/python3.11/site-packages/fastapi/utils.py", line 90, in create_response_field
raise fastapi.exceptions.FastAPIError(
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'starlette.responses.Response'> is a valid pydantic field type
@hofrob with a test case so small, you'd have to wonder why the tests haven't catched this before release.
This issue should be fixed by https://github.com/tiangolo/fastapi/pull/5855
@hofrob with a test case so small, you'd have to wonder why the tests haven't catched this before release.
I guess we're all invited to add tests and fixes to this project. :shrug:
This issue should be fixed by #5855
The pr sets response_model=None
for Response
subclasses, I wonder if there is way to support subclasses of Response
Thanks for the report and discussion everyone! :coffee:
The simple use case of a single Response
class is now supported in FastAPI 0.89.1 (just release) :tada:
And for the other use cases where you want to have more complex type annotations (e.g. unions, other types), you can use response_model=None
.
There's a lot of new docs about it here: https://fastapi.tiangolo.com/tutorial/response-model/#other-return-type-annotations
Also, this is sort of a duplicate of https://github.com/tiangolo/fastapi/issues/5857 (it's the same issue underneath).
Fastapi version 0.89.1 solves the issue in my codebase.
Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.
I have the same issue To resolve this issue I found only one way:
-
pip show fastapi
: Version: 0.101.0 -
pip uninstall fastapi
- Then I modified my
requirements.txt
fromfastapi
tofastapi==0.88
-
pip install -r requirements.txt
-
pip uninstall fastapi
- Then I modified my
requirements.txt
again fromfastapi==0.88
tofastapi
-
pip install -r requirements.txt
And now my server runs without error...
I think we should open a new issue, but I am also reproducing, using fastapi 0.103.1, and migrating from pydantic v1 to pydantic v2 (2.4.1, tried with 2.2.1 as well)
I think we should open a new issue, but I am also reproducing, using fastapi 0.103.1, and migrating from pydantic v1 to pydantic v2 (2.4.1, tried with 2.2.1 as well)
Please create a discussion. This issue was solved.