Describe the bug
FastAPI fails to generate openapi.json when the schema contains types declared with typing.NewType
To Reproduce
Steps to reproduce the behavior:
failme.py with contents:from typing import NewType
from fastapi import FastAPI, Query, Body
app = FastAPI()
Identifier = NewType("Identifier", int)
@app.post("/inpath/{num}")
async def inpath(num: Identifier) -> str:
return f"2*num={2*num}"
@app.post("/inquery/")
async def inquery(num: Identifier = Query(...)) -> str:
return f"2*num={2*num}"
@app.post("/inbody/")
async def inbody(num: Identifier = Body(...)) -> str:
return f"2*num={2*num}"
uvloop failme:app
[...]
File ".../lib/python3.7/site-packages/fastapi/applications.py", line 87, in openapi
return JSONResponse(self.openapi())
File ".../lib/python3.7/site-packages/fastapi/applications.py", line 79, in openapi
openapi_prefix=self.openapi_prefix,
File ".../lib/python3.7/site-packages/fastapi/openapi/utils.py", line 254, in get_openapi
result = get_openapi_path(route=route, model_name_map=model_name_map)
File ".../lib/python3.7/site-packages/fastapi/openapi/utils.py", line 163, in get_openapi_path
all_route_params=all_route_params
File ".../lib/python3.7/site-packages/fastapi/openapi/utils.py", line 87, in get_openapi_operation_parameters
"schema": field_schema(param, model_name_map={})[0],
File "pydantic/schema.py", line 288, in pydantic.schema.field_schema
File "pydantic/schema.py", line 518, in pydantic.schema.field_type_schema
File "pydantic/schema.py", line 745, in pydantic.schema.field_singleton_schema
TypeError: issubclass() arg 1 must be a class
Expected behavior
The OpenAPI documentation to be rendered rendered.
Screenshots

Environment:
This seems to be an upstream bug: samuelcolvin/pydantic#545
The bug was fixed in: samuelcolvin/pydantic#649
So upgrading to the most recent pydantic version should fix the problem. #423 seems to handle this. Looking forward to it :slightly_smiling_face:
But #423 is closed without merge. It's sad. @tiangolo
@Victor-Savu @xyb #423 was replaced with a different PR upgrading to newer pydantic. It is now merged; as of 0.38 NewType works for schema generation.
FYI: Resolved in #463
Thanks guys for the report, @dmontagu for the fix, and @Victor-Savu for reporting back/closing the issue. :tada: :rocket:
Its not working together with parameters validation.
user_id_path = Path(..., title='The ID of the User to get', ge=1)
UserId = NewType('UserId', int)
@users_router.get(
path='/{user_id}',
response_model=UserResponseModel,
responses={404: {'model': NotFoundModel}},
)
async def get_user(user_id: UserId = user_id_path) -> UserResponseModel:
return await User.get_or_404(user_id)
Traceback
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/uvicorn/subprocess.py", line 62, in subprocess_started
target(sockets=sockets)
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/uvicorn/main.py", line 382, in run
loop.run_until_complete(self.serve(sockets=sockets))
File "uvloop/loop.pyx", line 1456, in uvloop.loop.Loop.run_until_complete
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/uvicorn/main.py", line 389, in serve
config.load()
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/uvicorn/config.py", line 288, in load
self.loaded_app = import_from_string(self.app)
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/uvicorn/importer.py", line 20, in import_from_string
module = importlib.import_module(module_str)
File "/home/pentusha/.venvs/backend2/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "./api/asgi.py", line 1, in <module>
from .main import get_app
File "./api/main.py", line 5, in <module>
from api.users.views import users_router
File "./api/users/views.py", line 18, in <module>
async def get_user(user_id: UserId = user_id_path) -> UserResponseModel:
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/fastapi/routing.py", line 514, in decorator
self.add_api_route(
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/fastapi/routing.py", line 453, in add_api_route
route = route_class(
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/fastapi/routing.py", line 370, in __init__
self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/fastapi/dependencies/utils.py", line 291, in get_dependant
param_field = get_param_field(
File "/home/pentusha/.venvs/backend2/lib/python3.8/site-packages/fastapi/dependencies/utils.py", line 375, in get_param_field
annotation = get_annotation_from_field_info(annotation, field_info, param_name)
File "pydantic/schema.py", line 801, in pydantic.schema.get_annotation_from_field_info
ValueError: On field "user_id" the following field constraints are set but not enforced: ge.
For more details see https://pydantic-docs.helpmanual.io/usage/schema/#unenforced-field-constraints
Most helpful comment
FYI: Resolved in #463