smartystreets_ruby_sdk 5.14.11 → 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 +56 -0
- 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 +8 -7
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
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Ruby Gem Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '*'
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
env:
|
|
11
|
+
GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v3
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
|
|
18
|
+
- uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: '2.6'
|
|
21
|
+
bundler-cache: false
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-node@v2
|
|
24
|
+
|
|
25
|
+
- name: Clean
|
|
26
|
+
run: |
|
|
27
|
+
rm -f *.gem
|
|
28
|
+
git checkout lib/smartystreets_ruby_sdk/version.rb
|
|
29
|
+
|
|
30
|
+
- name: Dependencies
|
|
31
|
+
run: |
|
|
32
|
+
gem install minitest
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
run: |
|
|
36
|
+
rake test
|
|
37
|
+
|
|
38
|
+
- name: Set Environment Variable
|
|
39
|
+
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
|
40
|
+
|
|
41
|
+
- name: Grab Version
|
|
42
|
+
run: |
|
|
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 \
|
|
45
|
+
&& gem build *.gemspec \
|
|
46
|
+
&& git checkout lib/smartystreets_ruby_sdk/version.rb
|
|
47
|
+
|
|
48
|
+
- name: Push to rubygems.org
|
|
49
|
+
run: |
|
|
50
|
+
mkdir -p $HOME/.gem
|
|
51
|
+
touch $HOME/.gem/credentials
|
|
52
|
+
chmod 0600 $HOME/.gem/credentials
|
|
53
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
54
|
+
gem push *.gem
|
|
55
|
+
env:
|
|
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
|
-
autorequire:
|
|
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
|
|
@@ -72,13 +72,14 @@ dependencies:
|
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
74
|
version: 0.12.0
|
|
75
|
-
description:
|
|
75
|
+
description:
|
|
76
76
|
email:
|
|
77
77
|
- support@smartystreets.com
|
|
78
78
|
executables: []
|
|
79
79
|
extensions: []
|
|
80
80
|
extra_rdoc_files: []
|
|
81
81
|
files:
|
|
82
|
+
- ".github/workflows/gem-publish.yml"
|
|
82
83
|
- ".gitignore"
|
|
83
84
|
- CHANGELOG.md
|
|
84
85
|
- Dockerfile
|
|
@@ -178,7 +179,7 @@ homepage: https://github.com/smartystreets/smartystreets-ruby-sdk
|
|
|
178
179
|
licenses:
|
|
179
180
|
- Apache-2.0
|
|
180
181
|
metadata: {}
|
|
181
|
-
post_install_message:
|
|
182
|
+
post_install_message:
|
|
182
183
|
rdoc_options: []
|
|
183
184
|
require_paths:
|
|
184
185
|
- lib
|
|
@@ -193,8 +194,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
193
194
|
- !ruby/object:Gem::Version
|
|
194
195
|
version: '0'
|
|
195
196
|
requirements: []
|
|
196
|
-
rubygems_version: 3.3.
|
|
197
|
-
signing_key:
|
|
197
|
+
rubygems_version: 3.0.3.1
|
|
198
|
+
signing_key:
|
|
198
199
|
specification_version: 4
|
|
199
200
|
summary: An official library for the SmartyStreets APIs
|
|
200
201
|
test_files: []
|