| from abc import ABC, abstractmethod
|
| from typing import Optional
|
| from fastapi import UploadFile
|
|
|
|
|
| class StorageProvider(ABC):
|
| """Abstract base class for storage providers."""
|
|
|
| @abstractmethod
|
| async def upload_file(
|
| self, file: UploadFile, user_id: int, folder: str = "avatar"
|
| ) -> str:
|
| """Upload a file and return the storage key."""
|
| raise NotImplementedError
|
|
|
| @abstractmethod
|
| def get_file_url(self, file_key: str) -> Optional[str]:
|
| """Get a public URL for a stored file if available."""
|
| raise NotImplementedError
|
|
|
| @abstractmethod
|
| async def delete_file(self, file_key: str) -> bool:
|
| """Delete a stored file and return success status."""
|
| raise NotImplementedError
|
|
|
| @abstractmethod
|
| async def upload_bytes(
|
| self,
|
| content: bytes,
|
| user_id: int,
|
| folder: str = "thumbnails",
|
| filename: Optional[str] = None,
|
| content_type: str = "image/png",
|
| ) -> str:
|
| """Upload raw bytes and return the storage key."""
|
| raise NotImplementedError
|
|
|
| @abstractmethod
|
| async def download_file(self, file_key: str) -> Optional[bytes]:
|
| """Download file bytes by storage key, or None if not found."""
|
| raise NotImplementedError
|
|
|