test_task_crm/app/main.py

77 lines
2.6 KiB
Python

"""FastAPI application factory."""
from __future__ import annotations
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from app.api.routes import api_router
from app.core.cache import init_cache, shutdown_cache
from app.core.config import settings
from app.core.middleware.cache_monitor import CacheAvailabilityMiddleware
PROJECT_ROOT = Path(__file__).resolve().parent.parent
FRONTEND_DIST = PROJECT_ROOT / "frontend" / "dist"
FRONTEND_INDEX = FRONTEND_DIST / "index.html"
def create_app() -> FastAPI:
"""Build FastAPI application instance."""
@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
await init_cache()
try:
yield
finally:
await shutdown_cache()
application = FastAPI(title=settings.project_name, version=settings.version, lifespan=lifespan)
application.include_router(api_router)
application.add_middleware(CacheAvailabilityMiddleware)
application.add_middleware(
CORSMiddleware,
allow_origins=[
"https://kitchen-crm.k1nq.tech",
"http://192.168.31.51",
"http://localhost:8000",
"http://0.0.0.0:8000",
"http://127.0.0.1:8000",
# "*",
],
allow_credentials=True,
allow_methods=["*"], # Разрешить все HTTP-методы
allow_headers=["*"], # Разрешить все заголовки
)
if FRONTEND_DIST.exists() and FRONTEND_INDEX.exists():
assets_dir = FRONTEND_DIST / "assets"
if assets_dir.exists():
application.mount("/assets", StaticFiles(directory=assets_dir), name="frontend-assets")
@application.get("/", include_in_schema=False)
async def serve_frontend_root() -> FileResponse: # pragma: no cover - simple file response
return FileResponse(FRONTEND_INDEX)
@application.get("/{path:path}", include_in_schema=False)
async def serve_frontend_path(
path: str,
) -> FileResponse: # pragma: no cover - simple file response
if path == "" or path.startswith("api"):
raise HTTPException(status_code=404)
candidate = FRONTEND_DIST / path
if candidate.is_file():
return FileResponse(candidate)
return FileResponse(FRONTEND_INDEX)
return application
app = create_app()