telesign 2.2.2__tar.gz → 2.2.4__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 (35) hide show
  1. {telesign-2.2.2 → telesign-2.2.4}/LICENSE.txt +7 -7
  2. {telesign-2.2.2/telesign.egg-info → telesign-2.2.4}/PKG-INFO +9 -9
  3. {telesign-2.2.2 → telesign-2.2.4}/README.rst +8 -8
  4. telesign-2.2.4/examples/intelligence/1_get_risk_score_and_related_insights.py +29 -0
  5. {telesign-2.2.2 → telesign-2.2.4}/setup.py +1 -1
  6. telesign-2.2.4/telesign/intelligence.py +39 -0
  7. telesign-2.2.4/telesign/phoneid.py +28 -0
  8. {telesign-2.2.2 → telesign-2.2.4}/telesign/rest.py +70 -36
  9. {telesign-2.2.2 → telesign-2.2.4}/telesign/util.py +6 -0
  10. {telesign-2.2.2 → telesign-2.2.4/telesign.egg-info}/PKG-INFO +9 -9
  11. {telesign-2.2.2 → telesign-2.2.4}/telesign.egg-info/SOURCES.txt +3 -0
  12. telesign-2.2.4/tests/test_phoneid.py +48 -0
  13. {telesign-2.2.2 → telesign-2.2.4}/tests/test_rest.py +68 -0
  14. telesign-2.2.2/telesign/phoneid.py +0 -54
  15. {telesign-2.2.2 → telesign-2.2.4}/MANIFEST.in +0 -0
  16. {telesign-2.2.2 → telesign-2.2.4}/examples/appverify/1_get_status_by_external_id.py +0 -0
  17. {telesign-2.2.2 → telesign-2.2.4}/examples/messaging/1_send_message.py +0 -0
  18. {telesign-2.2.2 → telesign-2.2.4}/examples/messaging/2_send_message_with_verification_code.py +0 -0
  19. {telesign-2.2.2 → telesign-2.2.4}/examples/phoneid/1_check_phone_type_to_block_voip.py +0 -0
  20. {telesign-2.2.2 → telesign-2.2.4}/examples/phoneid/2_cleansing.py +0 -0
  21. {telesign-2.2.2 → telesign-2.2.4}/examples/score/1_check_phone_number_risk_level.py +0 -0
  22. {telesign-2.2.2 → telesign-2.2.4}/examples/voice/1_send_voice_call.py +0 -0
  23. {telesign-2.2.2 → telesign-2.2.4}/examples/voice/2_send_voice_call_with_verification_code.py +0 -0
  24. {telesign-2.2.2 → telesign-2.2.4}/examples/voice/3_send_voice_call_french.py +0 -0
  25. {telesign-2.2.2 → telesign-2.2.4}/setup.cfg +0 -0
  26. {telesign-2.2.2 → telesign-2.2.4}/telesign/__init__.py +0 -0
  27. {telesign-2.2.2 → telesign-2.2.4}/telesign/appverify.py +0 -0
  28. {telesign-2.2.2 → telesign-2.2.4}/telesign/messaging.py +0 -0
  29. {telesign-2.2.2 → telesign-2.2.4}/telesign/score.py +0 -0
  30. {telesign-2.2.2 → telesign-2.2.4}/telesign/voice.py +0 -0
  31. {telesign-2.2.2 → telesign-2.2.4}/telesign.egg-info/dependency_links.txt +0 -0
  32. {telesign-2.2.2 → telesign-2.2.4}/telesign.egg-info/requires.txt +0 -0
  33. {telesign-2.2.2 → telesign-2.2.4}/telesign.egg-info/top_level.txt +0 -0
  34. {telesign-2.2.2 → telesign-2.2.4}/tests/__init__.py +0 -0
  35. {telesign-2.2.2 → telesign-2.2.4}/tests/test_util.py +0 -0
@@ -1,11 +1,11 @@
1
- Copyright (c) 2017 TeleSign Corp.
1
+ Copyright (c) 2023 Telesign Corp.
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
- of the Software, and to permit persons to whom the Software is furnished to do
8
- so, subject to the following conditions:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
9
 
10
10
  The above copyright notice and this permission notice shall be included in all
11
11
  copies or substantial portions of the Software.
@@ -1,25 +1,25 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: telesign
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: TeleSign SDK
5
5
  Home-page: https://github.com/telesign/python_telesign
6
6
  Author: TeleSign Corp.
7
7
  Author-email: support@telesign.com
8
8
  License: MIT
9
9
  Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/python_banner.jpg
10
- :target: https://developer.telesign.com
10
+ :target: https://standard.telesign.com
11
11
 
12
12
  .. image:: https://img.shields.io/travis/TeleSign/python_telesign.svg
