smartystreets-python-sdk 5.6.0__tar.gz → 6.0.0__tar.gz

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 (91) hide show
  1. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/PKG-INFO +2 -2
  2. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/custom_header_sender.py +3 -0
  3. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/errors.py +2 -0
  4. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/exceptions.py +6 -0
  5. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/request.py +1 -0
  6. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/requests_sender.py +3 -0
  7. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/response.py +9 -0
  8. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/status_code_sender.py +5 -3
  9. smartystreets_python_sdk-6.0.0/smartystreets_python_sdk/us_enrichment/__init__.py +14 -0
  10. smartystreets_python_sdk-6.0.0/smartystreets_python_sdk/us_enrichment/client.py +206 -0
  11. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_enrichment/lookup.py +47 -21
  12. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/candidate.py +2 -0
  13. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk.egg-info/PKG-INFO +2 -2
  14. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk_version/__init__.py +1 -1
  15. smartystreets_python_sdk-5.6.0/smartystreets_python_sdk/us_enrichment/__init__.py +0 -2
  16. smartystreets_python_sdk-5.6.0/smartystreets_python_sdk/us_enrichment/client.py +0 -158
  17. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/LICENSE.md +0 -0
  18. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/README.md +0 -0
  19. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/setup.cfg +0 -0
  20. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/setup.py +0 -0
  21. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/__init__.py +0 -0
  22. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/basic_auth_credentials.py +0 -0
  23. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/batch.py +0 -0
  24. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/client_builder.py +0 -0
  25. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/custom_query_sender.py +0 -0
  26. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_autocomplete/__init__.py +0 -0
  27. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_autocomplete/candidate.py +0 -0
  28. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_autocomplete/client.py +0 -0
  29. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_autocomplete/lookup.py +0 -0
  30. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_postal_code/__init__.py +0 -0
  31. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_postal_code/candidate.py +0 -0
  32. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_postal_code/client.py +0 -0
  33. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_postal_code/lookup.py +0 -0
  34. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/__init__.py +0 -0
  35. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/analysis.py +0 -0
  36. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/candidate.py +0 -0
  37. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/changes.py +0 -0
  38. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/client.py +0 -0
  39. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/components.py +0 -0
  40. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/language_mode.py +0 -0
  41. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/lookup.py +0 -0
  42. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/metadata.py +0 -0
  43. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/international_street/rootlevel.py +0 -0
  44. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/license_sender.py +0 -0
  45. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/native_serializer.py +0 -0
  46. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/proxy.py +0 -0
  47. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/retry_sender.py +0 -0
  48. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/shared_credentials.py +0 -0
  49. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/signing_sender.py +0 -0
  50. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/static_credentials.py +0 -0
  51. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/url_prefix_sender.py +0 -0
  52. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_autocomplete_pro/__init__.py +0 -0
  53. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_autocomplete_pro/client.py +0 -0
  54. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_autocomplete_pro/geolocation_type.py +0 -0
  55. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_autocomplete_pro/lookup.py +0 -0
  56. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_autocomplete_pro/suggestion.py +0 -0
  57. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_enrichment/response.py +0 -0
  58. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/__init__.py +0 -0
  59. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/address.py +0 -0
  60. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/client.py +0 -0
  61. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/lookup.py +0 -0
  62. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/metadata.py +0 -0
  63. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_extract/result.py +0 -0
  64. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/__init__.py +0 -0
  65. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/address.py +0 -0
  66. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/client.py +0 -0
  67. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/coordinate.py +0 -0
  68. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/lookup.py +0 -0
  69. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/response.py +0 -0
  70. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_reverse_geo/result.py +0 -0
  71. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/__init__.py +0 -0
  72. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/analysis.py +0 -0
  73. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/client.py +0 -0
  74. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/component_analysis.py +0 -0
  75. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/components.py +0 -0
  76. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/lookup.py +0 -0
  77. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/match_info.py +0 -0
  78. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/match_type.py +0 -0
  79. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/metadata.py +0 -0
  80. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_street/output_format.py +0 -0
  81. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/__init__.py +0 -0
  82. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/alternate_county.py +0 -0
  83. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/city.py +0 -0
  84. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/client.py +0 -0
  85. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/lookup.py +0 -0
  86. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/result.py +0 -0
  87. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk/us_zipcode/zipcode.py +0 -0
  88. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk.egg-info/SOURCES.txt +0 -0
  89. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk.egg-info/dependency_links.txt +0 -0
  90. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk.egg-info/requires.txt +0 -0
  91. {smartystreets_python_sdk-5.6.0 → smartystreets_python_sdk-6.0.0}/smartystreets_python_sdk.egg-info/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smartystreets_python_sdk
