Installation
pip install sirv-client
from sirv_image import SirvClient
Quick Start
from sirv_image import SirvClient
sirv = SirvClient(domain='demo.sirv.com', defaults={'q': 80})
# Build a URL
sirv.url('/image.jpg', {'w': 300, 'h': 200, 'format': 'webp'})
# => https://demo.sirv.com/image.jpg?q=80&w=300&h=200&format=webp
# Generate an image tag
sirv.image('/photo.jpg', alt='A photo')
# => <img class="Sirv" data-src="https://demo.sirv.com/photo.jpg" alt="A photo">
# Generate a script tag
sirv.script_tag(modules=['spin', 'zoom'])
# => <script src="https://scripts.sirv.com/sirvjs/v3/sirv.spin.zoom.js" async></script>
Constructor
SirvClient(domain, defaults=None)
| Option | Type | Description |
|---|---|---|
domain | str | Required. Sirv domain (e.g. 'demo.sirv.com') |
defaults | dict | Default query parameters merged into every URL |
sirv = SirvClient(
domain='demo.sirv.com',
defaults={'q': 80}
)
url(path, params=None)
Build a full Sirv URL. Nested dicts are flattened to dot-notation query parameters. Default parameters are merged with the provided params.
| Param | Type | Description |
|---|---|---|
path | str | Asset path (e.g. '/image.jpg') |
params | dict | Transformation parameters (nested dicts are flattened) |
# Simple params
sirv.url('/image.jpg', {'w': 300, 'h': 200, 'format': 'webp'})
# => https://demo.sirv.com/image.jpg?q=80&w=300&h=200&format=webp
# Nested params flatten to dot-notation
sirv.url('/image.jpg', {'crop': {'type': 'face', 'pad': {'width': 10, 'height': 10}}})
# => ...?q=80&crop.type=face&crop.pad.width=10&crop.pad.height=10
# Params override defaults
sirv.url('/image.jpg', {'q': 90})
# => https://demo.sirv.com/image.jpg?q=90
src_set(path, params=None, *, widths=None, min_width=None, max_width=None, tolerance=0.15, device_pixel_ratios=None)
Generate a srcset string for responsive images. Supports three modes:
Explicit widths
sirv.src_set('/image.jpg', {'format': 'webp'}, widths=[320, 640, 960, 1280, 1920])
# => https://demo.sirv.com/image.jpg?q=80&format=webp&w=320 320w,
# https://demo.sirv.com/image.jpg?q=80&format=webp&w=640 640w, ...
Auto-generated widths (tolerance)
Generates widths between min_width and max_width, stepping by current *= 1 + tolerance * 2.
sirv.src_set('/image.jpg', {'format': 'webp'},
min_width=200, max_width=2000, tolerance=0.15
)
Device pixel ratios (DPR)
Generates DPR variants with automatic variable quality: q = round(baseQ × 0.75(dpr-1)). Width and height are multiplied by the DPR.
sirv.src_set('/hero.jpg', {'w': 600, 'h': 400}, device_pixel_ratios=[1, 2, 3])
# 1x: q=80, w=600, h=400
# 2x: q=60, w=1200, h=800
# 3x: q=45, w=1800, h=1200
| Option | Type | Description |
|---|---|---|
widths | list[int] | Explicit list of widths |
min_width | int | Minimum width for auto-generation |
max_width | int | Maximum width for auto-generation |
tolerance | float | Step tolerance (default 0.15) |
device_pixel_ratios | list[int] | DPR values (e.g. [1, 2, 3]) |
image(path, *, transform=None, viewer=None, alt=None, class_name=None)
Generate an <img> tag for a Sirv image with class="Sirv" and data-src.
| Option | Type | Description |
|---|---|---|
transform | dict | Transformation parameters for the URL |
viewer | dict | Viewer options (serialized to data-options) |
alt | str | Alt text |
class_name | str | Additional CSS class(es) |
sirv.image('/tomatoes.jpg', alt='Fresh tomatoes')
# => <img class="Sirv" data-src="https://demo.sirv.com/tomatoes.jpg" alt="Fresh tomatoes">
sirv.image('/photo.jpg',
transform={'w': 800, 'format': 'webp'},
viewer={'autostart': 'visible', 'threshold': 200},
class_name='hero-image'
)
# => <img class="Sirv hero-image" data-src="...?q=80&w=800&format=webp"
# data-options="autostart:visible;threshold:200">
zoom(path, *, transform=None, viewer=None, class_name=None)
Generate a <div> tag for a Sirv zoom viewer with data-type="zoom".
| Option | Type | Description |
|---|---|---|
transform | dict | Transformation parameters |
viewer | dict | Viewer options |
class_name | str | Additional CSS class(es) |
sirv.zoom('/product.jpg')
# => <div class="Sirv" data-src="https://demo.sirv.com/product.jpg" data-type="zoom"></div>
sirv.zoom('/product.jpg', viewer={'mode': 'deep', 'wheel': False})
# => <div ... data-type="zoom" data-options="mode:deep;wheel:False"></div>
spin(path, *, viewer=None, class_name=None)
Generate a <div> tag for a Sirv 360 spin viewer. No data-type attribute is added (Sirv JS auto-detects .spin files).
| Option | Type | Description |
|---|---|---|
viewer | dict | Viewer options |
class_name | str | Additional CSS class(es) |
sirv.spin('/product.spin')
# => <div class="Sirv" data-src="https://demo.sirv.com/product.spin"></div>
sirv.spin('/product.spin', viewer={'autostart': 'visible', 'autospin': 'lazy'})
video(path, *, viewer=None, class_name=None)
Generate a <div> tag for a Sirv video.
sirv.video('/clip.mp4')
# => <div class="Sirv" data-src="https://demo.sirv.com/clip.mp4"></div>
model(path, *, viewer=None, class_name=None)
Generate a <div> tag for a Sirv 3D model viewer.
sirv.model('/shoe.glb')
# => <div class="Sirv" data-src="https://demo.sirv.com/shoe.glb"></div>
gallery(items, *, viewer=None, class_name=None)
Generate a gallery container with multiple asset divs. Each item can have its own type, transform params, and viewer options. Gallery-level viewer options apply to the container.
Item properties
| Property | Type | Description |
|---|---|---|
src | str | Required. Asset path |
type | str | Asset type override (e.g. 'zoom') |
transform | dict | Per-item transformation params |
viewer | dict | Per-item viewer options |
Gallery options
| Option | Type | Description |
|---|---|---|
viewer | dict | Gallery-level viewer options |
class_name | str | Additional CSS class(es) |
sirv.gallery([
{'src': '/product.spin'},
{'src': '/front.jpg', 'type': 'zoom'},
{'src': '/side.jpg', 'type': 'zoom'},
{'src': '/video.mp4'}
], viewer={'arrows': True, 'thumbnails': 'bottom'})
# => <div class="Sirv" data-options="arrows:True;thumbnails:bottom">
# <div data-src="https://demo.sirv.com/product.spin"></div>
# <div data-src="https://demo.sirv.com/front.jpg" data-type="zoom"></div>
# <div data-src="https://demo.sirv.com/side.jpg" data-type="zoom"></div>
# <div data-src="https://demo.sirv.com/video.mp4"></div>
# </div>
script_tag(*, modules=None, async_attr=True)
Generate a <script> tag to load Sirv JS. Optionally specify modules to load only what you need.
| Option | Type | Description |
|---|---|---|
modules | list[str] | Modules to load (e.g. ['spin', 'zoom']) |
async_attr | bool | Add async attribute (default True) |
sirv.script_tag()
# => <script src="https://scripts.sirv.com/sirvjs/v3/sirv.js" async></script>
sirv.script_tag(modules=['spin', 'zoom'])
# => <script src="https://scripts.sirv.com/sirvjs/v3/sirv.spin.zoom.js" async></script>
Full Examples
Responsive Product Page
from sirv_image import SirvClient
sirv = SirvClient(domain='mystore.sirv.com', defaults={'q': 80})
# Responsive image with srcset
srcset = sirv.src_set('/hero.jpg', {'format': 'webp'},
widths=[320, 640, 960, 1280, 1920]
)
print(f'<img srcset="{srcset}" sizes="100vw">')
# Product gallery with zoom, spin, and video
gallery = sirv.gallery([
{'src': '/products/shoe.spin'},
{'src': '/products/shoe-front.jpg', 'type': 'zoom'},
{'src': '/products/shoe-side.jpg', 'type': 'zoom'},
{'src': '/products/shoe-video.mp4'}
], viewer={'thumbnails': 'bottom'})
# Load Sirv JS for spin + zoom
script = sirv.script_tag(modules=['spin', 'zoom'])
Thumbnail Grid with Face Crop
images = ['/team/alice.jpg', '/team/bob.jpg', '/team/carol.jpg']
html = '\n'.join(
sirv.image(path,
transform={'w': 200, 'h': 200, 'crop': {'type': 'face'}},
alt=path.split('/')[-1]
)
for path in images
)