13
- :target: https://travis-ci.org/TeleSign/python_telesign
13
+ :target: https://travis-ci.org/TeleSign/python_telesign
14
14
 
15
15
  .. image:: https://img.shields.io/codecov/c/github/TeleSign/python_telesign.svg
16
- :target: https://codecov.io/gh/TeleSign/python_telesign
16
+ :target: https://codecov.io/gh/TeleSign/python_telesign
17
17
 
18
18
  .. image:: https://img.shields.io/pypi/v/telesign.svg
19
- :target: https://pypi.python.org/pypi/telesign
19
+ :target: https://pypi.python.org/pypi/telesign
20
20
 
21
21
  .. image:: https://img.shields.io/pypi/l/telesign.svg
22
- :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
22
+ :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
23
23
 
24
24
  ===================
25
25
  TeleSign Python SDK
@@ -36,7 +36,7 @@ Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/p
36
36
  -------------
37
37
 
38
38
  Code documentation is included in the SDK. Complete documentation, quick start guides and reference material
39
- for the TeleSign API is available within the `TeleSign Developer Center <https://developer.telesign.com/>`_.
39
+ for the TeleSign API is available within the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
40
40
 
41
41
  Installation
42
42
  ------------
@@ -88,14 +88,14 @@ Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/p
88
88
  print(response.json)
89
89
 
90
90
  .. code-block:: javascript
91
-
91
+
92
92
  {'reference_id': 'DGFDF6E11AB86303ASDFD425BE00000657',
93
93
  'status': {'code': 103,
94
94
  'description': 'Call in progress',
95
95
  'updated_on': '2016-12-12T00:39:58.325559Z'}}
96
96
 
97
97
  For more examples, see the `examples <https://github.com/TeleSign/python_telesign/tree/master/examples>`_ folder or
98
- visit the `TeleSign Developer Center <https://developer.telesign.com/>`_.
98
+ visit the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
99
99
 
100
100
  Keywords: telesign,sms,voice,mobile,authentication,identity,messaging
101
101
  Platform: UNKNOWN
@@ -1,17 +1,17 @@
1
1
  .. image:: https://raw.github.com/TeleSign/python_telesign/master/python_banner.jpg
2
- :target: https://developer.telesign.com
2
+ :target: https://standard.telesign.com
3
3
 
4
4
  .. image:: https://img.shields.io/travis/TeleSign/python_telesign.svg
5
- :target: https://travis-ci.org/TeleSign/python_telesign
5
+ :target: https://travis-ci.org/TeleSign/python_telesign
6
6
 
7
7
  .. image:: https://img.shields.io/codecov/c/github/TeleSign/python_telesign.svg
8
- :target: https://codecov.io/gh/TeleSign/python_telesign
8
+ :target: https://codecov.io/gh/TeleSign/python_telesign
9
9
 
10
10
  .. image:: https://img.shields.io/pypi/v/telesign.svg
11
- :target: https://pypi.python.org/pypi/telesign
11
+ :target: https://pypi.python.org/pypi/telesign
12
12
 
13
13
  .. image:: https://img.shields.io/pypi/l/telesign.svg
14
- :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
14
+ :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
15
15
 
16
16
  ===================
17
17
  TeleSign Python SDK
@@ -28,7 +28,7 @@ Documentation
28
28
  -------------
29
29
 
30
30
  Code documentation is included in the SDK. Complete documentation, quick start guides and reference material
31
- for the TeleSign API is available within the `TeleSign Developer Center <https://developer.telesign.com/>`_.
31
+ for the TeleSign API is available within the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
32
32
 
33
33
  Installation
34
34
  ------------
@@ -80,11 +80,11 @@ Here is a basic code example with the JSON response.
80
80
  print(response.json)
81
81
 
82
82
  .. code-block:: javascript
83
-
83
+
84
84
  {'reference_id': 'DGFDF6E11AB86303ASDFD425BE00000657',
85
85
  'status': {'code': 103,
86
86
  'description': 'Call in progress',
87
87
  'updated_on': '2016-12-12T00:39:58.325559Z'}}
88
88
 
89
89
  For more examples, see the `examples <https://github.com/TeleSign/python_telesign/tree/master/examples>`_ folder or