3
- Version: 5.6.0
3
+ Version: 6.0.0
4
4
  Summary: An official library to help Python developers easily access the SmartyStreets APIs
5
5
  Home-page: https://github.com/smartystreets/smartystreets-python-sdk
6
- Download-URL: https://github.com/smartystreets/smartystreets-python-sdk/tarball/5.6.0
6
+ Download-URL: https://github.com/smartystreets/smartystreets-python-sdk/tarball/6.0.0
7
7
  Author: SmartyStreets SDK Team
8
8
  Author-email: support@smartystreets.com
9
9
  License: Apache 2
@@ -14,6 +14,9 @@ class CustomHeaderSender:
14
14
  def build_request(self, smarty_request):
15
15
  request = Request(url=smarty_request.url_prefix, params=smarty_request.parameters)
16
16
  request.headers = self.apply_headers()
17
+ if smarty_request.headers:
18
+ for key, value in smarty_request.headers.items():
19
+ request.headers[key] = value
17
20
  if smarty_request.payload:
18
21
  request.data = smarty_request.payload
19
22
  request.method = 'POST'
@@ -22,3 +22,5 @@ SERVICE_UNAVAILABLE = "Service Unavailable. Try again later."
22
22
 
23
23
  GATEWAY_TIMEOUT = "The upstream data provider did not respond in a timely fashion and the request failed. " \
24
24
  "A serious, yet rare occurrence indeed."
25
+
26
+ NOT_MODIFIED = "Not Modified: The requested record has not been modified since the previous request with the Etag value."
@@ -44,3 +44,9 @@ class GatewayTimeoutError(SmartyException):
44
44
 
45
45
  class BatchFullError(SmartyException):
46
46
  pass
47
+
48
+
49
+ class NotModifiedError(SmartyException):
50
+ def __init__(self, message=None, response_etag=None):
51
+ super().__init__(message)
52
+ self.response_etag = response_etag
@@ -10,3 +10,4 @@ class Request:
10
10
  self.referer = None
11
11
  self.content_type = 'application/json'
12
12
  self.auth = None
13
+ self.headers = {}
@@ -55,6 +55,9 @@ def build_request(smarty_request):
55
55
  request.headers['Content-Type'] = smarty_request.content_type
56
56
  if smarty_request.referer:
57
57
  request.headers['Referer'] = smarty_request.referer
58
+ if smarty_request.headers:
59
+ for key, value in smarty_request.headers.items():
60
+ request.headers[key] = value
58
61
  if smarty_request.auth:
59
62
  request.auth = smarty_request.auth
60
63
  if smarty_request.payload:
@@ -10,3 +10,12 @@ class Response:
10
10
  return None
11
11
  else:
12
12
  return self.headers[header]
13
+
14
+ def find_header(self, name):
15
+ if self.headers is None:
16
+ return None
17
+ target = name.lower()
18
+ for key, value in self.headers.items():
19
+ if key.lower() == target:
20
+ return value
21
+ return None
@@ -25,10 +25,12 @@ class StatusCodeSender:
25
25
  response = self.inner.send(request)
26
26
 
27
27
  if not response.error:
28
- if response.status_code != 429:
29
- response.error = statuses.get(response.status_code)
30
- else:
28
+ if response.status_code == 304:
29
+ response.error = exceptions.NotModifiedError(errors.NOT_MODIFIED, response.find_header('etag'))
30
+ elif response.status_code == 429:
31
31
  response.error = self.parse_rate_limit_response(response)
