sirv_rest_api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7988f44acfb48928112d2a3f31248e986d17dcaf89e92958d801c7dfb6df2c61
4
+ data.tar.gz: b9d7df63ec359638f85eca234d9738bd59ffd4151e98d5787e8080f91d466fbe
5
+ SHA512:
6
+ metadata.gz: 5dbcaa95009de205b9840857f30f4a4f9036035ce6ac456b766e97bd3e8e9ee0506413c300d08eb26a091853e95e986d14ed015253f309d49a1b82e2b7864a83
7
+ data.tar.gz: 0c8613b0eee94fa033d99189484196ee6be94f5510ea068ddad5f9ed19893fda037e682eaa2d5f79091587cf4a73a95a07d63f6d84a548e940ac16e30f3c7db7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sirv Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # Sirv REST API Ruby SDK
2
+
3
+ Official Ruby SDK for the [Sirv REST API](https://apidocs.sirv.com/). Provides a simple, type-safe way to interact with Sirv's image hosting and processing platform.
4
+
5
+ ## Features
6
+
7
+ - Complete coverage of all 40+ Sirv REST API endpoints
8
+ - Automatic token management with configurable expiry
9
+ - Thread-safe client
10
+ - Retry logic with exponential backoff
11
+ - Comprehensive model classes
12
+ - Iterator patterns for paginated results
13
+ - Zero external dependencies (uses Ruby stdlib only)
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'sirv_rest_api'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ ```bash
26
+ bundle install
27
+ ```
28
+
29
+ Or install it yourself:
30
+
31
+ ```bash
32
+ gem install sirv_rest_api
33
+ ```
34
+
35
+ ## Requirements
36
+
37
+ - Ruby 2.7 or later
38
+
39
+ ## Quick Start
40
+
41
+ ```ruby
42
+ require 'sirv_rest_api'
43
+
44
+ # Create client
45
+ client = SirvRestApi::Client.new(
46
+ client_id: 'your-client-id',
47
+ client_secret: 'your-client-secret'
48
+ )
49
+
50
+ # Connect (authenticate)
51
+ token = client.connect
52
+ puts "Connected! Token expires in #{token.expires_in} seconds"
53
+
54
+ # Get account info
55
+ account = client.get_account_info
56
+ puts "Account: #{account.alias}"
57
+ puts "CDN URL: #{account.cdn_url}"
58
+
59
+ # List folder contents
60
+ folder = client.read_folder_contents('/')
61
+ folder.contents.each do |item|
62
+ type = item.directory? ? '[DIR]' : '[FILE]'
63
+ puts "#{type} #{item.filename}"
64
+ end
65
+ ```
66
+
67
+ ## Configuration
68
+
69
+ ```ruby
70
+ client = SirvRestApi::Client.new(
71
+ # Required
72
+ client_id: 'your-client-id',
73
+ client_secret: 'your-client-secret',
74
+
75
+ # Optional
76
+ base_url: 'https://api.sirv.com', # Default
77
+ auto_refresh_token: true, # Default: true
78
+ token_refresh_buffer: 60, # Seconds before expiry to refresh (default: 60)
79
+ timeout: 30, # Request timeout in seconds (default: 30)
80
+ max_retries: 3 # Max retries on 5xx errors (default: 3)
81
+ )
82
+ ```
83
+
84
+ ## Custom Token Expiry
85
+
86
+ You can customize how long the token is valid (5-604800 seconds):
87
+
88
+ ```ruby
89
+ # Request a token valid for 1 hour (3600 seconds)
90
+ token = client.connect(expires_in: 3600)
91
+
92
+ # Request a token valid for 7 days (604800 seconds)
93
+ token = client.connect(expires_in: 604800)
94
+ ```
95
+
96
+ ## API Reference
97
+
98
+ ### Authentication
99
+
100
+ ```ruby
101
+ # Connect and get token
102
+ token = client.connect
103
+ token = client.connect(expires_in: 3600) # Custom expiry
104
+
105
+ # Check connection status
106
+ client.connected?
107
+
108
+ # Get current token
109
+ client.access_token
110
+ ```
111
+
112
+ ### Account Operations
113
+
114
+ ```ruby
115
+ # Get account info
116
+ account = client.get_account_info
117
+
118
+ # Update account settings
119
+ client.update_account(minify: { enabled: true })
120
+
121
+ # Get rate limits
122
+ limits = client.get_account_limits
123
+
124
+ # Get storage info
125
+ storage = client.get_storage_info
126
+
127
+ # Get billing plan
128
+ plan = client.get_billing_plan
129
+
130
+ # Get account users
131
+ users = client.get_account_users
132
+
133
+ # Search events
134
+ events = client.search_events(level: 'error', from: '2024-01-01')
135
+ ```
136
+
137
+ ### File Operations
138
+
139
+ ```ruby
140
+ # Get file info
141
+ info = client.get_file_info('/path/to/file.jpg')
142
+
143
+ # Read folder contents
144
+ folder = client.read_folder_contents('/my-folder')
145
+
146
+ # Iterate folder (handles pagination)
147
+ client.each_folder_item('/my-folder') do |file|
148
+ puts file.filename
149
+ end
150
+
151
+ # Search files
152
+ results = client.search_files(query: '*.jpg', size: 10)
153
+
154
+ # Iterate search results (handles pagination)
155
+ client.each_search_result(query: '*') do |file|
156
+ puts file.filename
157
+ end
158
+
159
+ # Upload file
160
+ client.upload_file('/path/to/dest.jpg', File.binread('./image.jpg'))
161
+
162
+ # Upload from local path
163
+ client.upload_file_from_path('/path/to/dest.jpg', './local-file.jpg')
164
+
165
+ # Download file
166
+ content = client.download_file('/path/to/file.jpg')
167
+
168
+ # Download file to local path
169
+ client.download_file_to('/path/to/file.jpg', './local-file.jpg')
170
+
171
+ # Create folder
172
+ client.create_folder('/new-folder')
173
+
174
+ # Delete file
175
+ client.delete_file('/path/to/file.jpg')
176
+
177
+ # Copy file
178
+ client.copy_file(from: '/source.jpg', to: '/dest.jpg')
179
+
180
+ # Rename/move file
181
+ client.rename_file(from: '/old.jpg', to: '/new.jpg')
182
+
183
+ # Fetch from URL
184
+ client.fetch_url(url: 'https://example.com/image.jpg', filename: '/fetched/image.jpg')
185
+ ```
186
+
187
+ ### Metadata Operations
188
+
189
+ ```ruby
190
+ # Get file metadata
191
+ meta = client.get_file_meta('/path/to/file.jpg')
192
+
193
+ # Set file metadata
194
+ client.set_file_meta('/path/to/file.jpg', {
195
+ title: 'My Image',
196
+ description: 'A beautiful image',
197
+ tags: ['nature', 'landscape']
198
+ })
199
+
200
+ # Get/set individual metadata fields
201
+ title = client.get_file_title('/path/to/file.jpg')
202
+ client.set_file_title('/path/to/file.jpg', 'New Title')
203
+
204
+ tags = client.get_file_tags('/path/to/file.jpg')
205
+ client.add_file_tags('/path/to/file.jpg', ['tag1', 'tag2'])
206
+ client.remove_file_tags('/path/to/file.jpg', ['tag1'])
207
+
208
+ # Product metadata
209
+ product = client.get_product_meta('/path/to/file.jpg')
210
+ client.set_product_meta('/path/to/file.jpg', {
211
+ name: 'Product Name',
212
+ sku: 'SKU-123',
213
+ brand: 'Brand Name'
214
+ })
215
+
216
+ # Approval flag
217
+ approved = client.get_approval_flag('/path/to/file.jpg')
218
+ client.set_approval_flag('/path/to/file.jpg', true)
219
+ ```
220
+
221
+ ### JWT Protected URLs
222
+
223
+ ```ruby
224
+ jwt = client.generate_jwt(filename: '/protected/image.jpg', expires_in: 3600)
225
+ puts "Protected URL: #{jwt.url}"
226
+ ```
227
+
228
+ ### Spins/360 Operations
229
+
230
+ ```ruby
231
+ # Convert spin to video
232
+ video_file = client.spin_to_video('/spin/product.spin', options: {
233
+ width: 800,
234
+ height: 600
235
+ })
236
+
237
+ # Convert video to spin
238
+ spin_file = client.video_to_spin('/video/product.mp4')
239
+
240
+ # Export spin to marketplaces
241
+ client.export_spin_to_amazon(filename: '/spin/product.spin', asin: 'B01234567')
242
+ client.export_spin_to_walmart(filename: '/spin/product.spin')
243
+ client.export_spin_to_home_depot(filename: '/spin/product.spin')
244
+ client.export_spin_to_lowes(filename: '/spin/product.spin')
245
+ client.export_spin_to_grainger(filename: '/spin/product.spin')
246
+ ```
247
+
248
+ ### Statistics
249
+
250
+ ```ruby
251
+ # HTTP transfer stats
252
+ http_stats = client.get_http_stats(from: '2024-01-01', to: '2024-01-31')
253
+
254
+ # Spin views stats (max 5-day range)
255
+ spin_stats = client.get_spin_views_stats(from: '2024-01-01', to: '2024-01-05')
256
+
257
+ # Storage stats
258
+ storage_stats = client.get_storage_stats(from: '2024-01-01', to: '2024-01-31')
259
+ ```
260
+
261
+ ## Error Handling
262
+
263
+ ```ruby
264
+ begin
265
+ account = client.get_account_info
266
+ rescue SirvRestApi::AuthenticationError => e
267
+ puts "Authentication failed: #{e.message}"
268
+ rescue SirvRestApi::NotFoundError => e
269
+ puts "Not found: #{e.message}"
270
+ rescue SirvRestApi::RateLimitError => e
271
+ puts "Rate limit exceeded: #{e.message}"
272
+ rescue SirvRestApi::ApiError => e
273
+ puts "API error: #{e.message} (status #{e.status_code})"
274
+ end
275
+ ```
276
+
277
+ ## Thread Safety
278
+
279
+ The client is thread-safe and can be used from multiple threads:
280
+
281
+ ```ruby
282
+ threads = 10.times.map do |i|
283
+ Thread.new do
284
+ info = client.get_file_info("/file#{i}.jpg")
285
+ puts info.filename
286
+ end
287
+ end
288
+ threads.each(&:join)
289
+ ```
290
+
291
+ ## Development
292
+
293
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
294
+
295
+ To install this gem onto your local machine, run `bundle exec rake install`.
296
+
297
+ ## License
298
+
299
+ MIT License - see [LICENSE](LICENSE) for details.
300
+
301
+ ## Links
302
+
303
+ - [Sirv Website](https://sirv.com)
304
+ - [API Documentation](https://apidocs.sirv.com/)
305
+ - [Sirv Help Center](https://sirv.com/help/)
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ task default: :test
13
+
14
+ desc "Run tests with real credentials"
15
+ task :test_live do
16
+ ruby "test/live_test.rb"
17
+ end
18
+
19
+ desc "Generate YARD documentation"
20
+ task :doc do
21
+ sh "yard doc lib/**/*.rb"
22
+ end
23
+
24
+ desc "Build the gem"
25
+ task :build do
26
+ sh "gem build sirv_rest_api.gemspec"
27
+ end