90
- visit the `TeleSign Developer Center <https://developer.telesign.com/>`_.
90
+ visit the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
@@ -0,0 +1,29 @@
1
+ """Example code that makes requests to intelligence API."""
2
+ from __future__ import print_function
3
+ from telesign.intelligence import IntelligenceClient
4
+
5
+ customer_1 = "your_customer_id-44ZA-47B5-95B9-ACXM9B1E5CAA"
6
+ api_key_1 = "your_api_key_or_password"
7
+
8
+ phone_number = "15555551212"
9
+ account_lifecycle_event = "create"
10
+
11
+ body = {
12
+ "contact_details": {"email": "ghopper@gmail.com", "phone_number": "15555551212"},
13
+ "external_id": "REG432538",
14
+ "account_lifecycle_event": "create",
15
+ "ip": "1.1.1.1",
16
+ "device_id": "2e4fa042234d",
17
+ }
18
+
19
+ client = IntelligenceClient(customer_1, api_key_1)
20
+ response = client.intelligence(body)
21
+
22
+ if response.ok:
23
+ print(
24
+ "Phone number {} has a '{}' risk level and the score is '{}'.".format(
25
+ response.json["phone_details"]["numbering"]["original"]["phone_number"],
26
+ response.json["risk"]["level"],
27
+ response.json["risk"]["score"],
28
+ )
29
+ )
@@ -11,7 +11,7 @@ mock = ['mock'] if needs_mock else []
11
11
 
12
12
  here = path.abspath(path.dirname(__file__))
13
13
 
14
- version = "2.2.2"
14
+ version = "2.2.4"
15
15
 
16
16
  with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
17
17
  long_description = f.read()
@@ -0,0 +1,39 @@
1
+ """Client to make requests to intelligence API."""
2
+ from __future__ import unicode_literals
3
+
4
+ from telesign.rest import RestClient
5
+ from telesign.util import AuthMethod
6
+
7
+ INTELLIGENCE_BASE_URL = "https://detect.telesign.com"
8
+ INTELLIGENCE_ENDPOINT_PATH = "/intelligence"
9
+
10
+
11
+ class IntelligenceClient(RestClient):
12
+ """
13
+ It is critical today to evaluate fraud risk throughout the entire customer journey.
14
+
15
+ Telesign Intelligence makes it easy to understand the risk and the reason behind it with tailored scoring models
16
+ and comprehensive reason codes.
17
+ """
18
+
19
+ def __init__(self, customer_id, api_key, **kwargs):
20
+ super(IntelligenceClient, self).__init__(
21
+ customer_id=customer_id,
22
+ api_key=api_key,
23
+ rest_endpoint=INTELLIGENCE_BASE_URL,
24
+ auth_method=AuthMethod.BASIC.value,
25
+ **kwargs
26
+ )
27
+
28
+ def intelligence(self, params):
29
+ """
30
+ Telesign Intelligence is like a credit check for digital profiles.
31
+
32
+ You submit a phone number, IP, and email to the service, the individual
33
+ identifiers are each evaluated, and then a score is returned telling you how risky
34
+ that user is. You decide whether to proceed based on the score.
35
+
36
+ See https://developer.telesign.com/enterprise/docs/intelligence-overview
37
+ for detailed API documentation.
38
+ """
39
+ return self.post(INTELLIGENCE_ENDPOINT_PATH, body=params, query_params=None)
@@ -0,0 +1,28 @@
1
+ from __future__ import unicode_literals
2
+
3
+ import json
4
+
5
+ from telesign.rest import RestClient
6
+
7
+ PHONEID_RESOURCE = "/v1/phoneid/{phone_number}"
8
+
9
+
10
+ class PhoneIdClient(RestClient):
11
+ """
12
+ A set of APIs that deliver deep phone number data attributes that help optimize the end user
13
+ verification process and evaluate risk.
14
+ """
15
+
16
+ def __init__(self, customer_id, api_key, **kwargs):
17
+ super(PhoneIdClient, self).__init__(customer_id, api_key, **kwargs)
18
+
19
+ def phoneid(self, phone_number, **params):
20
+ """
21
+ The PhoneID API provides a cleansed phone number, phone type, and telecom carrier information to determine the
22
+ best communication method - SMS or voice.
23
+
24
+ See https://developer.telesign.com/docs/phoneid-api for detailed API documentation.
25
+ """
26
+ return self.post(PHONEID_RESOURCE.format(phone_number=phone_number),
27
+ json_fields=params,
28
+ **params)
@@ -1,6 +1,5 @@
1
1
  from __future__ import unicode_literals
2
2
 
3
- from requests import post
4
3
  import hmac
5
4
  import uuid
6
5
  from base64 import b64encode, b64decode
@@ -9,8 +8,10 @@ from hashlib import sha256
9
8
  from platform import python_version
10
9
 
11
10
  import requests
11
+ import json
12
12
 
13
13
  import telesign
14
+ from telesign.util import AuthMethod
14
15
 
15
16
 
16
17
  class RestClient(requests.models.RequestEncodingMixin):
@@ -51,7 +52,8 @@ class RestClient(requests.models.RequestEncodingMixin):
51
52
  api_key,
