mirror of
http://100.103.83.12:3003/fegger/pv-agent.git
synced 2026-09-17 16:06:23 +00:00
feat(agent): add test frontend and Docker stack
This commit is contained in:
@@ -12,9 +12,11 @@ import secrets
|
||||
import threading
|
||||
import uuid
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
@@ -27,6 +29,8 @@ from .retrieve import Retriever
|
||||
API_VERSION = "v1"
|
||||
DATA_SCOPE = "knowledge_base_only"
|
||||
_REQUEST_ID_RE = re.compile(r"^[A-Za-z0-9._:-]{1,128}$")
|
||||
WEB_DIR = Path(__file__).resolve().parent.parent / "web"
|
||||
_WEB_ASSETS = {"app.js", "styles.css"}
|
||||
logger = logging.getLogger(__name__)
|
||||
bearer = HTTPBearer(auto_error=False)
|
||||
bearer_credentials = Depends(bearer)
|
||||
@@ -170,9 +174,37 @@ async def add_request_id(request: Request, call_next):
|
||||
request.state.request_id = request_id
|
||||
response = await call_next(request)
|
||||
response.headers["X-Request-ID"] = request_id
|
||||
response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
response.headers["X-Frame-Options"] = "DENY"
|
||||
response.headers["Referrer-Policy"] = "no-referrer"
|
||||
if request.url.path == "/" or request.url.path.startswith("/assets/"):
|
||||
response.headers["Content-Security-Policy"] = (
|
||||
"default-src 'self'; base-uri 'none'; form-action 'self'; "
|
||||
"frame-ancestors 'none'; img-src 'self' data:; "
|
||||
"script-src 'self'; style-src 'self'; connect-src 'self'"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@app.get("/", include_in_schema=False, response_class=FileResponse)
|
||||
def frontend() -> FileResponse:
|
||||
return FileResponse(
|
||||
WEB_DIR / "index.html",
|
||||
media_type="text/html",
|
||||
headers={"Cache-Control": "no-store"},
|
||||
)
|
||||
|
||||
|
||||
@app.get("/assets/{asset_name}", include_in_schema=False, response_class=FileResponse)
|
||||
def frontend_asset(asset_name: str) -> FileResponse:
|
||||
if asset_name not in _WEB_ASSETS:
|
||||
raise HTTPException(status_code=404, detail="Asset nicht gefunden.")
|
||||
return FileResponse(
|
||||
WEB_DIR / asset_name,
|
||||
headers={"Cache-Control": "public, max-age=3600"},
|
||||
)
|
||||
|
||||
|
||||
def _request_id(request: Request) -> str:
|
||||
return getattr(request.state, "request_id", uuid.uuid4().hex)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user