response_modelCreating a Pydantic model that has a field with an arbitrary class will raise RuntimeError stating that there is no validator for class ArbitraryClass:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class ArbitraryClass:
def __init__(self, attr: str) -> None:
self.attr = attr
class SomeModel(BaseModel):
name: str = 'SomeModel'
arbitrary_field: ArbitraryClass
class Config:
arbitrary_types_allowed = True
@app.get('/')
async def return_model_with_arbitrary_type():
model = SomeModel(arbitrary_field=ArbitraryClass('attr_value'))
return model
response_model specifiedThis works fine, since Pydantic allows creation of models where fields have arbitrary types when we use arbitrary_types_allowed in Config. The returned JSON is also nicely formatted, asattribute: value pair:
{
"name": "SomeModel",
"arbitrary_field": {
"attr": "attr_value"
}
}
response_modelWhen we try to specify that the response model for this endpoint is SomeModel:
@app.get('/', response_model=SomeModel)
async def return_model_with_arbitrary_type():
model = SomeModel(arbitrary_field=ArbitraryClass('attr_value'))
return model
We get an error:
Traceback (most recent call last):
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/utils.py", line 65, in create_response_field
return response_field(field_info=field_info)
File "pydantic/fields.py", line 284, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 362, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 538, in pydantic.fields.ModelField.populate_validators
File "pydantic/validators.py", line 629, in find_validators
RuntimeError: no validator found for <class 'backend.main.ArbitraryClass'>, see `arbitrary_types_allowed` in Config
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/Users/fisheye36/Projects/fastapi-issue/src/backend/__main__.py", line 1, in <module>
from backend.main import run_server
File "/Users/fisheye36/Projects/fastapi-issue/src/backend/main.py", line 37, in <module>
async def return_model_with_arbitrary_type():
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/routing.py", line 494, in decorator
self.add_api_route(
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/routing.py", line 439, in add_api_route
route = route_class(
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/routing.py", line 315, in __init__
] = create_cloned_field(self.response_field)
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/utils.py", line 91, in create_cloned_field
use_type.__fields__[f.name] = create_cloned_field(
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/utils.py", line 94, in create_cloned_field
new_field = create_response_field(name=field.name, type_=use_type)
File "/Users/fisheye36/Projects/fastapi-issue/.env/lib/python3.8/site-packages/fastapi/utils.py", line 67, in create_response_field
raise fastapi.exceptions.FastAPIError(
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'backend.main.ArbitraryClass'> is a valid pydantic field type
Pydantic allows models like that. FastAPI also allows returning models like that and handles them well. The only problem here is something wrong happens when that kind of model is specified as a response model.
I know I could create validators for ArbitraryClass, but what if the class is coming from some other library and I can't edit its source?
I am running into this as well. This was also previously reported here but the issue was closed before resolved.
Strange, I was searching for similar issues but couldn't find any.
The comment here seems interesting: https://github.com/tiangolo/fastapi/issues/1186#issuecomment-667780031
@tiangolo could you please take a look at the issue I reported? It seems that @bcb's comment was overlooked. Also, my explanation here is more understandable (and easily reproducible) than in #1186.
Most helpful comment
I am running into this as well. This was also previously reported here but the issue was closed before resolved.