52
53
  rest_endpoint='https://rest-api.telesign.com',
53
54
  proxies=None,
54
- timeout=10):
55
+ timeout=10,
56
+ auth_method=None):
55
57
  """
56
58
  TeleSign RestClient useful for making generic RESTful requests against our API.
57
59
 
@@ -73,6 +75,8 @@ class RestClient(requests.models.RequestEncodingMixin):
73
75
 
74
76
  self.timeout = timeout
75
77
 
78
+ self.auth_method = auth_method
79
+
76
80
  @staticmethod
77
81
  def generate_telesign_headers(customer_id,
78
82
  api_key,
@@ -82,7 +86,8 @@ class RestClient(requests.models.RequestEncodingMixin):
82
86
  date_rfc2616=None,
83
87
  nonce=None,
84
88
  user_agent=None,
85
- content_type=None):
89
+ content_type=None,
90
+ auth_method=None):
86
91
  """
87
92
  Generates the TeleSign REST API headers used to authenticate requests.
88
93
 
@@ -101,6 +106,7 @@ class RestClient(requests.models.RequestEncodingMixin):
101
106
  :param nonce: A unique cryptographic nonce for the request, as a string.
102
107
  :param user_agent: (optional) User Agent associated with the request, as a string.
103
108
  :param content_type: (optional) ContentType of the request, as a string.
109
+ :param auth_method: (optional) Authentication type ex: Basic, HMAC etc
104
110
  :return: The TeleSign authentication headers.
105
111
  """
106
112
  if date_rfc2616 is None:
@@ -112,31 +118,39 @@ class RestClient(requests.models.RequestEncodingMixin):
112
118
  if not content_type:
113
119
  content_type = "application/x-www-form-urlencoded" if method_name in ("POST", "PUT") else ""
114
120
 
115
- auth_method = "HMAC-SHA256"
121
+ # Default auth_method is Digest if not explicitly specified
122
+ if auth_method == AuthMethod.BASIC:
123
+ usr_apikey = "{customer_id}:{api_key}".format(customer_id=customer_id,
124
+ api_key=api_key)
125
+ b64val = b64encode(usr_apikey.encode())
126
+ authorization = "{auth_method} {b64val}".format(auth_method=AuthMethod.BASIC,
127
+ b64val=b64val.decode())
128
+ else:
129
+ auth_method = AuthMethod.HMAC_SHA256
116
130
 
117
- string_to_sign_builder = ["{method}".format(method=method_name)]
131
+ string_to_sign_builder = ["{method}".format(method=method_name)]
118
132
 
119
- string_to_sign_builder.append("\n{content_type}".format(content_type=content_type))
133
+ string_to_sign_builder.append("\n{content_type}".format(content_type=content_type))
120
134
 
121
- string_to_sign_builder.append("\n{date}".format(date=date_rfc2616))
135
+ string_to_sign_builder.append("\n{date}".format(date=date_rfc2616))
122
136
 
123
- string_to_sign_builder.append("\nx-ts-auth-method:{auth_method}".format(auth_method=auth_method))
137
+ string_to_sign_builder.append("\nx-ts-auth-method:{auth_method}".format(auth_method=auth_method))
124
138
 
125
- string_to_sign_builder.append("\nx-ts-nonce:{nonce}".format(nonce=nonce))
139
+ string_to_sign_builder.append("\nx-ts-nonce:{nonce}".format(nonce=nonce))
126
140
 
127
- if content_type and url_encoded_fields:
128
- string_to_sign_builder.append("\n{fields}".format(fields=url_encoded_fields))
141
+ if content_type and url_encoded_fields:
142
+ string_to_sign_builder.append("\n{fields}".format(fields=url_encoded_fields))
129
143
 
130
- string_to_sign_builder.append("\n{resource}".format(resource=resource))
144
+ string_to_sign_builder.append("\n{resource}".format(resource=resource))
131
145
 
132
- string_to_sign = "".join(string_to_sign_builder)
146
+ string_to_sign = "".join(string_to_sign_builder)
133
147
 
134
- signer = hmac.new(b64decode(api_key), string_to_sign.encode("utf-8"), sha256)
135
- signature = b64encode(signer.digest()).decode("utf-8")
148
+ signer = hmac.new(b64decode(api_key), string_to_sign.encode("utf-8"), sha256)
149
+ signature = b64encode(signer.digest()).decode("utf-8")
136
150
 
137
- authorization = "TSA {customer_id}:{signature}".format(
138
- customer_id=customer_id,
139
- signature=signature)
151
+ authorization = "TSA {customer_id}:{signature}".format(
152
+ customer_id=customer_id,
153
+ signature=signature)
140
154
 
141
155
  headers = {
142
156
  "Authorization": authorization,
@@ -151,69 +165,89 @@ class RestClient(requests.models.RequestEncodingMixin):
151
165
 
152
166
  return headers
153
167
 
154
- def post(self, resource, **params):
168
+ def post(self, resource, body=None, json_fields=None, **query_params):
155
169
  """
