smartystreets_ruby_sdk 2.0.2 → 3.0.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1 -1
  3. data/Vagrantfile +4 -2
  4. data/examples/international_example.rb +31 -0
  5. data/examples/us_autocomplete_example.rb +38 -0
  6. data/examples/us_extract_example.rb +52 -0
  7. data/examples/us_street_multiple_address_example.rb +11 -9
  8. data/examples/us_street_single_address_example.rb +3 -3
  9. data/examples/us_zipcode_multiple_lookup_example.rb +7 -5
  10. data/examples/us_zipcode_single_lookup_example.rb +3 -3
  11. data/lib/smartystreets_ruby_sdk/batch.rb +7 -3
  12. data/lib/smartystreets_ruby_sdk/client_builder.rb +118 -0
  13. data/lib/smartystreets_ruby_sdk/errors.rb +15 -7
  14. data/lib/smartystreets_ruby_sdk/exceptions.rb +12 -5
  15. data/lib/smartystreets_ruby_sdk/international_street.rb +10 -0
  16. data/lib/smartystreets_ruby_sdk/international_street/analysis.rb +13 -0
  17. data/lib/smartystreets_ruby_sdk/international_street/candidate.rb +33 -0
  18. data/lib/smartystreets_ruby_sdk/international_street/client.rb +56 -0
  19. data/lib/smartystreets_ruby_sdk/international_street/components.rb +55 -0
  20. data/lib/smartystreets_ruby_sdk/international_street/language_mode.rb +5 -0
  21. data/lib/smartystreets_ruby_sdk/international_street/lookup.rb +80 -0
  22. data/lib/smartystreets_ruby_sdk/international_street/metadata.rb +14 -0
  23. data/lib/smartystreets_ruby_sdk/json_able.rb +3 -3
  24. data/lib/smartystreets_ruby_sdk/native_sender.rb +6 -2
  25. data/lib/smartystreets_ruby_sdk/request.rb +2 -1
  26. data/lib/smartystreets_ruby_sdk/retry_sender.rb +5 -7
  27. data/lib/smartystreets_ruby_sdk/us_autocomplete.rb +7 -0
  28. data/lib/smartystreets_ruby_sdk/us_autocomplete/client.rb +66 -0
  29. data/lib/smartystreets_ruby_sdk/us_autocomplete/geolocation_type.rb +5 -0
  30. data/lib/smartystreets_ruby_sdk/us_autocomplete/lookup.rb +34 -0
  31. data/lib/smartystreets_ruby_sdk/us_autocomplete/suggestion.rb +14 -0
  32. data/lib/smartystreets_ruby_sdk/us_extract.rb +8 -0
  33. data/lib/smartystreets_ruby_sdk/us_extract/address.rb +22 -0
  34. data/lib/smartystreets_ruby_sdk/us_extract/client.rb +46 -0
  35. data/lib/smartystreets_ruby_sdk/us_extract/lookup.rb +20 -0
  36. data/lib/smartystreets_ruby_sdk/us_extract/metadata.rb +15 -0
  37. data/lib/smartystreets_ruby_sdk/us_extract/result.rb +19 -0
  38. data/lib/smartystreets_ruby_sdk/us_street.rb +1 -1
  39. data/lib/smartystreets_ruby_sdk/us_street/analysis.rb +1 -0
  40. data/lib/smartystreets_ruby_sdk/us_street/candidate.rb +1 -0
  41. data/lib/smartystreets_ruby_sdk/us_street/client.rb +9 -5
  42. data/lib/smartystreets_ruby_sdk/us_street/components.rb +3 -0
  43. data/lib/smartystreets_ruby_sdk/us_street/lookup.rb +6 -0
  44. data/lib/smartystreets_ruby_sdk/us_street/match_type.rb +5 -0
  45. data/lib/smartystreets_ruby_sdk/us_street/metadata.rb +1 -0
  46. data/lib/smartystreets_ruby_sdk/us_zipcode.rb +1 -1
  47. data/lib/smartystreets_ruby_sdk/us_zipcode/alternate_county.rb +13 -0
  48. data/lib/smartystreets_ruby_sdk/us_zipcode/city.rb +2 -0
  49. data/lib/smartystreets_ruby_sdk/us_zipcode/client.rb +12 -4
  50. data/lib/smartystreets_ruby_sdk/us_zipcode/lookup.rb +4 -0
  51. data/lib/smartystreets_ruby_sdk/us_zipcode/result.rb +3 -2
  52. data/lib/smartystreets_ruby_sdk/us_zipcode/zip_code.rb +16 -3
  53. data/lib/smartystreets_ruby_sdk/version.rb +1 -1
  54. metadata +28 -7
  55. data/lib/smartystreets_ruby_sdk/core_client_builder.rb +0 -57
  56. data/lib/smartystreets_ruby_sdk/match_type.rb +0 -5
  57. data/lib/smartystreets_ruby_sdk/us_street/client_builder.rb +0 -15
  58. data/lib/smartystreets_ruby_sdk/us_zipcode/client_builder.rb +0 -15
