Description
This client provides an easy way to interact with version 2 of the Shutterstock, Inc. API which gives you access to millions of photos, illustrations and footage clips. You will need a Client ID and Client Secret from Shutterstock to use this client.
The API operations are done within the context of a specific user/account. Below are some examples of how to use the API client.
Currently, this API only supports Images, not videos or music.
Installation
Add this line to your application's Gemfile:
gem 'shutterstock-v2'
And then execute:
$ bundle
Or install it yourself as:
$ gem install shutterstock-v2
Quick Start
First, see the Authentication section to generate a client_id, client_secret and access_token
require 'shutterstock-v2'
Shutterstock::Client.instance.configure do |config|
config.client_id = "xxx"
config.client_secret = "xxx"
config.access_token = "xxx"
end
images = Shutterstock::Image.search("blue rose")
images.total_count
# => 170416
images.count # Only returns first page of results
# => 20
image = images.first
image.id
# => 353732165
image.description
# => "close-up blue rose isolated on white background macro"
# License image for download, finding appropriate license from user's subscriptions
license = image.license
if !license.error
`wget #{license.download}`
end
# Create a collection
collection = Shutterstock::Collection.create("blue rose")
# Add first page of results from our search to the collection
collection.add_image(images)
# Delete the collection
collection.destroy
Configuration
Configuration is through a call to the Shutterstock::Client
singleton. All subsequent calls will use these configuration options.
You can receive a Client ID and Client Secret from Shutterstock. A non-expiring access_token can be generated through API calls. See the Authentication section below.
require 'shutterstock-v2'
Shutterstock::Client.instance.configure do |config|
config.client_id = "xxx"
config.client_secret = "xxx"
config.access_token = "xxx"
end
Image
image = Shutterstock::Image.find(118139110)
# => #<Shutterstock::Image>
image.assets
# => #<Shutterstock::ImageAssets>
image.assets.preview.url
# => "https://image.shutterstock.com/display_pic_with_logo/1306729/118139110/stock-photo-adorable-labrador-puppy-playing-with-a-chew-toy-on-white-backdrop-118139110.jpg
image.assets.huge.height
# => 3090
image.keywords
# => ["animal", "animal themes", "backgrounds", "cute", "dog", ...]
image.description
# => "Adorable Labrador Puppy Playing with a Chew Toy on White Backdrop"
image.adult?
# => false
# Requires editorial consent before licenseing
image.editorial?
# => false
image.similar
# => #<Shutterstock::Images>, an array of #<Shutterstock::Image>
# Currently only returns first page of results
image.similar.total_count # total count of similar images
Retrieving all image data
Some queries don't return full image data. Use fill
to retrieve all data for a Shutterstock::Image
# collection.items only returns image id's
first_collection_of_user = Shutterstock::Collection.list.first
image = first_collection_of_user.items.first
# Description isn't downloaded by default
image.description
# => nil
image.fill
image.description
# => "Rose Garden"
image.assets.preview.url
# => "http://...."
# .fill returns self, to help with chaining
image.fill.description
# .fill can also be used on a image list
images = Shutterstock::Collection.list.fill
images.first.description
Searching for Images
purple_cats = Shutterstock::Image.search("purple cat")
purple_cats.first.id
# => 431931730
Shutterstock has a strong searching capability. Pass a hash to utilize all search parameters available.
# one older japanese male teenager with a garden with a model release in landscape format
images = Shutterstock::Image.search({
query: 'garden',
people_number: 1,
people_ethnicity: 'japanese',
people_gender: 'male',
people_age: 'teenagers',
people_model_released: true,
orientation: 'horizontal'})
images.first.assets.preview.url
Image Licencing
To license an image for use, call license
on a Shutterstock::Image
. You'll receive a Shutterstock::License
object back with any errors, the allotment from your plan, and the download url. license
will find a valid subscription for the image size, and use that to purchase the image. Optionally specify the size (small, medium, huge, vector) and format (jpg, eps).
If an image requires editorial approval, license
requests it.
licensed = Image.find(553180399).license
licensed.allotment_charge # 1 if not previously licensed, otherwise 0
licensed.download
# => "https://download.shutterstock.com/gatekeeper/abc/original.jpg"
# License the smallest asset of the image. Supports: small, medium, huge, vector. Default: huge.
licensed = Image.find(553180399).license(size: 'small')
# License the vector image
licensed = Image.find(553956103).license(size: 'vector', format: 'eps')
You can choose a specific subscription, or license multiple images through Shutterstock::License
. See Subscriptions below.
Collections
collection = Shutterstock::Collection.find(21722255) # get a collection
collection.items # array of Shutterstock::Images
# metadata
collection.name # name of collection
collection.cover_item # Shutterstock::Image of cover image
## Create Collection
new_collection = Shutterstock::Collection.create("mynewcollection")
## Update Collection
new_collection.update(name: "updatename")
## Destroy Collection
new_collection.destroy
## Add Image to Collection
collection.add_image(987654321)
# or use any Shutterstock::Image object
collection.add_image(Image.find(12345))
# Can add multiple images
collection.add_image([1234, 2345, 3456])
## Remove image from Collection
collection.remove_image(987654321)
## Show all collections for current user (linked to access_token)
result = Shutterstock::Collection.list
If you don't have a Shutterstock::Collection
object handy, call the class with a collection ID
new_collection = Shutterstock::Collection.create("mynewcollection")
collection_id = new_collection.id
Shutterstock::Collection.update(id: collection_id, name: "updatename")
Shutterstock::Collection.destroy(id: collection_id)
Shutterstock::Collection.add_image(id: collection_id, image_id: 987654321)
Shutterstock::Collection.remove_image({id: collection_id, image_id: 987654321})
Subscriptions
# Find active (not expired) subscriptions for current user
subscriptions = Shutterstock::User.subscriptions.active
sub = subscriptions.first
sub.description
# => "Monthly Subscription"
sub.allotment.downloads_limit
# => 350
sub.allotment.downloads_left
# => 314
sub.has_downloads_left?
# => true
# Find a subscription for a specific image size
# Searches active subscriptions with downloads left
sub_id = Shutterstock::User.subscriptions.find_subscription_for_image_size('small').id
# => "s9999999"
# Images can be licensed using a subscription id
Shutterstock::License.license(subscription_id: sub_id, image_id: 1234)
Shutterstock::License.license(subscription_id: sub_id, image_id: Shutterstock::Image.find(1234))
# Optionally choose the size, format, or acknowledge the image will be used for editorial purposes
Shutterstock::License.license(subscription_id: sub_id, image_id: 1234, format: 'jpg', size: 'huge', editorial_acknowledgement: true)
# To specify metadata with the license request, use a hash
license_request = { image_id: 1234, metadata: { job: "job1", purchase_order: 'purchase order 1'}}
Shutterstock::License.license(subscription_id: sub_id, image_id: license_request)
# License multiple images by sending an array of image_ids, Shutterstock::Image objects, or hashes to license_multiple
licenses = Shutterstock::License.license_multiple(subscription_id: sub_id, image_id: [1234, 2345, 3456])
if !licenses.errors
`wget #{licenses.first.url}`
end
Authentication
To use this library, first register an application at Shutterstock.
An access_token is needed. If your integration uses only one user account, you can follow the single user integration directions to find the access_token.
Specify a scope
to limit the queries that can be run by this token.
Manually retrieve an access_token
require 'shutterstock-v2'
puts "Retrieves access_token from Shutterstock API"
puts "First, create an application from this page:"
puts "https://developers.shutterstock.com/applications"
puts
puts "Enter Client ID"
client_id = gets.strip
puts
puts "Enter Client Secret"
client_secret = gets.strip
# Create configuration
Shutterstock::Client.instance.configure do |config|
config.client_id = client_id
config.client_secret = client_secret
end
puts "Requesting auth from Shutterstock..."
url = Shutterstock::Auth.get_authorize_url(redirect_uri: 'http://localhost',
state: 'my_state',
scope: 'licenses.create licenses.view purchases.view collections.view collections.edit')
puts
puts "Open this url in your process to complete the authication process :"
puts url
puts
puts "Authorize with your Shutterstock username/password."
puts
puts "You will be redirected to a localhost URL. Find the code= parameter in the URI"
puts "For example: http://localhost/?code=Dc4nSMazdKkFtk7AyBkSG3&state=my_state"
puts "Code is Dc4nSMazdKkFtk7AyBkSG3"
puts
puts "Enter the code= parameter here:"
code = gets.strip
begin
result = Shutterstock::Auth.get_access_token(code: code)
puts "You are now authenticated."
puts
puts "access_token is : #{result["access_token"]}"
puts "Use this in the config section:"
puts "Shutterstock::Client.instance.configure do |config|"
puts " config.client_id = '#{client_id}'"
puts " config.client_secret = '#{client_secret}'"
puts " config.access_token = '#{result["access_token"]}'"
puts "end"
puts
rescue Shutterstock::FailedResponse => e
puts "Authentication failed : #{e.msg}"
end
Tests
To run the tests using mocked responses, use
rspec
To run the tests using making real API requests, use
VCR_OFF=1 SSTK_CLIENT_ID=<clientid> SSTK_CLIENT_SECRET=<secret> SSTK_ACCESS_TOKEN=<token> rspec
Note: some tests will fail because they rely on new IDs supplied when the mocks were created.
When adding new test, uncomment options[:record] = :new_episodes line in spec/spec-helper.rb
. And delete existing yml file
Automation
If you would like to automatically run tests when files are chaged, run bundle exec guard
.
This will monitor lib
and spec
and will run the appropriate tests. After a test runs, hit ENTER
to re-run all tests.
Based on v1 code
The structure of this API code was based on the Shutterstock API Version 1.
Major changes:
- Using version 2 of the Shutterstock API
- switched to Faraday for http requests
- used rspec 3 expect format
- added objects to support Image class
- added subscriptions and purchasing
Limitations:
- Currently limited to first page of results