81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI, status
|
|
from fastapi.openapi.utils import get_openapi
|
|
from fastapi.responses import FileResponse
|
|
from fastapi.security import HTTPBearer
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
|
from app.api.router import api_router
|
|
from app.core.config import get_settings
|
|
from app.core.exceptions import register_exception_handlers
|
|
from app.core.logging import setup_logging
|
|
from app.db.init_db import initialize_database
|
|
|
|
settings = get_settings()
|
|
setup_logging(settings.log_level)
|
|
STATIC_DIR = Path(__file__).resolve().parent / "static"
|
|
|
|
bearer_scheme = HTTPBearer()
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(_: FastAPI):
|
|
initialize_database()
|
|
yield
|
|
|
|
|
|
app = FastAPI(
|
|
title=settings.app_name,
|
|
version="1.0.0",
|
|
lifespan=lifespan,
|
|
swagger_ui_parameters={},
|
|
)
|
|
app.openapi_tags = [
|
|
{"name": "auth", "description": "Регистрация и вход в систему"},
|
|
{"name": "catalog", "description": "Каталог товаров"},
|
|
{"name": "orders", "description": "Управление заказами"},
|
|
{"name": "payments", "description": "Оплата заказов"},
|
|
]
|
|
security_schemes = {
|
|
"BearerAuth": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "JWT",
|
|
"description": "Введите JWT токен, получен через POST /api/v1/auth/login",
|
|
},
|
|
}
|
|
app.openapi_schema = None # Force regeneration
|
|
|
|
register_exception_handlers(app)
|
|
app.include_router(api_router, prefix=settings.api_v1_prefix)
|
|
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
|
|
|
|
|
@app.get("/health", status_code=status.HTTP_200_OK, summary="Health check")
|
|
def health_check() -> dict[str, str]:
|
|
return {"status": "ok"}
|
|
|
|
|
|
@app.get("/", include_in_schema=False)
|
|
def frontend_index() -> FileResponse:
|
|
return FileResponse(STATIC_DIR / "index.html")
|
|
|
|
|
|
def custom_openapi():
|
|
if app.openapi_schema:
|
|
return app.openapi_schema
|
|
openapi_schema = get_openapi(
|
|
title=app.title,
|
|
version=app.version,
|
|
routes=app.routes,
|
|
)
|
|
openapi_schema["components"]["securitySchemes"] = security_schemes
|
|
app.openapi_schema = openapi_schema
|
|
return app.openapi_schema
|
|
|
|
app.openapi = custom_openapi # type: ignore[method-assign]
|