[BUG] python-fastapi: free-form objects cause a pydantic failure
Created by: chludwig-haufe
Description
I gave the (beta) python-fastapi generator a try on a PoC API. The API's response model contains some free-form object attributes like the following:
definition:
# ...
SearchSortCriteria:
type: object
SearchResultPaging:
type: object
SearchQuery:
properties:
searchTerm:
type: string
page:
$ref: '#/definitions/SearchResultPaging'
sorting:
$ref: '#/definitions/SearchSortCriteria'
(Obviously, the API definition needs some more work, but that's besides the point.)
The generator python-fastapi
translates this into the following Python module :
# coding: utf-8
from datetime import date, datetime # noqa: F401
import re # noqa: F401
from typing import Dict, List, Optional # noqa: F401
from pydantic import AnyUrl, BaseModel, EmailStr, validator # noqa: F401
class SearchQuery(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
SearchQuery - a model defined in OpenAPI
search_term: The search_term of this SearchQuery [Optional].
page: The page of this SearchQuery [Optional].
sorting: The sorting of this SearchQuery [Optional].
"""
search_term: Optional[str] = None
page: Optional[object] = None
sorting: Optional[object] = None
This module fails to import with an error as follows (stack trace shortened):
Traceback (most recent call last):
File "/Users/ludwigc/.pyenv/versions/search-middleware/bin/uvicorn", line 8, in <module>
sys.exit(main())
File "/Users/ludwigc/.pyenv/versions/3.9.5/envs/search-middleware/lib/python3.9/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
[...]
File "/Users/ludwigc/.pyenv/versions/3.9.5/lib/python3.9/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
[...]
File "/Users/ludwigc/search-middleware/src/aurora/middleware/search/models/search_query.py", line 13, in <module>
class SearchQuery(BaseModel):
File "pydantic/main.py", line 299, in pydantic.main.ModelMetaclass.__new__
File "pydantic/fields.py", line 411, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 342, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 456, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 670, in pydantic.fields.ModelField.populate_validators
File "pydantic/validators.py", line 715, in find_validators
RuntimeError: no validator found for <class 'object'>, see `arbitrary_types_allowed` in Config
openapi-generator version
Head of master branch as of June 8, 2021 (c379f5bc)
Suggest a fix
Adding a Pydantic Config
class to each model class that allows arbitrary types does not feel right. That's an escape hatch that should be used only where indeed needed.
IMHO, the “correct” type hint for such free-form objects is Dict[str, Any]
.