refactor api

This commit is contained in:
2026-09-25 19:42:47 +02:00
parent e856c1fa43
commit 8755142c97
49 changed files with 1652 additions and 1829 deletions
+57
View File
@@ -0,0 +1,57 @@
"""All server settings in one place. Values marked (env) can be set with an
environment variable of the same name, e.g. in compose.yaml."""
import os
from pathlib import Path
from dotenv import load_dotenv
API_ROOT = Path(__file__).resolve().parents[2] # api/ locally, /app in Docker
BUILD_PATH = Path(os.getenv("BUILD_PATH", API_ROOT / "build_models")) # (env)
DATABASE_DIR = Path(os.getenv("DATABASE_DIR", API_ROOT / "database")) # (env)
DATABASE = DATABASE_DIR / "reviews.db"
load_dotenv(DATABASE_DIR / ".env")
API_KEY = os.getenv("API_KEY") # (env) if missing, protected endpoints reject every request
ORIGINS = [
"https://marvinkrausser.com",
]
# ---- Models ----
BIRD_MODEL_FILE = "bird_cnn"
BIRD_IMAGE_SIZE = 64
BIRD_C_HIDDEN = 16
FACE_MODEL_FILE = "face_detection_yolo"
FACE_IMAGE_SIZE = 64
FACE_GRID = 6
FACE_C_HIDDEN = 16
FACE_SIZE_ACTIVATION = "exp" # must match how the deployed weights were trained
FACE_THRESHOLD = 0.9
# ---- Resource limits (the server is weak, keep everything small and bounded) ----
# Number of predictions (bird or face) that may run at the same time. (env)
PARALLEL_INFERENCES = max(1, int(os.getenv("PARALLEL_INFERENCES", "1")))
# Extra requests allowed to wait for a free slot; anything beyond is rejected. (env)
QUEUED_INFERENCES = max(0, int(os.getenv("QUEUED_INFERENCES", "1")))
# PyTorch threads used by EACH running prediction. Total CPU use is roughly
# PARALLEL_INFERENCES * TORCH_THREADS, so keep the product <= your CPU cores. (env)
TORCH_THREADS = max(1, int(os.getenv("TORCH_THREADS", "1")))
MAX_UPLOAD_BYTES = int(max(1, float(os.getenv("MAX_UPLOAD_MEGABYTES", "15"))) * 1024 * 1024) # (env)
MAX_FRAME_BYTES = 1 * 1024 * 1024
MAX_IMAGE_PIXELS = 20_000_000
DECODE_DRAFT_SIZE = (256, 256) # JPEG decodes at reduced scale, still larger than the 64px model input
MAX_WEBSOCKETS = 3
MAX_WEBSOCKETS_PER_IP = 1
FACE_MAX_FPS = float(os.getenv("FACE_MAX_FPS", "5.5")) # (env) per websocket connection
FACE_MIN_INTERVAL = 1 / FACE_MAX_FPS
# ---- Rate limits: at most LIMIT requests per WINDOW seconds per IP ----
PREDICT_RATE_LIMIT = max(1, int(os.getenv("PREDICT_RATE_LIMIT", "10"))) # (env)
PREDICT_RATE_WINDOW = max(1.0, float(os.getenv("PREDICT_RATE_WINDOW", "60"))) # (env)
REVIEW_RATE_LIMIT = max(1, int(os.getenv("REVIEW_RATE_LIMIT", "5"))) # (env)
REVIEW_RATE_WINDOW = max(1.0, float(os.getenv("REVIEW_RATE_WINDOW", "60"))) # (env)