You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:07:26