@@ -0,0 +1,5 @@
1
+ module GeolocationType
2
+ CITY = 'city'
3
+ STATE = 'state'
4
+ NONE = 'null'
5
+ end
@@ -0,0 +1,34 @@
1
+ require_relative '../json_able'
2
+
3
+ module USAutocomplete
4
+ # In addition to holding all of the input data for this lookup, this class also will contain the result
5
+ # of the lookup after it comes back from the API.
6
+ #
7
+ # See "https://smartystreets.com/docs/cloud/us-autocomplete-api#http-request-input-fields"
8
+ class Lookup < JSONAble
9
+
10
+ attr_accessor :result, :prefix, :state_filter, :prefer, :max_suggestions, :geolocate_type, :city_filter
11
+
12
+ def initialize(prefix=nil, suggestions=nil, city_filter=nil, state_filter=nil, prefer=nil, geolocate_type=nil)
13
+ @result = []
14
+ @prefix = prefix
15
+ @max_suggestions = suggestions
16
+ @city_filter = city_filter ? city_filter : []
17
+ @state_filter = state_filter ? state_filter : []
18
+ @prefer = prefer ? prefer : []
19
+ @geolocate_type = geolocate_type
20
+ end
21
+
22
+ def add_city_filter(city)
23
+ @city_filter.push(city)
24
+ end
25
+
26
+ def add_state_filter(state)
27
+ @state_filter.push(state)
28
+ end
29
+
30
+ def add_prefer(prefer)
31
+ @prefer.push(prefer)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module USAutocomplete
2
+ # See "https://smartystreets.com/docs/cloud/us-autocomplete-api#http-response"
3
+ class Suggestion
4
+
5
+ attr_reader :text, :street_line, :state, :city
6
+
7
+ def initialize(obj)
8
+ @text = obj.fetch('text', nil)
9
+ @street_line = obj.fetch('street_line', nil)
10
+ @city = obj.fetch('city', nil)
11
+ @state = obj.fetch('state', nil)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ require_relative './us_extract/lookup'
2
+ require_relative './us_extract/address'
3
+ require_relative './us_extract/metadata'
4
+ require_relative './us_extract/result'
5
+ require_relative './us_extract/client'
6
+
7
+ module USExtract
8
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../us_street/candidate'
2
+
3
+ module USExtract
4
+ # See "https://smartystreets.com/docs/cloud/us-extract-api#http-response-status"
5
+ class Address
6
+ attr_reader :text, :start, :verified, :end, :line, :candidates
7
+
8
+ def initialize(obj)
9
+ @text = obj['text']
10
+ @verified = obj['verified']
11
+ @line = obj['line']
12
+ @start = obj['start']
13
+ @end = obj['end']
14
+ candidates = obj.fetch('api_output', [])
15
+ @candidates = []
16
+
17
+ candidates.each { |candidate|
18
+ @candidates.push(USStreet::Candidate.new(candidate))
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../request'
2
+ require_relative '../exceptions'
3
+ require_relative 'result'
4
+
5
+ module USExtract
6
+ # It is recommended to instantiate this class using ClientBuilder.build_us_extract_api_client()
7
+ class Client
8
+ def initialize(sender, serializer)
9
+ @sender = sender
10
+ @serializer = serializer
11
+ end
12
+
13
+ # Sends a Lookup object to the US Extract Code API and stores the result in the Lookup's result field.
14
+ # It also returns the result directly.
15
+ def send(lookup)
16
+ if lookup.nil? or lookup.text.nil? or not lookup.text.is_a? String or lookup.text.empty?
17
+ raise SmartyException, 'Client.send() requires a Lookup with the "text" field set'
18
+ end
19
+
20
+ request = build_request(lookup)
21
+ response = @sender.send(request)
22
+ result = Result.new(@serializer.deserialize(response.payload))
23
+
24
+ lookup.result = result
25
+ end
26
+
27
+ def build_request(lookup)
28
+ request = Request.new
29
+ request.content_type = 'text/plain'
30
+ request.payload = lookup.text
31
+
32
+ add_parameter(request, 'html', lookup.html.to_s)
33
+ add_parameter(request, 'aggressive', lookup.aggressive.to_s)
34
+ add_parameter(request, 'addr_line_breaks', lookup.addresses_have_line_breaks.to_s)
35
+ add_parameter(request, 'addr_per_line', lookup.addresses_per_line.to_s)
36
+
37
+ request
38
+ end
39
+
40
+ def add_parameter(request, key, value)
41
+ if value and not value.empty?
42
+ request.parameters[key] = value
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../json_able'
2
+
3
+ module USExtract
4
+ # In addition to holding all of the input data for this lookup, this class also will contain the result
5
+ # of the lookup after it comes back from the API.
6
+ #
7
+ # See "https://smartystreets.com/docs/cloud/us-extract-api#http-request-input-fields"
8
+ class Lookup < JSONAble
9
+ attr_accessor :text, :result, :aggressive, :addresses_per_line, :html, :addresses_have_line_breaks
10
+
11
+ def initialize(text=nil, html=nil, aggressive=nil, addresses_have_line_breaks=nil, addresses_per_line=nil)
12
+ @text = text
13
+ @html = html
14
+ @aggressive = aggressive
15
+ @addresses_have_line_breaks = addresses_have_line_breaks
16
+ @addresses_per_line = addresses_per_line
17
+ @result = nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module USExtract
2
+ # See "https://smartystreets.com/docs/cloud/us-extract-api#http-response-status"
3
+ class Metadata
4
+ attr_reader :unicode, :lines, :verified_count, :character_count, :bytes, :address_count
5
+
6
+ def initialize(obj)
7
+ @lines = obj['lines']
8
+ @unicode = obj['unicode']
9
+ @address_count = obj['address_count']
10
+ @verified_count = obj['verified_count']
11
+ @bytes = obj['bytes']
12
+ @character_count = obj['character_count']
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require_relative './address'
2
+ require_relative './metadata'
3
+
4
+ module USExtract
5
+ # See "https://smartystreets.com/docs/cloud/us-extract-api#http-response-status"
6
+ class Result
7
+ attr_reader :metadata, :addresses
8
+
9
+ def initialize(obj)
10
+ @metadata = Metadata.new(obj.fetch('meta', {}))
11
+ addresses = obj.fetch('addresses', [])
12
+ @addresses = []
13
+
14
+ addresses.each { |address|
15
+ @addresses.push(Address.new(address))
16
+ }
17
+ end
18
+ end
19
+ end
@@ -1,10 +1,10 @@
1
1
  require_relative './us_street/analysis'
2
2
  require_relative './us_street/candidate'
3
3
  require_relative './us_street/client'
4
- require_relative './us_street/client_builder'
5
4
  require_relative './us_street/components'
6
5
  require_relative './us_street/lookup'
7
6
  require_relative './us_street/metadata'
7
+ require_relative './us_street/match_type'
8
8
 
9
9
  module USStreet
10
10
  end
@@ -1,4 +1,5 @@
1
1
  module USStreet
2
+ # See "https://smartystreets.com/docs/cloud/us-street-api#analysis"
2
3
  class Analysis
3
4
  attr_reader :lacs_link_code, :active, :footnotes, :lacs_link_indicator, :dpv_match_code, :is_suite_link_match,
4
5
  :is_ews_match, :dpv_footnotes, :cmra, :vacant
@@ -3,6 +3,7 @@ require_relative 'metadata'
3
3
  require_relative 'analysis'
4
4
 
5
5
  module USStreet
6
+ # See "https://smartystreets.com/docs/cloud/us-street-api#metadata"
6
7
  class Candidate
7
8
  attr_reader :input_index, :candidate_index, :addressee, :delivery_line_1, :delivery_line_2, :delivery_point_barcode,
8
9
  :last_line, :metadata, :components, :analysis
@@ -3,22 +3,26 @@ require_relative '../request'
3
3
  require_relative 'candidate'
4
4
 
5
5
  module USStreet
6
+ # It is recommended to instantiate this class using ClientBuilder.build_us_street_api_client
6
7
  class Client
7
8
  def initialize(sender, serializer)
8
9
  @sender = sender
9
10
  @serializer = serializer
10
11
  end
11
12
 
13
+ # Sends a Lookup object to the US Street API and stores the result in the Lookup's result field.
12
14
  def send_lookup(lookup)
13
15
  batch = Batch.new
14
16
  batch.add(lookup)
15
17
  send_batch(batch)
16
18
  end
17
19
 
20
+ # Sends a Batch object containing no more than 100 Lookup objects to the US Street API and stores the
21
+ # results in the result field of the Lookup object.
18
22
  def send_batch(batch)
19
23
  smarty_request = Request.new
20
24
 
21
- return if batch.size == 0
25
+ return if batch.empty?
22
26
 
23
27
  converted_lookups = remap_keys(batch.all_lookups)
24
28
  smarty_request.payload = @serializer.serialize(converted_lookups)
@@ -35,7 +39,7 @@ module USStreet
35
39
 
36
40
  def remap_keys(obj)
37
41
  converted_obj = []
38
- obj.each { |lookup|
42
+ obj.each do |lookup|
39
43
  converted_lookup = {}
40
44
 
41
45
  converted_lookup['street'] = lookup.street
@@ -51,15 +55,15 @@ module USStreet
51
55
  converted_lookup['candidates'] = lookup.candidates
52
56
 
53
57
  converted_obj.push(converted_lookup)
54
- }
58
+ end
55
59
  converted_obj
56
60
  end
57
61
 
58
62
  def assign_candidates_to_lookups(batch, candidates)
59
- candidates.each { |raw_candidate|
63
+ candidates.each do |raw_candidate|
60
64
  candidate = Candidate.new(raw_candidate)
61
65
  batch[candidate.input_index].result.push(candidate)
62
- }
66
+ end
63
67
  end
64
68
  end
65
69
  end
@@ -1,4 +1,7 @@
1
1
  module USStreet
2
+ # This class contains the matched address broken down into its fundamental pieces.
3
+ #
4
+ # See "https://smartystreets.com/docs/cloud/us-street-api#components"
2
5
  class Components
3
6
  attr_reader :street_postdirection, :delivery_point_check_digit, :secondary_designator, :secondary_number, :zipcode,
4
7
  :pmb_number, :state_abbreviation, :extra_secondary_designator, :urbanization, :street_name, :city_name,
@@ -1,6 +1,12 @@
1
1
  require_relative '../json_able'
2
2
 
3
3
  module USStreet
4
+ # In addition to holding all of the input data for this lookup, this class also will contain
5
+ # the result of the lookup after it comes back from the API.
6
+ #
7
+ # See "https://smartystreets.com/docs/cloud/us-street-api#input-fields"
8
+ #
9
+ # @match:: Must be set to 'strict', 'range', or 'invalid'. Constants for these are in match_type.rb
4
10
  class Lookup < JSONAble
5
11
  attr_accessor :input_id, :street, :street2, :secondary, :city, :state, :zipcode, :lastline, :addressee, :urbanization,
6
12
  :match, :candidates, :result
@@ -0,0 +1,5 @@
1
+ module MatchType
2
+ STRICT = 'strict'.freeze
3
+ RANGE = 'range'.freeze
4
+ INVALID = 'invalid'.freeze
5
+ end
@@ -1,4 +1,5 @@
1
1
  module USStreet
2
+ # See "https://smartystreets.com/docs/cloud/us-street-api#metadata"
2
3
  class Metadata
3
4
  attr_reader :elot_sort, :longitude, :elot_sequence, :county_fips, :building_default_indicator, :rdi,
4
5
  :congressional_district, :latitude, :precision, :time_zone, :zip_type, :county_name, :utc_offset,
@@ -1,9 +1,9 @@
1
1
  require_relative './us_zipcode/city'
2
2
  require_relative './us_zipcode/client'
3
- require_relative './us_zipcode/client_builder'
4
3
  require_relative './us_zipcode/lookup'
5
4
  require_relative './us_zipcode/result'
6
5
  require_relative './us_zipcode/zip_code'
6
+ require_relative './us_zipcode/alternate_county'
7
7
 
8
8
  module USZipcode
9
9
  end
@@ -0,0 +1,13 @@
1
+ module USZipcode
2
+ # See "https://smartystreets.com/docs/cloud/us-zipcode-api#zipcodes"
3
+ class AlternateCounty
4
+ attr_reader :state_abbreviation, :state, :county_name, :county_fips
5
+
6
+ def initialize(obj)
7
+ @county_fips = obj.fetch('county_fips', nil)
8
+ @county_name = obj.fetch('county_name', nil)
9
+ @state_abbreviation = obj.fetch('state_abbreviation', nil)
10
+ @state = obj.fetch('state', nil)
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,6 @@
1
1
  module USZipcode
2
+ # Known in the SmartyStreets US ZIP Code API documentation as a city_state
3
+ # See "https://smartystreets.com/docs/cloud/us-zipcode-api#cities"
2
4
  class City
3
5
  attr_reader :mailable_city, :state_abbreviation, :state, :city
4
6
 
@@ -3,22 +3,26 @@ require_relative '../batch'
3
3
  require_relative '../request'
4
4
 
5
5
  module USZipcode
6
+ # It is recommended to instantiate this class using ClientBuilder.build_us_zipcode_api_client.
6
7
  class Client
7
8
  def initialize(sender, serializer)
8
9
  @sender = sender
9
10
  @serializer = serializer
10
11
  end
11
12
 
13
+ # Sends a Lookup object to the US ZIP Code API and stores the result in the Lookup's result field.
12
14
  def send_lookup(lookup)
13
15
  batch = Batch.new
14
16
  batch.add(lookup)
15
17
  send_batch(batch)
16
18
  end
17
19
 
20
+ # Sends a Batch object containing no more than 100 Lookup objects to the US ZIP Code API and stores the
21
+ # results in the result field of the Lookup object.
18
22
  def send_batch(batch)
19
23
  smarty_request = Request.new
20
24
 
21
- return if batch.size == 0
25
+ return if batch.empty?
22
26
 
23
27
  converted_lookups = remap_keys(batch.all_lookups)
24
28
  smarty_request.payload = @serializer.serialize(converted_lookups)
@@ -44,14 +48,18 @@ module USZipcode
44
48
  obj.each do |lookup|
45
49
  converted_lookup = {}
46
50
 
47
- converted_lookup['city'] = lookup.city
48
- converted_lookup['state'] = lookup.state
49
- converted_lookup['zipcode'] = lookup.zipcode
51
+ add_field(converted_lookup, 'city', lookup.city)
52
+ add_field(converted_lookup, 'state', lookup.state)
53
+ add_field(converted_lookup, 'zipcode', lookup.zipcode)
50
54
 
51
55
  converted_obj.push(converted_lookup)
52
56
  end
53
57
 
54
58
  converted_obj
55
59
  end
60
+
61
+ def add_field(converted_lookup, key, value)
62
+ converted_lookup[key] = value unless value.nil? or value.empty?
63
+ end
56
64
  end
57
65
  end
@@ -1,5 +1,9 @@
1
1
  require_relative '../json_able'
2
2
  module USZipcode
3
+ # In addition to holding all of the input data for this lookup, this class also
4
+ # will contain the result of the lookup after it comes back from the API.
5
+ #
6
+ # See "https://smartystreets.com/docs/cloud/us-zipcode-api#http-request-input-fields"
3
7
  class Lookup < JSONAble
4
8
  attr_accessor :result, :state, :zipcode, :input_id, :city
5
9
 
@@ -2,6 +2,7 @@ require_relative 'city'
2
2
  require_relative 'zip_code'
3
3
 
4
4
  module USZipcode
5
+ # See "https://smartystreets.com/docs/cloud/us-zipcode-api#root"
5
6
  class Result
6
7
  attr_reader :reason, :input_index, :cities, :zipcodes, :status
7
8
 
@@ -16,8 +17,8 @@ module USZipcode
16
17
  @zipcodes = convert_zipcodes
17
18
  end
18
19
 
19
- def is_valid?
20
- @status == nil and @reason == nil
20
+ def valid?
21
+ @status.nil? and @reason.nil?
21
22
  end
22
23
 
23
24
  def convert_cities
@@ -1,6 +1,11 @@
1
+ require_relative 'alternate_county'
2
+
1
3
  module USZipcode
4
+ # See "https://smartystreets.com/docs/cloud/us-zipcode-api#zipcodes"
2
5
  class ZipCode
3
- attr_reader :longitude, :county_name, :zipcode, :zipcode_type, :county_fips, :latitude, :precision, :default_city, :alternate_counties
6
+ attr_reader :longitude, :county_name, :zipcode, :zipcode_type, :county_fips,
7
+ :latitude, :precision, :default_city, :alternate_counties,
8
+ :state_abbreviation, :state
4
9
 
5
10
  def initialize(obj)
6
11
  @zipcode = obj['zipcode']
@@ -11,7 +16,15 @@ module USZipcode
11
16
  @latitude = obj['latitude']
12
17
  @longitude = obj['longitude']
13
18
  @precision = obj['precision']
14
- @alternate_counties = obj.fetch('alternate_counties', [])
19
+ @state = obj['state']
20
+ @state_abbreviation = obj['state_abbreviation']
21
+ alternate_counties = obj.fetch('alternate_counties', [])
22
+
23
+ @alternate_counties = []
24
+
25
+ alternate_counties.each do |county|
26
+ @alternate_counties.push(USZipcode::AlternateCounty.new(county))
27
+ end
15
28
  end
16
29
  end
17
- end
30
+ end