156
170
  Generic TeleSign REST API POST handler.
157
171
 
158
172
  :param resource: The partial resource URI to perform the request against, as a string.
159
- :param params: Body params to perform the POST request with, as a dictionary.
173
+ :param body: (optional) A dictionary sent as a part of request body.
174
+ :param query_params: query_params to perform the POST request with, as a dictionary.
160
175
  :return: The RestClient Response object.
161
176
  """
162
- return self._execute(self.session.post, 'POST', resource, **params)
177
+ return self._execute(self.session.post, 'POST', resource, body, json_fields, **query_params)
163
178
 
164
- def get(self, resource, **params):
179
+ def get(self, resource, body=None, json_fields=None, **query_params):
165
180
  """
166
181
  Generic TeleSign REST API GET handler.
167
182
 
168
183
  :param resource: The partial resource URI to perform the request against, as a string.
169
- :param params: Body params to perform the GET request with, as a dictionary.
184
+ :param body: (optional) A dictionary sent as a part of request body.
185
+ :param query_params: query_params to perform the GET request with, as a dictionary.
170
186
  :return: The RestClient Response object.
171
187
  """
172
- return self._execute(self.session.get, 'GET', resource, **params)
188
+ return self._execute(self.session.get, 'GET', resource, body, json_fields, **query_params)
173
189
 
174
- def put(self, resource, **params):
190
+ def put(self, resource, body=None, json_fields=None, **query_params):
175
191
  """
176
192
  Generic TeleSign REST API PUT handler.
177
193
 
178
194
  :param resource: The partial resource URI to perform the request against, as a string.
179
- :param params: Body params to perform the PUT request with, as a dictionary.
195
+ :param body: (optional) A dictionary sent as a part of request body.
196
+ :param query_params: query_params to perform the PUT request with, as a dictionary.
180
197
  :return: The RestClient Response object.
181
198
  """
182
- return self._execute(self.session.put, 'PUT', resource, **params)
199
+ return self._execute(self.session.put, 'PUT', resource, body, json_fields, **query_params)
183
200
 
184
- def delete(self, resource, **params):
201
+ def delete(self, resource, body=None, json_fields=None, **query_params):
185
202
  """
186
203
  Generic TeleSign REST API DELETE handler.
187
204
 
188
205
  :param resource: The partial resource URI to perform the request against, as a string.
189
- :param params: Body params to perform the DELETE request with, as a dictionary.
206
+ :param body: (optional) A dictionary sent as a part of request body.
207
+ :param query_params: query_params to perform the DELETE request with, as a dictionary.
190
208
  :return: The RestClient Response object.
191
209
  """
192
- return self._execute(self.session.delete, 'DELETE', resource, **params)
210
+ return self._execute(self.session.delete, 'DELETE', resource, body, json_fields, **query_params)
193
211
 
194
- def _execute(self, method_function, method_name, resource, **params):
212
+ def _execute(self, method_function, method_name, resource, body=None, json_fields=None, **query_params):
195
213
  """
196
214
  Generic TeleSign REST API request handler.
197
215
 
198
216
  :param method_function: The Requests HTTP request function to perform the request.
199
217
  :param method_name: The HTTP method name, as an upper case string.
200
218
  :param resource: The partial resource URI to perform the request against, as a string.
201
- :param params: Body params to perform the HTTP request with, as a dictionary.
219
+ :param body: (optional) A dictionary sent as a part of request body.
220
+ :param query_params: query_params to perform the HTTP request with, as a dictionary.
202
221
  :return: The RestClient Response object.
