smartystreets_ruby_sdk 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/gem-publish.yml +58 -0
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Dockerfile +10 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +202 -0
  8. data/Makefile +33 -0
  9. data/README.md +31 -0
  10. data/Rakefile +5 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/docker-compose.yml +12 -0
  14. data/examples/international_autocomplete_example.rb +47 -0
  15. data/examples/international_example.rb +53 -0
  16. data/examples/us_autocomplete_pro_example.rb +56 -0
  17. data/examples/us_extract_example.rb +63 -0
  18. data/examples/us_reverse_geo_example.rb +47 -0
  19. data/examples/us_street_multiple_address_example.rb +87 -0
  20. data/examples/us_street_single_address_example.rb +67 -0
  21. data/examples/us_zipcode_multiple_lookup_example.rb +80 -0
  22. data/examples/us_zipcode_single_lookup_example.rb +55 -0
  23. data/lib/smartystreets_ruby_sdk/batch.rb +59 -0
  24. data/lib/smartystreets_ruby_sdk/client_builder.rb +188 -0
  25. data/lib/smartystreets_ruby_sdk/custom_header_sender.rb +13 -0
  26. data/lib/smartystreets_ruby_sdk/errors.rb +27 -0
  27. data/lib/smartystreets_ruby_sdk/exceptions.rb +39 -0
  28. data/lib/smartystreets_ruby_sdk/international_autocomplete/client.rb +61 -0
  29. data/lib/smartystreets_ruby_sdk/international_autocomplete/lookup.rb +21 -0
  30. data/lib/smartystreets_ruby_sdk/international_autocomplete/suggestion.rb +16 -0
  31. data/lib/smartystreets_ruby_sdk/international_street/analysis.rb +17 -0
  32. data/lib/smartystreets_ruby_sdk/international_street/candidate.rb +23 -0
  33. data/lib/smartystreets_ruby_sdk/international_street/changes.rb +15 -0
  34. data/lib/smartystreets_ruby_sdk/international_street/client.rb +63 -0
  35. data/lib/smartystreets_ruby_sdk/international_street/components.rb +58 -0
  36. data/lib/smartystreets_ruby_sdk/international_street/language_mode.rb +9 -0
  37. data/lib/smartystreets_ruby_sdk/international_street/lookup.rb +82 -0
  38. data/lib/smartystreets_ruby_sdk/international_street/metadata.rb +17 -0
  39. data/lib/smartystreets_ruby_sdk/international_street/rootlevel.rb +25 -0
  40. data/lib/smartystreets_ruby_sdk/international_street.rb +12 -0
  41. data/lib/smartystreets_ruby_sdk/json_able.rb +19 -0
  42. data/lib/smartystreets_ruby_sdk/license_sender.rb +15 -0
  43. data/lib/smartystreets_ruby_sdk/logger.rb +7 -0
  44. data/lib/smartystreets_ruby_sdk/native_sender.rb +85 -0
  45. data/lib/smartystreets_ruby_sdk/native_serializer.rb +13 -0
  46. data/lib/smartystreets_ruby_sdk/proxy.rb +16 -0
  47. data/lib/smartystreets_ruby_sdk/request.rb +14 -0
  48. data/lib/smartystreets_ruby_sdk/response.rb +11 -0
  49. data/lib/smartystreets_ruby_sdk/retry_sender.rb +39 -0
  50. data/lib/smartystreets_ruby_sdk/shared_credentials.rb +13 -0
  51. data/lib/smartystreets_ruby_sdk/signing_sender.rb +13 -0
  52. data/lib/smartystreets_ruby_sdk/sleeper.rb +7 -0
  53. data/lib/smartystreets_ruby_sdk/static_credentials.rb +13 -0
  54. data/lib/smartystreets_ruby_sdk/status_code_sender.rb +41 -0
  55. data/lib/smartystreets_ruby_sdk/url_prefix_sender.rb +14 -0
  56. data/lib/smartystreets_ruby_sdk/us_autocomplete/client.rb +72 -0
  57. data/lib/smartystreets_ruby_sdk/us_autocomplete/geolocation_type.rb +9 -0
  58. data/lib/smartystreets_ruby_sdk/us_autocomplete/lookup.rb +38 -0
  59. data/lib/smartystreets_ruby_sdk/us_autocomplete/suggestion.rb +16 -0
  60. data/lib/smartystreets_ruby_sdk/us_autocomplete.rb +9 -0
  61. data/lib/smartystreets_ruby_sdk/us_autocomplete_pro/client.rb +78 -0
  62. data/lib/smartystreets_ruby_sdk/us_autocomplete_pro/geolocation_type.rb +8 -0
  63. data/lib/smartystreets_ruby_sdk/us_autocomplete_pro/lookup.rb +63 -0
  64. data/lib/smartystreets_ruby_sdk/us_autocomplete_pro/suggestion.rb +18 -0
  65. data/lib/smartystreets_ruby_sdk/us_autocomplete_pro.rb +10 -0
  66. data/lib/smartystreets_ruby_sdk/us_extract/address.rb +24 -0
  67. data/lib/smartystreets_ruby_sdk/us_extract/client.rb +49 -0
  68. data/lib/smartystreets_ruby_sdk/us_extract/lookup.rb +22 -0
  69. data/lib/smartystreets_ruby_sdk/us_extract/metadata.rb +17 -0
  70. data/lib/smartystreets_ruby_sdk/us_extract/result.rb +21 -0
  71. data/lib/smartystreets_ruby_sdk/us_extract.rb +10 -0
  72. data/lib/smartystreets_ruby_sdk/us_reverse_geo/address.rb +16 -0
  73. data/lib/smartystreets_ruby_sdk/us_reverse_geo/client.rb +38 -0
  74. data/lib/smartystreets_ruby_sdk/us_reverse_geo/coordinate.rb +25 -0
  75. data/lib/smartystreets_ruby_sdk/us_reverse_geo/lookup.rb +21 -0
  76. data/lib/smartystreets_ruby_sdk/us_reverse_geo/result.rb +20 -0
  77. data/lib/smartystreets_ruby_sdk/us_reverse_geo/us_reverse_geo_response.rb +17 -0
  78. data/lib/smartystreets_ruby_sdk/us_reverse_geo.rb +12 -0
  79. data/lib/smartystreets_ruby_sdk/us_street/analysis.rb +24 -0
  80. data/lib/smartystreets_ruby_sdk/us_street/candidate.rb +27 -0
  81. data/lib/smartystreets_ruby_sdk/us_street/client.rb +78 -0
  82. data/lib/smartystreets_ruby_sdk/us_street/components.rb +35 -0
  83. data/lib/smartystreets_ruby_sdk/us_street/lookup.rb +32 -0
  84. data/lib/smartystreets_ruby_sdk/us_street/match_type.rb +10 -0
  85. data/lib/smartystreets_ruby_sdk/us_street/metadata.rb +30 -0
  86. data/lib/smartystreets_ruby_sdk/us_street.rb +12 -0
  87. data/lib/smartystreets_ruby_sdk/us_zipcode/alternate_county.rb +15 -0
  88. data/lib/smartystreets_ruby_sdk/us_zipcode/city.rb +16 -0
  89. data/lib/smartystreets_ruby_sdk/us_zipcode/client.rb +72 -0
  90. data/lib/smartystreets_ruby_sdk/us_zipcode/lookup.rb +21 -0
  91. data/lib/smartystreets_ruby_sdk/us_zipcode/result.rb +47 -0
  92. data/lib/smartystreets_ruby_sdk/us_zipcode/zip_code.rb +33 -0
  93. data/lib/smartystreets_ruby_sdk/us_zipcode.rb +11 -0
  94. data/lib/smartystreets_ruby_sdk/version.rb +3 -0
  95. data/lib/smartystreets_ruby_sdk.rb +33 -0
  96. data/ruby-sdk-demo.json +354 -0
  97. data/smartystreets_ruby_sdk.gemspec +26 -0
  98. metadata +201 -0