32
+ else:
33
+ response.error = statuses.get(response.status_code)
32
34
 
33
35
  return response
34
36
 
@@ -0,0 +1,14 @@
1
+ from .business import BusinessDetailAttributes, BusinessDetailResponse, BusinessEntry, BusinessSummaryResponse
2
+ from .client import Client
3
+ from .lookup import (
4
+ BusinessDetailLookup,
5
+ BusinessLookup,
6
+ GeoReferenceLookup,
7
+ Lookup,
8
+ LookupBase,
9
+ PrincipalLookup,
10
+ RiskLookup,
11
+ SecondaryCountLookup,
12
+ SecondaryLookup,
13
+ )
14
+ from .response import *
@@ -0,0 +1,206 @@
1
+ from urllib.parse import quote
2
+
3
+ from smartystreets_python_sdk import Request
4
+ from smartystreets_python_sdk.exceptions import SmartyException
5
+ from .business import BusinessSummaryResponse, BusinessDetailResponse
6
+ from .lookup import (
7
+ BusinessDetailLookup,
8
+ BusinessLookup,
9
+ GeoReferenceLookup,
10
+ Lookup,
11
+ PrincipalLookup,
12
+ RiskLookup,
13
+ SecondaryCountLookup,
14
+ SecondaryLookup,
15
+ )
16
+ from .response import Response
17
+
18
+
19
+ class Client:
20
+ def __init__(self, sender, serializer):
21
+ """
22
+ It is recommended to instantiate this class using ClientBuilder.build_us_enrichment_api_client()
23
+ """
24
+ self.sender = sender
25
+ self.serializer = serializer
26
+
27
+ def send_property_principal_lookup(self, lookup):
28
+ if isinstance(lookup, str):
29
+ l = PrincipalLookup(lookup)
30
+ send_lookup(self, l)
31
+ return l.result
32
+ else:
33
+ lookup.dataset = 'property'
34
+ lookup.dataSubset = 'principal'
35
+ send_lookup(self, lookup)
36
+ return lookup.result
37
+
38
+ def send_geo_reference_lookup(self, lookup):
39
+ if isinstance(lookup, str):
40
+ l = GeoReferenceLookup(lookup)
41
+ send_lookup(self, l)
42
+ return l.result
43
+ else:
44
+ lookup.dataset = 'geo-reference'
45
+ lookup.dataSubset = None
46
+ send_lookup(self, lookup)
47
+ return lookup.result
48
+
49
+ def send_risk_lookup(self, lookup):
50
+ if isinstance(lookup, str):
51
+ l = RiskLookup(lookup)
52
+ send_lookup(self, l)
53
+ return l.result
54
+ else:
55
+ lookup.dataset = 'risk'
56
+ lookup.dataSubset = None
57
+ send_lookup(self, lookup)
58
+ return lookup.result
59
+
60
+ def send_secondary_lookup(self, lookup):
61
+ if isinstance(lookup, str):
62
+ l = SecondaryLookup(lookup)
63
+ send_lookup(self, l)
64
+ return l.result
65
+ else:
66
+ lookup.dataset = 'secondary'
67
+ lookup.dataSubset = None
68
+ send_lookup(self, lookup)
69
+ return lookup.result
70
+
71
+ def send_secondary_count_lookup(self, lookup):
72
+ if isinstance(lookup, str):
73
+ l = SecondaryCountLookup(lookup)
74
+ send_lookup(self, l)
75
+ return l.result
76
+ else:
77
+ lookup.dataset = 'secondary'
78
+ lookup.dataSubset = 'count'
79
+ send_lookup(self, lookup)
80
+ return lookup.result
81
+
82
+ def send_generic_lookup(self, lookup, dataset, dataSubset):
83
+ if isinstance(lookup, str):
84
+ l = Lookup(lookup, dataset, dataSubset)
85
+ send_lookup(self, l)
86
+ return l.result
87
+ else:
88
+ lookup.dataset = dataset
89
+ lookup.dataSubset = dataSubset
90
+ send_lookup(self, lookup)
91
+ return lookup.result
92
+
93
+ def send_business_lookup(self, lookup):
94
+ if isinstance(lookup, str):
95
+ l = BusinessLookup(lookup)
96
+ send_lookup(self, l, BusinessSummaryResponse)
97
+ return l.result
98
+ else:
99
+ lookup.dataset = 'business'
100
+ lookup.dataSubset = None
101
+ send_lookup(self, lookup, BusinessSummaryResponse)
102
+ return lookup.result
103
+
104
+ def send_business_detail_lookup(self, lookup):
105
+ if isinstance(lookup, str):
106
+ l = BusinessDetailLookup(lookup)
107
+ send_business_detail_lookup(self, l)
108
+ return l.result
109
+ else:
110
+ send_business_detail_lookup(self, lookup)
111
+ return lookup.result
112
+
113
+
114
+ def send_lookup(client: Client, lookup, response_class=Response):
115
+ """
116
+ Sends a Lookup object to the US Enrichment API and stores the result in the Lookup's result field.
117
+ """
118
+ if lookup is None or (
119
+ _is_blank(getattr(lookup, 'smartykey', None))
120
+ and _is_blank(getattr(lookup, 'street', None))
121
+ and _is_blank(getattr(lookup, 'freeform', None))
122
+ ):
123
+ raise SmartyException("Lookup requires one of 'smartykey', 'street', or 'freeform' to be set")
124
+
125
+ request = build_request(lookup)
126
+ raw = _dispatch(client, request, lookup)
127
+ lookup.result = [response_class(candidate) for candidate in raw]
128
+ return lookup.result
129
+
130
+
131
+ def send_business_detail_lookup(client: Client, lookup):
132
+ if lookup is None or _is_blank(getattr(lookup, 'business_id', None)):
133
+ raise SmartyException("BusinessDetailLookup requires a non-empty 'business_id'")
134
+
135
+ request = Request()
136
+ request.url_components = 'business/' + quote(lookup.business_id, safe='')
137
+ request.parameters = _common_parameters(lookup)
138
+ _apply_etag_header(request, lookup)
139
+
140
+ raw = _dispatch(client, request, lookup)
141
+ if not raw:
142
+ lookup.result = None
143
+ elif len(raw) > 1:
144
+ raise SmartyException(
145
+ "business detail response contained {} results; expected at most 1".format(len(raw))
146
+ )
147
+ else:
148
+ lookup.result = BusinessDetailResponse(raw[0])
149
+ return lookup.result
150
+
151
+
152
+ def build_request(lookup):
153
+ request = Request()
154
+ request.url_components = _url_components(lookup)
155
+ request.parameters = _address_parameters(lookup)
156
+ request.parameters.update(_common_parameters(lookup))
157
+ _apply_etag_header(request, lookup)
158
+ return request
159
+
160
+
161
+ def _url_components(lookup):
162
+ if lookup.smartykey is not None:
163
+ base = lookup.smartykey + "/" + lookup.dataset
164
+ else:
165
+ base = 'search/' + lookup.dataset
166
+ if lookup.dataSubset is None:
167
+ return base
168
+ return base + "/" + lookup.dataSubset
169
+
170
+
171
+ def _address_parameters(lookup):
172
+ params = {}
173
+ for key in ('freeform', 'street', 'city', 'state', 'zipcode', 'features'):
174
+ value = getattr(lookup, key, None)
175
+ if value:
176
+ params[key] = value
177
+ return params
178
+
179
+
180
+ def _common_parameters(lookup):
181
+ params = {}
182
+ if lookup.include_array:
183
+ params['include'] = ','.join(lookup.include_array)
184
+ if lookup.exclude_array:
185
+ params['exclude'] = ','.join(lookup.exclude_array)
186
+ for key, value in lookup.custom_parameter_array.items():
187
+ params[key] = value
188
+ return params
189
+
190
+
191
+ def _apply_etag_header(request, lookup):
192
+ if lookup.request_etag is not None:
193
+ request.headers['Etag'] = lookup.request_etag
194
+
195
+
196
+ def _dispatch(client, request, lookup):
197
+ response = client.sender.send(request)
198
+ lookup.response_etag = response.find_header('etag')
199
+ if response.error:
200
+ raise response.error
201
+ raw = client.serializer.deserialize(response.payload)
202
+ return raw or []
203
+
204
+
205
+ def _is_blank(value):
206
+ return value is None or (isinstance(value, str) and value.strip() == '')
@@ -4,15 +4,36 @@ geoReferenceDataset = "geo-reference"
4
4
  riskDataset = "risk"
