shopify-api-limits 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +21 -26
- data/lib/shopify-api-limits.rb +8 -14
- data/lib/shopify-api-limits/shopify_api/limits.rb +72 -0
- data/lib/shopify-api-limits/version.rb +1 -1
- data/spec/limits.rb +13 -11
- metadata +2 -2
- data/lib/shopify-api-limits/shopify_api/shopify_api.rb +0 -72
data/README.rdoc
CHANGED
@@ -23,28 +23,23 @@ ActiveResource does not make it easy to read the HTTP response headers, since th
|
|
23
23
|
end
|
24
24
|
|
25
25
|
== Solution
|
26
|
-
Hack ActiveResource::Connection to introduce a new attr_reader :response and
|
26
|
+
Hack ActiveResource::Connection to introduce a new attr_reader :response and capture the returned HTTPResponse instance from the #handle_response method.
|
27
27
|
|
28
|
-
|
28
|
+
module ActiveResource
|
29
29
|
class Connection
|
30
|
-
# HACK
|
30
|
+
# HACK: Add an attr_reader for response
|
31
31
|
attr_reader :response
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@response = handle_response(result)
|
41
|
-
rescue Timeout::Error => e
|
42
|
-
raise TimeoutError.new(e.message)
|
43
|
-
rescue OpenSSL::SSL::SSLError => e
|
44
|
-
raise SSLError.new(e.message)
|
45
|
-
end
|
33
|
+
# capture the original #handle_response as an unbound method instead of using alias
|
34
|
+
handle_response = self.instance_method(:handle_response)
|
35
|
+
|
36
|
+
# re-implement #handle_response to capture the returned HTTPResponse to an instance var.
|
37
|
+
define_method(:handle_response) do |response|
|
38
|
+
@response = handle_response.bind(self).call(response)
|
39
|
+
end
|
46
40
|
end
|
47
|
-
end
|
41
|
+
end
|
42
|
+
|
48
43
|
|
49
44
|
Now it's possible to access the HTTPResponse instance directly from ActiveResource, via:
|
50
45
|
foo = ActiveResource::Base.connection.response['http-header-param-foo']
|
@@ -55,23 +50,23 @@ Now it's possible to access the HTTPResponse instance directly from ActiveResour
|
|
55
50
|
gem "shopify-api-limits"
|
56
51
|
|
57
52
|
== Usage
|
58
|
-
count_shop = ShopifyAPI.
|
59
|
-
limit_shop = ShopifyAPI.
|
53
|
+
count_shop = ShopifyAPI.credit_used :shop
|
54
|
+
limit_shop = ShopifyAPI.credit_limit :shop
|
60
55
|
|
61
|
-
count_global = ShopifyAPI.
|
62
|
-
limit_global = ShopifyAPI.
|
56
|
+
count_global = ShopifyAPI.credit_used :global
|
57
|
+
limit_global = ShopifyAPI.credit_limit :global
|
63
58
|
|
64
|
-
Generally, you shouldn't need to use the methods above directly -- rather they're used under-the-hood by the following helpful methods which don't require a scope (
|
59
|
+
Generally, you shouldn't need to use the methods above directly -- rather, they're used under-the-hood by the following helpful methods which don't require a scope (<b>:shop/:global</b>): If the <b>:global</b> scope has fewer calls available than the <b>:local</b> scope, the methods will operate upon the <b>:global</b> scope; otherwise, values will be returned based upon the <b>:shop</b> scope.
|
65
60
|
|
66
|
-
unless ShopifyAPI.
|
67
|
-
#make
|
61
|
+
unless ShopifyAPI.credit_maxed?
|
62
|
+
#make a ShopifyAPI call
|
68
63
|
end
|
69
64
|
|
70
|
-
until ShopifyAPI.
|
65
|
+
until ShopifyAPI.credit_maxed? || stop_condition
|
71
66
|
# make some ShopifyAPI calls
|
72
67
|
end
|
73
68
|
|
74
|
-
while ShopifyAPI.
|
69
|
+
while ShopifyAPI.credit_left || stop_condition
|
75
70
|
# make some ShopifyAPI calls
|
76
71
|
end
|
77
72
|
|
data/lib/shopify-api-limits.rb
CHANGED
@@ -4,22 +4,16 @@ module ShopifyAPI
|
|
4
4
|
module Limits
|
5
5
|
# Connection hack
|
6
6
|
require 'shopify-api-limits/active_resource/connection'
|
7
|
+
require 'shopify-api-limits/shopify_api/limits'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
class Error < StandardError
|
11
|
-
def self.status_code(code = nil)
|
12
|
-
return @code unless code
|
13
|
-
@code = code
|
14
|
-
end
|
15
|
-
|
16
|
-
def status_code
|
17
|
-
self.class.status_code
|
18
|
-
end
|
9
|
+
def self.included(klass)
|
10
|
+
klass.send(:extend, ClassMethods)
|
19
11
|
end
|
20
|
-
|
21
|
-
class
|
22
|
-
class
|
12
|
+
|
13
|
+
class Error < StandardError; end
|
14
|
+
class GlobalError < Error; end
|
15
|
+
class ShopError < Error; end
|
16
|
+
|
23
17
|
end
|
24
18
|
end
|
25
19
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ShopifyAPI
|
2
|
+
module Limits
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
# Takes form num_requests_executed/max_requests
|
6
|
+
# Eg: 101/3000
|
7
|
+
CREDIT_LIMIT_HEADER_PARAM = {
|
8
|
+
:global => 'http_x_shopify_api_call_limit',
|
9
|
+
:shop => 'http_x_shopify_shop_api_call_limit'
|
10
|
+
}
|
11
|
+
|
12
|
+
##
|
13
|
+
# How many more API calls can I make?
|
14
|
+
# @return {Integer}
|
15
|
+
#
|
16
|
+
def credit_left
|
17
|
+
shop = credit_limit(:shop) - credit_used(:shop)
|
18
|
+
global = credit_limit(:global) - credit_used(:global)
|
19
|
+
shop < global ? shop : global
|
20
|
+
end
|
21
|
+
alias_method :available_calls, :credit_left
|
22
|
+
|
23
|
+
##
|
24
|
+
# Have I reached my API call limit?
|
25
|
+
# @return {Boolean}
|
26
|
+
#
|
27
|
+
def credit_maxed?
|
28
|
+
credit_left == 0
|
29
|
+
end
|
30
|
+
alias_method :maxed?, :credit_maxed?
|
31
|
+
|
32
|
+
##
|
33
|
+
# How many total API calls can I make?
|
34
|
+
# NOTE: subtracting 1 from credit_limit because I think ShopifyAPI cuts off at 299/2999 or shop/global limits.
|
35
|
+
# @param {Symbol} scope [:shop|:global]
|
36
|
+
# @return {Integer}
|
37
|
+
#
|
38
|
+
def credit_limit(scope=:shop)
|
39
|
+
@api_credit_limit ||= {}
|
40
|
+
@api_credit_limit[scope] ||= api_credit_limit_param(scope).pop.to_i - 1
|
41
|
+
end
|
42
|
+
alias_method :call_limit, :credit_limit
|
43
|
+
|
44
|
+
##
|
45
|
+
# How many API calls have I made?
|
46
|
+
# @param {Symbol} scope [:shop|:global]
|
47
|
+
# @return {Integer}
|
48
|
+
#
|
49
|
+
def credit_used(scope=:shop)
|
50
|
+
api_credit_limit_param(scope).shift.to_i
|
51
|
+
end
|
52
|
+
alias_method :call_count, :credit_used
|
53
|
+
|
54
|
+
##
|
55
|
+
# @return {HTTPResonse}
|
56
|
+
#
|
57
|
+
def response
|
58
|
+
Shop.current unless ActiveResource::Base.connection.response
|
59
|
+
ActiveResource::Base.connection.response
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return {Array}
|
66
|
+
#
|
67
|
+
def api_credit_limit_param(scope)
|
68
|
+
response[CREDIT_LIMIT_HEADER_PARAM[scope]].split('/')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/limits.rb
CHANGED
@@ -3,30 +3,32 @@ require './spec/boot'
|
|
3
3
|
|
4
4
|
describe "Limits" do
|
5
5
|
it "Can fetch local limits" do
|
6
|
-
count = ShopifyAPI.
|
7
|
-
limit = ShopifyAPI.
|
6
|
+
count = ShopifyAPI.credit_used :shop
|
7
|
+
limit = ShopifyAPI.credit_limit :shop
|
8
8
|
|
9
|
-
(count < 300 && count > 0).should be_true
|
10
9
|
(count < limit).should be_true
|
11
|
-
|
12
|
-
|
10
|
+
(count > 0).should be_true
|
11
|
+
ShopifyAPI.credit_maxed?.should be_false
|
12
|
+
(ShopifyAPI.credit_left > 0).should be_true
|
13
13
|
end
|
14
14
|
|
15
15
|
it "Can fetch global limits" do
|
16
|
-
count = ShopifyAPI.
|
17
|
-
limit = ShopifyAPI.
|
16
|
+
count = ShopifyAPI.credit_used :global
|
17
|
+
limit = ShopifyAPI.creidt_limit :global
|
18
18
|
|
19
19
|
(count < 3000 && count > 0).should be_true
|
20
20
|
(count < limit).should be_true
|
21
|
-
ShopifyAPI.
|
22
|
-
(ShopifyAPI.
|
21
|
+
ShopifyAPI.credit_maxed?.should be_false
|
22
|
+
(ShopifyAPI.credit_left > 0).should be_true
|
23
23
|
end
|
24
24
|
|
25
25
|
it "Can execute up to local max" do
|
26
|
-
until ShopifyAPI.
|
26
|
+
until ShopifyAPI.credit_maxed?
|
27
27
|
ShopifyAPI::Shop.current
|
28
|
-
puts "avail: #{ShopifyAPI.
|
28
|
+
puts "avail: #{ShopifyAPI.credit_left}, maxed: #{ShopifyAPI.credit_maxed?}"
|
29
29
|
end
|
30
|
+
ShopifyAPI.credit_maxed?.should be_true
|
31
|
+
(ShopifyAPI.credit_left == 0).should be_true
|
30
32
|
end
|
31
33
|
|
32
34
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: shopify-api-limits
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Chris Scott
|
@@ -62,7 +62,7 @@ files:
|
|
62
62
|
- Rakefile
|
63
63
|
- lib/shopify-api-limits.rb
|
64
64
|
- lib/shopify-api-limits/active_resource/connection.rb
|
65
|
-
- lib/shopify-api-limits/shopify_api/
|
65
|
+
- lib/shopify-api-limits/shopify_api/limits.rb
|
66
66
|
- lib/shopify-api-limits/version.rb
|
67
67
|
- shopify-api-limits.gemspec
|
68
68
|
- spec/boot.rb
|
@@ -1,72 +0,0 @@
|
|
1
|
-
module ShopifyAPI
|
2
|
-
module Limits
|
3
|
-
def self.included(klass)
|
4
|
-
klass.send(:extend, ClassMethods)
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
|
10
|
-
# Takes form num_requests_executed/max_requests
|
11
|
-
# Eg: 101/3000
|
12
|
-
CALL_LIMIT_HEADER_PARAM = {
|
13
|
-
:global => 'http_x_shopify_api_call_limit',
|
14
|
-
:shop => 'http_x_shopify_shop_api_call_limit'
|
15
|
-
}
|
16
|
-
|
17
|
-
##
|
18
|
-
# How many more API calls can I make?
|
19
|
-
# @return {Integer}
|
20
|
-
#
|
21
|
-
def available_calls
|
22
|
-
shop = call_limit(:shop) - call_count(:shop)
|
23
|
-
global = call_limit(:global) - call_count(:global)
|
24
|
-
shop < global ? shop : global
|
25
|
-
end
|
26
|
-
|
27
|
-
##
|
28
|
-
# Have I reached my API call limit?
|
29
|
-
# @return {Boolean}
|
30
|
-
#
|
31
|
-
def maxed?
|
32
|
-
available_calls == 0
|
33
|
-
end
|
34
|
-
|
35
|
-
##
|
36
|
-
# How many total API calls can I make?
|
37
|
-
# NOTE: subtracting 1 from call_limit because I think ShopifyAPI cuts off at 299/2999 or shop/global limits.
|
38
|
-
# @param {Symbol} scope [:shop|:global]
|
39
|
-
# @return {Integer}
|
40
|
-
#
|
41
|
-
def call_limit(scope=:shop)
|
42
|
-
@api_call_limit ||= {}
|
43
|
-
@api_call_limit[scope] ||= api_call_limit_param(scope).pop.to_i - 1
|
44
|
-
end
|
45
|
-
|
46
|
-
##
|
47
|
-
# How many API calls have I made?
|
48
|
-
# @param {Symbol} scope [:shop|:global]
|
49
|
-
# @return {Integer}
|
50
|
-
#
|
51
|
-
def call_count(scope=:shop)
|
52
|
-
api_call_limit_param(scope).shift.to_i
|
53
|
-
end
|
54
|
-
|
55
|
-
##
|
56
|
-
# @return {HTTPResonse}
|
57
|
-
#
|
58
|
-
def response
|
59
|
-
Shop.current unless ActiveResource::Base.connection.response
|
60
|
-
ActiveResource::Base.connection.response
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
##
|
66
|
-
# @return {Array}
|
67
|
-
#
|
68
|
-
def api_call_limit_param(scope)
|
69
|
-
response[CALL_LIMIT_HEADER_PARAM[scope]].split('/')
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|