93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
"""
|
|
===============================================================================
|
|
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
|
|
from routers.files import router as files_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)
|
|
app.include_router(files_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):
|
|
if clean_path.endswith(".js"):
|
|
return FileResponse(target, media_type="application/javascript")
|
|
elif clean_path.endswith(".css"):
|
|
return FileResponse(target, media_type="text/css")
|
|
return FileResponse(target)
|
|
|
|
filename = os.path.basename(clean_path)
|
|
for root, _, files in os.walk(STATIC_DIR):
|
|
if filename in files:
|
|
full_path = os.path.join(root, filename)
|
|
media = "application/javascript" if filename.endswith(".js") else "text/css"
|
|
return FileResponse(full_path, media_type=media)
|
|
|
|
raise HTTPException(status_code=404, detail="File not found") |