Saudi_Law_Vision / app /utils /file_handler.py
MustafaHussein's picture
update
1fce3ef
Raw History Blame Contribute Delete
3.02 kB
"""
File handling utilities
Upload, download, and manage files
"""
import os
import uuid
from typing import Optional
from pathlib import Path
from fastapi import UploadFile, HTTPException
from app.core.constants import (
MAX_UPLOAD_SIZE,
ALLOWED_DOCUMENT_EXTENSIONS,
ALLOWED_IMAGE_EXTENSIONS,
DOCUMENTS_DIR,
IMAGES_DIR
)
def validate_file_size(file: UploadFile, max_size: int = MAX_UPLOAD_SIZE) -> bool:
"""
Validate file size
Args:
file: Uploaded file
max_size: Maximum allowed size in bytes
Returns:
True if valid
Raises:
HTTPException: If file is too large
"""
file.file.seek(0, 2) # Seek to end
file_size = file.file.tell()
file.file.seek(0) # Reset
if file_size > max_size:
raise HTTPException(
status_code=413,
detail=f"File too large. Maximum size: {max_size / 1024 / 1024:.1f}MB"
)
return True
def validate_file_extension(filename: str, allowed_extensions: set) -> bool:
"""
Validate file extension
Args:
filename: File name
allowed_extensions: Set of allowed extensions
Returns:
True if valid
Raises:
HTTPException: If extension not allowed
"""
ext = Path(filename).suffix.lower()
if ext not in allowed_extensions:
raise HTTPException(
status_code=400,
detail=f"File type not allowed. Allowed: {', '.join(allowed_extensions)}"
)
return True
def generate_unique_filename(original_filename: str) -> str:
"""
Generate unique filename
Args:
original_filename: Original file name
Returns:
Unique filename
"""
ext = Path(original_filename).suffix
unique_name = f"{uuid.uuid4()}{ext}"
return unique_name
async def save_upload_file(
file: UploadFile,
destination_dir: str,
allowed_extensions: set = ALLOWED_DOCUMENT_EXTENSIONS
) -> str:
"""
Save uploaded file
Args:
file: Uploaded file
destination_dir: Directory to save file
allowed_extensions: Allowed file extensions
Returns:
Saved file path
"""
# Validate
validate_file_size(file)
validate_file_extension(file.filename, allowed_extensions)
# Create directory if not exists
os.makedirs(destination_dir, exist_ok=True)
# Generate unique filename
filename = generate_unique_filename(file.filename)
file_path = os.path.join(destination_dir, filename)
# Save file
with open(file_path, "wb") as f:
content = await file.read()
f.write(content)
return file_path
def delete_file(file_path: str) -> bool:
"""
Delete file
Args:
file_path: Path to file
Returns:
True if deleted
"""
if os.path.exists(file_path):
os.remove(file_path)
return True
return False