Spaces:
Runtime error
Runtime error
from fastapi import FastAPI | |
from fastapi.routing import APIRoute | |
from fastapi.staticfiles import StaticFiles | |
from fastapi_users import FastAPIUsers | |
from starlette.middleware.cors import CORSMiddleware | |
from starlette.requests import Request | |
from starlette.responses import FileResponse | |
from app.api import api_router | |
from app.core.config import settings | |
from app.deps.users import fastapi_users, jwt_authentication | |
from app.schemas.user import UserCreate, UserRead, UserUpdate | |
import os | |
from httpx_oauth.clients.google import GoogleOAuth2 # google client | |
# for dev only | |
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" | |
def create_app(): | |
description = f"{settings.PROJECT_NAME} API" | |
app = FastAPI( | |
title=settings.PROJECT_NAME, | |
openapi_url=f"{settings.API_PATH}/openapi.json", | |
docs_url="/docs/", | |
description=description, | |
redoc_url=None, | |
) | |
setup_routers(app, fastapi_users) | |
setup_cors_middleware(app) | |
serve_static_app(app) | |
return app | |
def setup_routers(app: FastAPI, fastapi_users: FastAPIUsers) -> None: | |
app.include_router(api_router, prefix=settings.API_PATH) | |
app.include_router( | |
fastapi_users.get_auth_router( | |
jwt_authentication, | |
requires_verification=False, | |
), | |
prefix=f"{settings.API_PATH}/auth/jwt", | |
tags=["auth"], | |
) | |
app.include_router( | |
fastapi_users.get_register_router(UserRead, UserCreate), | |
prefix=f"{settings.API_PATH}/auth", | |
tags=["auth"], | |
) | |
app.include_router( | |
fastapi_users.get_users_router( | |
UserRead, UserUpdate, requires_verification=False | |
), | |
prefix=f"{settings.API_PATH}/users", | |
tags=["users"], | |
) | |
google_oauth_client = GoogleOAuth2( | |
os.getenv("GOOGLE_OAUTH_CLIENT_ID", ""), | |
os.getenv("GOOGLE_OAUTH_CLIENT_SECRET", ""), | |
) | |
app.include_router( | |
fastapi_users.get_oauth_router( | |
google_oauth_client, jwt_authentication, "SECRET" | |
), | |
prefix="/auth/google", | |
tags=["auth"], | |
) | |
# The following operation needs to be at the end of this function | |
use_route_names_as_operation_ids(app) | |
def serve_static_app(app): | |
app.mount("/", StaticFiles(directory="static"), name="static") | |
async def _add_404_middleware(request: Request, call_next): | |
"""Serves static assets on 404""" | |
response = await call_next(request) | |
path = request["path"] | |
if path.startswith(settings.API_PATH) or path.startswith("/docs"): | |
return response | |
if response.status_code == 404: | |
return FileResponse("static/index.html") | |
return response | |
def setup_cors_middleware(app): | |
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=["*"], | |
expose_headers=["Content-Range", "Range"], | |
allow_headers=["Authorization", "Range", "Content-Range"], | |
) | |
def use_route_names_as_operation_ids(app: FastAPI) -> None: | |
""" | |
Simplify operation IDs so that generated API clients have simpler function | |
names. | |
Should be called only after all routes have been added. | |
""" | |
route_names = set() | |
for route in app.routes: | |
if isinstance(route, APIRoute): | |
if route.name in route_names: | |
raise Exception("Route function names should be unique") | |
route.operation_id = route.name | |
route_names.add(route.name) | |