Source code for imgproxykit.transform

from dataclasses import dataclass
from itertools import starmap
from typing import Unpack

from typing_extensions import TypedDict

from imgproxykit.options import Option, ScalarOption
from imgproxykit.types import FormatType, ResizeType


[docs] class ScalarOptions(TypedDict, total=False, closed=True): """Optional scalar processing arguments accepted by :class:`Transform`.""" auto_rotate: bool blur: float cachebuster: str dpr: float enforce_thumbnail: bool enlarge: bool expires: int filename: str format: FormatType height: int keep_copyright: bool max_animation_frame_resolution: float max_animation_frames: int max_bytes: int max_result_dimension: int max_src_file_size: int max_src_resolution: float min_height: int min_width: int pixelate: int preserve_hdr: bool quality: int raw: bool resizing_type: ResizeType return_attachment: bool rotate: int sharpen: float strip_color_profile: bool strip_metadata: bool width: int
[docs] @dataclass(frozen=True, slots=True, init=False) class Transform: """ Define reusable image processing options. Stores an immutable tuple of options for reuse with :meth:`imgproxykit.Client.url`. Pass option instances or scalar keyword arguments; scalar options follow the positional options in keyword order. Options retain their supplied order during serialization. Imgproxy determines the image processing pipeline and resolves omitted arguments using its defaults. Preset options reference names configured on the imgproxy server and are not expanded here. Attributes: options: Tuple of processing options. Defaults to an empty tuple, which adds no processing option segments to the URL. """ # TODO: Add immutable derivation with explicit append/replace/remove # semantics. Define conflicts between overlapping options (Resize, Size, # Width, Height), repeated options, and server presets without expanding # preset definitions locally. Support clearing inherited options to # restore server defaults. # TODO: Document with examples that option order controls serialization # and overrides, while imgproxy determines the processing pipeline. options: tuple[Option, ...] def __init__( self, *options: Option, **kwargs: Unpack[ScalarOptions], ) -> None: """ Collect positional options, followed by scalar keyword options. Args: *options: Processing option instances in serialization order. Repeated options are retained without merging. **kwargs: Scalar processing arguments, such as ``quality=85`` or ``format='webp'``. Converted to option instances and appended in keyword order. Examples: Combine a resize option with scalar quality and format options: >>> from imgproxykit import Transform >>> from imgproxykit.options import Resize >>> thumbnail = Transform( ... Resize(width=96, height=96, mode='fill'), ... quality=85, ... format='webp', ... ) >>> [option.name for option in thumbnail.options] ['resize', 'quality', 'format'] """ # Keep variadic options while initializing a frozen dataclass. # Bypassing __setattr__ is safe until initialization is finished. scalar_options = tuple(starmap(ScalarOption.from_kwarg, kwargs.items())) object.__setattr__(self, 'options', (*options, *scalar_options))