Class: Itrp::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/itrp/client.rb,
lib/itrp/client/version.rb

Constant Summary collapse

MAX_PAGE_SIZE =
100
DEFAULT_HEADER =
{'Content-Type' => 'application/json'}
VERSION =
'1.1.3'

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Client

Create a new ITRP Client

Shared configuration for all ITRP Clients:

Itrp.configure do |config|
  config.api_token = 'd41f5868feb65fc87fa2311a473a8766ea38bc40'
  config.account = 'my-sandbox'
  ...
end

Override configuration per ITRP Client: itrp = Itrp::Client.new(account: ‘trusted-sandbox’)

All options available:

- logger:      The Ruby Logger instance, default: Logger.new(STDOUT)
- host:        The ITRP API host, default: 'https://api.itrp.com'
- api_version: The ITRP API version, default: 'v1'
- api_token:   *required* The ITRP API token
- account:     Specify a different (trusted) account to work with
               @see http://developer.itrp.com/v1/#multiple-accounts
- source:      The Source used when creating new records
               @see http://developer.itrp.com/v1/general/source/

- max_retry_time: maximum nr of seconds to wait for server to respond (default = 5400 = 1.5 hours)
                  the sleep time between retries starts at 2 seconds and doubles after each retry
                  retry times: 2, 6, 18, 54, 162, 486, 1458, 4374, 13122, ... seconds
                  one retry will always be performed unless you set the value to -1
- read_timeout:   HTTP GET read timeout in seconds (default = 25)
- block_at_rate_limit: Set to +true+ to block the request until the rate limit is lifted, default: +false+
                       @see http://developer.itrp.com/v1/#rate-limiting

- proxy_host:     Define in case HTTP traffic needs to go through a proxy
- proxy_port:     Port of the proxy, defaults to 8080
- proxy_user:     Proxy user
- proxy_password: Proxy password


60
61
62
63
64
65
66
67
68
# File 'lib/itrp/client.rb', line 60

def initialize(options = {})
  @options = Itrp.configuration.current.merge(options)
  [:host, :api_version, :api_token].each do |required_option|
    raise ::Itrp::Exception.new("Missing required configuration option #{required_option}") if option(required_option).blank?
  end
  @ssl, @domain, @port = ssl_domain_port_path(option(:host))
  @ssl_verify_none = options[:ssl_verify_none]
  @logger = @options[:logger]
end

Instance Method Details

#delete(path, params = {}, header = {}) ⇒ Object

send HTTPS DELETE request and return instance of Itrp::Response



102
103
104
# File 'lib/itrp/client.rb', line 102

def delete(path, params = {}, header = {})
  _send(Net::HTTP::Delete.new(expand_path(path, params), expand_header(header)))
end

#each(path, params = {}, header = {}, &block) ⇒ Object

Yield all retrieved resources one-by-one for the given (paged) API query. Raises an ::Itrp::Exception with the response retrieved from ITRP is invalid Returns total nr of resources yielded (for logging)



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/itrp/client.rb', line 78

def each(path, params = {}, header = {}, &block)
  # retrieve the resources using the max page size (least nr of API calls)
  next_path = expand_path(path, {per_page: MAX_PAGE_SIZE, page: 1}.merge(params))
  size = 0
  while next_path
    # retrieve the records (with retry and optionally wait for rate-limit)
    response = get(next_path, {}, header)
    # raise exception in case the response is invalid
    raise ::Itrp::Exception.new(response.message) unless response.valid?
    # yield the resources
    response.json.each{ |resource| yield resource }
    size += response.json.size
    # go to the next page
    next_path = response.pagination_relative_link(:next)
  end
  size
end

#export(types, from = nil, block_until_completed = false) ⇒ Object

Export CSV files

Parameters:

  • types:

    The types to export, e.g. person, organization, people_contact_details

  • from:

    Retrieve all files since a given data and time

  • block_until_completed:

    Set to true to monitor the export progress

Raises:

  • Itrp::Exception in case the export progress could not be monitored



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/itrp/client.rb', line 155

