Coverage for src / lexigram / contracts / infra / storage / protocols.py: 0%
25 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Storage blob protocol class definitions."""
3from __future__ import annotations
5from datetime import timedelta
6from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
8from lexigram.contracts.core.provider import ProviderProtocol
9from lexigram.contracts.infra.storage.models import FileInfo
11if TYPE_CHECKING:
12 from collections.abc import AsyncIterator
14 from lexigram.contracts.core import HealthCheckResult
17@runtime_checkable
18class BlobStoreProtocol(Protocol):
19 """Protocol for blob storage operations.
21 This interface defines the contract for file storage backends
22 (S3, GCS, Azure Blob, local filesystem, etc.).
24 Example:
25 ```python
26 class S3BlobStore:
27 async def upload(self, path: str, data: bytes, **options) -> FileInfo:
28 await self._client.put_object(Bucket=self._bucket, Key=path, Body=data)
29 return FileInfo(path=path, size=len(data), ...)
30 ```
31 """
33 async def upload(
34 self,
35 path: str,
36 data: bytes | AsyncIterator[bytes],
37 content_type: str | None = None,
38 **options: Any,
39 ) -> FileInfo:
40 """Upload data to the storage backend.
42 Args:
43 path: Storage path/key.
44 data: File content as bytes or async iterator.
45 content_type: MIME type of the content.
46 **options: Additional upload options.
48 Returns:
49 FileInfo with path, size, and metadata.
50 """
51 ...
53 async def download(self, path: str) -> bytes:
54 """Download file content into memory.
56 Args:
57 path: Storage path/key.
59 Returns:
60 File content as bytes.
61 """
62 ...
64 def stream(self, path: str, chunk_size: int = 8192) -> AsyncIterator[bytes]:
65 """Stream file content (memory efficient).
67 Args:
68 path: Storage path/key.
69 chunk_size: Size of each chunk in bytes.
71 Yields:
72 File content in chunks.
73 """
74 ...
76 async def delete(self, path: str) -> None:
77 """Delete a file.
79 Args:
80 path: Storage path/key.
81 """
82 ...
84 async def exists(self, path: str) -> bool:
85 """Check if file exists.
87 Args:
88 path: Storage path/key.
90 Returns:
91 True if file exists.
92 """
93 ...
95 async def info(self, path: str) -> FileInfo:
96 """Get file metadata.
98 Args:
99 path: Storage path/key.
101 Returns:
102 FileInfo with size, content_type, etc.
103 """
104 ...
106 def list(self, prefix: str = "") -> AsyncIterator[FileInfo]:
107 """List files with a given prefix.
109 Args:
110 prefix: Path prefix to filter by.
112 Yields:
113 FileInfo for each matching file.
114 """
115 ...
117 async def get_url(self, path: str) -> str:
118 """Get public URL (if applicable).
120 Args:
121 path: Storage path/key.
123 Returns:
124 Public URL string.
125 """
126 ...
128 async def get_presigned_url(
129 self,
130 path: str,
131 expires_in: timedelta = timedelta(hours=1),
132 method: str = "GET",
133 ) -> str:
134 """Get a temporary secure URL.
136 Args:
137 path: Storage path/key.
138 expires_in: URL validity window as a :class:`~datetime.timedelta`
139 (default one hour). Pass ``timedelta(minutes=5)`` for secure
140 short-lived downloads or ``timedelta(hours=24)`` for bulk exports.
141 method: HTTP method (GET or PUT).
143 Returns:
144 Presigned URL string.
145 """
146 ...
148 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
149 """Perform health check.
151 Returns:
152 Structured health check result.
153 """
154 ...
157@runtime_checkable
158class StorageDriverProtocol(Protocol):
159 """Protocol for storage driver implementations.
161 This interface extends BlobStoreProtocol with driver-specific operations
162 such as copy, move, and batch operations. Storage drivers
163 (S3, GCS, Azure, local filesystem, memory) should implement this
164 protocol or extend BaseDriver.
166 Example:
167 ```python
168 class S3Driver:
169 async def copy(self, source: str, destination: str) -> None:
170 await self._client.copy_object(Bucket=self._bucket, Key=destination, CopySource=source)
172 async def move(self, source: str, destination: str) -> None:
173 await self.copy(source, destination)
174 await self.delete(source)
175 ```
176 """
178 async def copy(self, source: str, destination: str) -> None:
179 """Copy a file from source to destination.
181 Args:
182 source: Source storage path/key.
183 destination: Destination storage path/key.
184 """
185 ...
187 async def move(self, source: str, destination: str) -> None:
188 """Move a file from source to destination.
190 Args:
191 source: Source storage path/key.
192 destination: Destination storage path/key.
193 """
194 ...
196 async def copy_batch(self, operations: list[tuple[str, str]]) -> list[str]:
197 """Execute batch copy operations.
199 Args:
200 operations: List of (source, destination) tuples.
202 Returns:
203 List of destination paths that were copied.
204 """
205 ...
208@runtime_checkable
209class StorageProviderProtocol(ProviderProtocol, Protocol):
210 """Protocol for storage providers.
212 Storage providers are responsible for setting up blob stores,
213 file systems, and CDN integration.
214 """
217__all__ = [
218 "BlobStoreProtocol",
219 "FileInfo",
220 "StorageDriverProtocol",
221 "StorageProviderProtocol",
222]