KeyError when building openapi file
See original GitHub issueIssue Description
Describe the bug
I deployed a service using FastAPI and Ormar on two different servers. On the first one it works, and on the second one I get this error when accessing /docs
or /openapi.json
(I believe most of the traceback is not useful):
Summary: (click to unfold the whole traceback)
File "/api/pkgs/fastapi/utils.py", line 28, in get_model_definitions
model_name = model_name_map[model]
│ └ <class 'abc.Team_PJX'>
└ {<class 'abc.Team_TLK'>: 'Team_TLK', <enum 'TicketStatus'>: 'TicketStatus', <class 'abc.Project_RLS'>: 'Project_RLS', <class ...
KeyError: <class 'abc.Team_PJX'>
File "/api/pkgs/fastapi/utils.py", line 28, in get_model_definitions
model_name = model_name_map[model]
│ └ <class 'abc.Team_PJX'>
└ {<class 'abc.Team_TLK'>: 'Team_TLK', <enum 'TicketStatus'>: 'TicketStatus', <class 'abc.Project_RLS'>: 'Project_RLS', <class ...
KeyError: <class 'abc.Team_PJX'>
Exception in ASGI application
Traceback (most recent call last):
File "/api/run.py", line 70, in <module>
server.run()
│ └ <function Server.run at 0x7fbf689e23a0>
└ <uvicorn.main.Server object at 0x7fbf6ea4bd00>
File "/api/pkgs/uvicorn/main.py", line 419, in run
loop.run_until_complete(self.serve(sockets=sockets))
│ │ │ │ └ None
│ │ │ └ <function Server.serve at 0x7fbf689e2430>
│ │ └ <uvicorn.main.Server object at 0x7fbf6ea4bd00>
│ └ <function BaseEventLoop.run_until_complete at 0x7fbf6b0f3700>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/lib64/python3.8/asyncio/base_events.py", line 603, in run_until_complete
self.run_forever()
│ └ <function BaseEventLoop.run_forever at 0x7fbf6b0f3670>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/lib64/python3.8/asyncio/base_events.py", line 570, in run_forever
self._run_once()
│ └ <function BaseEventLoop._run_once at 0x7fbf6b0f61f0>
└ <_UnixSelectorEventLoop running=True closed=False debug=False>
File "/usr/lib64/python3.8/asyncio/base_events.py", line 1859, in _run_once
handle._run()
│ └ <function Handle._run at 0x7fbf6b574f70>
└ <Handle <TaskWakeupMethWrapper object at 0x7fbf5c5aaee0>(<Future finished result=None>)>
File "/usr/lib64/python3.8/asyncio/events.py", line 81, in _run
self._context.run(self._callback, *self._args)
│ │ │ │ │ └ <member '_args' of 'Handle' objects>
│ │ │ │ └ <Handle <TaskWakeupMethWrapper object at 0x7fbf5c5aaee0>(<Future finished result=None>)>
│ │ │ └ <member '_callback' of 'Handle' objects>
│ │ └ <Handle <TaskWakeupMethWrapper object at 0x7fbf5c5aaee0>(<Future finished result=None>)>
│ └ <member '_context' of 'Handle' objects>
└ <Handle <TaskWakeupMethWrapper object at 0x7fbf5c5aaee0>(<Future finished result=None>)>
File "/api/pkgs/uvicorn/protocols/http/h11_impl.py", line 389, in run_asgi
result = await app(self.scope, self.receive, self.send)
│ │ │ │ │ │ └ <function RequestResponseCycle.send at 0x7fbf68768790>
│ │ │ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>
│ │ │ │ └ <function RequestResponseCycle.receive at 0x7fbf68768820>
│ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7fbf687941f0>
File "/api/pkgs/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <fastapi.applications.FastAPI object at 0x7fbf66e39850>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7fbf687941f0>
File "/api/pkgs/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
File "/api/pkgs/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7fbf64fdd9d0>
└ <fastapi.applications.FastAPI object at 0x7fbf66e39850>
File "/api/pkgs/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/api/pkgs/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7fbf64fdeee0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <starlette.middleware.base.BaseHTTPMiddleware object at 0x7fbf64fdd9a0>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7fbf64fdd9d0>
File "/api/pkgs/starlette/middleware/base.py", line 25, in __call__
response = await self.dispatch_func(request, self.call_next)
│ │ │ │ └ <function BaseHTTPMiddleware.call_next at 0x7fbf66a819d0>
│ │ │ └ <starlette.middleware.base.BaseHTTPMiddleware object at 0x7fbf64fdd9a0>
│ │ └ <starlette.requests.Request object at 0x7fbf640dd340>
│ └ <function PrometheusFastApiInstrumentator.instrument.<locals>.dispatch_middleware at 0x7fbf65196ee0>
└ <starlette.middleware.base.BaseHTTPMiddleware object at 0x7fbf64fdd9a0>
File "/api/pkgs/prometheus_fastapi_instrumentator/instrumentation.py", line 150, in dispatch_middleware
raise e from None
File "/api/pkgs/prometheus_fastapi_instrumentator/instrumentation.py", line 145, in dispatch_middleware
response = await call_next(request)
│ └ <starlette.requests.Request object at 0x7fbf640dd340>
└ <bound method BaseHTTPMiddleware.call_next of <starlette.middleware.base.BaseHTTPMiddleware object at 0x7fbf64fdd9a0>>
File "/api/pkgs/starlette/middleware/base.py", line 45, in call_next
task.result()
│ └ <method 'result' of '_asyncio.Task' objects>
└ <Task finished name='Task-5469' coro=<BaseHTTPMiddleware.call_next.<locals>.coro() done, defined at /api/pkgs/starlette/middl...
File "/api/pkgs/starlette/middleware/base.py", line 38, in coro
await self.app(scope, receive, send)
│ │ │ │ └ <bound method Queue.put of <Queue at 0x7fbf64e0ea30 maxsize=0 tasks=1>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <starlette.middleware.cors.CORSMiddleware object at 0x7fbf64fdd970>
└ <starlette.middleware.base.BaseHTTPMiddleware object at 0x7fbf64fdd9a0>
File "/api/pkgs/starlette/middleware/cors.py", line 78, in __call__
await self.app(scope, receive, send)
│ │ │ │ └ <bound method Queue.put of <Queue at 0x7fbf64e0ea30 maxsize=0 tasks=1>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <starlette.exceptions.ExceptionMiddleware object at 0x7fbf64fdda60>
└ <starlette.middleware.cors.CORSMiddleware object at 0x7fbf64fdd970>
File "/api/pkgs/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/api/pkgs/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7fbf64a939d0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <fastapi.routing.APIRouter object at 0x7fbf657a9250>
└ <starlette.exceptions.ExceptionMiddleware object at 0x7fbf64fdda60>
File "/api/pkgs/starlette/routing.py", line 580, in __call__
await route.handle(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7fbf64a939d0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <function Route.handle at 0x7fbf66ad3b80>
└ <starlette.routing.Route object at 0x7fbf653fb5b0>
File "/api/pkgs/starlette/routing.py", line 241, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7fbf64a939d0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x7fbf5c5aad90>>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('172.42.56.164', 8080),...
│ └ <function request_response.<locals>.app at 0x7fbf653fdee0>
└ <starlette.routing.Route object at 0x7fbf653fb5b0>
File "/api/pkgs/starlette/routing.py", line 52, in app
response = await func(request)
│ └ <starlette.requests.Request object at 0x7fbf5c5aa130>
└ <function FastAPI.setup.<locals>.openapi at 0x7fbf653fdd30>
File "/api/pkgs/fastapi/applications.py", line 152, in openapi
return JSONResponse(self.openapi())
│ │ └ <function FastAPI.openapi at 0x7fbf66a91af0>
│ └ <fastapi.applications.FastAPI object at 0x7fbf66e39850>
└ <class 'starlette.responses.JSONResponse'>
File "/api/pkgs/fastapi/applications.py", line 130, in openapi
self.openapi_schema = get_openapi(
│ │ └ <function get_openapi at 0x7fbf66a81430>
│ └ None
└ <fastapi.applications.FastAPI object at 0x7fbf66e39850>
File "/api/pkgs/fastapi/openapi/utils.py", line 363, in get_openapi
definitions = get_model_definitions(
└ <function get_model_definitions at 0x7fbf66b27af0>
File "/api/pkgs/fastapi/utils.py", line 28, in get_model_definitions
model_name = model_name_map[model]
│ └ <class 'abc.Team_PJX'>
└ {<class 'abc.Team_TLK'>: 'Team_TLK', <enum 'TicketStatus'>: 'TicketStatus', <class 'abc.Project_RLS'>: 'Project_RLS', <class ...
KeyError: <class 'abc.Team_PJX'>
To Reproduce
I’m not sure how to reproduce this. As stated above, only one of two identical deployments fails with this error. I’ll see what happens when I redeploy the two services (if the failing one is fixed by the update) and report back. In the meanwhile maybe you’ll have a hunch 🙂
Expected behavior No errors, openapi.json can be generated.
Versions (please complete the following information):
- Database backend used: sqlite
- Python version: 3.8
ormar
version: 0.10.15pydantic
version: 1.8.2- if applicable
fastapi
version: 0.65.2
Issue Analytics
- State:
- Created 2 years ago
- Comments:14 (13 by maintainers)
Top Results From Across the Web
KeyError when generating openapi when using subclasses as ...
First check I added a very descriptive title to this issue. I used the GitHub search to find a similar issue and didn't...
Read more >Gets duplicated mapping key error using openapi 3.0
You don't have any duplicate keys in your file, but it is invalid (i.e. not valid YAML) because of the indentation of the...
Read more >The error message 'KeyError: key not found: "endpoint"' is ...
I have a Swagger/OpenAPI .json file that I wish to import. I am running the following command: Raw. $ 3scale import openapi -d...
Read more >Build a RESTful API with Flask, MongoDB, and Python
There's no way to get PyMongo to return the document that was just inserted in a single operation (although an upsert using find_one_and_update ......
Read more >Python KeyError Exceptions and How to Handle Them
In this tutorial, you'll learn how to handle Python KeyError exceptions. They are often caused by a bad key lookup in a dictionary,...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hey @pawamoy I was able to reproduce the issue.
The solution is trying to add cache to save and reuse the pydantic generated type. When fastapi tries to generate the openapi.json the method
get_pydantic()
is been called so many times, so there are some times where.join(choices(string.ascii_uppercase, k=3))
makes de exact same output so when this happen the Exception is raised.Make sense. But without reproducibility, it will be hard to do anything about this 😅