Add comprehensive test suite for image processing and related services
- Implement tests for database generator to ensure proper session handling. - Create tests for EXIF extraction and conversion functions. - Add tests for image-related endpoints, ensuring proper data retrieval and isolation between clients. - Develop tests for OCR functionality, including language detection and text extraction. - Introduce tests for the image processing pipeline, covering success and failure scenarios. - Validate rate limiting functionality and ensure independent counters for different clients. - Implement scraper tests to verify HTML content fetching and error handling. - Add unit tests for various services, including storage and filename generation. - Establish worker entry point for ARQ to handle background image processing tasks.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Router — Files : sert les fichiers locaux via URLs signées HMAC.
|
||||
|
||||
Monté uniquement quand STORAGE_BACKEND == "local".
|
||||
"""
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from app.config import settings
|
||||
from app.services.storage_backend import get_storage_backend, LocalStorage
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/files", tags=["Fichiers"])
|
||||
|
||||
|
||||
@router.get(
|
||||
"/signed/{token}",
|
||||
summary="Télécharger un fichier via URL signée",
|
||||
description="Valide le token HMAC et retourne le fichier correspondant.",
|
||||
)
|
||||
async def serve_signed_file(token: str):
|
||||
"""Sert un fichier local via un token HMAC signé."""
|
||||
backend = get_storage_backend()
|
||||
|
||||
if not isinstance(backend, LocalStorage):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Endpoint non disponible avec le backend de stockage actuel",
|
||||
)
|
||||
|
||||
# Valider le token
|
||||
path = backend.validate_token(token)
|
||||
if path is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Token invalide ou expiré",
|
||||
)
|
||||
|
||||
# Vérifier que le fichier existe
|
||||
abs_path = backend.get_absolute_path(path)
|
||||
if not abs_path.exists():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_410_GONE,
|
||||
detail="Le fichier n'existe plus",
|
||||
)
|
||||
|
||||
# Détecter le content type
|
||||
suffix = abs_path.suffix.lower()
|
||||
mime_map = {
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".png": "image/png",
|
||||
".gif": "image/gif",
|
||||
".webp": "image/webp",
|
||||
".bmp": "image/bmp",
|
||||
".tiff": "image/tiff",
|
||||
}
|
||||
media_type = mime_map.get(suffix, "application/octet-stream")
|
||||
|
||||
return FileResponse(
|
||||
path=str(abs_path),
|
||||
media_type=media_type,
|
||||
filename=abs_path.name,
|
||||
)
|
||||
Reference in New Issue
Block a user