Official Python SDK for Sirv REST API - Image CDN, 360 Spins, and Media Management
Project description
Sirv REST API Python SDK
Official Python SDK for the Sirv REST API - Image CDN, 360 Spins, and Media Management.
Features
- Full API Coverage: All Sirv REST API endpoints implemented
- Type Hints: Complete type annotations for IDE support
- Automatic Token Management: Auto-refresh tokens before expiry
- Pagination Helpers: Generators for iterating through large result sets
- Context Manager Support: Use with
withstatement for automatic cleanup - Retry Logic: Built-in retry mechanism for failed requests
Installation
pip install sirv-rest-api
Or with optional async support:
pip install sirv-rest-api[async]
Quick Start
from sirv_rest_api import SirvClient
# Initialize the client
client = SirvClient(
client_id="your-client-id",
client_secret="your-client-secret"
)
# Connect to get access token
client.connect()
# Get account information
account = client.get_account_info()
print(f"CDN URL: {account['cdnURL']}")
# Upload a file
client.upload_file("/images/photo.jpg", "./local/photo.jpg")
# Search for files
results = client.search_files({"query": "*.jpg", "size": 100})
for file in results['hits']:
print(file['filename'])
Using Context Manager
from sirv_rest_api import SirvClient
with SirvClient(
client_id="your-client-id",
client_secret="your-client-secret"
) as client:
account = client.get_account_info()
print(f"Account: {account['alias']}")
# Session automatically closed
API Reference
Authentication
Connect
Authenticate and obtain a bearer token. Tokens are automatically refreshed before expiry.
token_info = client.connect()
print(f"Token expires in: {token_info['expiresIn']} seconds")
print(f"Scopes: {token_info['scope']}")
# Optional: Request a token with custom expiry time (5-604800 seconds)
token_info = client.connect(expires_in=3600) # Token valid for 1 hour
The connect() method accepts an optional expires_in parameter to customize token lifetime:
- Range: 5 to 604800 seconds (7 days)
- Default: 1200 seconds (20 minutes)
Check Connection Status
if client.is_connected():
print("Client is connected")
Account Management
Get Account Info
account = client.get_account_info()
print(f"CDN URL: {account['cdnURL']}")
print(f"Alias: {account['alias']}")
print(f"Created: {account['dateCreated']}")
Update Account Settings
client.update_account({
"minify": {"enabled": True},
"fetching": {
"enabled": True,
"type": "http",
"http": {"url": "https://example.com/images"}
}
})
Get API Rate Limits
limits = client.get_account_limits()
print(f"REST API - Remaining: {limits['rest']['remaining']}/{limits['rest']['limit']}")
Get Storage Info
storage = client.get_storage_info()
print(f"Used: {storage['used'] / 1e9:.2f} GB of {storage['allowance'] / 1e9:.2f} GB")
print(f"Files: {storage['files']}")
Get Account Users
users = client.get_account_users()
for user in users:
print(f"{user['email']} - {user['role']}")
Get Billing Plan
plan = client.get_billing_plan()
print(f"Plan: {plan['name']}")
print(f"Storage: {plan['storage'] / 1e9:.2f} GB")
Search Account Events
events = client.search_events({
"level": "error",
"module": "files",
"from_": "2024-01-01",
"to": "2024-01-31"
})
for event in events:
print(f"{event['timestamp']}: {event['message']}")
Mark Events as Seen
client.mark_events_seen(["event-id-1", "event-id-2"])
User Management
Get User Info
# Current user
user = client.get_user_info()
print(f"Email: {user['email']}")
print(f"S3 Key: {user.get('s3Key')}")
# Specific user
user = client.get_user_info(user_id="user-123")
File Operations
Upload Files
# Upload from file path
client.upload_file("/images/photo.jpg", "./local/photo.jpg")
# Upload from bytes
with open("photo.jpg", "rb") as f:
photo_bytes = f.read()
client.upload_file("/images/photo.jpg", photo_bytes)
# Upload with options
client.upload_file(
"/images/photo.jpg",
"./local/photo.jpg",
options={"content_type": "image/jpeg"}
)
Download Files
# Download to bytes
content = client.download_file("/images/photo.jpg")
# Download to local file
client.download_file_to("/images/photo.jpg", "./downloads/photo.jpg")
Get File Info
info = client.get_file_info("/images/photo.jpg")
print(f"Size: {info['size']} bytes")
print(f"Content-Type: {info['contentType']}")
print(f"Modified: {info['mtime']}")
Copy Files
client.copy_file("/images/photo.jpg", "/backup/photo.jpg")
Rename/Move Files
client.rename_file("/images/old-name.jpg", "/images/new-name.jpg")
# Move to different folder
client.rename_file("/images/photo.jpg", "/archive/photo.jpg")
Delete Files
# Delete single file
client.delete_file("/images/old-photo.jpg")
# Batch delete
result = client.batch_delete(["/old/file1.jpg", "/old/file2.jpg", "/old/file3.jpg"])
print(f"Job ID: {result.get('jobId')}")
# Check batch delete status
status = client.get_batch_delete_status(result['jobId'])
print(f"Status: {status['status']}")
Fetch from URL
client.fetch_url(
url="https://example.com/image.jpg",
filename="/fetched/image.jpg",
wait=True # Wait for completion
)
Folder Operations
Create Folder
client.create_folder("/images/2024")
Read Folder Contents
# Single page
contents = client.read_folder_contents("/images")
for item in contents['contents']:
if item['isDirectory']:
print(f"[DIR] {item['filename']}")
else:
print(f"[FILE] {item['filename']} - {item['size']} bytes")
# With pagination
contents = client.read_folder_contents("/images")
while True:
for item in contents['contents']:
print(item['filename'])
if not contents.get('continuation'):
break
contents = client.read_folder_contents("/images", contents['continuation'])
Iterate All Folder Contents
# Automatically handles pagination
for item in client.iterate_folder_contents("/images"):
print(f"{item['filename']}: {item.get('size', 'dir')}")
Folder Options
# Get folder options
options = client.get_folder_options("/spins")
print(f"Scan spins: {options.get('scanSpins')}")
# Set folder options
client.set_folder_options("/spins", {"scanSpins": True})
Search
Search Files
results = client.search_files({
"query": "*.jpg",
"size": 100,
"sort": {"field": "mtime", "order": "desc"},
"filters": {
"dirname": "/images",
"minSize": 10000,
"maxSize": 5000000
}
})
print(f"Found {results['total']} files")
for file in results['hits']:
print(f"{file['filename']} - {file['size']} bytes")
Paginated Search
results = client.search_files({"query": "*.png"})
all_files = results['hits']
while results.get('scrollId') and results['hits']:
results = client.scroll_search(results['scrollId'])
all_files.extend(results['hits'])
print(f"Total files found: {len(all_files)}")
Iterate Search Results
# Automatically handles pagination
for file in client.iterate_search_results({"query": "*.png", "size": 1000}):
print(file['filename'])
Metadata Management
File Metadata
# Get all metadata
meta = client.get_file_meta("/images/photo.jpg")
print(f"Title: {meta.get('title')}")
print(f"Description: {meta.get('description')}")
print(f"Tags: {meta.get('tags')}")
# Set metadata
client.set_file_meta("/images/photo.jpg", {
"title": "Beautiful Sunset",
"description": "Photo taken at the beach during sunset",
"tags": ["sunset", "beach", "nature", "landscape"]
})
Title
# Get title
result = client.get_file_title("/images/photo.jpg")
print(result['title'])
# Set title
client.set_file_title("/images/photo.jpg", "My Beautiful Photo")
Description
# Get description
result = client.get_file_description("/images/photo.jpg")
print(result['description'])
# Set description
client.set_file_description("/images/photo.jpg", "A stunning landscape photograph")
Tags
# Get tags
result = client.get_file_tags("/images/photo.jpg")
print(result['tags'])
# Add tags
client.add_file_tags("/images/photo.jpg", ["nature", "landscape"])
# Remove tags
client.remove_file_tags("/images/photo.jpg", ["old-tag"])
Product Metadata
# Get product metadata
product = client.get_product_meta("/products/item.jpg")
print(f"SKU: {product.get('sku')}")
print(f"Brand: {product.get('brand')}")
# Set product metadata
client.set_product_meta("/products/item.jpg", {
"id": "PROD-123",
"name": "Blue Widget",
"sku": "BW-001",
"brand": "Acme",
"category": "Widgets"
})
Approval Flag
# Get approval status
result = client.get_approval_flag("/images/photo.jpg")
print(f"Approved: {result['approved']}")
# Set approval flag
client.set_approval_flag("/images/photo.jpg", True)
ZIP Operations
# Create ZIP archive
result = client.batch_zip({
"filenames": ["/images/1.jpg", "/images/2.jpg", "/images/3.jpg"],
"filename": "/archives/photos.zip"
})
print(f"Job ID: {result.get('jobId')}")
# Check ZIP job status
status = client.get_zip_status(result['jobId'])
if status['status'] == 'completed':
print(f"ZIP created: {status['filename']}")
JWT Protected URLs
jwt = client.generate_jwt({
"filename": "/protected/image.jpg",
"expiresIn": 3600, # 1 hour
"secureParams": {
"w": "800",
"h": "600"
}
})
print(f"Protected URL: {jwt['url']}")
print(f"Token: {jwt['token']}")
360 Spin Operations
Convert Spin to Video
result = client.spin2video({
"filename": "/spins/product.spin",
"options": {
"width": 1920,
"height": 1080,
"loops": 2,
"format": "mp4"
}
})
print(f"Video created: {result['filename']}")
Convert Video to Spin
result = client.video2spin({
"filename": "/videos/turntable.mp4",
"targetFilename": "/spins/product.spin",
"options": {
"frames": 36,
"start": 0,
"duration": 10
}
})
print(f"Spin created: {result['filename']}")
Export Spin to Marketplaces
# Amazon
client.export_spin_to_amazon({
"filename": "/spins/product.spin",
"asin": "B08N5WRWNW"
})
# Walmart
client.export_spin_to_walmart({
"filename": "/spins/product.spin",
"productId": "123456789"
})
# Home Depot
client.export_spin_to_home_depot({
"filename": "/spins/product.spin",
"productId": "123456789"
})
# Lowe's
client.export_spin_to_lowes({
"filename": "/spins/product.spin",
"productId": "123456789"
})
# Grainger
client.export_spin_to_grainger({
"filename": "/spins/product.spin",
"productId": "123456789"
})
Points of Interest
# Get POIs
pois = client.get_points_of_interest("/spins/product.spin")
for poi in pois:
print(f"{poi['name']}: ({poi['x']}, {poi['y']}) frame {poi.get('frame')}")
# Set POI
client.set_point_of_interest("/spins/product.spin", {
"name": "logo",
"x": 0.5,
"y": 0.3,
"frame": 0
})
# Delete POI
client.delete_point_of_interest("/spins/product.spin", "logo")
Statistics
HTTP Transfer Stats
stats = client.get_http_stats("2024-01-01", "2024-01-31")
for day in stats:
print(f"{day['date']}: {day['transfer'] / 1e9:.2f} GB transferred")
Spin Views Stats
# Max 5-day range
stats = client.get_spin_views_stats("2024-01-01", "2024-01-05")
for day in stats:
print(f"{day['date']}: {day['views']} views, {day.get('spins', 0)} interactions")
Storage Stats
stats = client.get_storage_stats("2024-01-01", "2024-01-31")
for day in stats:
print(f"{day['date']}: {day['storage'] / 1e9:.2f} GB, {day.get('files', 0)} files")
Error Handling
from sirv_rest_api import SirvClient, SirvApiError
client = SirvClient(
client_id="your-client-id",
client_secret="your-client-secret"
)
try:
client.connect()
info = client.get_file_info("/nonexistent/file.jpg")
except SirvApiError as e:
print(f"API Error: {e.message}")
print(f"Status Code: {e.status_code}")
print(f"Error Code: {e.error_code}")
except Exception as e:
print(f"Unexpected error: {e}")
Configuration Options
client = SirvClient(
client_id="your-client-id",
client_secret="your-client-secret",
base_url="https://api.sirv.com", # API base URL
auto_refresh_token=True, # Auto-refresh tokens (default: True)
token_refresh_buffer=60, # Seconds before expiry to refresh (default: 60)
timeout=30, # Request timeout in seconds (default: 30)
max_retries=3 # Max retries for failed requests (default: 3)
)
Getting Your API Credentials
- Log in to your Sirv account
- Go to Settings > API
- Create a new API client or use existing credentials
- Copy your
Client IDandClient Secret
Links
License
MIT License - see LICENSE file for details.
Support
- Email: support@sirv.com
- Documentation: https://sirv.com/help/
- API Docs: https://apidocs.sirv.com/
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sirv_rest_api-1.0.0.tar.gz.
File metadata
- Download URL: sirv_rest_api-1.0.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52f04c09fbd50e36397414791bf995bc15eaf039a75b77ca81573c6a2c762f35
|
|
| MD5 |
6c2e370f508cf3a02f4871b7f4f7152e
|
|
| BLAKE2b-256 |
09630a8fbf428198de2be48c90f68bf3b8507e94af44f5f02592dc8d48cbae0b
|
File details
Details for the file sirv_rest_api-1.0.0-py3-none-any.whl.
File metadata
- Download URL: sirv_rest_api-1.0.0-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f657c3971529810a14f8af75e937b9f3ca54c40642c1c8119b3c0eeea3fe4c0e
|
|
| MD5 |
d20fff4f01e72f735f4bc209bcfdf1d3
|
|
| BLAKE2b-256 |
cb1966d715daf713347cd07c9910eb0b945035b021f00580e5b262730b04eb62
|