pco_api 1.3.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/lib/pco/api/endpoint.rb +25 -4
- data/lib/pco/api/version.rb +1 -1
- data/lib/pco/api.rb +4 -3
- data/spec/pco/api/endpoint_spec.rb +42 -0
- data/spec/pco/api_spec.rb +9 -0
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80591277ecc37d298f7a7c68c35d32cd9f5d117f401ee6c811a417aab5b9e494
|
4
|
+
data.tar.gz: 756f395bb87741e0786452d1391a47c08bc3a36df064f8fa6d368706e49128de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a64b77f5502cb0e7a83b3841596002402ed6484738185f0397d4bd9fccd451c3b3494e95a7e9c13a22f9123e20509c484b77528db19a2b972e8bfc61db43ff3d
|
7
|
+
data.tar.gz: a7c05f672220939fc491e20e334ba5511173ac4ed50e3bf3969530d7f1556cd7ed8147b0172dc1d727ed9696e134c32ab4a7cb3564585cfd96abea2743a8ff26
|
data/README.md
CHANGED
@@ -210,6 +210,7 @@ The following errors may be raised by the library, depending on the API response
|
|
210
210
|
| 404 | `PCO::API::Errors::NotFound` < `PCO::API::Errors::ClientError` |
|
211
211
|
| 405 | `PCO::API::Errors::MethodNotAllowed` < `PCO::API::Errors::ClientError` |
|
212
212
|
| 422 | `PCO::API::Errors::UnprocessableEntity` < `PCO::API::Errors::ClientError` |
|
213
|
+
| 429 | `PCO::API::Errors::TooManyRequests` < `PCO::API::Errors::ClientError` |
|
213
214
|
| other 4xx errors | `PCO::API::Errors::ClientError` |
|
214
215
|
| 500 | `PCO::API::Errors::InternalServerError` < `PCO::API::Errors::ServerError` |
|
215
216
|
| other 5xx errors | `PCO::API::Errors::ServerError` |
|
@@ -221,6 +222,7 @@ The exception object has the following methods:
|
|
221
222
|
| status | HTTP status code returned by the server |
|
222
223
|
| message | the message returned by the API |
|
223
224
|
| detail | the full error response returned by the API |
|
225
|
+
| headers | hash of HTTP headers returned by the API |
|
224
226
|
|
225
227
|
The `message` should be a simple string given by the API, e.g. "Resource Not Found".
|
226
228
|
|
@@ -229,6 +231,17 @@ In the case of validation errors, the `message` is a summary string built from t
|
|
229
231
|
Alternatively, you may rescue `PCO::API::Errors::BaseError` and branch your code based on
|
230
232
|
the status code returned by calling `error.status`.
|
231
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
|
+
|
232
245
|
## Copyright & License
|
233
246
|
|
234
247
|
Copyright Ministry Centered Technologies. Licensed MIT.
|
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
|
@@ -126,15 +137,25 @@ module PCO
|
|
126
137
|
Faraday.new(url: url) do |faraday|
|
127
138
|
faraday.response :json, content_type: /\bjson$/
|
128
139
|
if @basic_auth_token && @basic_auth_secret
|
129
|
-
faraday.basic_auth @basic_auth_token, @basic_auth_secret
|
140
|
+
faraday.request :basic_auth, @basic_auth_token, @basic_auth_secret
|
130
141
|
elsif @oauth_access_token
|
131
|
-
faraday.
|
142
|
+
faraday.request :authorization, 'Bearer', @oauth_access_token
|
132
143
|
else
|
133
144
|
fail Errors::AuthRequiredError, "You must specify either HTTP basic auth credentials or an OAuth2 access token."
|
134
145
|
end
|
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
|
-
end
|
161
|
+
end
|
data/lib/pco/api/version.rb
CHANGED
data/lib/pco/api.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
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pco_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Planning Center Online
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: faraday_middleware
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: excon
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,12 +109,13 @@ files:
|
|
109
109
|
- lib/pco/api/version.rb
|
110
110
|
- lib/pco_api.rb
|
111
111
|
- spec/pco/api/endpoint_spec.rb
|
112
|
+
- spec/pco/api_spec.rb
|
112
113
|
- spec/spec_helper.rb
|
113
114
|
homepage: https://github.com/planningcenter/pco_api_ruby
|
114
115
|
licenses:
|
115
116
|
- MIT
|
116
117
|
metadata: {}
|
117
|
-
post_install_message:
|
118
|
+
post_install_message:
|
118
119
|
rdoc_options: []
|
119
120
|
require_paths:
|
120
121
|
- lib
|
@@ -129,10 +130,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
130
|
- !ruby/object:Gem::Version
|
130
131
|
version: '0'
|
131
132
|
requirements: []
|
132
|
-
rubygems_version: 3.0.3
|
133
|
-
signing_key:
|
133
|
+
rubygems_version: 3.0.3.1
|
134
|
+
signing_key:
|
134
135
|
specification_version: 4
|
135
136
|
summary: API wrapper for api.planningcenteronline.com
|
136
137
|
test_files:
|
138
|
+
- spec/pco/api_spec.rb
|
137
139
|
- spec/pco/api/endpoint_spec.rb
|
138
140
|
- spec/spec_helper.rb
|