How to debug Fastapi openapi generation error
Asked Answered
C

4

4

I spend some time going over this error but had no success.

File "C:\Users\ebara.conda\envs\asci\lib\site-packages\fastapi\openapi\utils.py", line 388, in get_openapi flat_models=flat_models, model_name_map=model_name_map

File "C:\Users\ebara.conda\envs\asci\lib\site-packages\fastapi\utils.py", line 28, in get_model_definitions model_name = model_name_map[model]

KeyError: <class 'pydantic.main.Body_login_access_token_api_v1_login_access_token_post'>

The problem is that I'm trying to build a project with user authentication from OpenAPI form to create new users in database.

I've used backend part of this template project https://github.com/tiangolo/full-stack-fastapi-postgresql

Everything works except for Authentication like here.

@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
    db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()) -> Any:

When I add this part form_data: OAuth2PasswordRequestForm = Depends() - and go to /docs page - this error appears (Failed to load API definition. Fetch error. Internal Server Error /openapi.json)

error picture .

The server itself runs in normal mode, but it can't load the open API. If I remove the aforementioned formdata part - then everything works smoothly, but without Authorisation. I tried to debug it, but I have no success. I think it might be connected to a dependency graph or some start-up issues, but have no guess how to trace it back.

Here is the full working example which will reproduce the error. The link points out the code which causes the problem. If you will comment out lines 18-39 - the docs will open without any problems. https://github.com/BEEugene/fastapi_error_demo/blob/master/fastapi_service/api/api_v1/endpoints/login.py

Any ideas on how to debug or why this error happens?

Christinchristina answered 7/12, 2021 at 8:46 Comment(5)
How are you running the app?Gezira
@niko, I run it with this command uvicorn app.main:app --reload --log-level debug --port 6008Christinchristina
Have you tried running it via docker? I.e. docker-compose up --build -d (This is the intended usage afaik) If so, does the error persist?Gezira
@Chris, thank you for the comment. I added the link to the GitHub repository. This can be reproduced within a service, so I added the full version to test it.Christinchristina
@tiangolo, any ideas?Christinchristina
C
1

It seems that in my case - the main error issue was that I was an idiot.

As said, if you will comment out lines 18-39 - the docs will open without any problems. But, you will notice this warning:

UserWarning: Duplicate Operation ID read_users_api_v1_users__get for function read_users at ...\fastapi_error\fastapi_service\api\api_v1\endpoints\users.py warnings. Warn(message)

I've started to compare all the files and it is appeared that I included router to the fastapi twice:

import logging
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware

from fastapi_service.api.api_v1.api import api_router
from fastapi_service.core.config import settings
from fastapi_service.core.event_handlers import (start_app_handler,
                                                 stop_app_handler)

log = logging.getLogger(__name__)

def get_app(mode="prod") -> FastAPI:

    fast_app = FastAPI(title=settings.PROJECT_NAME,
                       version=settings.APP_VERSION,
                       debug=settings.IS_DEBUG)
                       # openapi_url=f"{settings.API_V1_STR}/openapi.json")
    #  first time when I included the router
    fast_app.include_router(api_router, prefix=f"{settings.API_V1_STR}")
    fast_app.mode = mode
    logger = log.getChild("get_app")
    logger.info("adding startup")
    fast_app.add_event_handler("startup", start_app_handler(fast_app))
    logger.info("adding shutdown")
    fast_app.add_event_handler("shutdown", stop_app_handler(fast_app))

    return fast_app


app = get_app()