203
222
  """
204
223
  resource_uri = "{api_host}{resource}".format(api_host=self.api_host, resource=resource)
205
224
 
206
- url_encoded_fields = self._encode_params(params)
225
+ url_encoded_fields = self._encode_params(query_params)
226
+ if json_fields:
227
+ fields = json.dumps(json_fields)
228
+ url_encoded_fields = fields
229
+
230
+ if body or json_fields:
231
+ content_type = "application/json"
232
+ else:
233
+ content_type = None # set later
207
234
 
208
235
  headers = RestClient.generate_telesign_headers(self.customer_id,
209
236
  self.api_key,
210
237
  method_name,
211
238
  resource,
212
239
  url_encoded_fields,
213
- user_agent=self.user_agent)
214
-
240
+ user_agent=self.user_agent,
241
+ content_type=content_type,
242
+ auth_method=self.auth_method)
215
243
  if method_name in ['POST', 'PUT']:
216
- payload = {'data': url_encoded_fields}
244
+ payload = {}
245
+ if body:
246
+ payload['json'] = body
247
+ if query_params:
248
+ payload['data'] = url_encoded_fields
249
+ if json_fields:
250
+ payload = {'data': url_encoded_fields}
217
251
  else:
218
252
  payload = {'params': url_encoded_fields}
219
253
 
@@ -4,6 +4,7 @@ from hmac import HMAC
4
4
  from base64 import b64decode, b64encode
5
5
  from hashlib import sha256
6
6
  from random import SystemRandom
7
+ from enum import Enum
7
8
 
8
9
 
9
10
  def to_utc_rfc3339(a_datetime):
@@ -40,3 +41,8 @@ def verify_telesign_callback_signature(api_key, signature, json_str):
40
41
  signatures_equal = False
41
42
 
42
43
  return signatures_equal
44
+
45
+
46
+ class AuthMethod(Enum):
47
+ BASIC = "Basic"
48
+ HMAC_SHA256 = "HMAC-SHA256"
@@ -1,25 +1,25 @@
1
1
  Metadata-Version: 1.1
2
2
  Name: telesign
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: TeleSign SDK
5
5
  Home-page: https://github.com/telesign/python_telesign
6
6
  Author: TeleSign Corp.
7
7
  Author-email: support@telesign.com
8
8
  License: MIT
9
9
  Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/python_banner.jpg
10
- :target: https://developer.telesign.com
10
+ :target: https://standard.telesign.com
11
11
 
12
12
  .. image:: https://img.shields.io/travis/TeleSign/python_telesign.svg
13
- :target: https://travis-ci.org/TeleSign/python_telesign
13
+ :target: https://travis-ci.org/TeleSign/python_telesign
14
14
 
15
15
  .. image:: https://img.shields.io/codecov/c/github/TeleSign/python_telesign.svg
16
- :target: https://codecov.io/gh/TeleSign/python_telesign
16
+ :target: https://codecov.io/gh/TeleSign/python_telesign
17
17
 
18
18
  .. image:: https://img.shields.io/pypi/v/telesign.svg
19
- :target: https://pypi.python.org/pypi/telesign
19
+ :target: https://pypi.python.org/pypi/telesign
20
20
 
21
21
  .. image:: https://img.shields.io/pypi/l/telesign.svg
22
- :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
22
+ :target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
23
23
 
24
24
  ===================
25
25
  TeleSign Python SDK
@@ -36,7 +36,7 @@ Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/p
36
36
  -------------
37
37
 
38
38
  Code documentation is included in the SDK. Complete documentation, quick start guides and reference material
39
- for the TeleSign API is available within the `TeleSign Developer Center <https://developer.telesign.com/>`_.
39
+ for the TeleSign API is available within the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
40
40
 
41
41
  Installation
42
42
  ------------
@@ -88,14 +88,14 @@ Description: .. image:: https://raw.github.com/TeleSign/python_telesign/master/p
88
88
  print(response.json)
89
89
 
90
90
  .. code-block:: javascript
91
-
91
+
92
92
  {'reference_id': 'DGFDF6E11AB86303ASDFD425BE00000657',
93
93
  'status': {'code': 103,
94
94
  'description': 'Call in progress',
95
95
  'updated_on': '2016-12-12T00:39:58.325559Z'}}
96
96
 
97
97
  For more examples, see the `examples <https://github.com/TeleSign/python_telesign/tree/master/examples>`_ folder or
98
- visit the `TeleSign Developer Center <https://developer.telesign.com/>`_.
98
+ visit the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
99
99
 
100
100
  Keywords: telesign,sms,voice,mobile,authentication,identity,messaging
101
101
  Platform: UNKNOWN
@@ -4,6 +4,7 @@ README.rst
4
4
  setup.cfg
5
5
  setup.py
6
6
  examples/appverify/1_get_status_by_external_id.py
7
+ examples/intelligence/1_get_risk_score_and_related_insights.py
7
8
  examples/messaging/1_send_message.py
8
9
  examples/messaging/2_send_message_with_verification_code.py
9
10
  examples/phoneid/1_check_phone_type_to_block_voip.py
@@ -14,6 +15,7 @@ examples/voice/2_send_voice_call_with_verification_code.py
14
15
  examples/voice/3_send_voice_call_french.py
15
16
  telesign/__init__.py
16
17
  telesign/appverify.py
18
+ telesign/intelligence.py
17
19
  telesign/messaging.py
18
20
  telesign/phoneid.py
19
21
  telesign/rest.py
@@ -26,5 +28,6 @@ telesign.egg-info/dependency_links.txt
26
28
  telesign.egg-info/requires.txt
27
29
  telesign.egg-info/top_level.txt
28
30
  tests/__init__.py
31
+ tests/test_phoneid.py
29
32
  tests/test_rest.py
30
33
  tests/test_util.py
@@ -0,0 +1,48 @@
1
+ from __future__ import unicode_literals
2
+ import os
3
+ from unittest import TestCase
4
+ from telesign.phoneid import PhoneIdClient
5
+
6
+ class TestPhoneId(TestCase):
7
+ def setUp(self):
8
+ self.customer_id = os.getenv('CUSTOMER_ID', 'FFFFFFFF-EEEE-DDDD-1234-AB1234567890')
9
+ self.api_key = os.getenv('API_KEY', 'EXAMPLE----TE8sTgg45yusumoN6BYsBVkh+yRJ5czgsnCehZaOYldPJdmFh6NeX8kunZ2zU1YWaUw/0wV6xfw==')
10
+ self.phone_number_test = "11234567890"
11
+
12
+ def test_phoneid_constructor(self):
13
+
14
+ client = PhoneIdClient(self.customer_id,
15
+ self.api_key)
16
+
17
+ self.assertEqual(client.customer_id, self.customer_id)
18
+ self.assertEqual(client.api_key, self.api_key)
19
+
20
+
21
+ def test_phoneid_pid_contact(self):
22
+
23
+ client = PhoneIdClient(self.customer_id, self.api_key)
24
+ content_type_expected = 'application/json'
25
+ status_code_expected = 200
26
+
27
+ payload = {
28
+ "addons": {
29
+ "contact": {}
30
+ },
31
+ "phone_number": self.phone_number_test
32
+ }
33
+
34
+ response = client.phoneid(**payload)
35
+
36
+ self.assertEqual(response.headers.get('Content-Type'), content_type_expected, "Content-Type args do not match expected")
37
+ self.assertEqual(response.status_code, status_code_expected, "Status code args do not match expected")
38
+
39
+ def test_phoneid_pid(self):
40
+
41
+ client = PhoneIdClient(self.customer_id, self.api_key)
42
+ content_type_expected = 'application/json'
43
+ status_code_expected = 200
44
+
45
+ response = client.phoneid(self.phone_number_test)
46
+
47
+ self.assertEqual(response.headers.get('Content-Type'), content_type_expected, "Content-Type args do not match expected")
48
+ self.assertEqual(response.status_code, status_code_expected, "Status code args do not match expected")
@@ -6,6 +6,7 @@ from unittest import TestCase
6
6
  from uuid import UUID
7
7
 
8
8
  from telesign.rest import RestClient
9
+ from telesign.util import AuthMethod
9
10
 
10
11
  if sys.version_info < (3, 3):
11
12
  from mock import Mock, patch
@@ -104,6 +105,29 @@ class TestRest(TestCase):
104
105
 
105
106
  self.assertEqual(expected_authorization_header, actual_headers['Authorization'])
106
107
 
108
+ def test_generate_telesign_headers_with_post_basic_authentication(self):
109
+ method_name = 'POST'
110
+ date_rfc2616 = 'Wed, 14 Dec 2016 18:20:12 GMT'
111
+ nonce = 'A1592C6F-E384-4CDB-BC42-C3AB970369E9'
112
+ resource = '/v1/resource'
113
+
114
+ expected_authorization_header = ('Basic RkZGRkZGRkYtRUVFRS1ERERELTEyMzQtQUIxMjM'
115
+ '0NTY3ODkwOkVYQU1QTEUtLS0tVEU4c1RnZzQ1eXVzdW1vTjZCWXNCVmto'
116
+ 'K3lSSjVjemdzbkNlaFphT1lsZFBKZG1GaDZOZVg4a3VuWjJ6VTFZV2FV'
117
+ 'dy8wd1Y2eGZ3PT0=')
118
+
119
+ actual_headers = RestClient.generate_telesign_headers(self.customer_id,
120
+ self.api_key,
121
+ method_name,
122
+ resource,
123
+ '',
124
+ date_rfc2616=date_rfc2616,
125
+ nonce=nonce,
126
+ user_agent='unit_test',
127
+ auth_method=AuthMethod.BASIC.value)
128
+
129
+ self.assertEqual(expected_authorization_header, actual_headers['Authorization'])
130
+
107
131
  def test_generate_telesign_headers_default_date_and_nonce(self):
108
132
  method_name = 'GET'
109
133
  resource = '/v1/resource'
@@ -144,6 +168,28 @@ class TestRest(TestCase):
144
168
  self.assertEqual(post_kwargs, expected_post_kwargs,
145
169
  "client.session.post.call_args kwargs do not match expected")
146
170
 
171
+ @patch('telesign.rest.RestClient.generate_telesign_headers', return_value={})
172
+ def test_post_body(self, mock_generate_telesign_headers):
173
+ test_host = 'https://test.com'
174
+ test_resource = '/test/resource'
175
+ test_params = {'test': '123_\u03ff_test'}
176
+
177
+ client = RestClient(self.customer_id, self.api_key, rest_endpoint=test_host)
178
+ client.session.post = Mock()
179
+
180
+ expected_post_args = (u'https://test.com/test/resource',)
181
+ expected_post_kwargs = {'headers': {}, 'json': test_params, 'timeout': client.timeout}
182
+
183
+ client.post(test_resource, body=test_params)
184
+
185
+ self.assertEqual(client.session.post.call_count, 1, "client.session.post not called")
186
+
187
+ post_args, post_kwargs = client.session.post.call_args
188
+ self.assertEqual(post_args, expected_post_args,
189
+ "client.session.post.call_args args do not match expected")
190
+ self.assertEqual(post_kwargs, expected_post_kwargs,
191
+ "client.session.post.call_args kwargs do not match expected")
192
+
147
193
  @patch('telesign.rest.RestClient.generate_telesign_headers', return_value={})
148
194
  def test_get(self, mock_generate_telesign_headers):
149
195
  test_host = 'https://test.com'
@@ -209,3 +255,25 @@ class TestRest(TestCase):
209
255
  "client.session.delete.call_args args do not match expected")
210
256
  self.assertEqual(delete_kwargs, expected_delete_kwargs,
211
257
  "client.session.delete.call_args kwargs do not match expected")
258
+
259
+ @patch('telesign.rest.RestClient.generate_telesign_headers', return_value={})
260
+ def test_post_basic_auth(self, mock_generate_telesign_headers):
261
+ test_host = 'https://test.com'
262
+ test_resource = '/test/resource'
263
+ test_params = {'test': '123_\u03ff_test'}
264
+
265
+ client = RestClient(self.customer_id, self.api_key, rest_endpoint=test_host, auth_method=AuthMethod.BASIC.value)
266
+ client.session.post = Mock()
267
+
268
+ expected_post_args = (u'https://test.com/test/resource',)
269
+ expected_post_kwargs = {'headers': {}, 'data': 'test=123_%CF%BF_test', 'timeout': client.timeout}
270
+
271
+ client.post(test_resource, **test_params)
272
+
273
+ self.assertEqual(client.session.post.call_count, 1, "client.session.post not called")
274
+
275
+ post_args, post_kwargs = client.session.post.call_args
276
+ self.assertEqual(post_args, expected_post_args,
277
+ "client.session.post.call_args args do not match expected")
278
+ self.assertEqual(post_kwargs, expected_post_kwargs,
279
+ "client.session.post.call_args kwargs do not match expected")
@@ -1,54 +0,0 @@
1
- from __future__ import unicode_literals
2
-
3
- import json
4
-
5
- from telesign.rest import RestClient
6
-
7
- PHONEID_RESOURCE = "/v1/phoneid/{phone_number}"
8
-
9
-
10
- class PhoneIdClient(RestClient):
11
- """
12
- A set of APIs that deliver deep phone number data attributes that help optimize the end user
13
- verification process and evaluate risk.
14
- """
15
-
16
- def __init__(self, customer_id, api_key, **kwargs):
17
- super(PhoneIdClient, self).__init__(customer_id, api_key, **kwargs)
18
-
19
- def phoneid(self, phone_number, **params):
20
- """
21
- The PhoneID API provides a cleansed phone number, phone type, and telecom carrier information to determine the
22
- best communication method - SMS or voice.
23
-
24
- See https://developer.telesign.com/docs/phoneid-api for detailed API documentation.
25
- """
26
- return self.post(PHONEID_RESOURCE.format(phone_number=phone_number),
27
- **params)
28
-
29
- def _execute(self, method_function, method_name, resource, **params):
30
- resource_uri = "{api_host}{resource}".format(api_host=self.api_host, resource=resource)
31
-
32
- json_fields = json.dumps(params)
33
-
34
- content_type = "application/json" if method_name in ("POST", "PUT") else ""
35
-
36
- headers = self.generate_telesign_headers(self.customer_id,
37
- self.api_key,
38
- method_name,
39
- resource,
40
- json_fields,
41
- user_agent=self.user_agent,
42
- content_type=content_type)
43
-
44
- if method_name in ['POST', 'PUT']:
45
- payload = {'data': json_fields}
46
- else:
47
- payload = {'params': json_fields}
48
-
49
- response = self.Response(method_function(resource_uri,
50
- headers=headers,
51
- timeout=self.timeout,
52
- **payload))
53
-
54
- return response
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes