dp-zp-agent/app/main.py
2026-08-14 23:45:15 +02:00

139 lines
2.4 KiB
Python

from __future__ import annotations
import asyncio
import logging
import sys
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import (
FastAPI,
Request,
)
from fastapi.middleware.cors import (
CORSMiddleware,
)
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(
0,
str(PROJECT_ROOT),
)
from app.routes import router
from app.security import (
validate_security_configuration,
)
from scripts.embedding_utils import embed_query
logger = logging.getLogger(__name__)
OPENWEBUI_ORIGIN = (
"https://ui.tukekemt.xyz"
)
@asynccontextmanager
async def lifespan(
_: FastAPI,
):
validate_security_configuration()
try:
await asyncio.to_thread(
embed_query,
"warmup",
)
except Exception:
logger.exception(
"Predhriatie embedding modelu "
"zlyhalo. API pokračuje bez "
"úspešného warm-upu."
)
yield
app = FastAPI(
title="ZP Agent API",
description=(
"RAG API pre vyhľadávanie "
"a získavanie informácií "
"z repozitára záverečných prác "
"ZP Wiki."
),
version="0.9.0",
lifespan=lifespan,
# Interaktívne Swagger/ReDoc rozhrania
# nepotrebujeme vystavovať.
# /openapi.json zostáva dostupné,
# pretože ho používa OpenWebUI.
docs_url=None,
redoc_url=None,
)
app.add_middleware(
CORSMiddleware,
allow_origins=[
OPENWEBUI_ORIGIN,
],
allow_credentials=True,
allow_methods=[
"GET",
"POST",
"OPTIONS",
],
allow_headers=[
"Authorization",
"Content-Type",
"X-API-Key",
],
allow_private_network=True,
)
@app.middleware(
"http"
)
async def add_security_headers(
request: Request,
call_next,
):
response = await call_next(
request
)
# API odpovede obsahujú retrieval kontext,
# preto ich nechceme ukladať do cache.
response.headers[
"Cache-Control"
] = "no-store"
response.headers[
"X-Content-Type-Options"
] = "nosniff"
response.headers[
"Referrer-Policy"
] = "no-referrer"
response.headers[
"X-Frame-Options"
] = "DENY"
return response
app.include_router(
router
)