Coverage for fastblocks/adapters/images/_base.py: 100%
20 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 00:47 -0700
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 00:47 -0700
1"""Base classes and protocols for image adapters."""
3from contextlib import suppress
4from typing import Any, Protocol
5from uuid import UUID
7from acb.config import AdapterBase, Settings
8from acb.depends import depends
11class ImagesBaseSettings(Settings): # type: ignore[misc]
12 """Base settings for image adapters."""
14 cdn_url: str | None = None
15 media_bucket: str = "media"
16 default_transformations: dict[str, Any] = {}
17 lazy_loading: bool = True
20class ImagesProtocol(Protocol):
21 """Protocol for image adapter implementations."""
23 async def upload_image(self, file_data: bytes, filename: str) -> str: ...
24 async def get_image_url(
25 self, image_id: str, transformations: dict[str, Any] | None = None
26 ) -> str: ...
27 def get_img_tag(self, image_id: str, alt: str, **attributes: Any) -> str: ...
30class ImagesBase(AdapterBase): # type: ignore[misc]
31 """Base class for image adapters."""
33 # Required ACB 0.19.0+ metadata
34 MODULE_ID: UUID = UUID("01937d86-4f2a-7b3c-8d9e-f3b4d3c2b1a1") # Static UUID7
35 MODULE_STATUS = "stable"
37 def __init__(self) -> None:
38 """Initialize image adapter."""
39 # Register with ACB dependency system
40 with suppress(Exception):
41 depends.set(self)
43 async def upload_image(self, file_data: bytes, filename: str) -> str:
44 """Upload image and return image ID."""
45 raise NotImplementedError()
47 async def get_image_url(
48 self, image_id: str, transformations: dict[str, Any] | None = None
49 ) -> str:
50 """Generate image URL with optional transformations."""
51 raise NotImplementedError()
53 def get_img_tag(self, image_id: str, alt: str, **attributes: Any) -> str:
54 """Generate complete img tag with attributes."""
55 raise NotImplementedError()