smartystreets_ruby_sdk 5.14.13 → 5.14.14
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/.github/workflows/gem-publish.yml +3 -6
- data/examples/us_street_single_address_example.rb +9 -5
- data/lib/smartystreets_ruby_sdk/client_builder.rb +4 -4
- data/lib/smartystreets_ruby_sdk/custom_header_sender.rb +3 -3
- data/lib/smartystreets_ruby_sdk/errors.rb +1 -2
- data/lib/smartystreets_ruby_sdk/native_sender.rb +13 -5
- data/lib/smartystreets_ruby_sdk/request.rb +2 -2
- data/lib/smartystreets_ruby_sdk/response.rb +3 -2
- data/lib/smartystreets_ruby_sdk/retry_sender.rb +18 -7
- data/lib/smartystreets_ruby_sdk/status_code_sender.rb +18 -0
- data/lib/smartystreets_ruby_sdk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1edcb3f9748038e66ecee27cea05ddabaf8ba620a31d1868d8ea4d646f490011
|
|
4
|
+
data.tar.gz: a8581fb18d074bd4015b54d97f4a85739e76551eb0ea1b2a639b57bf3fad4095
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3c3e96df14a5ed1c0834fe4e664637bac9edced38b9e65c01d920e0653469b968092dab7648a6fc4d3d745980239cea37047193d95da80f1efa898e9eff76057
|
|
7
|
+
data.tar.gz: 74b31b8f16737035405eef5c3d8ca114b6d27c90ff255550cac8ecc73b87e2247e727f1f03a591a1c08f1cce74f7a3ba96def607c2e17f2ba3c3b425e1949b9f
|
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
steps:
|
|
14
14
|
- uses: actions/checkout@v3
|
|
15
15
|
with:
|
|
16
|
-
fetch-depth: 0
|
|
16
|
+
fetch-depth: 0
|
|
17
17
|
|
|
18
18
|
- uses: ruby/setup-ruby@v1
|
|
19
19
|
with:
|
|
@@ -40,10 +40,8 @@ jobs:
|
|
|
40
40
|
|
|
41
41
|
- name: Grab Version
|
|
42
42
|
run: |
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
end" >> version.rb \
|
|
46
|
-
&& cat version.rb \
|
|
43
|
+
sed -i "s/0\.0\.0/${{ env.RELEASE_VERSION }}/g" lib/smartystreets_ruby_sdk/version.rb \
|
|
44
|
+
&& cat lib/smartystreets_ruby_sdk/version.rb \
|
|
47
45
|
&& gem build *.gemspec \
|
|
48
46
|
&& git checkout lib/smartystreets_ruby_sdk/version.rb
|
|
49
47
|
|
|
@@ -54,6 +52,5 @@ jobs:
|
|
|
54
52
|
chmod 0600 $HOME/.gem/credentials
|
|
55
53
|
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
56
54
|
gem push *.gem
|
|
57
|
-
# chmod 0600 /root/.gem/credentials
|
|
58
55
|
env:
|
|
59
56
|
GEM_HOST_API_KEY: "${{secrets.GEM_HOST_API_KEY}}"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'smartystreets_ruby_sdk/static_credentials'
|
|
2
2
|
require 'smartystreets_ruby_sdk/client_builder'
|
|
3
3
|
require 'smartystreets_ruby_sdk/us_street/lookup'
|
|
4
|
+
require 'smartystreets_ruby_sdk/us_street/match_type'
|
|
4
5
|
|
|
5
6
|
class USStreetSingleAddressExample
|
|
6
7
|
def run
|
|
@@ -16,9 +17,11 @@ class USStreetSingleAddressExample
|
|
|
16
17
|
# The appropriate license values to be used for your subscriptions
|
|
17
18
|
# can be found on the Subscriptions page of the account dashboard.
|
|
18
19
|
# https://www.smartystreets.com/docs/cloud/licensing
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
#
|
|
21
|
+
# To try with a proxy, add this method call after with_licences
|
|
22
|
+
# with_proxy('localhost', 8080, 'proxyUser', 'proxyPassword')
|
|
23
|
+
client = SmartyStreets::ClientBuilder.new(credentials).with_licenses(['us-core-cloud']).
|
|
24
|
+
build_us_street_api_client
|
|
22
25
|
|
|
23
26
|
# Documentation for input fields can be found at:
|
|
24
27
|
# https://smartystreets.com/docs/cloud/us-street-api
|
|
@@ -34,7 +37,8 @@ class USStreetSingleAddressExample
|
|
|
34
37
|
lookup.state = 'CA'
|
|
35
38
|
lookup.zipcode = '21229'
|
|
36
39
|
lookup.candidates = 3
|
|
37
|
-
lookup.match =
|
|
40
|
+
lookup.match = SmartyStreets::USStreet::MatchType::INVALID
|
|
41
|
+
# "invalid" is the most permissive match,
|
|
38
42
|
# this will always return at least one result even if the address is invalid.
|
|
39
43
|
# Refer to the documentation for additional Match Strategy options.
|
|
40
44
|
|
|
@@ -64,4 +68,4 @@ class USStreetSingleAddressExample
|
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
example = USStreetSingleAddressExample.new
|
|
67
|
-
example.run
|
|
71
|
+
example.run
|
|
@@ -39,7 +39,7 @@ module SmartyStreets
|
|
|
39
39
|
@max_timeout = 10
|
|
40
40
|
@url_prefix = nil
|
|
41
41
|
@proxy = nil
|
|
42
|
-
@
|
|
42
|
+
@header = nil
|
|
43
43
|
@licenses = %w()
|
|
44
44
|
@debug = nil
|
|
45
45
|
end
|
|
@@ -98,8 +98,8 @@ module SmartyStreets
|
|
|
98
98
|
# headers is a Hash object.
|
|
99
99
|
#
|
|
100
100
|
# Returns self to accommodate method chaining.
|
|
101
|
-
def with_custom_headers(
|
|
102
|
-
@
|
|
101
|
+
def with_custom_headers(header)
|
|
102
|
+
@header = header
|
|
103
103
|
self
|
|
104
104
|
end
|
|
105
105
|
|
|
@@ -170,7 +170,7 @@ module SmartyStreets
|
|
|
170
170
|
|
|
171
171
|
sender = StatusCodeSender.new(sender)
|
|
172
172
|
|
|
173
|
-
sender = CustomHeaderSender.new(sender, @
|
|
173
|
+
sender = CustomHeaderSender.new(sender, @header) unless @header.nil?
|
|
174
174
|
|
|
175
175
|
sender = SigningSender.new(@signer, sender) unless @signer.nil?
|
|
176
176
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module SmartyStreets
|
|
2
2
|
class CustomHeaderSender
|
|
3
|
-
def initialize(inner,
|
|
3
|
+
def initialize(inner, header)
|
|
4
4
|
@inner = inner
|
|
5
|
-
@
|
|
5
|
+
@header = header
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def send(request)
|
|
9
|
-
request.
|
|
9
|
+
request.header = @header
|
|
10
10
|
@inner.send(request)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -15,8 +15,7 @@ module SmartyStreets
|
|
|
15
15
|
|
|
16
16
|
UNPROCESSABLE_ENTITY = 'GET request lacked required fields.'.freeze
|
|
17
17
|
|
|
18
|
-
TOO_MANY_REQUESTS = '
|
|
19
|
-
we restrict the number of requests coming from a given source over too short of a time.'.freeze
|
|
18
|
+
TOO_MANY_REQUESTS = 'The rate limit has been exceeded.'.freeze
|
|
20
19
|
|
|
21
20
|
INTERNAL_SERVER_ERROR = 'Internal Server Error.'.freeze
|
|
22
21
|
|
|
@@ -24,7 +24,11 @@ module SmartyStreets
|
|
|
24
24
|
|
|
25
25
|
http.finish if http.started?
|
|
26
26
|
rescue StandardError => err
|
|
27
|
-
|
|
27
|
+
if response.nil?
|
|
28
|
+
return Response.new(nil, nil, nil, err)
|
|
29
|
+
else
|
|
30
|
+
return Response.new(nil, nil, response.header, err)
|
|
31
|
+
end
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
build_smarty_response(response)
|
|
@@ -43,12 +47,16 @@ module SmartyStreets
|
|
|
43
47
|
request.body = smarty_request.payload
|
|
44
48
|
request['User-Agent'] = "smartystreets (sdk:ruby@#{SmartyStreets::VERSION})"
|
|
45
49
|
request['Referer'] = smarty_request.referer unless smarty_request.referer.nil?
|
|
46
|
-
set_custom_headers(smarty_request.
|
|
50
|
+
set_custom_headers(smarty_request.header, request)
|
|
47
51
|
request
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
def build_smarty_response(native_response)
|
|
51
|
-
|
|
55
|
+
if native_response.header.nil?
|
|
56
|
+
Response.new(native_response.body, native_response.code)
|
|
57
|
+
else
|
|
58
|
+
Response.new(native_response.body, native_response.code, native_response.header)
|
|
59
|
+
end
|
|
52
60
|
end
|
|
53
61
|
|
|
54
62
|
def build_http(request)
|
|
@@ -70,8 +78,8 @@ module SmartyStreets
|
|
|
70
78
|
URI.encode_www_form(smarty_request.parameters)
|
|
71
79
|
end
|
|
72
80
|
|
|
73
|
-
def self.set_custom_headers(
|
|
74
|
-
|
|
81
|
+
def self.set_custom_headers(smarty_header, request)
|
|
82
|
+
smarty_header.each do |key, values|
|
|
75
83
|
if values.respond_to? :each
|
|
76
84
|
values.each do |value|
|
|
77
85
|
request.add_field(key, value)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module SmartyStreets
|
|
2
2
|
class Request
|
|
3
|
-
attr_accessor :parameters, :payload, :url_prefix, :referer, :
|
|
3
|
+
attr_accessor :parameters, :payload, :url_prefix, :referer, :header, :content_type
|
|
4
4
|
|
|
5
5
|
def initialize
|
|
6
6
|
@parameters = {}
|
|
7
7
|
@payload = nil
|
|
8
8
|
@url_prefix = nil
|
|
9
9
|
@referer = nil
|
|
10
|
-
@
|
|
10
|
+
@header = {}
|
|
11
11
|
@content_type = 'application/json'
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module SmartyStreets
|
|
2
2
|
class Response
|
|
3
|
-
attr_accessor :payload, :status_code, :error
|
|
3
|
+
attr_accessor :payload, :status_code, :header, :error
|
|
4
4
|
|
|
5
|
-
def initialize(payload, status_code, error = nil)
|
|
5
|
+
def initialize(payload, status_code, header = nil, error = nil)
|
|
6
6
|
@payload = payload
|
|
7
7
|
@status_code = status_code
|
|
8
|
+
@header = header
|
|
8
9
|
@error = error
|
|
9
10
|
end
|
|
10
11
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module SmartyStreets
|
|
2
2
|
class RetrySender
|
|
3
3
|
MAX_BACKOFF_DURATION = 10
|
|
4
|
-
STATUS_INTERNAL_SERVER_ERROR = 500
|
|
5
4
|
STATUS_TOO_MANY_REQUESTS = 429
|
|
5
|
+
STATUS_TO_RETRY = [408, 429, 500, 502, 503, 504]
|
|
6
6
|
|
|
7
7
|
def initialize(max_retries, inner, sleeper, logger)
|
|
8
8
|
@max_retries = max_retries
|
|
@@ -15,14 +15,20 @@ module SmartyStreets
|
|
|
15
15
|
response = @inner.send(request)
|
|
16
16
|
|
|
17
17
|
(0..@max_retries-1).each do |i|
|
|
18
|
-
if response.status_code.to_i == STATUS_TOO_MANY_REQUESTS
|
|
19
|
-
backoff(5)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
break if response.status_code.to_i < STATUS_INTERNAL_SERVER_ERROR
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
break if STATUS_TO_RETRY.include?(response.status_code.to_i) == false
|
|
25
20
|
|
|
21
|
+
if response.status_code.to_i == STATUS_TOO_MANY_REQUESTS
|
|
22
|
+
seconds_to_backoff = 10
|
|
23
|
+
if response.header.nil? == false
|
|
24
|
+
if Integer(response.header["Retry-After"], exception: false)
|
|
25
|
+
seconds_to_backoff = response.header["Retry-After"].to_i
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
rate_limit_backoff(seconds_to_backoff)
|
|
29
|
+
else
|
|
30
|
+
backoff(i)
|
|
31
|
+
end
|
|
26
32
|
response = @inner.send(request)
|
|
27
33
|
end
|
|
28
34
|
|
|
@@ -35,5 +41,10 @@ module SmartyStreets
|
|
|
35
41
|
@logger.log("There was an error processing the request. Retrying in #{backoff_duration} seconds...")
|
|
36
42
|
@sleeper.sleep(backoff_duration)
|
|
37
43
|
end
|
|
44
|
+
|
|
45
|
+
def rate_limit_backoff(backoff_duration)
|
|
46
|
+
@logger.log("Rate limit reached. Retrying in #{backoff_duration} seconds...")
|
|
47
|
+
@sleeper.sleep(backoff_duration)
|
|
48
|
+
end
|
|
38
49
|
end
|
|
39
50
|
end
|
|
@@ -10,11 +10,29 @@ module SmartyStreets
|
|
|
10
10
|
def send(request)
|
|
11
11
|
response = @inner.send(request)
|
|
12
12
|
|
|
13
|
+
if response.status_code == '429'
|
|
14
|
+
response.error = parse_rate_limit_response(response)
|
|
15
|
+
end
|
|
13
16
|
assign_exception(response) if response.error == nil
|
|
14
17
|
|
|
15
18
|
response
|
|
16
19
|
end
|
|
17
20
|
|
|
21
|
+
def parse_rate_limit_response(response)
|
|
22
|
+
error_message = ""
|
|
23
|
+
if !response.payload.nil?
|
|
24
|
+
response_json = JSON.parse(response.payload)
|
|
25
|
+
response_json["errors"].each do |error|
|
|
26
|
+
error_message += (" " + error["message"])
|
|
27
|
+
end
|
|
28
|
+
error_message.strip!
|
|
29
|
+
end
|
|
30
|
+
if error_message == ""
|
|
31
|
+
error_message = TOO_MANY_REQUESTS
|
|
32
|
+
end
|
|
33
|
+
TooManyRequestsError.new(error_message)
|
|
34
|
+
end
|
|
35
|
+
|
|
18
36
|
def assign_exception(response)
|
|
19
37
|
response.error = case response.status_code
|
|
20
38
|
when '401'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smartystreets_ruby_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.14.
|
|
4
|
+
version: 5.14.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SmartyStreets SDK Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-09-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|