7bc27da33a
Upload documents for AI context, exam images for Moodle questions, per-template storage limits, embedded images in XML export, and GUIA_API_Y_FLUJO.md with full endpoint documentation.
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
import re
|
|
from html import escape
|
|
from typing import Annotated
|
|
|
|
from fastapi import Depends, Header, HTTPException, status
|
|
|
|
from app.core.config import Settings, get_settings
|
|
|
|
|
|
CONTROL_CHARS = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f]")
|
|
ROLE_INJECTION_HINTS = re.compile(
|
|
r"(ignore\s+(all\s+)?previous|system\s*:|developer\s*:|act\s+as\s+system)",
|
|
flags=re.IGNORECASE,
|
|
)
|
|
|
|
|
|
def require_api_key(
|
|
settings: Annotated[Settings, Depends(get_settings)],
|
|
x_api_key: Annotated[str | None, Header(alias="X-API-Key")] = None,
|
|
) -> None:
|
|
if not x_api_key or x_api_key != settings.api_key:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Invalid or missing API key",
|
|
)
|
|
|
|
|
|
def clean_text(value: str, *, max_length: int = 8_000) -> str:
|
|
cleaned = CONTROL_CHARS.sub("", value).strip()
|
|
if len(cleaned) > max_length:
|
|
cleaned = cleaned[:max_length].strip()
|
|
return cleaned
|
|
|
|
|
|
def sanitize_prompt_input(value: str, *, max_length: int = 4_000) -> str:
|
|
cleaned = clean_text(value, max_length=max_length)
|
|
return ROLE_INJECTION_HINTS.sub("[filtered instruction]", cleaned)
|
|
|
|
|
|
def html_text(value: str) -> str:
|
|
return escape(clean_text(value), quote=True)
|