pco_api 1.3.1 → 2.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eee1d9d3e7b4407dfc0b5f183021246c34a1467936fb77743c4cd45a1767b9b7
4
- data.tar.gz: 014ec30ad0b2c1b814b10da5ee26716f55cea5bf85a782e4230feaadf7f0c260
3
+ metadata.gz: 6e9b56ec41159e601c1afb0b4fa004797f91d0ae845ba396e09617738f98cdea
4
+ data.tar.gz: 931ed18a093f13ba313d6070b2307d888db9d38fe434308f76e6b0b5b0cf9715
5
5
  SHA512:
6
- metadata.gz: b36cca693f502f4c4b123aa22c61b72d41ccd51457eee7c2aef87454559d1fb7ffe85241ec97ab8832925830f864e773ce22b319d278f474245826f44bfe20e1
7
- data.tar.gz: 3c16320118da5aee58fcec347cae41df8c215d176331863d61d079a0b47bbc23998816ff09dbecbce888177faa7847da2f13f66fe4c984622fb74cb641eb9372
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
@@ -3,9 +3,10 @@ require_relative 'api/errors'
3
3
 
4
4
  module PCO
5
5
  module API
6
- module_function
7
- def new(**args)
8
- Endpoint.new(**args)
6
+ class << self
7
+ def new(**args)
8
+ Endpoint.new(**args)
9
+ end
9
10
  end
10
11
  end
11
12
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  module PCO
2
2
  module API
3
- VERSION = '1.3.1'
3
+ VERSION = '2.0.0'
4
4
  end
5
5
  end
@@ -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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pco_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Planning Center Online