5
5
  secondaryDataset = "secondary"
6
6
  countDataSubset = "count"
7
+ businessDataset = "business"
7
8
  noneDataSubset = None
8
9
 
9
- class Lookup:
10
- def __init__(self, smartykey = None, dataset = None, dataSubset = None, features = None, freeform = None, street = None, city = None, state = None, zipcode = None):
10
+
11
+ class LookupBase:
12
+ def __init__(self):
13
+ self.include_array = []
14
+ self.exclude_array = []
15
+ self.request_etag = None
16
+ self.response_etag = None
17
+ self.custom_parameter_array = {}
18
+
19
+ def add_custom_parameter(self, parameter, value):
20
+ self.custom_parameter_array[parameter] = value
21
+
22
+ def add_include_attribute(self, attribute):
23
+ if attribute not in self.include_array:
24
+ self.include_array.append(attribute)
25
+
26
+ def add_exclude_attribute(self, attribute):
27
+ if attribute not in self.exclude_array:
28
+ self.exclude_array.append(attribute)
29
+
30
+
31
+ class Lookup(LookupBase):
32
+ def __init__(self, smartykey=None, dataset=None, dataSubset=None, features=None, freeform=None, street=None, city=None, state=None, zipcode=None):
33
+ super().__init__()
11
34
  self.smartykey = smartykey