def export(types, from = nil, block_until_completed = false)
  data = {type: [types].flatten.join(',')}
  data[:from] = from unless from.blank?
  response = post('/export', data)
  if response.valid?
    if response.raw.code.to_s == '204'
      @logger.info { "No changed records for '#{data[:type]}' since #{data[:from]}." }
      return response
    end
    @logger.info { "Export for '#{data[:type]}' successfully queued with token '#{response[:token]}'." }
  end

  if block_until_completed
    raise ::Itrp::UploadFailed.new("Failed to queue '#{data[:type]}' export. #{response.message}") unless response.valid?
    token = response[:token]
    while true
      response = get("/export/#{token}")
      unless response.valid?
        sleep(5)
        response = get("/export/#{token}") # single retry to recover from a network error
        raise ::Itrp::Exception.new("Unable to monitor progress for '#{data[:type]}' export. #{response.message}") unless response.valid?
      end
      # wait 30 seconds while the response is OK and export is still busy
      break unless ['queued', 'processing'].include?(response[:state])
      @logger.debug { "Export of '#{data[:type]}' is #{response[:state]}. Checking again in 30 seconds." }
      sleep(30)
    end
  end

  response
end

#get(path, params = {}, header = {}) ⇒ Object

send HTTPS GET request and return instance of Itrp::Response



97
98
99
# File 'lib/itrp/client.rb', line 97

def get(path, params = {}, header = {})
  _send(Net::HTTP::Get.new(expand_path(path, params), expand_header(header)))
end

#import(csv, type, block_until_completed = false) ⇒ Object

upload a CSV file to import

Parameters:

  • csv:

    The CSV File or the location of the CSV file

  • type:

    The type, e.g. person, organization, people_contact_details

Raises:

  • Itrp::UploadFailed in case the file could was not accepted by ITRP and block_until_completed is true

  • Itrp::Exception in case the import progress could not be monitored



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/itrp/client.rb', line 122

def import(csv, type, block_until_completed = false)
  csv = File.open(csv, 'rb') unless csv.respond_to?(:path) && csv.respond_to?(:read)
  data, headers = Itrp::Multipart::Post.prepare_query(type: type, file: csv)
  request = Net::HTTP::Post.new(expand_path('/import'), expand_header(headers))
  request.body = data
  response = _send(request)
  @logger.info { "Import file '#{csv.path}' successfully uploaded with token '#{response[:token]}'." } if response.valid?

  if block_until_completed
    raise ::Itrp::UploadFailed.new("Failed to queue #{type} import. #{response.message}") unless response.valid?
    token = response[:token]
    while true
      response = get("/import/#{token}")
      unless response.valid?
        sleep(5)
        response = get("/import/#{token}") # single retry to recover from a network error
        raise ::Itrp::Exception.new("Unable to monitor progress for #{type} import. #{response.message}") unless response.valid?
      end
      # wait 30 seconds while the response is OK and import is still busy
      break unless ['queued', 'processing'].include?(response[:state])
      @logger.debug { "Import of '#{csv.path}' is #{response[:state]}. Checking again in 30 seconds." }
      sleep(30)
    end
  end

  response
end

#loggerObject



187
188
189
# File 'lib/itrp/client.rb', line 187

def logger
  @logger
end

#option(key) ⇒ Object

Retrieve an option



71
72
73
# File 'lib/itrp/client.rb', line 71

def option(key)
  @options[key]
end

#post(path, data = {}, header = {}) ⇒ Object

send HTTPS POST request and return instance of Itrp::Response



113
114
115
# File 'lib/itrp/client.rb', line 113

def post(path, data = {}, header = {})
  _send(json_request(Net::HTTP::Post, path, data, header))
end

#put(path, data = {}, header = {}) ⇒ Object Also known as: patch

send HTTPS PATCH request and return instance of Itrp::Response



107
108
109
# File 'lib/itrp/client.rb', line 107

def put(path, data = {}, header = {})
  _send(json_request(Net::HTTP::Patch, path, data, header))
end