pco_api 1.3.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/lib/pco/api.rb +4 -3
- data/lib/pco/api/endpoint.rb +22 -1
- data/lib/pco/api/version.rb +1 -1
- data/spec/pco/api/endpoint_spec.rb +42 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e9b56ec41159e601c1afb0b4fa004797f91d0ae845ba396e09617738f98cdea
|
4
|
+
data.tar.gz: 931ed18a093f13ba313d6070b2307d888db9d38fe434308f76e6b0b5b0cf9715
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21f690d99a0ea0896ab49a416d64ae802c7f993a6f63afa725b7e6ab098a2049a6d7aad3e1dc7b0f230eb2db4bb2faceba7760d054b0c8595138708438348a66
|
7
|
+
data.tar.gz: cc5b2478ae1de0b2911594483573266d9f3447078b81529c97e9765c209d49af7b9c99f80a14a089d6c92d0c7d5be3e33cde7a17a4d25cfc4ad64e0f0d030e37
|
data/README.md
CHANGED
@@ -231,6 +231,17 @@ In the case of validation errors, the `message` is a summary string built from t
|
|
231
231
|
Alternatively, you may rescue `PCO::API::Errors::BaseError` and branch your code based on
|
232
232
|
the status code returned by calling `error.status`.
|
233
233
|
|
234
|
+
### TooManyRequests Error
|
235
|
+
|
236
|
+
By default, PCO::API::Endpoint will sleep and retry a request that fails with TooManyRequests due
|
237
|
+
to rate limiting. If you would rather catch and handle such errors yourself, you can disable this
|
238
|
+
behavior like this:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
api = PCO::API.new(...)
|
242
|
+
api.retry_when_rate_limited = false
|
243
|
+
```
|
244
|
+
|
234
245
|
## Copyright & License
|
235
246
|
|
236
247
|
Copyright Ministry Centered Technologies. Licensed MIT.
|
data/lib/pco/api.rb
CHANGED
data/lib/pco/api/endpoint.rb
CHANGED
@@ -12,6 +12,8 @@ module PCO
|
|
12
12
|
class Endpoint
|
13
13
|
attr_reader :url, :last_result
|
14
14
|
|
15
|
+
attr_accessor :retry_when_rate_limited
|
16
|
+
|
15
17
|
def initialize(url: URL, oauth_access_token: nil, basic_auth_token: nil, basic_auth_secret: nil, connection: nil)
|
16
18
|
@url = url
|
17
19
|
@oauth_access_token = oauth_access_token
|
@@ -19,6 +21,7 @@ module PCO
|
|
19
21
|
@basic_auth_secret = basic_auth_secret
|
20
22
|
@connection = connection || _build_connection
|
21
23
|
@cache = {}
|
24
|
+
@retry_when_rate_limited = true
|
22
25
|
end
|
23
26
|
|
24
27
|
def method_missing(method_name, *_args)
|
@@ -29,7 +32,7 @@ module PCO
|
|
29
32
|
_build_endpoint(id.to_s)
|
30
33
|
end
|
31
34
|
|
32
|
-
def respond_to?(method_name)
|
35
|
+
def respond_to?(method_name, _include_all = false)
|
33
36
|
endpoint = _build_endpoint(method_name.to_s)
|
34
37
|
begin
|
35
38
|
endpoint.get
|
@@ -43,6 +46,8 @@ module PCO
|
|
43
46
|
def get(params = {})
|
44
47
|
@last_result = @connection.get(@url, params)
|
45
48
|
_build_response(@last_result)
|
49
|
+
rescue Errors::TooManyRequests => e
|
50
|
+
_retry_after_timeout?(e) ? retry : raise
|
46
51
|
end
|
47
52
|
|
48
53
|
def post(body = {})
|
@@ -50,6 +55,8 @@ module PCO
|
|
50
55
|
req.body = _build_body(body)
|
51
56
|
end
|
52
57
|
_build_response(@last_result)
|
58
|
+
rescue Errors::TooManyRequests => e
|
59
|
+
_retry_after_timeout?(e) ? retry : raise
|
53
60
|
end
|
54
61
|
|
55
62
|
def patch(body = {})
|
@@ -57,6 +64,8 @@ module PCO
|
|
57
64
|
req.body = _build_body(body)
|
58
65
|
end
|
59
66
|
_build_response(@last_result)
|
67
|
+
rescue Errors::TooManyRequests => e
|
68
|
+
_retry_after_timeout?(e) ? retry : raise
|
60
69
|
end
|
61
70
|
|
62
71
|
def delete
|
@@ -66,6 +75,8 @@ module PCO
|
|
66
75
|
else
|
67
76
|
_build_response(@last_result)
|
68
77
|
end
|
78
|
+
rescue Errors::TooManyRequests => e
|
79
|
+
_retry_after_timeout?(e) ? retry : raise
|
69
80
|
end
|
70
81
|
|
71
82
|
private
|
@@ -135,6 +146,16 @@ module PCO
|
|
135
146
|
faraday.adapter :excon
|
136
147
|
end
|
137
148
|
end
|
149
|
+
|
150
|
+
def _retry_after_timeout?(e)
|
151
|
+
if @retry_when_rate_limited
|
152
|
+
secs = e.headers['Retry-After']
|
153
|
+
Kernel.sleep(secs ? secs.to_i : 1)
|
154
|
+
true
|
155
|
+
else
|
156
|
+
false
|
157
|
+
end
|
158
|
+
end
|
138
159
|
end
|
139
160
|
end
|
140
161
|
end
|
data/lib/pco/api/version.rb
CHANGED
@@ -124,6 +124,48 @@ describe PCO::API::Endpoint do
|
|
124
124
|
}.to raise_error(PCO::API::Errors::ServerError)
|
125
125
|
end
|
126
126
|
end
|
127
|
+
|
128
|
+
context 'given a 429 error due to rate limiting' do
|
129
|
+
subject { base.people.v2 }
|
130
|
+
|
131
|
+
let(:result) do
|
132
|
+
{
|
133
|
+
'type' => 'Organization',
|
134
|
+
'id' => '1',
|
135
|
+
'name' => 'Ministry Centered Technologies',
|
136
|
+
'links' => {}
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
before do
|
141
|
+
stub_request(:get, 'https://api.planningcenteronline.com/people/v2')
|
142
|
+
.to_return([
|
143
|
+
{ status: 429, headers: { 'retry-after' => '2' } },
|
144
|
+
{ status: 200, body: { data: result }.to_json, headers: { 'Content-Type' => 'application/vnd.api+json' } }
|
145
|
+
])
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'given retry_when_rate_limited is true' do
|
149
|
+
before do
|
150
|
+
subject.retry_when_rate_limited = true
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'sleeps, then makes the call again' do
|
154
|
+
expect(Kernel).to receive(:sleep).with(2)
|
155
|
+
expect(subject.get).to be_a(Hash)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'given retry_when_rate_limited is false' do
|
160
|
+
before do
|
161
|
+
subject.retry_when_rate_limited = false
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'raises the TooManyRequests error' do
|
165
|
+
expect { subject.get }.to raise_error(PCO::API::Errors::TooManyRequests)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
127
169
|
end
|
128
170
|
|
129
171
|
describe '#post' do
|