12
35
  self.dataset = dataset
13
36
  self.dataSubset = dataSubset
14
- self.include_array = []
15
- self.exclude_array = []
16
37
  self.features = features
17
38
  self.freeform = freeform
18
39
  self.street = street
@@ -20,35 +41,40 @@ class Lookup:
20
41
  self.state = state
21
42
  self.zipcode = zipcode
22
43
  self.result = []
23
- self.custom_parameter_array = {}
24
-
25
- def add_custom_parameter(self, parameter, value):
26
- self.custom_parameter_array[parameter] = value
27
44
 
28
- def add_include_attribute(self, attribute):
29
- if (attribute not in self.include_array):
30
- self.include_array.append(attribute)
31
-
32
- def add_exclude_attribute(self, attribute):
33
- if (attribute not in self.exclude_array):
34
- self.exclude_array.append(attribute)
35
45
 
36
46
  class PrincipalLookup(Lookup):
37
- def __init__(self, smartykey = None):
47
+ def __init__(self, smartykey=None):
38
48
  super().__init__(smartykey, propertyDataset, principalDataSubset)
39
49
 
50
+
40
51
  class GeoReferenceLookup(Lookup):
41
- def __init__(self, smartykey = None):
52
+ def __init__(self, smartykey=None):
42
53
  super().__init__(smartykey, geoReferenceDataset, noneDataSubset)
43
54
 
55
+
44
56
  class RiskLookup(Lookup):
45
- def __init__(self, smartykey = None):
57
+ def __init__(self, smartykey=None):
46
58
  super().__init__(smartykey, riskDataset, noneDataSubset)
47
59
 
60
+
48
61
  class SecondaryLookup(Lookup):
49
- def __init__(self, smartykey = None):
62
+ def __init__(self, smartykey=None):
50
63
  super().__init__(smartykey, secondaryDataset, noneDataSubset)
51
64
 
65
+
52
66
  class SecondaryCountLookup(Lookup):
