Variants¶
Define the image sizes your application uses as a dictionary of names and
Transform objects. Pass that dictionary to
variants() to generate a URL for each name.
Build a set of URLs¶
Start with a complete transformation for each variant:
from imgproxykit import Client, Transform
products = {
'small': Transform(width=320),
'medium': Transform(width=640),
'large': Transform(width=1280),
}
client = Client('https://imgproxy.example.com')
source_url = 'https://originals.example.com/product.jpg'
product_urls = client.variants(source_url, variants=products)
small_url = product_urls['small'] # Access a URL by its variant name.
product_urls contains a URL for each of the three widths. Read an
individual URL by its name, or pass the dictionary to your template or API
response. The keys and their order match products; an empty input
mapping returns an empty dictionary.
Each URL is built through url() using the client’s
signing configuration.
Compose reusable sets¶
Keep common quality and format settings in a shared transformation. Unpack its options into complete transformations for each product size and avatar crop, as described in Transformations:
from imgproxykit import Client, Transform
from imgproxykit.options import Resize
# Share quality and output format across both sets.
base = Transform(quality=85, format='webp')
products = {
# Add dimensions to the shared options for each variant.
'small': Transform(*base.options, width=320),
'medium': Transform(*base.options, width=640),
'large': Transform(*base.options, width=1280),
}
avatars = {
'thumbnail': Transform(
*base.options,
Resize(width=48, height=48, mode='fill'),
),
'profile': Transform(
*base.options,
Resize(width=192, height=192, mode='fill'),
),
}
client = Client('https://imgproxy.example.com')
product_urls = client.variants(
'https://originals.example.com/product.jpg',
variants=products,
)
another_product_urls = client.variants(
'https://originals.example.com/another-product.jpg',
variants=products,
)
avatar_urls = client.variants(
'https://originals.example.com/avatar.jpg',
variants=avatars,
)
Define these sets once and reuse them for different source images.
product_urls and another_product_urls have the same names and
processing settings, with URLs pointing to their respective sources.
avatar_urls uses the separate avatar set.
The names belong to your application: small and profile do not have
special meaning to imgproxy. Each value supplies its full transformation;
the client uses it unchanged.
Type the variant names¶
Plain dictionaries work without annotations. To check names when accessing
the resulting URLs, define a Literal union for each set and annotate
its dictionary:
from typing import Literal
type ProductKeys = Literal['small', 'medium', 'large']
type AvatarKeys = Literal['thumbnail', 'profile']
products: dict[ProductKeys, Transform] = {
'small': Transform(*base.options, width=320),
'medium': Transform(*base.options, width=640),
'large': Transform(*base.options, width=1280),
}
Annotate avatars as dict[AvatarKeys, Transform] in the same way.
The calls above then return dict[ProductKeys, str] and
dict[AvatarKeys, str], respectively. A type checker accepts
product_urls['small'] and reports product_urls['profile'] as an
invalid key.
Without an explicit key annotation, a regular string-keyed dictionary
typically produces dict[str, str]. A literal union limits the allowed
key names; it does not require every name in the union to be present.
Next steps¶
Transformations — compose processing options.
Processing options — choose dimensions, formats, and other settings.
Client — complete client signatures.