class AdoptAPet::Client

Class for interfacing with the Adopt-A-Pet API @author Stephen Dolan

@!attribute api_key

@return [String] the user's API key to use in connections

@!attribute conn

@return [Faraday::Connection] a Faraday object to make requests

Attributes

api_key[RW]
conn[RW]

Public Class Methods

new(api_key = AdoptAPet.api_key) click to toggle source

Create a single instance of a Pet Photo @author Stephen Dolan

@param [String] api_key the API key to authenticate with

@return [void]

@example Initialize a new Adopt-A-Pet Client

client = AdoptAPet::Client.new('my_api_key')
pets   = client.pets_at_shelter('12345')
# File lib/adopt_a_pet/client.rb, line 22
def initialize(api_key = AdoptAPet.api_key)
  raise(AdoptAPet::Error, 'API key is required.') unless api_key

  self.api_key = api_key
  self.conn    = setup_connection
end

Public Instance Methods

limited_pet_details(pet_id, options = {}) click to toggle source

Retrieves a subset of the total pet data for a single pet @author Stephen Dolan

@param [Integer] pet_id the ID of a single pet @param [Hash] opts a placeholder for any options the user would like to submit

@return [Pet] a Pet object

@example

client = AdoptAPet::Client.new('my_key')
pet    = client.limited_pet_details(123456)
my_pet_special_needs = pet.special_needs
# File lib/adopt_a_pet/client.rb, line 81
def limited_pet_details(pet_id, options = {})
  query = options.merge(pet_id: pet_id)
  response = perform_get('/search/limited_pet_details', query)
  Pet.new(response.dig('pet'))
end
pet_details(pet_id, options = {}) click to toggle source

Retrieves a complete data set for a single pet @author Stephen Dolan

@param [Integer] pet_id the ID of a single pet @param [Hash] opts a placeholder for any options the user would like to submit

@return [Pet] a Pet object

@example

client = AdoptAPet::Client.new('my_key')
pet    = client.pet_details(123456)
my_pet_housetrained = pet.housetrained
# File lib/adopt_a_pet/client.rb, line 99
def pet_details(pet_id, options = {})
  query = options.merge(pet_id: pet_id)
  response = perform_get('/search/pet_details', query)
  Pet.new(response.dig('pet'))
end
pets_at_shelter(shelter_id, options = {}) click to toggle source

Retrieves all pets at a shelter @author Stephen Dolan

@param [Integer] shelter_id the ID of the shelter to list pets at @param [Hash] opts the options to include with the request @option opts [String] :start_number (1) where to start results @option opts [String] :end_number (50) where to end results

@return [Array<Pet>] a collection of Pets

@example

client = AdoptAPet::Client.new('my_key')
pets   = client.pets_at_shelter(12345)
my_pet_name = pets.first.name
# File lib/adopt_a_pet/client.rb, line 43
def pets_at_shelter(shelter_id, options = {})
  query = options.merge(shelter_id: shelter_id)
  response = perform_get('/search/pets_at_shelter', query)
  Pet.multiple(response)
end
pets_at_shelters(shelter_ids, options = {}) click to toggle source

Retrieves all pets at multiple shelters @author Stephen Dolan

@param [Array<Integer>] shelter_ids set of shelter IDs to search for pets at @param [Hash] opts the options to include with the request @option opts [String] :start_number (1) where to start results @option opts [String] :end_number (50) where to end results

@return [Array<Pet>] a collection of Pets

@example

client = AdoptAPet::Client.new('my_key')
pets   = client.pets_at_shelter(12345, end_number: 1000)
my_pet_name = pets.first.name
# File lib/adopt_a_pet/client.rb, line 63
def pets_at_shelters(shelter_ids, options = {})
  query = options.merge(shelter_id: shelter_ids)
  response = perform_get('/search/pets_at_shelters', query)
  Pet.multiple(response)
end

Private Instance Methods

check_ok_response(response_object) click to toggle source

Verify that there was no issue with an 'ok' response @author Stephen Dolan

@param [Hash] a Ruby hash representing an Adopt-A-Pet API response

@raise [Exception] if the response is not valid, throw an exception

@return [true] always return true if there is no exception

# File lib/adopt_a_pet/client.rb, line 201
def check_ok_response(response_object)
  return true unless response_object.key? 'exception'

  exception_message = response_object.dig('exception', 'details')
  raise "Bad request. Exception occurred: #{exception_message}"
end
perform_get(uri, options = {}) click to toggle source

Helper method to fetch data from the Adopt-A-Pet API endpoint @author Stephen Dolan

@param [String] the URI to make the GET request to @param [Hash] opts the options to include with the request @option opts [String] :start_number (1) where to start results @option opts [String] :end_number (50) where to end results

@return [Hash] an Adopt-A-Pet JSON API response parsed to a Ruby Hash

# File lib/adopt_a_pet/client.rb, line 134
def perform_get(uri, options = {})
  # Always fetch the output in JSON format
  options = options.merge(output: :json)

  # Always include the API key
  options = options.merge(key: api_key)

  # Always set the API version to version 1
  options = options.merge(v: 1)

  # Make the request
  response = conn.get(uri, options)

  # Validate the body and transform into a Ruby object
  process_json_response(response.body)
end
process_json_response(response_body) click to toggle source

Parses a JSON body into a Ruby object if it is a valid response @author Stephen Dolan

@param [String] the JSON response body from an Adopt-A-Pet API request

@return [Hash] an Adopt-A-Pet JSON API response parsed to a Ruby Hash

# File lib/adopt_a_pet/client.rb, line 157
def process_json_response(response_body)
  # Parse the response into a Ruby object
  response_object = JSON.parse(response_body)

  # Return the Ruby object if the response was valid
  return response_object if valid_json_response(response_object)
end
setup_connection() click to toggle source

Instantiate a Faraday connector with a base URL and adapter @author stephen dolan

@return [Faraday::Connection] a faraday object to make requests

# File lib/adopt_a_pet/client.rb, line 111
def setup_connection
  # Set up a flexible connection to append the URI to and make requests with
  Faraday.new(url: 'https://api.adoptapet.com') do |faraday|
    # Include to log responses to STDOUT
    # faraday.response :logger

    # Don't encode identical URL paramaeters with []
    faraday.options.params_encoder = Faraday::FlatParamsEncoder

    # Use the default Net::HTTP adapter
    faraday.adapter Faraday.default_adapter
  end
end
valid_json_response(response_object) click to toggle source

Ensure that the JSON HTTP response received is valid @author Stephen Dolan

@param [Hash] a Ruby hash representing an Adopt-A-Pet API response

@raise [Exception] if the response is not valid, throw an exception

@return [true] always return true if the method completes

# File lib/adopt_a_pet/client.rb, line 173
def valid_json_response(response_object)
  # Grab the status from the response
  response_status = response_object.dig('status')

  # If we receive a status 'ok', make sure there are no exceptions
  # If we receive a status 'fail', raise an exception
  # If we receive anything else, raise an exception
  if response_status == 'ok'
    check_ok_response(response_object)
  elsif response_status == 'fail'
    puts response_object
    raise 'Bad request. Response returned status "fail".'
  else
    raise 'Bad request. Invalid response status returned.'
  end

  # Return true if all validations pass
  true
end