@@ -0,0 +1,47 @@
1
+ require 'smartystreets_ruby_sdk/static_credentials'
2
+ require '../lib/smartystreets_ruby_sdk/client_builder'
3
+ require '../lib/smartystreets_ruby_sdk/us_reverse_geo/lookup'
4
+
5
+ class USReverseGeoExample
6
+ Lookup = SmartyStreets::USReverseGeo::Lookup
7
+
8
+ def run
9
+ # auth_id = 'Your SmartyStreets Auth ID here'
10
+ # auth_token = 'Your SmartyStreets Auth Token here'
11
+
12
+ # We recommend storing your secret keys in environment variables instead---it's safer!
13
+ auth_id = ENV['SMARTY_AUTH_ID']
14
+ auth_token = ENV['SMARTY_AUTH_TOKEN']
15
+
16
+ credentials = SmartyStreets::StaticCredentials.new(auth_id, auth_token)
17
+
18
+ # The appropriate license values to be used for your subscriptions
19
+ # can be found on the Subscriptions page of the account dashboard.
20
+ # https://www.smartystreets.com/docs/cloud/licensing
21
+ client = SmartyStreets::ClientBuilder.new(credentials).with_licenses(['us-reverse-geocoding-cloud'])
22
+ .build_us_reverse_geo_api_client
23
+
24
+ # Documentation for input fields can be found at:
25
+ # https://smartystreets.com/docs/cloud/us-reverse-geo-api#http-request-input-fields
26
+
27
+ lookup = Lookup.new(40.111111, -111.111111)
28
+
29
+ response = client.send(lookup)
30
+ result = response.results[0]
31
+
32
+ coordinate = result.coordinate
33
+ puts "Latitude: #{coordinate.latitude}"
34
+ puts "Longitude: #{coordinate.longitude}\n"
35
+
36
+ puts "Distance: #{result.distance}\n"
37
+
38
+ address = result.address
39
+ puts "Street: #{address.street}"
40
+ puts "City: #{address.city}"
41
+ puts "State Abbreviation: #{address.state_abbreviation}"
42
+ puts "ZIP Code: #{address.zipcode}"
43
+ puts "License: #{coordinate.get_license}"
44
+ end
45
+ end
46
+
47
+ USReverseGeoExample.new.run
@@ -0,0 +1,87 @@
1
+ require 'smartystreets_ruby_sdk/static_credentials'
2
+ require 'smartystreets_ruby_sdk/client_builder'
3
+ require 'smartystreets_ruby_sdk/batch'
4
+ require 'smartystreets_ruby_sdk/us_street/lookup'
5
+
6
+ class USStreetMultipleAddressExample
7
+ Lookup = SmartyStreets::USStreet::Lookup
8
+
9
+ def run
10
+ # auth_id = 'Your SmartyStreets Auth ID here'
11
+ # auth_token = 'Your SmartyStreets Auth Token here'
12
+
13
+ # We recommend storing your secret keys in environment variables instead---it's safer!
14
+ auth_id = ENV['SMARTY_AUTH_ID']
15
+ auth_token = ENV['SMARTY_AUTH_TOKEN']
16
+
17
+ credentials = SmartyStreets::StaticCredentials.new(auth_id, auth_token)
18
+
19
+ # The appropriate license values to be used for your subscriptions
20
+ # can be found on the Subscriptions page of the account dashboard.
21
+ # https://www.smartystreets.com/docs/cloud/licensing
22
+ client = SmartyStreets::ClientBuilder.new(credentials).with_licenses(['us-core-cloud'])
23
+ .build_us_street_api_client
24
+ batch = SmartyStreets::Batch.new
25
+
26
+ # Documentation for input fields can be found at:
27
+ # https://smartystreets.com/docs/cloud/us-street-api
28
+
29
+ batch.add(Lookup.new)
30
+ batch[0].input_id = '8675309' # Optional ID from your system
31
+ batch[0].addressee = 'John Doe'
32
+ batch[0].street = '1600 amphitheatre parkway'
33
+ batch[0].street2 = 'second star to the right'
34
+ batch[0].secondary = 'APT 2'
35
+ batch[0].urbanization = '' # Only applies to Puerto Rico addresses
36
+ batch[0].lastline = 'Mountain view, California'
37
+ batch[0].zipcode = '21229'
38
+ batch[0].candidates = 3
39
+ batch[0].match = Lookup.INVALID # "invalid" is the most permissive match,
40
+ # this will always return at least one result even if the address is invalid.
41
+ # Refer to the documentation for additional Match Strategy options.
42
+
43
+ batch.add(Lookup.new('1 Rosedale, Baltimore, Maryland')) # Freeform addresses work too.
44
+ batch[1].candidates = 10 # Allows up to ten possible matches to be returned (default is 1).
45
+
46
+ batch.add(Lookup.new('123 Bogus Street, Pretend Lake, Oklahoma'))
47
+
48
+ batch.add(Lookup.new)
49
+ batch[3].street = '1 Infinite Loop'
50
+ batch[3].zipcode = '95014' # You can just input the street and ZIP if you want.
51
+
52
+ begin
53
+ client.send_batch(batch)
54
+ rescue SmartyStreets::SmartyError => err
55
+ puts err
56
+ return
57
+ end
58
+
59
+ batch.each_with_index do |lookup, i|
60
+ candidates = lookup.result
61
+
62
+ if candidates.empty?
63
+ puts "Address #{i} is invalid.\n\n"
64
+ next
65
+ end
66
+
67
+ puts "Address #{i} has at least one candidate.\n If the match parameter is set to STRICT, the address is valid.\n Otherwise, check the Analysis output fields to see if the address is valid."
68
+
69
+ candidates.each do |candidate|
70
+ components = candidate.components
71
+ metadata = candidate.metadata
72
+
73
+ puts "\nCandidate #{candidate.candidate_index} : "
74
+ puts "Input ID: #{candidate.input_id}"
75
+ puts "Delivery line 1: #{candidate.delivery_line_1}"
76
+ puts "Last line: #{candidate.last_line}"
77
+ puts "ZIP Code: #{components.zipcode}-#{components.plus4_code}"
78
+ puts "County: #{metadata.county_name}"
79
+ puts "Latitude: #{metadata.latitude}"
80
+ puts "Longitude: #{metadata.longitude}"
81
+ puts
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ USStreetMultipleAddressExample.new.run
@@ -0,0 +1,67 @@
1
+ require 'smartystreets_ruby_sdk/static_credentials'
2
+ require 'smartystreets_ruby_sdk/client_builder'
3
+ require 'smartystreets_ruby_sdk/us_street/lookup'
4
+
5
+ class USStreetSingleAddressExample
6
+ def run
7
+ # auth_id = 'Your SmartyStreets Auth ID here'
8
+ # auth_token = 'Your SmartyStreets Auth Token here'
9
+
10
+ # We recommend storing your secret keys in environment variables instead---it's safer!
11
+ auth_id = ENV['SMARTY_AUTH_ID']
12
+ auth_token = ENV['SMARTY_AUTH_TOKEN']
13
+
14
+ credentials = SmartyStreets::StaticCredentials.new(auth_id, auth_token)
15
+
16
+ # The appropriate license values to be used for your subscriptions
17
+ # can be found on the Subscriptions page of the account dashboard.
18
+ # https://www.smartystreets.com/docs/cloud/licensing
19
+ client = SmartyStreets::ClientBuilder.new(credentials).with_licenses(['us-core-cloud'])
20
+ # with_proxy('localhost', 8080, 'proxyUser', 'proxyPassword'). # Uncomment this line to try it with a proxy
21
+ build_us_street_api_client
22
+
23
+ # Documentation for input fields can be found at:
24
+ # https://smartystreets.com/docs/cloud/us-street-api
25
+
26
+ lookup = SmartyStreets::USStreet::Lookup.new
27
+ lookup.input_id = '24601' # Optional ID from your system
28
+ lookup.addressee = 'John Doe'
29
+ lookup.street = '1600 Amphitheatre Pkwy'
30
+ lookup.street2 = 'closet under the stairs'
31
+ lookup.secondary = 'APT 2'
32
+ lookup.urbanization = '' # Only applies to Puerto Rico addresses
33
+ lookup.city = 'Mountain View'
34
+ lookup.state = 'CA'
35
+ lookup.zipcode = '21229'
36
+ lookup.candidates = 3
37
+ lookup.match = Lookup.INVALID # "invalid" is the most permissive match,
38
+ # this will always return at least one result even if the address is invalid.
39
+ # Refer to the documentation for additional Match Strategy options.
40
+
41
+ begin
42
+ client.send_lookup(lookup)
43
+ rescue SmartyStreets::SmartyError => err
44
+ puts err
45
+ return
46
+ end
47
+
48
+ result = lookup.result
49
+
50
+ if result.empty?
51
+ puts 'No candidates. This means the address is not valid.'
52
+ return
53
+ end
54
+
55
+ first_candidate = result[0]
56
+
57
+ puts "There is at least one candidate.\n If the match parameter is set to STRICT, the address is valid.\n Otherwise, check the Analysis output fields to see if the address is valid.\n"
58
+ puts "Input ID: #{first_candidate.input_id}"
59
+ puts "ZIP Code: #{first_candidate.components.zipcode}"
60
+ puts "County: #{first_candidate.metadata.county_name}"
61
+ puts "Latitude: #{first_candidate.metadata.latitude}"
62
+ puts "Longitude: #{first_candidate.metadata.longitude}"
63
+ end
64
+ end
65
+
66
+ example = USStreetSingleAddressExample.new
67
+ example.run
@@ -0,0 +1,80 @@
1
+ require 'smartystreets_ruby_sdk/static_credentials'
2
+ require 'smartystreets_ruby_sdk/client_builder'
3
+ require 'smartystreets_ruby_sdk/batch'
4
+ require 'smartystreets_ruby_sdk/us_zipcode/lookup'
5
+
6
+ class USZipcodeMultipleLookupExample
7
+ Lookup = SmartyStreets::USZipcode::Lookup
8
+
9
+ def run
10
+ # auth_id = 'Your SmartyStreets Auth ID here'
11
+ # auth_token = 'Your SmartyStreets Auth Token here'
12
+
13
+ # We recommend storing your secret keys in environment variables instead---it's safer!
14
+ auth_id = ENV['SMARTY_AUTH_ID']
15
+ auth_token = ENV['SMARTY_AUTH_TOKEN']
16
+
17
+ credentials = SmartyStreets::StaticCredentials.new(auth_id, auth_token)
18
+
19
+ client = SmartyStreets::ClientBuilder.new(credentials).build_us_zipcode_api_client
20
+ batch = SmartyStreets::Batch.new
21
+
22
+ # Documentation for input fields can be found at:
23
+ # https://smartystreets.com/docs/cloud/us-zipcode-api
24
+
25
+ batch.add(Lookup.new)
26
+ batch[0].input_id = '01189998819991197253' # Optional ID from your system
27
+ batch[0].zipcode = '12345' # A Lookup may have a ZIP Code, city and state, or city, state, and ZIP Code
28
+
29
+ batch.add(Lookup.new)
30
+ batch[1].city = 'Phoenix'
31
+ batch[1].state = 'Arizona'
32
+
33
+ batch.add(Lookup.new('cupertino', 'CA', '95014')) # You can also set these with arguments
34
+
35
+
36
+ begin
37
+ client.send_batch(batch)
38
+ rescue SmartyError => err
39
+ puts err
40
+ return
41
+ end
42
+
43
+ batch.each_with_index { |lookup, i|
44
+ result = lookup.result
45
+ puts "Lookup #{i}:\n"
46
+
47
+ if result.status
48
+ puts "Status: #{result.status}"
49
+ puts "Reason: #{result.reason}"
50
+ next
51
+ end
52
+
53
+ cities = result.cities
54
+ puts "#{cities.length} City and State match(es):"
55
+
56
+ cities.each { |city|
57
+ puts "City: #{city.city}"
58
+ puts "State: #{city.state}"
59
+ puts "Mailable City: #{city.mailable_city}"
60
+ puts
61
+ }
62
+
63
+ zipcodes = result.zipcodes
64
+ puts "#{zipcodes.length} ZIP Code match(es):"
65
+
66
+ zipcodes.each { |zipcode|
67
+ puts "ZIP Code: #{zipcode.zipcode}"
68
+ puts "County: #{zipcode.county_name}"
69
+ puts "Latitude: #{zipcode.latitude}"
70
+ puts "Longitude: #{zipcode.longitude}"
71
+ puts
72
+ }
73
+
74
+ puts '***********************************'
75
+ }
76
+ end
77
+ end
78
+
79
+ example = USZipcodeMultipleLookupExample.new
80
+ example.run
@@ -0,0 +1,55 @@
1
+ require 'smartystreets_ruby_sdk/static_credentials'
2
+ require 'smartystreets_ruby_sdk/client_builder'
3
+ require 'smartystreets_ruby_sdk/us_zipcode/lookup'
4
+
5
+ class UsZipcodeSingleLookupExample
6
+ def run
7
+ # auth_id = 'Your SmartyStreets Auth ID here'
8
+ # auth_token = 'Your SmartyStreets Auth Token here'
9
+
10
+ # We recommend storing your secret keys in environment variables instead---it's safer!
11
+ auth_id = ENV['SMARTY_AUTH_ID']
12
+ auth_token = ENV['SMARTY_AUTH_TOKEN']
13
+
14
+ credentials = SmartyStreets::StaticCredentials.new(auth_id, auth_token)
15
+
16
+ client = SmartyStreets::ClientBuilder.new(credentials).build_us_zipcode_api_client
17
+
18
+ # Documentation for input fields can be found at:
19
+ # https://smartystreets.com/docs/cloud/us-zipcode-api
20
+
21
+ lookup = SmartyStreets::USZipcode::Lookup.new
22
+ lookup.input_id = 'dfc33cb6-829e-4fea-aa1b-b6d6580f0817' # Optional ID from your system
23
+ lookup.city = 'Mountain View'
24
+ lookup.state = 'California'
25
+ lookup.zipcode = '94043'
26
+
27
+ begin
28
+ client.send_lookup(lookup)
29
+ rescue SmartyStreets::SmartyError => err
30
+ puts err
31
+ return
32
+ end
33
+
34
+ result = lookup.result
35
+ zipcodes = result.zipcodes
36
+ cities = result.cities
37
+
38
+ puts "Input ID: #{result.input_id}"
39
+
40
+ cities.each do |city|
41
+ puts "\nCity: #{city.city}"
42
+ puts "State: #{city.state}"
43
+ puts "Mailable City: #{city.mailable_city}"
44
+ end
45
+
46
+ zipcodes.each do |zipcode|
47
+ puts "\nZIP Code: #{zipcode.zipcode}"
48
+ puts "Latitude: #{zipcode.latitude}"
49
+ puts "Longitude: #{zipcode.longitude}"
50
+ end
51
+ end
52
+ end
53
+
54
+ example = UsZipcodeSingleLookupExample.new
55
+ example.run
@@ -0,0 +1,59 @@
1
+ module SmartyStreets
2
+ # The Batch class is used to send up to 100 lookups at once
3
+ class Batch
4
+ include Enumerable
5
+ MAX_BATCH_SIZE = 100
6
+
7
+ attr_reader :all_lookups, :named_lookups
8
+
9
+ def initialize
10
+ @named_lookups = {}
11
+ @all_lookups = []
12
+ end
13
+
14
+ def add(lookup)
15
+ return false if full?
16
+
17
+ @all_lookups.push(lookup)
18
+
19
+ return true if lookup.input_id.nil?
20
+
21
+ @named_lookups[lookup.input_id] = lookup
22
+ true
23
+ end
24
+
25
+ def clear
26
+ @named_lookups.clear
27
+ @all_lookups.clear
28
+ end
29
+
30
+ def full?
31
+ size >= MAX_BATCH_SIZE
32
+ end
33
+
34
+ def empty?
35
+ size.zero?
36
+ end
37
+
38
+ def size
39
+ @all_lookups.length
40
+ end
41
+
42
+ def get_by_input_id(input_id)
43
+ @named_lookups[input_id]
44
+ end
45
+
46
+ def get_by_index(index)
47
+ @all_lookups[index]
48
+ end
49
+
50
+ def each(&block)
51
+ @all_lookups.each(&block)
52
+ end
53
+
54
+ def [](index)
55
+ @all_lookups[index]
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,188 @@
1
+ require_relative 'native_serializer'
2
+ require_relative 'native_sender'
3
+ require_relative 'status_code_sender'
4
+ require_relative 'signing_sender'
5
+ require_relative 'retry_sender'
6
+ require_relative 'url_prefix_sender'
7
+ require_relative 'license_sender'
8
+ require_relative 'sleeper'
9
+ require_relative 'logger'
10
+ require_relative 'proxy'
11
+ require_relative 'custom_header_sender'
12
+ require_relative 'us_street/client'
13
+ require_relative 'us_zipcode/client'
14
+ require_relative 'us_extract/client'
15
+ require_relative 'us_autocomplete/client'
16
+ require_relative 'international_street/client'
17
+ require_relative 'us_reverse_geo/client'
18
+ require_relative 'us_autocomplete_pro/client'
19
+
20
+ module SmartyStreets
21
+ # The ClientBuilder class helps you build a client object for one of the supported SmartyStreets APIs.
22
+ # You can use ClientBuilder's methods to customize settings like maximum retries or timeout duration.
23
+ # These methods are chainable, so you can usually get set up with one line of code.
24
+ class ClientBuilder
25
+ INTERNATIONAL_STREET_API_URL = 'https://international-street.api.smartystreets.com/verify'.freeze
26
+ INTERNATIONAL_AUTOCOMPLETE_API_URL = "https://international-autocomplete.api.smartystreets.com/lookup".freeze
27
+ US_AUTOCOMPLETE_API_URL = 'https://us-autocomplete.api.smartystreets.com/suggest'.freeze
28
+ US_AUTOCOMPLETE_PRO_API_URL = 'https://us-autocomplete-pro.api.smartystreets.com/lookup'.freeze
29
+ US_EXTRACT_API_URL = 'https://us-extract.api.smartystreets.com/'.freeze
30
+ US_STREET_API_URL = 'https://us-street.api.smartystreets.com/street-address'.freeze
31
+ US_ZIP_CODE_API_URL = 'https://us-zipcode.api.smartystreets.com/lookup'.freeze
32
+ US_REVERSE_GEO_API_URL = 'https://us-reverse-geo.api.smartystreets.com/lookup'.freeze
33
+
34
+ def initialize(signer)
35
+ @signer = signer
36
+ @serializer = NativeSerializer.new
37
+ @http_sender = nil
38
+ @max_retries = 5
39
+ @max_timeout = 10
40
+ @url_prefix = nil
41
+ @proxy = nil
42
+ @headers = nil
43
+ @licenses = %w()
44
+ @debug = nil
45
+ end
46
+
47
+ # Sets the maximum number of times to retry sending the request to the API. (Default is 5)
48
+ #
49
+ # Returns self to accommodate method chaining.
50
+ def retry_at_most(max_retries)
51
+ @max_retries = max_retries
52
+ self
53
+ end
54
+
55
+ # The maximum time (in seconds) to wait for the response to be read. (Default is 10)
56
+ #
57
+ # Returns self to accommodate method chaining.
58
+ def with_max_timeout(max_timeout)
59
+ @max_timeout = max_timeout
60
+ self
61
+ end
62
+
63
+ # Default is a series of nested senders. (See build_sender()
64
+ #
65
+ # Returns self to accommodate method chaining.
66
+ def with_sender(sender)
67
+ @http_sender = sender
68
+ self
69
+ end
70
+
71
+ # Changes the Serializer from the default.
72
+ #
73
+ # Returns self to accommodate method chaining.
74
+ def with_serializer(serializer)
75
+ @serializer = serializer
76
+ self
77
+ end
78
+
79
+ # This may be useful when using a local installation of the SmartyStreets APIs.
80
+ # base_url is a string that defaults to the URL for the API corresponding to the Client object being built.
81
+ #
82
+ # Returns self to accommodate method chaining.
83
+ def with_base_url(base_url)
84
+ @url_prefix = base_url
85
+ self
86
+ end
87
+
88
+ # Assigns a proxy through which all requests will be sent.
89
+ # proxy is a Proxy object from this module.
90
+ #
91
+ # Returns self to accommodate method chaining.
92
+ def with_proxy(host, port, username, password)
93
+ @proxy = SmartyStreets::Proxy.new(host, port, username, password)
94
+ self
95
+ end
96
+
97
+ # Allows you to submit custom headers using a Hash.
98
+ # headers is a Hash object.
99
+ #
100
+ # Returns self to accommodate method chaining.
101
+ def with_custom_headers(headers)
102
+ @headers = headers
103
+ self
104
+ end
105
+
106
+ # Allows the caller to specify the subscription license (aka "track") they wish to use.
107
+ #
108
+ # Returns self to accommodate method chaining.
109
+ def with_licenses(licenses)
110
+ @licenses.concat licenses
111
+ self
112
+ end
113
+
114
+ # Enables debug mode, which will print information about the HTTP request and response to $stdout.
115
+ #
116
+ # Returns self to accommodate method chaining.
117
+ def with_debug
118
+ @debug = true
119
+ self
120
+ end
121
+
122
+ # <editor-fold desc="Build methods">
123
+
124
+ def build_international_street_api_client
125
+ ensure_url_prefix_not_null(INTERNATIONAL_STREET_API_URL)
126
+ InternationalStreet::Client.new(build_sender, @serializer)
127
+ end
128
+
129
+ def build_international_autocomplete_api_client
130
+ ensure_url_prefix_not_null(INTERNATIONAL_AUTOCOMPLETE_API_URL)
131
+ InternationalAutocomplete::Client.new(build_sender, @serializer)
132
+ end
133
+
134
+ def build_us_autocomplete_api_client # Deprecated
135
+ ensure_url_prefix_not_null(US_AUTOCOMPLETE_API_URL)
136
+ USAutocomplete::Client.new(build_sender, @serializer)
137
+ end
138
+
139
+ def build_us_autocomplete_pro_api_client
140
+ ensure_url_prefix_not_null(US_AUTOCOMPLETE_PRO_API_URL)
141
+ USAutocompletePro::Client.new(build_sender, @serializer)
142
+ end
143
+
144
+ def build_us_extract_api_client
145
+ ensure_url_prefix_not_null(US_EXTRACT_API_URL)
146
+ USExtract::Client.new(build_sender, @serializer)
147
+ end
148
+
149
+ def build_us_street_api_client
150
+ ensure_url_prefix_not_null(US_STREET_API_URL)
151
+ USStreet::Client.new(build_sender, @serializer)
152
+ end
153
+
154
+ def build_us_zipcode_api_client
155
+ ensure_url_prefix_not_null(US_ZIP_CODE_API_URL)
156
+ USZipcode::Client.new(build_sender, @serializer)
157
+ end
158
+
159
+ def build_us_reverse_geo_api_client
160
+ ensure_url_prefix_not_null(US_REVERSE_GEO_API_URL)
161
+ USReverseGeo::Client.new(build_sender, @serializer)
162
+ end
163
+
164
+ # </editor-fold>
165
+
166
+ def build_sender
167
+ return @http_sender unless @http_sender.nil?
168
+
169
+ sender = NativeSender.new(@max_timeout, @proxy, @debug)
170
+
171
+ sender = StatusCodeSender.new(sender)
172
+
173
+ sender = CustomHeaderSender.new(sender, @headers) unless @headers.nil?
174
+
175
+ sender = SigningSender.new(@signer, sender) unless @signer.nil?
176
+
177
+ sender = RetrySender.new(@max_retries, sender, SmartyStreets::Sleeper.new,SmartyStreets::Logger.new) if @max_retries > 0
178
+
179
+ sender = LicenseSender.new(sender, @licenses)
180
+
181
+ URLPrefixSender.new(@url_prefix, sender)
182
+ end
183
+
184
+ def ensure_url_prefix_not_null(url)
185
+ @url_prefix = url if @url_prefix.nil?
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,13 @@
1
+ module SmartyStreets
2
+ class CustomHeaderSender
3
+ def initialize(inner, headers)
4
+ @inner = inner
5
+ @headers = headers
6
+ end
7
+
8
+ def send(request)
9
+ request.headers = @headers
10
+ @inner.send(request)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ module SmartyStreets
2
+ BAD_CREDENTIALS = 'Unauthorized: The credentials were provided incorrectly or did not match any existing,
3
+ active credentials.'.freeze
4
+
5
+ PAYMENT_REQUIRED = 'Payment Required: There is no active subscription
6
+ for the account associated with the credentials submitted with the request.'.freeze
7
+
8
+ FORBIDDEN = 'Because the international service is currently in a limited release phase, only approved accounts' \
9
+ ' may access the service.'.freeze
10
+
11
+ REQUEST_ENTITY_TOO_LARGE = 'Request Entity Too Large: The request body has exceeded the maximum size.'.freeze
12
+
13
+ BAD_REQUEST = 'Bad Request (Malformed Payload): A GET request lacked a street field or the request body of a
14
+ POST request contained malformed JSON, possibly because a value was submitted as a number rather than as a string.'.freeze
15
+
16
+ UNPROCESSABLE_ENTITY = 'GET request lacked required fields.'.freeze
17
+
18
+ TOO_MANY_REQUESTS = 'When using public "website key" authentication,
19
+ we restrict the number of requests coming from a given source over too short of a time.'.freeze
20
+
21
+ INTERNAL_SERVER_ERROR = 'Internal Server Error.'.freeze
22
+
23
+ SERVICE_UNAVAILABLE = 'Service Unavailable. Try again later.'.freeze
24
+
25
+ GATEWAY_TIMEOUT = 'The upstream data provider did not respond in a timely fashion and the request failed. ' \
26
+ 'A serious, yet rare occurrence indeed.'.freeze
27
+ end
@@ -0,0 +1,39 @@
1
+ module SmartyStreets
2
+
3
+ class SmartyError < StandardError
4
+ end
5
+
6
+ class BadCredentialsError < SmartyError
7
+ end
8
+
9
+ class ForbiddenError < SmartyError
10
+ end
11
+
12
+ class PaymentRequiredError < SmartyError
13
+ end
14
+
15
+ class RequestEntityTooLargeError < SmartyError
16
+ end
17
+
18
+ class BadRequestError < SmartyError
19
+ end
20
+
21
+ class UnprocessableEntityError < SmartyError
22
+ end
23
+
24
+ class TooManyRequestsError < SmartyError
25
+ end
26
+
27
+ class InternalServerError < SmartyError
28
+ end
29
+
30
+ class ServiceUnavailableError < SmartyError
31
+ end
32
+
33
+ class GatewayTimeoutError < SmartyError
34
+ end
35
+
36
+ class BatchFullError < SmartyError
37
+ end
38
+
39
+ end