""" =============================================================================== FILE: modules/web_api/main.py PROJECT: SCUD Orion AI (Unified Repository) MODULE: web_api (Main Application Entry Point) ROLE: Инициализация FastAPI приложения, подключение роутеров и статики. =============================================================================== """ # ANCHOR[APP_INIT_IMPORTS] import os import sys import logging CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) if CURRENT_DIR not in sys.path: sys.path.insert(0, CURRENT_DIR) from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, JSONResponse from fastapi.exceptions import RequestValidationError from routers.auth import router as auth_router from routers.admin import router as admin_router from routers.tasks import router as tasks_router from routers.chat import router as chat_router # ANCHOR[APP_CONFIG] logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler()] ) STATIC_DIR = os.path.join(CURRENT_DIR, "static") app = FastAPI(title="SCUD Orion AI Context API", version="2.5") if os.path.exists(STATIC_DIR): app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") @app.exception_handler(RequestValidationError) async def validation_exception_handler(request, exc): logging.error(f"❌ ОШИБКА ВАЛИДАЦИИ 422 НА {request.url}: {exc.errors()}") return JSONResponse( status_code=422, content={"detail": exc.errors(), "body": str(exc)} ) # ANCHOR[ROUTER_REGISTRATION] app.include_router(auth_router) app.include_router(admin_router) app.include_router(tasks_router) app.include_router(chat_router) # ANCHOR[ROOT_STATIC_ROUTES] @app.get("/") def read_root(): index_path = os.path.join(STATIC_DIR, "index.html") if os.path.exists(index_path): return FileResponse(index_path) raise HTTPException(status_code=404, detail="Frontend index.html not found") @app.get("/favicon.ico") async def favicon(): file_path = os.path.join(STATIC_DIR, "favicon.ico") if os.path.exists(file_path): return FileResponse(file_path) raise HTTPException(status_code=404) @app.get("/{file_path:path}") def serve_static_fallback(file_path: str): clean_path = file_path.lstrip("/") target = os.path.join(STATIC_DIR, clean_path) if os.path.isfile(target): return FileResponse(target) filename = os.path.basename(clean_path) target_js = os.path.join(STATIC_DIR, "js", filename) if filename.endswith(".js") and os.path.isfile(target_js): return FileResponse(target_js, media_type="application/javascript") target_css = os.path.join(STATIC_DIR, "css", filename) if filename.endswith(".css") and os.path.isfile(target_css): return FileResponse(target_css, media_type="text/css") raise HTTPException(status_code=404, detail="File not found")