Coverage for src/lexigram/admin/services/storage/mixins.py: 100%
7 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 14:28 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 14:28 +0800
1"""Upload handler protocol for resource controllers."""
3from __future__ import annotations
5from typing import Any, BinaryIO, Protocol
7from lexigram.admin.exceptions import DataError
8from lexigram.admin.services.storage.types import AdminFileInfo
9from lexigram.result import Result
12class UploadHandlerProtocol(Protocol):
13 """Protocol for resource controllers that handle file uploads.
15 Implement this protocol in controllers that need file upload capability.
16 Inject ``AdminStorageService`` via DI and call ``storage.upload()`` directly.
18 Example:
19 class UserController(ResourceController):
20 def __init__(self, storage: AdminStorageService):
21 self.storage = storage
23 async def upload_avatar(
24 self, user_id: int, file: bytes, filename: str
25 ) -> Result[AdminFileInfo, DataError]:
26 from lexigram.admin.services.storage.types import AdminUploadOptions
27 options = AdminUploadOptions(resource_type="users", resource_id=user_id)
28 return await self.storage.upload(file, filename, options)
29 """
31 async def handle_upload(
32 self,
33 data: bytes | BinaryIO,
34 filename: str,
35 resource_type: str | None = None,
36 resource_id: Any = None,
37 allowed_types: list[str] | None = None,
38 max_size: int | None = None,
39 uploaded_by: Any = None,
40 ) -> Result[AdminFileInfo, DataError]:
41 """Handle a file upload.
43 Args:
44 data: File content as bytes or file-like object.
45 filename: Original filename.
46 resource_type: Resource type for storage path organization.
47 resource_id: Resource identifier.
48 allowed_types: Allowed MIME types.
49 max_size: Maximum file size in bytes.
50 uploaded_by: Uploading user identifier.
52 Returns:
53 Result containing AdminFileInfo on success, DataError on failure.
54 """
55 ...