53
- def __init__(self, smartykey = None):
54
- super().__init__(smartykey, secondaryDataset, countDataSubset)
67
+ def __init__(self, smartykey=None):
68
+ super().__init__(smartykey, secondaryDataset, countDataSubset)
69
+
70
+
71
+ class BusinessLookup(Lookup):
72
+ def __init__(self, smartykey=None):
73
+ super().__init__(smartykey, businessDataset, noneDataSubset)
74
+
75
+
76
+ class BusinessDetailLookup(LookupBase):
77
+ def __init__(self, business_id=None):
78
+ super().__init__()
79
+ self.business_id = business_id
80
+ self.result = None
@@ -23,6 +23,7 @@ class Candidate:
23
23
  self.last_line = obj.get('last_line', None)
24
24
  self.delivery_point_barcode = obj.get('delivery_point_barcode', None)
25
25
  self.smarty_key = obj.get('smarty_key', None)
26
+ self.smarty_key_ext = obj.get('smarty_key_ext', None)
26
27
  self.components = Components(obj.get('components', {}))
27
28
  self.metadata = Metadata(obj.get('metadata', {}))
28
29
  self.analysis = Analysis(obj.get('analysis', {}))
@@ -42,6 +43,7 @@ class Candidate:
42
43
  "last_line": self.last_line,
43
44
  "delivery_point_barcode": self.delivery_point_barcode,
44
45
  "smarty_key": self.smarty_key,
46
+ "smarty_key_ext": self.smarty_key_ext,
45
47
  "components": components_dict or None,
46
48
  "metadata": metadata_dict or None,
47
49
  "analysis": analysis_dict or None
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smartystreets_python_sdk
3
- Version: 5.6.0
3
+ Version: 6.0.0
4
4
  Summary: An official library to help Python developers easily access the SmartyStreets APIs
5
5
  Home-page: https://github.com/smartystreets/smartystreets-python-sdk
6
- Download-URL: https://github.com/smartystreets/smartystreets-python-sdk/tarball/5.6.0
6
+ Download-URL: https://github.com/smartystreets/smartystreets-python-sdk/tarball/6.0.0
7
7
  Author: SmartyStreets SDK Team
8
8
  Author-email: support@smartystreets.com
9
9
  License: Apache 2
@@ -1,2 +1,2 @@
1
1
  __version__ = '0.0.0' # DO NOT EDIT (this is updated by a build job when a new release is published)
