Sirv REST API Ruby SDK
Official Ruby SDK for the Sirv REST API. Provides a simple, type-safe way to interact with Sirv's image hosting and processing platform.
Features
- Complete coverage of all 40+ Sirv REST API endpoints
- Automatic token management with configurable expiry
- Thread-safe client
- Retry logic with exponential backoff
- Comprehensive model classes
- Iterator patterns for paginated results
- Zero external dependencies (uses Ruby stdlib only)
Installation
Add this line to your application's Gemfile:
gem 'sirv_rest_api'And then execute:
bundle installOr install it yourself:
gem install sirv_rest_apiRequirements
- Ruby 2.7 or later
Quick Start
require 'sirv_rest_api'
# Create client
client = SirvRestApi::Client.new(
client_id: 'your-client-id',
client_secret: 'your-client-secret'
)
# Connect (authenticate)
token = client.connect
puts "Connected! Token expires in #{token.expires_in} seconds"
# Get account info
account = client.get_account_info
puts "Account: #{account.alias}"
puts "CDN URL: #{account.cdn_url}"
# List folder contents
folder = client.read_folder_contents('/')
folder.contents.each do |item|
type = item.directory? ? '[DIR]' : '[FILE]'
puts "#{type} #{item.filename}"
endConfiguration
client = SirvRestApi::Client.new(
# Required
client_id: 'your-client-id',
client_secret: 'your-client-secret',
# Optional
base_url: 'https://api.sirv.com', # Default
auto_refresh_token: true, # 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 on 5xx errors (default: 3)
)Custom Token Expiry
You can customize how long the token is valid (5-604800 seconds):
# Request a token valid for 1 hour (3600 seconds)
token = client.connect(expires_in: 3600)
# Request a token valid for 7 days (604800 seconds)
token = client.connect(expires_in: 604800)API Reference
Authentication
# Connect and get token
token = client.connect
token = client.connect(expires_in: 3600) # Custom expiry
# Check connection status
client.connected?
# Get current token
client.access_tokenAccount Operations
# Get account info
account = client.get_account_info
# Update account settings
client.update_account(minify: { enabled: true })
# Get rate limits
limits = client.get_account_limits
# Get storage info
storage = client.get_storage_info
# Get billing plan
plan = client.get_billing_plan
# Get account users
users = client.get_account_users
# Search events
events = client.search_events(level: 'error', from: '2024-01-01')File Operations
# Get file info
info = client.get_file_info('/path/to/file.jpg')
# Read folder contents
folder = client.read_folder_contents('/my-folder')
# Iterate folder (handles pagination)
client.each_folder_item('/my-folder') do |file|
puts file.filename
end
# Search files
results = client.search_files(query: '*.jpg', size: 10)
# Iterate search results (handles pagination)
client.each_search_result(query: '*') do |file|
puts file.filename
end
# Upload file
client.upload_file('/path/to/dest.jpg', File.binread('./image.jpg'))
# Upload from local path
client.upload_file_from_path('/path/to/dest.jpg', './local-file.jpg')
# Download file
content = client.download_file('/path/to/file.jpg')
# Download file to local path
client.download_file_to('/path/to/file.jpg', './local-file.jpg')
# Create folder
client.create_folder('/new-folder')
# Delete file
client.delete_file('/path/to/file.jpg')
# Copy file
client.copy_file(from: '/source.jpg', to: '/dest.jpg')
# Rename/move file
client.rename_file(from: '/old.jpg', to: '/new.jpg')
# Fetch from URL
client.fetch_url(url: 'https://example.com/image.jpg', filename: '/fetched/image.jpg')Metadata Operations
# Get file metadata
meta = client.get_file_meta('/path/to/file.jpg')
# Set file metadata
client.set_file_meta('/path/to/file.jpg', {
title: 'My Image',
description: 'A beautiful image',
tags: ['nature', 'landscape']
})
# Get/set individual metadata fields
title = client.get_file_title('/path/to/file.jpg')
client.set_file_title('/path/to/file.jpg', 'New Title')
tags = client.get_file_tags('/path/to/file.jpg')
client.add_file_tags('/path/to/file.jpg', ['tag1', 'tag2'])
client.remove_file_tags('/path/to/file.jpg', ['tag1'])
# Product metadata
product = client.get_product_meta('/path/to/file.jpg')
client.set_product_meta('/path/to/file.jpg', {
name: 'Product Name',
sku: 'SKU-123',
brand: 'Brand Name'
})
# Approval flag
approved = client.get_approval_flag('/path/to/file.jpg')
client.set_approval_flag('/path/to/file.jpg', true)JWT Protected URLs
jwt = client.generate_jwt(filename: '/protected/image.jpg', expires_in: 3600)
puts "Protected URL: #{jwt.url}"Spins/360 Operations
# Convert spin to video
video_file = client.spin_to_video('/spin/product.spin', options: {
width: 800,
height: 600
})
# Convert video to spin
spin_file = client.video_to_spin('/video/product.mp4')
# Export spin to marketplaces
client.export_spin_to_amazon(filename: '/spin/product.spin', asin: 'B01234567')
client.export_spin_to_walmart(filename: '/spin/product.spin')
client.export_spin_to_home_depot(filename: '/spin/product.spin')
client.export_spin_to_lowes(filename: '/spin/product.spin')
client.export_spin_to_grainger(filename: '/spin/product.spin')Statistics
# HTTP transfer stats
http_stats = client.get_http_stats(from: '2024-01-01', to: '2024-01-31')
# Spin views stats (max 5-day range)
spin_stats = client.get_spin_views_stats(from: '2024-01-01', to: '2024-01-05')
# Storage stats
storage_stats = client.get_storage_stats(from: '2024-01-01', to: '2024-01-31')Error Handling
begin
account = client.get_account_info
rescue SirvRestApi::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue SirvRestApi::NotFoundError => e
puts "Not found: #{e.message}"
rescue SirvRestApi::RateLimitError => e
puts "Rate limit exceeded: #{e.message}"
rescue SirvRestApi::ApiError => e
puts "API error: #{e.message} (status #{e.status_code})"
endThread Safety
The client is thread-safe and can be used from multiple threads:
threads = 10.times.map do |i|
Thread.new do
info = client.get_file_info("/file#{i}.jpg")
puts info.filename
end
end
threads.each(&:join)Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests.
To install this gem onto your local machine, run bundle exec rake install.
License
MIT License - see LICENSE for details.