I have this FastAPI app working in the 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)
and in the routers/auth.py
I have:
@router.post("/complete", status_code=status.HTTP_201_CREATED)
async def complete_registration_create_user(db: db_dependency, create_user_request: CreateUserRequest):
"""Compeletes the registration when user submits password."""
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,
)
# Note: In a organisation all staff members should be approved by Owner.
try:
db.add(create_user_model)
await db.commit()
except IntegrityError as er:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=f"User {create_user_request.email} already exists. Choose a different email or try resetting the password."
)
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):
"""Login user for an access token"""
user = await authenticate_user(form_data.email, form_data.password, db)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate user."
)
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'}
all above works but as soon as I add the below udpate to specify openschema to 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
the auth endpoints starts resulting in Not found error i.e.
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
What can I try next?
If you want to mount a new FastAPI app, you should use
app.mount("/register", sub_app1)
But in your case, seems like you don't need this at all. I'm sure you just need to set APIRouter:
sub_app1 = APIRouter()
sub_app1.include_router(auth.router)
app.include_router(sub_app1, prefix="/register")
After this, you could apply custom OpenAPI function on app
:
app.openapi = custom_openapi
Finally, your code may look like this:
from fastapi import FastAPI, APIRouter
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.utils import get_openapi
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
sub_app1 = APIRouter()
sub_app1.include_router(auth.router)
app.include_router(sub_app1,prefix="/register")
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Authorisation API",
version="0.0.1",
description="API dealing with user and company registration.",
routes=app.routes,
)
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
Including routes documentation
But maybe you really need to mount app for some reason? Could you provide more details?