# Set all CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
    app.add_middleware(
        CORSMiddleware,
        allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
#  second time when I included the router
app.include_router(api_router, prefix=settings.API_V1_STR)

So, if you comment out (or just delete) the second router introduction - the app will work normally.

It seems, that the answer to my question on how to debug this error - is to find the point where the bug appears in fastapi and compare the values in it to the version where there is no error. In my case the number of keys in different dictionaries differed in the function get_model_definitions.

Christinchristina answered 3/9, 2022 at 9:57 Comment(0)
S
1

You are using Depends function without an argument. Maybe in the console, you were having the error provoked by a function. You must pass the OAuth2PasswordRequestForm function after importing it from fastapi.security to get the result you were expecting.

from fastapi.security import OAuth2PasswordRequestForm

form_data: OAuth2PasswordRequestForm = Depends(OAuth2PasswordRequestForm)

it might work.

Stillwell answered 29/5, 2022 at 16:25 Comment(3)
Hi! Thank you, unfortunately, it didn't work.Christinchristina
@Alexander, Depends can be use both ways,when you use a fastapi class like OAuth2PasswordRequestForm you can use ``` form_data: OAuth2PasswordRequestForm = Depends() ``` it is what is suggest by the doc btw. Example: github.com/Bastien-BO/fastapi-RBAC-microservice/blob/main/app/…Counterrevolution
I will try that mode, if I am not mistaken I got an error when i used that way you suggest. Thanks for the link to read about it.Stillwell
C
1

It seems that in my case - the main error issue was that I was an idiot.

As said, if you will comment out lines 18-39 - the docs will open without any problems. But, you will notice this warning:

UserWarning: Duplicate Operation ID read_users_api_v1_users__get for function read_users at ...\fastapi_error\fastapi_service\api\api_v1\endpoints\users.py warnings. Warn(message)

I've started to compare all the files and it is appeared that I included router to the fastapi twice:

import logging
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware

from fastapi_service.api.api_v1.api import api_router
from fastapi_service.core.config import settings
from fastapi_service.core.event_handlers import (start_app_handler,
                                                 stop_app_handler)

log = logging.getLogger(__name__)

def get_app(mode="prod") -> FastAPI:

    fast_app = FastAPI(title=settings.PROJECT_NAME,
                       version=settings.APP_VERSION,
                       debug=settings.IS_DEBUG)
                       # openapi_url=f"{settings.API_V1_STR}/openapi.json")
    #  first time when I included the router
    fast_app.include_router(api_router, prefix=f"{settings.API_V1_STR}")
    fast_app.mode = mode
    logger = log.getChild("get_app")
    logger.info("adding startup")
    fast_app.add_event_handler("startup", start_app_handler(fast_app))
    logger.info("adding shutdown")
    fast_app.add_event_handler("shutdown", stop_app_handler(fast_app))

    return fast_app


app = get_app()

# Set all CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
    app.add_middleware(
        CORSMiddleware,
        allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
#  second time when I included the router
app.include_router(api_router, prefix=settings.API_V1_STR)

So, if you comment out (or just delete) the second router introduction - the app will work normally.

It seems, that the answer to my question on how to debug this error - is to find the point where the bug appears in fastapi and compare the values in it to the version where there is no error. In my case the number of keys in different dictionaries differed in the function get_model_definitions.

Christinchristina answered 3/9, 2022 at 9:57 Comment(0)
S
1

I had the same problem. For me it was because I had code like this

from pydantic import BaseModel

class A(BaseModel):
   b: B

class B(BaseModel):
   c: int

but instead, Class B should have been defined above class A. This fixed it:

from pydantic import BaseModel

class B(BaseModel):
   c: int

class A(BaseModel):
   b: B

More info: https://mcmap.net/q/505529/-fastapi-pydantic-circular-references-in-separate-files

Regaring your original question on how to debug these or similar errors:

You probably have your routes defined somewhere. Comment all of your routers/routes out, then the openapi docs should generate (and they should show you have no routes. Then, enable the routes one by one and see which one causes the error. THis is how I debuged my situation.

Stockton answered 31/1, 2023 at 10:18 Comment(0)
A
1

In my case, I had two identical function names with identical parameters, when I renamed one of the functions the documentation gets generated

my error was something like

KeyError: <class 'pydantic.main.Body_post_message_post_QA_chat_post'>

and the function name and endpoint that had the error was

endpoint: post_QA_chat

function name: post message

it seems the class name that was mentioned in error

Body_post_message_post_QA_chat_post

named in a way

Body_function-name_endpoint

I think this could help to debug

Aglimmer answered 14/11, 2023 at 5:16 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.