class PopIt

A Ruby wrapper for the PopIt API.

Instead of writing the path to an API endpoint, you can use method chaining. For example:

require 'popit'
api = PopIt.new :instance_name => 'demo'
api.get 'persons/john-doe'

can be written as:

api.persons('john-doe').get

All methods and arguments between ‘api` and the HTTP method - in this case, `get` - become parts of the path.

@see github.com/mysociety/popit/blob/master/lib/apps/api/api_v1.js

Constants

VERSION

Attributes

apikey[R]

An API key.

host_name[R]

The PopIt API’s host name, eg “popit.mysociety.org”.

instance_name[R]

The instance name.

max_retries[R]

The maximum number of retries in case of HTTP 503 Service Unavailable errors.

port[R]

The PopIt API’s port, eg 80

version[R]

The PopIt API version, eg “v0.1”

Public Class Methods

new(opts = {}) click to toggle source

Initializes a PopIt API client.

@param [Hash] opts the API client’s configuration @option opts [String] :instance_name the instance name @option opts [String] :host_name the PopIt API’s host name, eg “popit.mysociety.org” @option opts [String] :post the PopIt API’s port, eg 80 @option opts [String] :version the PopIt API version, eg “v1” @option opts [String] :apikey an API key @option opts [String] :max_retries the maximum number of retries in case of

HTTP 503 Service Unavailable errors
# File lib/popit.rb, line 53
def initialize(opts = {})
  unless opts.has_key?(:instance_name)
    raise ArgumentError, 'Missing key :instance_name'
  end

  @instance_name = opts[:instance_name]
  @host_name     = opts[:host_name]   || 'popit.mysociety.org'
  @port          = opts[:port]        || 80
  @version       = opts[:version]     || 'v0.1'
  @apikey        = opts[:apikey]
  @max_retries   = opts[:max_retries] || 0

end

Public Instance Methods

delete(path, opts = {}) click to toggle source

Sends a DELETE request.

@param [String] path a path with no leading slash @param [Hash] opts key-value pairs for the query string @return [Hash] an empty hash

# File lib/popit.rb, line 99
def delete(path, opts = {})
  request(:delete, path, opts)
end
get(path, opts = {}) click to toggle source

Sends a GET request.

@param [String] path a path with no leading slash @param [Hash] opts key-value pairs for the query string @return the JSON response from the server

# File lib/popit.rb, line 72
def get(path, opts = {})
  request(:get, path, opts)
end
post(path, opts = {}) click to toggle source

Sends a POST request.

@param [String] path a path with no leading slash @param [Hash] opts key-value pairs for the message body @return the JSON response from the server

# File lib/popit.rb, line 81
def post(path, opts = {})
  request(:post, path, opts)
end
put(path, opts = {}) click to toggle source

Sends a PUT request.

@param [String] path a path with no leading slash @param [Hash] opts key-value pairs for the message body @return [nil] nothing

# File lib/popit.rb, line 90
def put(path, opts = {})
  request(:put, path, opts)
end

Private Instance Methods

method_missing(*args) click to toggle source
# File lib/popit.rb, line 155
def method_missing(*args)
  Chain.new(self, args)
end
request(http_method, path, opts = {}) click to toggle source
# File lib/popit.rb, line 105
def request(http_method, path, opts = {})
  attempts ||= 0

  path = "http://#{instance_name}.#{host_name}:#{port}/api/#{version}/#{path}"

  response = case http_method
  when :get
    self.class.send(http_method, path, :query => opts)
  when :delete
    self.class.send(http_method, path, :query => opts.merge(:apikey => apikey))
  when :post, :put
    self.class.send(http_method, path, :body => JSON.dump(opts.merge(:apikey => apikey)), :headers => {'Content-Type' => 'application/json'})
  end

  unless ['200', '201', '204'].include?(response.response.code)
    message = if Hash === response.parsed_response
      if response.parsed_response['error']
        response.parsed_response['error']
      elsif response.parsed_response['errors']
        response.parsed_response['errors'].join(', ')
      else
        response.parsed_response
      end
    else
      response.parsed_response
    end

    case response.response.code
    when '503'
      raise PopIt::ServiceUnavailable, message
    when '404'
      raise PopIt::PageNotFound, message
    when '401'
      raise PopIt::NotAuthenticated, message
    else
      raise PopIt::Error, message
    end
  end

  response.parsed_response && response.parsed_response['result']
rescue PopIt::ServiceUnavailable
  attempts += 1
  if attempts <= max_retries
    sleep attempts ** 2
    retry
  else
    raise
  end
end