为FastAPI添加自定义OpenAPI Schema后授权接口返回404的问题排查
问题
原本可正常运行的FastAPI应用,添加自定义OpenAPI Schema代码后,授权接口开始返回404 Not Found错误。
原有可运行代码
main.py
app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) sub_app1 = FastAPI() sub_app1.include_router(auth.router)
routers/auth.py
@router.post("/complete", status_code=status.HTTP_201_CREATED) async def complete_registration_create_user(db: db_dependency, create_user_request: CreateUserRequest): """完成用户提交密码后的注册流程""" hashed_password = bcrypt_context.hash(create_user_request.password) create_user_model = Users( email=create_user_request.email, hashed_password=hashed_password, phone=create_user_request.phone, ) # 注意:在组织中,所有员工账号需由所有者审批 try: db.add(create_user_model) await db.commit() except IntegrityError as er: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail=f"用户 {create_user_request.email} 已存在,请更换邮箱或尝试重置密码。" ) await db.refresh(create_user_model) return {"user": create_user_request.email} @router.post("/token", response_model=Token) async def user_login_for_access_token(form_data: Annotated[OAuth2EmailRequestForm, Depends()], db: db_dependency): """用户登录获取访问令牌""" user = await authenticate_user(form_data.email, form_data.password, db) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无法验证用户身份。" ) tenant_identifier = form_data.identifier token = create_access_token( user.email, user.id, tenant_identifier, timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) ) return {'access_token': token, 'token_type': 'bearer'}
添加的自定义OpenAPI代码
在main.py中加入以下代码后出现问题:
def custom_openapi(): if sub_app1.openapi_schema: return sub_app1.openapi_schema openapi_schema = get_openapi( title=" Authorisation API", version="0.0.1", description="API on this docs deals with all user and company registration.", routes=sub_app1.routes, ) sub_app1.openapi_schema = openapi_schema return sub_app1.openapi_schema sub_app1.openapi = custom_openapi
错误日志
INFO: 127.0.0.1:43756 - "POST /register/token?email=user2%40example.com&identifier=sada&password=string HTTP/1.1" 404 Not Found INFO: 127.0.0.1:44748 - "POST /register/complete HTTP/1.1" 404 Not Found
解决方法
补全子应用挂载代码:从日志的请求路径
/register/token来看,主应用并未将sub_app1挂载到/register路径下,添加以下代码到main.py:app.mount("/register", sub_app1)缺少挂载步骤会导致子应用的路由无法被主应用识别,这是最可能的原因。
修正自定义OpenAPI的路径前缀:在生成OpenAPI Schema时指定匹配挂载路径的前缀,避免路由路径不匹配:
openapi_schema = get_openapi( title="Authorisation API", version="0.0.1", description="API on this docs deals with all user and company registration.", routes=sub_app1.routes, openapi_prefix="/register" # 与挂载路径保持一致 )清除缓存并重启服务:自定义函数会缓存
openapi_schema,修改配置后需要重启服务,或者在修改挂载路径后手动删除sub_app1.openapi_schema再重新生成,确保新的路由信息被包含。调整路由注册顺序:确保
sub_app1.include_router(auth.router)在设置sub_app1.openapi = custom_openapi之前执行,避免生成的Schema遗漏路由:sub_app1 = FastAPI() # 先添加路由 sub_app1.include_router(auth.router) # 再设置自定义OpenAPI def custom_openapi(): # ... 原代码 sub_app1.openapi = custom_openapi验证子应用文档:访问
http://localhost:8000/register/docs查看生成的OpenAPI文档,确认/token和/complete接口是否存在。如果文档中没有这些接口,说明路由未被正确添加到子应用中。
内容的提问来源于stack exchange,提问作者Ciasto piekarz
相关产品推荐
相关产品推荐

