lago-ruby-client 1.45.0 → 1.47.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 +4 -4
- data/lib/lago/api/client.rb +12 -3
- data/lib/lago/api/connection.rb +111 -54
- data/lib/lago/api/logging_rate_limit_observer.rb +54 -0
- data/lib/lago/api/rate_limit_error.rb +23 -0
- data/lib/lago/api/rate_limit_info.rb +49 -0
- data/lib/lago/api/resources/base.rb +7 -1
- data/lib/lago/api/resources/customer.rb +5 -0
- data/lib/lago/api/resources/event.rb +7 -1
- data/lib/lago/api/resources/nested.rb +7 -1
- data/lib/lago/version.rb +1 -1
- data/lib/lago-ruby-client.rb +3 -0
- metadata +34 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1ce7eaf525a2785545ea91a30464c1da9da45a09c95d01a6b062cd4b51a85f5
|
|
4
|
+
data.tar.gz: 6d8be436f3b5b4155d8e72e28aea99082fd40dfa1070a18758e40842ede13d34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c10616c41e59442007247c9245bb91be08881744dbf91f9112dbe4043e7d19c33539aa50c8367f77a06a6d3fd49efa5d5a3add3f10842eaa05cc0d0ab0f2643d
|
|
7
|
+
data.tar.gz: adc378ba5f462f08880bbd3ff8b841b9432660a378f3dec36aeab4b4065e0ecaf07608a27ead50a49cea6eab701c250e0f2e89915d1d13df016f22c252dc95de
|
data/lib/lago/api/client.rb
CHANGED
|
@@ -53,13 +53,22 @@ module Lago
|
|
|
53
53
|
API_PATH = 'api/v1/'
|
|
54
54
|
|
|
55
55
|
class Client
|
|
56
|
-
attr_reader :api_key,
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
attr_reader :api_key,
|
|
57
|
+
:api_url,
|
|
58
|
+
:use_ingest_service,
|
|
59
|
+
:ingest_api_url,
|
|
60
|
+
:max_retries,
|
|
61
|
+
:retry_on_rate_limit,
|
|
62
|
+
:on_rate_limit_info
|
|
63
|
+
|
|
64
|
+
def initialize(api_key: nil, api_url: nil, use_ingest_service: false, ingest_api_url: nil, **options)
|
|
59
65
|
@api_key = api_key
|
|
60
66
|
@api_url = api_url
|
|
61
67
|
@use_ingest_service = use_ingest_service
|
|
62
68
|
@ingest_api_url = ingest_api_url
|
|
69
|
+
@max_retries = options.fetch(:max_retries, 3)
|
|
70
|
+
@retry_on_rate_limit = options.fetch(:retry_on_rate_limit, true)
|
|
71
|
+
@on_rate_limit_info = options[:on_rate_limit_info]
|
|
63
72
|
end
|
|
64
73
|
|
|
65
74
|
def base_api_url
|
data/lib/lago/api/connection.rb
CHANGED
|
@@ -6,84 +6,73 @@ module Lago
|
|
|
6
6
|
module Api
|
|
7
7
|
class Connection
|
|
8
8
|
RESPONSE_SUCCESS_CODES = [200, 201, 202, 204].freeze
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
DEFAULT_MAX_RETRIES = 3
|
|
10
|
+
INITIAL_BACKOFF = 1
|
|
11
|
+
BACKOFF_MULTIPLIER = 2
|
|
12
|
+
MAX_RETRY_DELAY = 20
|
|
13
|
+
|
|
14
|
+
def initialize(
|
|
15
|
+
api_key,
|
|
16
|
+
uri,
|
|
17
|
+
max_retries: DEFAULT_MAX_RETRIES,
|
|
18
|
+
retry_on_rate_limit: true,
|
|
19
|
+
on_rate_limit_info: nil
|
|
20
|
+
)
|
|
11
21
|
@api_key = api_key
|
|
12
22
|
@uri = uri
|
|
23
|
+
@max_retries = max_retries
|
|
24
|
+
@retry_on_rate_limit = retry_on_rate_limit
|
|
25
|
+
@on_rate_limit_info = on_rate_limit_info
|
|
13
26
|
end
|
|
14
27
|
|
|
15
28
|
def post(body, path = uri.path)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
path,
|
|
19
|
-
|
|
20
|
-
headers
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
handle_response(response)
|
|
29
|
+
method = 'POST'
|
|
30
|
+
execute_request(method:) do
|
|
31
|
+
http_client.send_request(method, path, prepare_payload(body), headers)
|
|
32
|
+
end
|
|
24
33
|
end
|
|
25
34
|
|
|
26
35
|
def put(path = uri.path, identifier:, body:)
|
|
36
|
+
method = 'PUT'
|
|
27
37
|
uri_path = identifier.nil? ? path : "#{path}/#{CGI.escapeURIComponent(identifier)}"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
prepare_payload(body),
|
|
32
|
-
headers
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
handle_response(response)
|
|
38
|
+
execute_request(method:) do
|
|
39
|
+
http_client.send_request(method, uri_path, prepare_payload(body), headers)
|
|
40
|
+
end
|
|
36
41
|
end
|
|
37
42
|
|
|
38
43
|
def patch(path = uri.path, identifier:, body:)
|
|
44
|
+
method = 'PATCH'
|
|
39
45
|
uri_path = identifier.nil? ? path : "#{path}/#{CGI.escapeURIComponent(identifier)}"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
prepare_payload(body),
|
|
44
|
-
headers
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
handle_response(response)
|
|
46
|
+
execute_request(method:) do
|
|
47
|
+
http_client.send_request(method, uri_path, prepare_payload(body), headers)
|
|
48
|
+
end
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
def get(path = uri.path, identifier:)
|
|
52
|
+
method = 'GET'
|
|
51
53
|
uri_path = identifier.nil? ? path : "#{path}/#{CGI.escapeURIComponent(identifier)}"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
prepare_payload(nil),
|
|
56
|
-
headers
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
handle_response(response)
|
|
54
|
+
execute_request(method:) do
|
|
55
|
+
http_client.send_request(method, uri_path, prepare_payload(nil), headers)
|
|
56
|
+
end
|
|
60
57
|
end
|
|
61
58
|
|
|
62
59
|
def destroy(path = uri.path, identifier:, options: nil)
|
|
60
|
+
method = 'DELETE'
|
|
63
61
|
uri_path = path
|
|
64
62
|
uri_path += "/#{CGI.escapeURIComponent(identifier)}" if identifier
|
|
65
63
|
uri_path += "?#{URI.encode_www_form(options)}" unless options.nil?
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
prepare_payload(nil),
|
|
70
|
-
headers
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
handle_response(response)
|
|
64
|
+
execute_request(method:) do
|
|
65
|
+
http_client.send_request(method, uri_path, prepare_payload(nil), headers)
|
|
66
|
+
end
|
|
74
67
|
end
|
|
75
68
|
|
|
76
69
|
def get_all(options, path = uri.path)
|
|
70
|
+
method = 'GET'
|
|
77
71
|
uri_path = options.empty? ? path : "#{path}?#{URI.encode_www_form(options)}"
|
|
78
72
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
prepare_payload(nil),
|
|
83
|
-
headers
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
handle_response(response)
|
|
73
|
+
execute_request(method:) do
|
|
74
|
+
http_client.send_request(method, uri_path, prepare_payload(nil), headers)
|
|
75
|
+
end
|
|
87
76
|
end
|
|
88
77
|
|
|
89
78
|
private
|
|
@@ -98,14 +87,47 @@ module Lago
|
|
|
98
87
|
}
|
|
99
88
|
end
|
|
100
89
|
|
|
101
|
-
def
|
|
102
|
-
|
|
90
|
+
def execute_request(retry_count = 0, method: nil, &block)
|
|
91
|
+
response = yield
|
|
92
|
+
handle_response(response, retry_count, block, method:)
|
|
93
|
+
end
|
|
103
94
|
|
|
104
|
-
|
|
95
|
+
def handle_response(response, retry_count, block, method: nil)
|
|
96
|
+
code = response.code.to_i
|
|
97
|
+
|
|
98
|
+
if code == 429 && @retry_on_rate_limit && retry_count < @max_retries
|
|
99
|
+
handle_rate_limit(response, retry_count, block, method:)
|
|
100
|
+
elsif !RESPONSE_SUCCESS_CODES.include?(code)
|
|
101
|
+
raise_error(response)
|
|
102
|
+
else
|
|
103
|
+
emit_rate_limit_info(response, method:)
|
|
104
|
+
parse_response_body(response)
|
|
105
|
+
end
|
|
105
106
|
rescue JSON::ParserError
|
|
106
107
|
response.body
|
|
107
108
|
end
|
|
108
109
|
|
|
110
|
+
def handle_rate_limit(response, retry_count, block, method: nil)
|
|
111
|
+
reset_seconds = extract_reset_seconds(response, retry_count)
|
|
112
|
+
sleep(reset_seconds)
|
|
113
|
+
execute_request(retry_count + 1, method:, &block)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def emit_rate_limit_info(response, method: nil)
|
|
117
|
+
return if @on_rate_limit_info.nil?
|
|
118
|
+
|
|
119
|
+
info = Lago::Api::RateLimitInfo.parse(response, method:, url: uri.to_s)
|
|
120
|
+
return if info.nil?
|
|
121
|
+
|
|
122
|
+
@on_rate_limit_info.call(info)
|
|
123
|
+
rescue StandardError => e
|
|
124
|
+
warn("Lago: on_rate_limit_info callback raised: #{e.class}: #{e.message}")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def parse_response_body(response)
|
|
128
|
+
response.body.empty? || JSON.parse(response.body)
|
|
129
|
+
end
|
|
130
|
+
|
|
109
131
|
def http_client
|
|
110
132
|
http_client = Net::HTTP.new(uri.hostname, uri.port)
|
|
111
133
|
http_client.use_ssl = true if uri.scheme == 'https'
|
|
@@ -120,7 +142,42 @@ module Lago
|
|
|
120
142
|
end
|
|
121
143
|
|
|
122
144
|
def raise_error(response)
|
|
123
|
-
|
|
145
|
+
code = response.code.to_i
|
|
146
|
+
|
|
147
|
+
raise Lago::Api::HttpError.new(code, response.body, uri) unless code == 429
|
|
148
|
+
|
|
149
|
+
limit, remaining, reset = parse_rate_limit_headers(response)
|
|
150
|
+
raise Lago::Api::RateLimitError.new(
|
|
151
|
+
code,
|
|
152
|
+
response.body,
|
|
153
|
+
uri,
|
|
154
|
+
limit:,
|
|
155
|
+
remaining:,
|
|
156
|
+
reset:
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def parse_rate_limit_headers(response)
|
|
161
|
+
limit = response['x-ratelimit-limit']&.to_i
|
|
162
|
+
remaining = response['x-ratelimit-remaining']&.to_i
|
|
163
|
+
reset = response['x-ratelimit-reset']&.to_i
|
|
164
|
+
|
|
165
|
+
[limit, remaining, reset]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def extract_reset_seconds(response, retry_count)
|
|
169
|
+
delay = if response['x-ratelimit-reset']
|
|
170
|
+
[response['x-ratelimit-reset'].to_i, INITIAL_BACKOFF].max
|
|
171
|
+
else
|
|
172
|
+
# Exponential backoff if header is missing
|
|
173
|
+
calculate_backoff(retry_count)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
[delay, MAX_RETRY_DELAY].min
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def calculate_backoff(retry_count)
|
|
180
|
+
INITIAL_BACKOFF * (BACKOFF_MULTIPLIER**retry_count)
|
|
124
181
|
end
|
|
125
182
|
end
|
|
126
183
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Lago
|
|
6
|
+
module Api
|
|
7
|
+
# Ready-to-use +on_rate_limit_info+ callable that logs a warning each time
|
|
8
|
+
# rate limit usage crosses one of the configured thresholds.
|
|
9
|
+
#
|
|
10
|
+
# Example:
|
|
11
|
+
# client = Lago::Api::Client.new(
|
|
12
|
+
# api_key: '...',
|
|
13
|
+
# on_rate_limit_info: Lago::Api::LoggingRateLimitObserver.new,
|
|
14
|
+
# )
|
|
15
|
+
class LoggingRateLimitObserver
|
|
16
|
+
DEFAULT_THRESHOLDS = [0.80, 0.90, 0.95].freeze
|
|
17
|
+
|
|
18
|
+
def initialize(thresholds: DEFAULT_THRESHOLDS, logger: nil, level: Logger::WARN)
|
|
19
|
+
@thresholds = thresholds.sort.reverse
|
|
20
|
+
@logger = logger || default_logger
|
|
21
|
+
@level = level
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(info)
|
|
25
|
+
pct = info.usage_pct
|
|
26
|
+
return if pct.nil?
|
|
27
|
+
|
|
28
|
+
return unless @thresholds.any? { |threshold| pct >= threshold }
|
|
29
|
+
|
|
30
|
+
@logger.add(
|
|
31
|
+
@level,
|
|
32
|
+
format(
|
|
33
|
+
'Lago rate limit at %<pct>.0f%% (limit=%<limit>s, remaining=%<remaining>s, ' \
|
|
34
|
+
'reset=%<reset>ss, %<method>s %<url>s)',
|
|
35
|
+
pct: pct * 100,
|
|
36
|
+
limit: info.limit.inspect,
|
|
37
|
+
remaining: info.remaining.inspect,
|
|
38
|
+
reset: info.reset.inspect,
|
|
39
|
+
method: info.method,
|
|
40
|
+
url: info.url,
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def default_logger
|
|
48
|
+
logger = Logger.new($stderr)
|
|
49
|
+
logger.progname = 'lago_ruby_client.rate_limit'
|
|
50
|
+
logger
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lago
|
|
4
|
+
module Api
|
|
5
|
+
class RateLimitError < HttpError
|
|
6
|
+
attr_reader :limit, :remaining, :reset
|
|
7
|
+
|
|
8
|
+
def initialize(code, body, uri, **options)
|
|
9
|
+
super(code, body, uri)
|
|
10
|
+
@limit = options[:limit]
|
|
11
|
+
@remaining = options[:remaining]
|
|
12
|
+
@reset = options[:reset]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def message
|
|
16
|
+
base_message = "HTTP #{error_code} - URI: #{uri}.\nError: #{error_body}"
|
|
17
|
+
return base_message unless reset
|
|
18
|
+
|
|
19
|
+
"#{base_message}\nRate limit will reset in #{reset} seconds."
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lago
|
|
4
|
+
module Api
|
|
5
|
+
# Parsed rate limit headers from a Lago API response.
|
|
6
|
+
#
|
|
7
|
+
# Delivered to the +on_rate_limit_info+ callback after every successful
|
|
8
|
+
# request so callers can build observability around the rate limit
|
|
9
|
+
# (warn at thresholds, emit metrics, etc.).
|
|
10
|
+
class RateLimitInfo
|
|
11
|
+
attr_reader :limit, :remaining, :reset, :method, :url
|
|
12
|
+
|
|
13
|
+
# Parses x-ratelimit-* headers from a Net::HTTPResponse-like object.
|
|
14
|
+
# Returns +nil+ when no rate limit headers are present.
|
|
15
|
+
def self.parse(response, method:, url:)
|
|
16
|
+
limit = response['x-ratelimit-limit']
|
|
17
|
+
remaining = response['x-ratelimit-remaining']
|
|
18
|
+
reset = response['x-ratelimit-reset']
|
|
19
|
+
|
|
20
|
+
return nil if limit.nil? && remaining.nil? && reset.nil?
|
|
21
|
+
|
|
22
|
+
new(
|
|
23
|
+
limit: limit&.to_i,
|
|
24
|
+
remaining: remaining&.to_i,
|
|
25
|
+
reset: reset&.to_i,
|
|
26
|
+
method:,
|
|
27
|
+
url:,
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def initialize(limit:, remaining:, reset:, method:, url:)
|
|
32
|
+
@limit = limit
|
|
33
|
+
@remaining = remaining
|
|
34
|
+
@reset = reset
|
|
35
|
+
@method = method
|
|
36
|
+
@url = url
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the fraction of the rate limit currently used as a Float in
|
|
40
|
+
# [0.0, 1.0], or +nil+ when the headers aren't usable (missing limit,
|
|
41
|
+
# zero limit, missing remaining).
|
|
42
|
+
def usage_pct
|
|
43
|
+
return nil if limit.nil? || remaining.nil? || limit.to_i <= 0
|
|
44
|
+
|
|
45
|
+
1.0 - (remaining.to_f / limit)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -59,7 +59,13 @@ module Lago
|
|
|
59
59
|
def connection
|
|
60
60
|
uri = URI.join(client.base_api_url, api_resource)
|
|
61
61
|
|
|
62
|
-
Lago::Api::Connection.new(
|
|
62
|
+
Lago::Api::Connection.new(
|
|
63
|
+
client.api_key,
|
|
64
|
+
uri,
|
|
65
|
+
max_retries: client.max_retries,
|
|
66
|
+
retry_on_rate_limit: client.retry_on_rate_limit,
|
|
67
|
+
on_rate_limit_info: client.on_rate_limit_info,
|
|
68
|
+
)
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
71
|
end
|
|
@@ -20,10 +20,15 @@ module Lago
|
|
|
20
20
|
|
|
21
21
|
def current_usage( # rubocop:disable Metrics/ParameterLists
|
|
22
22
|
external_customer_id, external_subscription_id, apply_taxes: nil,
|
|
23
|
+
charge_id: nil, charge_code: nil, billable_metric_code: nil, group: nil,
|
|
23
24
|
filter_by_charge_id: nil, filter_by_charge_code: nil, filter_by_group: nil, full_usage: nil
|
|
24
25
|
)
|
|
25
26
|
query_params = { external_subscription_id: external_subscription_id }
|
|
26
27
|
query_params[:apply_taxes] = apply_taxes unless apply_taxes.nil?
|
|
28
|
+
query_params[:charge_id] = charge_id unless charge_id.nil?
|
|
29
|
+
query_params[:charge_code] = charge_code unless charge_code.nil?
|
|
30
|
+
query_params[:billable_metric_code] = billable_metric_code unless billable_metric_code.nil?
|
|
31
|
+
group&.each { |k, v| query_params[:"group[#{k}]"] = v }
|
|
27
32
|
query_params[:filter_by_charge_id] = filter_by_charge_id unless filter_by_charge_id.nil?
|
|
28
33
|
query_params[:filter_by_charge_code] = filter_by_charge_code unless filter_by_charge_code.nil?
|
|
29
34
|
filter_by_group&.each { |k, v| query_params[:"filter_by_group[#{k}]"] = v }
|
|
@@ -16,7 +16,13 @@ module Lago
|
|
|
16
16
|
|
|
17
17
|
def create(params)
|
|
18
18
|
uri = URI("#{client.base_ingest_api_url}#{api_resource}")
|
|
19
|
-
connection = Lago::Api::Connection.new(
|
|
19
|
+
connection = Lago::Api::Connection.new(
|
|
20
|
+
client.api_key,
|
|
21
|
+
uri,
|
|
22
|
+
max_retries: client.max_retries,
|
|
23
|
+
retry_on_rate_limit: client.retry_on_rate_limit,
|
|
24
|
+
on_rate_limit_info: client.on_rate_limit_info,
|
|
25
|
+
)
|
|
20
26
|
|
|
21
27
|
payload = whitelist_params(params)
|
|
22
28
|
response = connection.post(payload, uri)[root_name]
|
|
@@ -8,7 +8,13 @@ module Lago
|
|
|
8
8
|
class Nested < Base
|
|
9
9
|
def initialize(client)
|
|
10
10
|
super(client)
|
|
11
|
-
@connection = Lago::Api::Connection.new(
|
|
11
|
+
@connection = Lago::Api::Connection.new(
|
|
12
|
+
client.api_key,
|
|
13
|
+
client.base_api_url,
|
|
14
|
+
max_retries: client.max_retries,
|
|
15
|
+
retry_on_rate_limit: client.retry_on_rate_limit,
|
|
16
|
+
on_rate_limit_info: client.on_rate_limit_info,
|
|
17
|
+
)
|
|
12
18
|
end
|
|
13
19
|
|
|
14
20
|
def create(*parent_ids, params)
|
data/lib/lago/version.rb
CHANGED
data/lib/lago-ruby-client.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lago-ruby-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.47.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lovro Colic
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: jwt
|
|
@@ -52,6 +51,20 @@ dependencies:
|
|
|
52
51
|
- - ">="
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: benchmark
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
55
68
|
- !ruby/object:Gem::Dependency
|
|
56
69
|
name: bigdecimal
|
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -192,6 +205,20 @@ dependencies:
|
|
|
192
205
|
- - "~>"
|
|
193
206
|
- !ruby/object:Gem::Version
|
|
194
207
|
version: '13.0'
|
|
208
|
+
- !ruby/object:Gem::Dependency
|
|
209
|
+
name: readline
|
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0'
|
|
215
|
+
type: :development
|
|
216
|
+
prerelease: false
|
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
195
222
|
- !ruby/object:Gem::Dependency
|
|
196
223
|
name: rspec
|
|
197
224
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -276,7 +303,6 @@ dependencies:
|
|
|
276
303
|
- - ">="
|
|
277
304
|
- !ruby/object:Gem::Version
|
|
278
305
|
version: '0'
|
|
279
|
-
description:
|
|
280
306
|
email:
|
|
281
307
|
- lovro@getlago.com
|
|
282
308
|
executables: []
|
|
@@ -287,6 +313,9 @@ files:
|
|
|
287
313
|
- lib/lago/api/client.rb
|
|
288
314
|
- lib/lago/api/connection.rb
|
|
289
315
|
- lib/lago/api/http_error.rb
|
|
316
|
+
- lib/lago/api/logging_rate_limit_observer.rb
|
|
317
|
+
- lib/lago/api/rate_limit_error.rb
|
|
318
|
+
- lib/lago/api/rate_limit_info.rb
|
|
290
319
|
- lib/lago/api/resources/activity_log.rb
|
|
291
320
|
- lib/lago/api/resources/add_on.rb
|
|
292
321
|
- lib/lago/api/resources/api_log.rb
|
|
@@ -341,7 +370,6 @@ metadata:
|
|
|
341
370
|
homepage_uri: https://www.getlago.com/
|
|
342
371
|
source_code_uri: https://github.com/getlago/lago-ruby-client
|
|
343
372
|
documentation_uri: https://doc.getlago.com
|
|
344
|
-
post_install_message:
|
|
345
373
|
rdoc_options: []
|
|
346
374
|
require_paths:
|
|
347
375
|
- lib
|
|
@@ -356,8 +384,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
356
384
|
- !ruby/object:Gem::Version
|
|
357
385
|
version: '0'
|
|
358
386
|
requirements: []
|
|
359
|
-
rubygems_version:
|
|
360
|
-
signing_key:
|
|
387
|
+
rubygems_version: 4.0.6
|
|
361
388
|
specification_version: 4
|
|
362
389
|
summary: Lago Rest API client
|
|
363
390
|
test_files: []
|