2
- __version__="5.6.0"
2
+ __version__="6.0.0"
@@ -1,2 +0,0 @@
1
- from .client import Client
2
- from .response import *
@@ -1,158 +0,0 @@
1
- from smartystreets_python_sdk import Request
2
- from smartystreets_python_sdk.exceptions import SmartyException
3
- from .lookup import PrincipalLookup, GeoReferenceLookup, RiskLookup, SecondaryLookup, SecondaryCountLookup, Lookup
4
- from .response import Response
5
-
6
-
7
- class Client:
8
- def __init__(self, sender, serializer):
9
- """
10
- It is recommended to instantiate this class using ClientBuilder.build_us_enrichment_api_client()
11
- """
12
- self.sender = sender
13
- self.serializer = serializer
14
-
15
- def send_property_principal_lookup(self, lookup):
16
- if isinstance(lookup, str):
17
- l = PrincipalLookup(lookup)
18
- send_lookup(self, l)
19
- return l.result
20
- else:
21
- lookup.dataset = 'property'
22
- lookup.dataSubset = 'principal'
23
- send_lookup(self, lookup)
24
- return lookup.result
25
-
26
- def send_geo_reference_lookup(self, lookup):
27
- if isinstance(lookup, str):
28
- l = GeoReferenceLookup(lookup)
29
- send_lookup(self, l)
30
- return l.result
31
- else:
32
- lookup.dataset = 'geo-reference'
33
- lookup.dataSubset = None
34
- send_lookup(self, lookup)
35
- return lookup.result
36
-
37
- def send_risk_lookup(self, lookup):
38
- if isinstance(lookup, str):
39
- l = RiskLookup(lookup)
40
- send_lookup(self, l)
41
- return l.result
42
- else:
43
- lookup.dataset = 'risk'
44
- lookup.dataSubset = None
45
- send_lookup(self, lookup)
46
- return lookup.result
47
-
48
- def send_secondary_lookup(self, lookup):
49
- if isinstance(lookup, str):
50
- l = SecondaryLookup(lookup)
51
- send_lookup(self, l)
52
- return l.result
53
- else:
54
- lookup.dataset = 'secondary'
55
- lookup.dataSubset = None
56
- send_lookup(self, lookup)
57
- return lookup.result
58
-
59
- def send_secondary_count_lookup(self, lookup):
60
- if isinstance(lookup, str):
61
- l = SecondaryCountLookup(lookup)
62
- send_lookup(self, l)
63
- return l.result
64
- else:
65
- lookup.dataset = 'secondary'
66
- lookup.dataSubset = 'count'
67
- send_lookup(self, lookup)
68
- return lookup.result
69
-
70
- def send_generic_lookup(self, lookup, dataset, dataSubset):
71
- if isinstance(lookup, str):
72
- l = Lookup(lookup, dataset, dataSubset)
73
- send_lookup(self, l)
74
- return l.result
75
- else:
76
- lookup.dataset = dataset
77
- lookup.dataSubset = dataSubset
78
- send_lookup(self, lookup)
79
- return lookup.result
80
-
81
-
82
- def send_lookup(client: Client, lookup):
83
- """
84
- Sends a Lookup object to the US Enrichment API and stores the result in the Lookup's result field.
85
- """
86
- if lookup is None or (lookup.smartykey is None and lookup.street is None and lookup.freeform is None):
87
- raise SmartyException('Client.send() requires a Lookup with either the "smartykey", "street, or "freeform" field set as a string')
88
-
89
- request = build_request(lookup)
90
-
91
- response = client.sender.send(request)
92
- if response.error:
93
- raise response.error
94
-
95
- response = client.serializer.deserialize(response.payload)
96
- result = []
97
- for candidate in response:
98
- result.append(Response(candidate))
99
- lookup.result = result
100
- return result
101
-
102
-
103
- def build_request(lookup):
104
- request = Request()
105
- if lookup.smartykey != None:
106
- if lookup.dataSubset == None:
107
- request.url_components = lookup.smartykey + "/" + lookup.dataset
108
- request.parameters = remap_keys(lookup)
109
- return request
110
-
111
- request.url_components = lookup.smartykey + "/" + lookup.dataset + "/" + lookup.dataSubset
112
- request.parameters = remap_keys(lookup)
113
-
114
- return request
115
- else:
116
- if lookup.dataSubset == None:
117
- request.url_components = 'search/' + lookup.dataset
118
- request.parameters = remap_keys(lookup)
119
- return request
120
-
121
- request.url_components = 'search/' + lookup.dataset + "/" + lookup.dataSubset
122
-
123
- request.parameters = remap_keys(lookup)
124
- return request
125
-
126
- def remap_keys(lookup):
127
- converted_lookup = {}
128
-
129
- if (lookup.freeform != None):
130
- add_field(converted_lookup, 'freeform', lookup.freeform)
131
- if (lookup.street != None):
132
- add_field(converted_lookup, 'street', lookup.street)
133
- if (lookup.city != None):
134
- add_field(converted_lookup, 'city', lookup.city)
135
- if (lookup.state != None):
136
- add_field(converted_lookup, 'state', lookup.state)
137
- if (lookup.zipcode != None):
138
- add_field(converted_lookup, 'zipcode', lookup.zipcode)
139
- if (lookup.include_array != None):
140
- add_field(converted_lookup, 'include', build_filter_string(lookup.include_array))
141
- if (lookup.exclude_array != None):
142
- add_field(converted_lookup, 'exclude', build_filter_string(lookup.exclude_array))
143
- if (lookup.features != None):
144
- add_field(converted_lookup, 'features', lookup.features)
145
-
146
-
147
- for parameter in lookup.custom_parameter_array:
148
- add_field(converted_lookup, parameter, lookup.custom_parameter_array[parameter])
149
-
150
- return converted_lookup
151
-
152
-
153
- def add_field(converted_lookup, key, value):
154
- if value:
155
- converted_lookup[key] = value
156
-
157
- def build_filter_string(filter_list):
158
- return ','.join(filter_list or []) or None