"""Definition of ObjectRepositoryInterface protocol and abstract base class.""" from abc import abstractmethod from io import BytesIO from typing import Protocol, runtime_checkable @runtime_checkable class ObjectRepositoryInterface(Protocol): """Interface that defines binary object CRUD methods.""" @abstractmethod def get(self, object_name: str) -> BytesIO | None: """Get an object by name. Returns ``None`` when the object does not exist. Returns an empty ``BytesIO`` for a zero-byte object. Use ``value is not None`` to test existence. Raises ConnectionError when not connected. Other backend errors propagate to the caller. """ ... @abstractmethod def put( self, object_name: str, data: BytesIO, content_type: str = "application/octet-stream", ) -> None: """Put an object by name. Accepts zero-byte ``BytesIO``. A zero-byte object is returned by ``get()`` as an empty buffer, not ``None``. Use ``delete()`` to remove an object entirely. """ ... @abstractmethod def delete(self, object_name: str) -> None: """Delete an object by name, removing it entirely.""" ... @abstractmethod def list_objects(self, prefix: str = "") -> list[str]: """List object names with an optional prefix.""" ...