from abc import ABC, abstractmethod class StorageClient(ABC): @abstractmethod async def download_bytes(self, bucket: str, path: str) -> bytes: """Download an object and return its raw bytes.""" @abstractmethod async def upload_bytes( self, bucket: str, path: str, data: bytes, content_type: str = "application/octet-stream" ) -> None: """Upload raw bytes to the given bucket/path.""" @abstractmethod async def get_presigned_url(self, bucket: str, path: str, expires: int = 3600) -> str: """Return a presigned GET URL valid for `expires` seconds.""" @abstractmethod async def get_object_size(self, bucket: str, path: str) -> int: """Return the object size in bytes without downloading it."""