Files
odysseus/src/upload_limits.py

45 lines
1.3 KiB
Python

"""Small helpers for route-local upload size caps."""
import os
from fastapi import HTTPException, UploadFile
DEFAULT_CHAT_UPLOAD_MAX_BYTES = 10 * 1024 * 1024
CHAT_UPLOAD_MAX_BYTES_ENV = "ODYSSEUS_CHAT_UPLOAD_MAX_BYTES"
def format_byte_limit(limit: int) -> str:
if limit % (1024 * 1024) == 0:
return f"{limit // (1024 * 1024)} MB"
if limit % 1024 == 0:
return f"{limit // 1024} KB"
return f"{limit} bytes"
def read_byte_limit_env(name: str, default: int) -> int:
raw = os.getenv(name)
if raw is None or not raw.strip():
return default
try:
limit = int(raw)
except ValueError as exc:
raise ValueError(f"{name} must be an integer byte count") from exc
if limit < 1:
raise ValueError(f"{name} must be greater than 0")
return limit
def get_chat_upload_max_bytes() -> int:
return read_byte_limit_env(CHAT_UPLOAD_MAX_BYTES_ENV, DEFAULT_CHAT_UPLOAD_MAX_BYTES)
async def read_upload_limited(upload: UploadFile, limit: int, label: str = "Upload") -> bytes:
"""Read an UploadFile with a hard byte cap."""
data = await upload.read(limit + 1)
if len(data) > limit:
raise HTTPException(
status_code=413,
detail=f"{label} exceeds {format_byte_limit(limit)} limit",
)
return data