Class: APIClient

Inherits:
Object
  • Object
show all
Defined in:
lib/carehq.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(account_id, api_key, api_secret, api_base_url: 'https://api.carehq.co.uk', timeout: nil) ⇒ APIClient

Returns a new instance of APIClient.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/carehq.rb', line 25

def initialize(
    ,
    api_key,
    api_secret,
    api_base_url: 'https://api.carehq.co.uk',
    timeout: nil
)

    # The Id of the CareHQ account the API key relates to
    @account_id = 

    # A key used to authenticate API calls to an account
    @api_key = api_key

    # A secret used to generate a signature for each API request
    @api_secret = api_secret

    # The base URL to use when calling the API
    @api_base_url = api_base_url

    # The period of time before requests to the API should timeout
    @timeout = timeout

    # NOTE: Rate limiting information is only available after a request
    # has been made.

    # The maximum number of requests per second that can be made with the
    # given API key.
    @rate_limit = nil

    # The time (seconds since epoch) when the current rate limit will
    # reset.
    @rate_limit_reset = nil

    # The number of requests remaining within the current limit before the
    # next reset.
    @rate_limit_remaining = nil
end

Instance Attribute Details

#rate_limitObject (readonly)

A client for the CareHQ API.



21
22
23
# File 'lib/carehq.rb', line 21

def rate_limit
  @rate_limit
end

#rate_limit_remainingObject (readonly)

Returns the value of attribute rate_limit_remaining.



23
24
25
# File 'lib/carehq.rb', line 23

def rate_limit_remaining
  @rate_limit_remaining
end

#rate_limit_resetObject (readonly)

Returns the value of attribute rate_limit_reset.



22
23
24
# File 'lib/carehq.rb', line 22

def rate_limit_reset
  @rate_limit_reset
end

Instance Method Details

#request(method, path, params: nil, data: nil) ⇒ Object

Raises:

  • (error_cls)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/carehq.rb', line 64

def request(method, path, params: nil, data: nil)
    # Call the API

    # Filter out params/data set to `nil` and ensure all arguments are
    # converted to strings.

    if params
        params.delete_if {|k, v| v.nil?}
    end

    if data
        data.delete_if {|k, v| v.nil?}
    end

    # Build the signature
    signature_data = method.downcase == 'get' ? params : data

    signature_values = []
    (signature_data or {}).each_pair do |key, value|
        signature_values.push(key)
        if value.kind_of?(Array)
            signature_values.concat(value)
        else
            signature_values.push(value)
        end
    end

    signature_body = signature_values.join ''

    timestamp = Time.now.to_f.to_s

    signature_hash = Digest::SHA1.new
    signature_hash.update timestamp
    signature_hash.update signature_body
    signature_hash.update @api_secret
    signature = signature_hash.hexdigest

    # Build the headers
    headers = {
        'Accept' => 'application/json',
        'X-CareHQ-AccountId' => @account_id,
        'X-CareHQ-APIKey' => @api_key,
        'X-CareHQ-Signature' => signature,
        'X-CareHQ-Timestamp' => timestamp
    }

    # Make the request
    url = [@api_base_url, '/v1/', path].join ''
    response = HTTPartyWrapper.method(method.downcase).call(
        url,
        {
            :query => params,
            :headers => headers,
            :body => data,
            :timeout => @timeout
        }
    )

    # Raise an error related to the response

    # Handle a successful response
    if [200, 204].include? response.code
        return response
    end

    error_cls = APIException.get_class_by_status_code(response.code)
    raise error_cls.new(
        response.code,
        response['hint'],
        response['arg_errors']
    )

end