telesign 2.2.3__py2.py3-none-any.whl
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.
- telesign/__init__.py +12 -0
- telesign/appverify.py +28 -0
- telesign/intelligence.py +39 -0
- telesign/messaging.py +37 -0
- telesign/phoneid.py +54 -0
- telesign/rest.py +253 -0
- telesign/score.py +25 -0
- telesign/util.py +48 -0
- telesign/voice.py +37 -0
- telesign-2.2.3.dist-info/LICENSE.txt +19 -0
- telesign-2.2.3.dist-info/METADATA +115 -0
- telesign-2.2.3.dist-info/RECORD +14 -0
- telesign-2.2.3.dist-info/WHEEL +6 -0
- telesign-2.2.3.dist-info/top_level.txt +1 -0
telesign/__init__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pkg_resources import get_distribution
|
|
2
|
+
|
|
3
|
+
__import__('pkg_resources').declare_namespace(__name__)
|
|
4
|
+
|
|
5
|
+
__version__ = get_distribution("telesign").version
|
|
6
|
+
__author__ = "TeleSign"
|
|
7
|
+
__copyright__ = "Copyright 2017, TeleSign Corp."
|
|
8
|
+
__credits__ = ["TeleSign"]
|
|
9
|
+
__license__ = "MIT"
|
|
10
|
+
__maintainer__ = "TeleSign Corp."
|
|
11
|
+
__email__ = "support@telesign.com"
|
|
12
|
+
__status__ = "Production"
|
telesign/appverify.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
from telesign.rest import RestClient
|
|
4
|
+
|
|
5
|
+
APPVERIFY_STATUS_RESOURCE = "/v1/mobile/verification/status/{external_id}"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AppVerifyClient(RestClient):
|
|
9
|
+
"""
|
|
10
|
+
App Verify is a secure, lightweight SDK that integrates a frictionless user verification process into existing
|
|
11
|
+
native mobile applications.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, customer_id, api_key, **kwargs):
|
|
15
|
+
super(AppVerifyClient, self).__init__(customer_id, api_key, **kwargs)
|
|
16
|
+
|
|
17
|
+
def status(self, external_id, **params):
|
|
18
|
+
"""
|
|
19
|
+
Retrieves the verification result for an App Verify transaction by external_id. To ensure a secure verification
|
|
20
|
+
flow you must check the status using TeleSign's servers on your backend. Do not rely on the SDK alone to
|
|
21
|
+
indicate a successful verification.
|
|
22
|
+
|
|
23
|
+
See https://developer.telesign.com/docs/app-verify-android-sdk-self#section-get-status-service or
|
|
24
|
+
https://developer.telesign.com/docs/app-verify-ios-sdk-self#section-get-status-service for detailed
|
|
25
|
+
API documentation.
|
|
26
|
+
"""
|
|
27
|
+
return self.get(APPVERIFY_STATUS_RESOURCE.format(external_id=external_id),
|
|
28
|
+
**params)
|
telesign/intelligence.py
ADDED
|
@@ -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)
|
telesign/messaging.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
from telesign.rest import RestClient
|
|
4
|
+
|
|
5
|
+
MESSAGING_RESOURCE = "/v1/messaging"
|
|
6
|
+
MESSAGING_STATUS_RESOURCE = "/v1/messaging/{reference_id}"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MessagingClient(RestClient):
|
|
10
|
+
"""
|
|
11
|
+
TeleSign's Messaging API allows you to easily send SMS messages. You can send alerts, reminders, and notifications,
|
|
12
|
+
or you can send verification messages containing one-time passcodes (OTP).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, customer_id, api_key, **kwargs):
|
|
16
|
+
super(MessagingClient, self).__init__(customer_id, api_key, **kwargs)
|
|
17
|
+
|
|
18
|
+
def message(self, phone_number, message, message_type, **params):
|
|
19
|
+
"""
|
|
20
|
+
Send a message to the target phone_number.
|
|
21
|
+
|
|
22
|
+
See https://developer.telesign.com/docs/messaging-api for detailed API documentation.
|
|
23
|
+
"""
|
|
24
|
+
return self.post(MESSAGING_RESOURCE,
|
|
25
|
+
phone_number=phone_number,
|
|
26
|
+
message=message,
|
|
27
|
+
message_type=message_type,
|
|
28
|
+
**params)
|
|
29
|
+
|
|
30
|
+
def status(self, reference_id, **params):
|
|
31
|
+
"""
|
|
32
|
+
Retrieves the current status of the message.
|
|
33
|
+
|
|
34
|
+
See https://developer.telesign.com/docs/messaging-api for detailed API documentation.
|
|
35
|
+
"""
|
|
36
|
+
return self.get(MESSAGING_STATUS_RESOURCE.format(reference_id=reference_id),
|
|
37
|
+
**params)
|
telesign/phoneid.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
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
|
telesign/rest.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
import hmac
|
|
4
|
+
import uuid
|
|
5
|
+
from base64 import b64encode, b64decode
|
|
6
|
+
from email.utils import formatdate
|
|
7
|
+
from hashlib import sha256
|
|
8
|
+
from platform import python_version
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
|
|
12
|
+
import telesign
|
|
13
|
+
from telesign.util import AuthMethod
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RestClient(requests.models.RequestEncodingMixin):
|
|
17
|
+
"""
|
|
18
|
+
The TeleSign RestClient is a generic HTTP REST client that can be extended to make requests against any of
|
|
19
|
+
TeleSign's REST API endpoints.
|
|
20
|
+
|
|
21
|
+
RequestEncodingMixin offers the function _encode_params for url encoding the body for use in string_to_sign outside
|
|
22
|
+
of a regular HTTP request.
|
|
23
|
+
|
|
24
|
+
See https://developer.telesign.com for detailed API documentation.
|
|
25
|
+
"""
|
|
26
|
+
user_agent = "TeleSignSDK/python-{sdk_version} Python/{python_version} Requests/{requests_version}".format(
|
|
27
|
+
sdk_version=telesign.__version__,
|
|
28
|
+
python_version=python_version(),
|
|
29
|
+
requests_version=requests.__version__)
|
|
30
|
+
|
|
31
|
+
class Response(object):
|
|
32
|
+
"""
|
|
33
|
+
A simple HTTP Response object to abstract the underlying Requests library response.
|
|
34
|
+
|
|
35
|
+
:param requests_response: A Requests response object.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, requests_response):
|
|
39
|
+
self.status_code = requests_response.status_code
|
|
40
|
+
self.headers = requests_response.headers
|
|
41
|
+
self.body = requests_response.text
|
|
42
|
+
self.ok = requests_response.ok
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
self.json = requests_response.json()
|
|
46
|
+
except (Exception, ValueError):
|
|
47
|
+
self.json = None
|
|
48
|
+
|
|
49
|
+
def __init__(self,
|
|
50
|
+
customer_id,
|
|
51
|
+
api_key,
|
|
52
|
+
rest_endpoint='https://rest-api.telesign.com',
|
|
53
|
+
proxies=None,
|
|
54
|
+
timeout=10,
|
|
55
|
+
auth_method=None):
|
|
56
|
+
"""
|
|
57
|
+
TeleSign RestClient useful for making generic RESTful requests against our API.
|
|
58
|
+
|
|
59
|
+
:param customer_id: Your customer_id string associated with your account.
|
|
60
|
+
:param api_key: Your api_key string associated with your account.
|
|
61
|
+
:param rest_endpoint: (optional) Override the default rest_endpoint to target another endpoint string.
|
|
62
|
+
:param proxies: (optional) Dictionary mapping protocol or protocol and hostname to the URL of the proxy.
|
|
63
|
+
:param timeout: (optional) How long to wait for the server to send data before giving up, as a float,
|
|
64
|
+
or as a (connect timeout, read timeout) tuple
|
|
65
|
+
"""
|
|
66
|
+
self.customer_id = customer_id
|
|
67
|
+
self.api_key = api_key
|
|
68
|
+
|
|
69
|
+
self.api_host = rest_endpoint
|
|
70
|
+
|
|
71
|
+
self.session = requests.Session()
|
|
72
|
+
|
|
73
|
+
self.session.proxies = proxies if proxies else {}
|
|
74
|
+
|
|
75
|
+
self.timeout = timeout
|
|
76
|
+
|
|
77
|
+
self.auth_method = auth_method
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def generate_telesign_headers(customer_id,
|
|
81
|
+
api_key,
|
|
82
|
+
method_name,
|
|
83
|
+
resource,
|
|
84
|
+
url_encoded_fields,
|
|
85
|
+
date_rfc2616=None,
|
|
86
|
+
nonce=None,
|
|
87
|
+
user_agent=None,
|
|
88
|
+
content_type=None,
|
|
89
|
+
auth_method=None):
|
|
90
|
+
"""
|
|
91
|
+
Generates the TeleSign REST API headers used to authenticate requests.
|
|
92
|
+
|
|
93
|
+
Creates the canonicalized string_to_sign and generates the HMAC signature. This is used to authenticate requests
|
|
94
|
+
against the TeleSign REST API.
|
|
95
|
+
|
|
96
|
+
See https://developer.telesign.com/docs/authentication for detailed API documentation.
|
|
97
|
+
|
|
98
|
+
:param customer_id: Your account customer_id.
|
|
99
|
+
:param api_key: Your account api_key.
|
|
100
|
+
:param method_name: The HTTP method name of the request as a upper case string, should be one of 'POST', 'GET',
|
|
101
|
+
'PUT' or 'DELETE'.
|
|
102
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
103
|
+
:param url_encoded_fields: HTTP body parameters to perform the HTTP request with, must be a urlencoded string.
|
|
104
|
+
:param date_rfc2616: The date and time of the request formatted in rfc 2616, as a string.
|
|
105
|
+
:param nonce: A unique cryptographic nonce for the request, as a string.
|
|
106
|
+
:param user_agent: (optional) User Agent associated with the request, as a string.
|
|
107
|
+
:param content_type: (optional) ContentType of the request, as a string.
|
|
108
|
+
:param auth_method: (optional) Authentication type ex: Basic, HMAC etc
|
|
109
|
+
:return: The TeleSign authentication headers.
|
|
110
|
+
"""
|
|
111
|
+
if date_rfc2616 is None:
|
|
112
|
+
date_rfc2616 = formatdate(usegmt=True)
|
|
113
|
+
|
|
114
|
+
if nonce is None:
|
|
115
|
+
nonce = str(uuid.uuid4())
|
|
116
|
+
|
|
117
|
+
if not content_type:
|
|
118
|
+
content_type = "application/x-www-form-urlencoded" if method_name in ("POST", "PUT") else ""
|
|
119
|
+
|
|
120
|
+
# Default auth_method is Digest if not explicitly specified
|
|
121
|
+
if auth_method == AuthMethod.BASIC.value:
|
|
122
|
+
usr_apikey = "{customer_id}:{api_key}".format(customer_id=customer_id,
|
|
123
|
+
api_key=api_key)
|
|
124
|
+
b64val = b64encode(usr_apikey.encode())
|
|
125
|
+
authorization = "{auth_method} {b64val}".format(auth_method=AuthMethod.BASIC.value,
|
|
126
|
+
b64val=b64val.decode())
|
|
127
|
+
else:
|
|
128
|
+
auth_method = AuthMethod.HMAC_SHA256.value
|
|
129
|
+
|
|
130
|
+
string_to_sign_builder = ["{method}".format(method=method_name)]
|
|
131
|
+
|
|
132
|
+
string_to_sign_builder.append("\n{content_type}".format(content_type=content_type))
|
|
133
|
+
|
|
134
|
+
string_to_sign_builder.append("\n{date}".format(date=date_rfc2616))
|
|
135
|
+
|
|
136
|
+
string_to_sign_builder.append("\nx-ts-auth-method:{auth_method}".format(auth_method=auth_method))
|
|
137
|
+
|
|
138
|
+
string_to_sign_builder.append("\nx-ts-nonce:{nonce}".format(nonce=nonce))
|
|
139
|
+
|
|
140
|
+
if content_type and url_encoded_fields:
|
|
141
|
+
string_to_sign_builder.append("\n{fields}".format(fields=url_encoded_fields))
|
|
142
|
+
|
|
143
|
+
string_to_sign_builder.append("\n{resource}".format(resource=resource))
|
|
144
|
+
|
|
145
|
+
string_to_sign = "".join(string_to_sign_builder)
|
|
146
|
+
|
|
147
|
+
signer = hmac.new(b64decode(api_key), string_to_sign.encode("utf-8"), sha256)
|
|
148
|
+
signature = b64encode(signer.digest()).decode("utf-8")
|
|
149
|
+
|
|
150
|
+
authorization = "TSA {customer_id}:{signature}".format(
|
|
151
|
+
customer_id=customer_id,
|
|
152
|
+
signature=signature)
|
|
153
|
+
|
|
154
|
+
headers = {
|
|
155
|
+
"Authorization": authorization,
|
|
156
|
+
"Date": date_rfc2616,
|
|
157
|
+
"Content-Type": content_type,
|
|
158
|
+
"x-ts-auth-method": auth_method,
|
|
159
|
+
"x-ts-nonce": nonce
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if user_agent:
|
|
163
|
+
headers['User-Agent'] = user_agent
|
|
164
|
+
|
|
165
|
+
return headers
|
|
166
|
+
|
|
167
|
+
def post(self, resource, body=None, **query_params):
|
|
168
|
+
"""
|
|
169
|
+
Generic TeleSign REST API POST handler.
|
|
170
|
+
|
|
171
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
172
|
+
:param body: (optional) A dictionary sent as a part of request body.
|
|
173
|
+
:param query_params: query_params to perform the POST request with, as a dictionary.
|
|
174
|
+
:return: The RestClient Response object.
|
|
175
|
+
"""
|
|
176
|
+
return self._execute(self.session.post, 'POST', resource, body, **query_params)
|
|
177
|
+
|
|
178
|
+
def get(self, resource, body=None, **query_params):
|
|
179
|
+
"""
|
|
180
|
+
Generic TeleSign REST API GET handler.
|
|
181
|
+
|
|
182
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
183
|
+
:param body: (optional) A dictionary sent as a part of request body.
|
|
184
|
+
:param query_params: query_params to perform the GET request with, as a dictionary.
|
|
185
|
+
:return: The RestClient Response object.
|
|
186
|
+
"""
|
|
187
|
+
return self._execute(self.session.get, 'GET', resource, body, **query_params)
|
|
188
|
+
|
|
189
|
+
def put(self, resource, body=None, **query_params):
|
|
190
|
+
"""
|
|
191
|
+
Generic TeleSign REST API PUT handler.
|
|
192
|
+
|
|
193
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
194
|
+
:param body: (optional) A dictionary sent as a part of request body.
|
|
195
|
+
:param query_params: query_params to perform the PUT request with, as a dictionary.
|
|
196
|
+
:return: The RestClient Response object.
|
|
197
|
+
"""
|
|
198
|
+
return self._execute(self.session.put, 'PUT', resource, body, **query_params)
|
|
199
|
+
|
|
200
|
+
def delete(self, resource, body=None, **query_params):
|
|
201
|
+
"""
|
|
202
|
+
Generic TeleSign REST API DELETE handler.
|
|
203
|
+
|
|
204
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
205
|
+
:param body: (optional) A dictionary sent as a part of request body.
|
|
206
|
+
:param query_params: query_params to perform the DELETE request with, as a dictionary.
|
|
207
|
+
:return: The RestClient Response object.
|
|
208
|
+
"""
|
|
209
|
+
return self._execute(self.session.delete, 'DELETE', resource, body, **query_params)
|
|
210
|
+
|
|
211
|
+
def _execute(self, method_function, method_name, resource, body=None, **query_params):
|
|
212
|
+
"""
|
|
213
|
+
Generic TeleSign REST API request handler.
|
|
214
|
+
|
|
215
|
+
:param method_function: The Requests HTTP request function to perform the request.
|
|
216
|
+
:param method_name: The HTTP method name, as an upper case string.
|
|
217
|
+
:param resource: The partial resource URI to perform the request against, as a string.
|
|
218
|
+
:param body: (optional) A dictionary sent as a part of request body.
|
|
219
|
+
:param query_params: query_params to perform the HTTP request with, as a dictionary.
|
|
220
|
+
:return: The RestClient Response object.
|
|
221
|
+
"""
|
|
222
|
+
resource_uri = "{api_host}{resource}".format(api_host=self.api_host, resource=resource)
|
|
223
|
+
|
|
224
|
+
url_encoded_fields = self._encode_params(query_params)
|
|
225
|
+
if body:
|
|
226
|
+
content_type = "application/json"
|
|
227
|
+
else:
|
|
228
|
+
content_type = None # set later
|
|
229
|
+
|
|
230
|
+
headers = RestClient.generate_telesign_headers(self.customer_id,
|
|
231
|
+
self.api_key,
|
|
232
|
+
method_name,
|
|
233
|
+
resource,
|
|
234
|
+
url_encoded_fields,
|
|
235
|
+
user_agent=self.user_agent,
|
|
236
|
+
content_type=content_type,
|
|
237
|
+
auth_method=self.auth_method)
|
|
238
|
+
|
|
239
|
+
if method_name in ['POST', 'PUT']:
|
|
240
|
+
payload = {}
|
|
241
|
+
if body:
|
|
242
|
+
payload['json'] = body
|
|
243
|
+
if query_params:
|
|
244
|
+
payload['data'] = url_encoded_fields
|
|
245
|
+
else:
|
|
246
|
+
payload = {'params': url_encoded_fields}
|
|
247
|
+
|
|
248
|
+
response = self.Response(method_function(resource_uri,
|
|
249
|
+
headers=headers,
|
|
250
|
+
timeout=self.timeout,
|
|
251
|
+
**payload))
|
|
252
|
+
|
|
253
|
+
return response
|
telesign/score.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
from telesign.rest import RestClient
|
|
4
|
+
|
|
5
|
+
SCORE_RESOURCE = "/v1/score/{phone_number}"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ScoreClient(RestClient):
|
|
9
|
+
"""
|
|
10
|
+
Score provides risk information about a specified phone number.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, customer_id, api_key, **kwargs):
|
|
14
|
+
super(ScoreClient, self).__init__(customer_id, api_key, **kwargs)
|
|
15
|
+
|
|
16
|
+
def score(self, phone_number, account_lifecycle_event, **params):
|
|
17
|
+
"""
|
|
18
|
+
Score is an API that delivers reputation scoring based on phone number intelligence, traffic patterns, machine
|
|
19
|
+
learning, and a global data consortium.
|
|
20
|
+
|
|
21
|
+
See https://developer.telesign.com/docs/score-api for detailed API documentation.
|
|
22
|
+
"""
|
|
23
|
+
return self.post(SCORE_RESOURCE.format(phone_number=phone_number),
|
|
24
|
+
account_lifecycle_event=account_lifecycle_event,
|
|
25
|
+
**params)
|
telesign/util.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
from hmac import HMAC
|
|
4
|
+
from base64 import b64decode, b64encode
|
|
5
|
+
from hashlib import sha256
|
|
6
|
+
from random import SystemRandom
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def to_utc_rfc3339(a_datetime):
|
|
11
|
+
"""
|
|
12
|
+
Helper function to format a timezone unaware/UTC datetime in rfc3339 utc timestamp the easy way.
|
|
13
|
+
"""
|
|
14
|
+
return "{date_string}Z".format(date_string=a_datetime.replace(microsecond=0).isoformat())
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def random_with_n_digits(n):
|
|
18
|
+
"""
|
|
19
|
+
Helper function to generate a random number n digits in length using a system random.
|
|
20
|
+
"""
|
|
21
|
+
return "".join(SystemRandom().choice('123456789') for _ in range(n))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def verify_telesign_callback_signature(api_key, signature, json_str):
|
|
25
|
+
"""
|
|
26
|
+
Verify that a callback was made by TeleSign and was not sent by a malicious client by verifying the signature.
|
|
27
|
+
|
|
28
|
+
:param api_key: the TeleSign API api_key associated with your account.
|
|
29
|
+
:param signature: the TeleSign Authorization header value supplied in the callback, as a string.
|
|
30
|
+
:param json_str: the POST body text, that is, the JSON string sent by TeleSign describing the transaction status.
|
|
31
|
+
"""
|
|
32
|
+
your_signature = b64encode(HMAC(b64decode(api_key), json_str.encode("utf-8"), sha256).digest()).decode("utf-8")
|
|
33
|
+
|
|
34
|
+
if len(signature) != len(your_signature):
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
# avoid timing attack with constant time equality check
|
|
38
|
+
signatures_equal = True
|
|
39
|
+
for x, y in zip(signature, your_signature):
|
|
40
|
+
if not x == y:
|
|
41
|
+
signatures_equal = False
|
|
42
|
+
|
|
43
|
+
return signatures_equal
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class AuthMethod(Enum):
|
|
47
|
+
BASIC = "Basic"
|
|
48
|
+
HMAC_SHA256 = "HMAC-SHA256"
|
telesign/voice.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import unicode_literals
|
|
2
|
+
|
|
3
|
+
from telesign.rest import RestClient
|
|
4
|
+
|
|
5
|
+
VOICE_RESOURCE = "/v1/voice"
|
|
6
|
+
VOICE_STATUS_RESOURCE = "/v1/voice/{reference_id}"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class VoiceClient(RestClient):
|
|
10
|
+
"""
|
|
11
|
+
TeleSign's Voice API allows you to easily send voice messages. You can send alerts, reminders, and notifications,
|
|
12
|
+
or you can send verification messages containing time-based, one-time passcodes (TOTP).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, customer_id, api_key, **kwargs):
|
|
16
|
+
super(VoiceClient, self).__init__(customer_id, api_key, **kwargs)
|
|
17
|
+
|
|
18
|
+
def call(self, phone_number, message, message_type, **params):
|
|
19
|
+
"""
|
|
20
|
+
Send a voice call to the target phone_number.
|
|
21
|
+
|
|
22
|
+
See https://developer.telesign.com/docs/voice-api for detailed API documentation.
|
|
23
|
+
"""
|
|
24
|
+
return self.post(VOICE_RESOURCE,
|
|
25
|
+
phone_number=phone_number,
|
|
26
|
+
message=message,
|
|
27
|
+
message_type=message_type,
|
|
28
|
+
**params)
|
|
29
|
+
|
|
30
|
+
def status(self, reference_id, **params):
|
|
31
|
+
"""
|
|
32
|
+
Retrieves the current status of the voice call.
|
|
33
|
+
|
|
34
|
+
See https://developer.telesign.com/docs/voice-api for detailed API documentation.
|
|
35
|
+
"""
|
|
36
|
+
return self.get(VOICE_STATUS_RESOURCE.format(reference_id=reference_id),
|
|
37
|
+
**params)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2023 Telesign Corp.
|
|
2
|
+
|
|
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
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: telesign
|
|
3
|
+
Version: 2.2.3
|
|
4
|
+
Summary: TeleSign SDK
|
|
5
|
+
Home-page: https://github.com/telesign/python_telesign
|
|
6
|
+
Author: TeleSign Corp.
|
|
7
|
+
Author-email: support@telesign.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: telesign,sms,voice,mobile,authentication,identity,messaging
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 2
|
|
16
|
+
Classifier: Programming Language :: Python :: 2.6
|
|
17
|
+
Classifier: Programming Language :: Python :: 2.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.4
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.5
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
23
|
+
License-File: LICENSE.txt
|
|
24
|
+
Requires-Dist: requests
|
|
25
|
+
|
|
26
|
+
.. image:: https://raw.github.com/TeleSign/python_telesign/master/python_banner.jpg
|
|
27
|
+
:target: https://standard.telesign.com
|
|
28
|
+
|
|
29
|
+
.. image:: https://img.shields.io/travis/TeleSign/python_telesign.svg
|
|
30
|
+
:target: https://travis-ci.org/TeleSign/python_telesign
|
|
31
|
+
|
|
32
|
+
.. image:: https://img.shields.io/codecov/c/github/TeleSign/python_telesign.svg
|
|
33
|
+
:target: https://codecov.io/gh/TeleSign/python_telesign
|
|
34
|
+
|
|
35
|
+
.. image:: https://img.shields.io/pypi/v/telesign.svg
|
|
36
|
+
:target: https://pypi.python.org/pypi/telesign
|
|
37
|
+
|
|
38
|
+
.. image:: https://img.shields.io/pypi/l/telesign.svg
|
|
39
|
+
:target: https://github.com/TeleSign/python_telesign/blob/master/LICENSE
|
|
40
|
+
|
|
41
|
+
===================
|
|
42
|
+
TeleSign Python SDK
|
|
43
|
+
===================
|
|
44
|
+
|
|
45
|
+
TeleSign is a communications platform as a service (CPaaS) company, founded on security. Since 2005, TeleSign has
|
|
46
|
+
been a trusted partner to the world’s leading websites and mobile applications, helping secure billions of end-user
|
|
47
|
+
accounts. Today, TeleSign’s data-driven, cloud communications platform is changing the way businesses engage with
|
|
48
|
+
customers and prevent fraud.
|
|
49
|
+
|
|
50
|
+
For more information about TeleSign, visit our `website <http://www.TeleSign.com>`_.
|
|
51
|
+
|
|
52
|
+
Documentation
|
|
53
|
+
-------------
|
|
54
|
+
|
|
55
|
+
Code documentation is included in the SDK. Complete documentation, quick start guides and reference material
|
|
56
|
+
for the TeleSign API is available within the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
|
|
57
|
+
|
|
58
|
+
Installation
|
|
59
|
+
------------
|
|
60
|
+
|
|
61
|
+
To install the TeleSign Python SDK:
|
|
62
|
+
|
|
63
|
+
.. code-block:: bash
|
|
64
|
+
|
|
65
|
+
$ pip install telesign
|
|
66
|
+
|
|
67
|
+
Python **2.7+** is required for the TeleSign Python SDK.
|
|
68
|
+
|
|
69
|
+
Authentication
|
|
70
|
+
--------------
|
|
71
|
+
|
|
72
|
+
You will need a Customer ID and API Key in order to use TeleSign’s API. If you already have an account you can retrieve
|
|
73
|
+
them from your account dashboard within the `Portal <https://portal.telesign.com/login>`_. If you have not signed up
|
|
74
|
+
yet, sign up `here <https://portal.telesign.com/signup>`_.
|
|
75
|
+
|
|
76
|
+
Dependencies
|
|
77
|
+
------------
|
|
78
|
+
|
|
79
|
+
We make use of popular, feature-rich and well-tested open-source libraries to perform the underlying functionality of
|
|
80
|
+
the SDK. These dependencies are managed by the community accepted package manager. If you are unable to add these
|
|
81
|
+
additional third party dependencies to your project we have ensured that the SDK code is easy to read and can serve as
|
|
82
|
+
sample code. We have also made sure that more complicated functions such as generate_telesign_headers can be easily
|
|
83
|
+
extracted from the SDK and used 'as is' in your project.
|
|
84
|
+
|
|
85
|
+
Python Code Example: Messaging
|
|
86
|
+
------------------------------
|
|
87
|
+
|
|
88
|
+
Here is a basic code example with the JSON response.
|
|
89
|
+
|
|
90
|
+
.. code-block:: python
|
|
91
|
+
|
|
92
|
+
from __future__ import print_function
|
|
93
|
+
from telesign.messaging import MessagingClient
|
|
94
|
+
|
|
95
|
+
customer_id = "FFFFFFFF-EEEE-DDDD-1234-AB1234567890"
|
|
96
|
+
api_key = "EXAMPLE----TE8sTgg45yusumoN6BYsBVkh+yRJ5czgsnCehZaOYldPJdmFh6NeX8kunZ2zU1YWaUw/0wV6xfw=="
|
|
97
|
+
|
|
98
|
+
phone_number = "phone_number"
|
|
99
|
+
message = "You're scheduled for a dentist appointment at 2:30PM."
|
|
100
|
+
message_type = "ARN"
|
|
101
|
+
|
|
102
|
+
messaging_client = MessagingClient(customer_id, api_key)
|
|
103
|
+
response = messaging_client.message(phone_number, message, message_type)
|
|
104
|
+
|
|
105
|
+
print(response.json)
|
|
106
|
+
|
|
107
|
+
.. code-block:: javascript
|
|
108
|
+
|
|
109
|
+
{'reference_id': 'DGFDF6E11AB86303ASDFD425BE00000657',
|
|
110
|
+
'status': {'code': 103,
|
|
111
|
+
'description': 'Call in progress',
|
|
112
|
+
'updated_on': '2016-12-12T00:39:58.325559Z'}}
|
|
113
|
+
|
|
114
|
+
For more examples, see the `examples <https://github.com/TeleSign/python_telesign/tree/master/examples>`_ folder or
|
|
115
|
+
visit the `TeleSign Standard Documentation <https://standard.telesign.com/>`_.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
telesign/__init__.py,sha256=D8kANX0FKxBD7-a7xQ21xPz3ojM2WAOK8lThGLtDZuE,367
|
|
2
|
+
telesign/appverify.py,sha256=wBeaeUxGmYcZkrbxkkXlG3-0oZr5sVvegzVpdvaoO2A,1195
|
|
3
|
+
telesign/intelligence.py,sha256=t-xwlgxkXw1OMupF5K4_UKWeTArOr9XPvddmqgZftPI,1452
|
|
4
|
+
telesign/messaging.py,sha256=v7l-eKUPqz7Nrwka0YNPMkC2TaoFUvQm3yp_djuTPu0,1367
|
|
5
|
+
telesign/phoneid.py,sha256=czEVgjDmbbWgDGanqclNhlmAYkD1jLYhEOXQs7M9F88,2111
|
|
6
|
+
telesign/rest.py,sha256=BtiRi0dc5h4OiWapdsfSBvLLwXB5swrwiACT7R-UAkc,11058
|
|
7
|
+
telesign/score.py,sha256=Kceu6IrirN9SsuT1geEWs0QHAn6H9ZNFyIDVHcBJdwg,908
|
|
8
|
+
telesign/util.py,sha256=stDxpL5ZQeGskE_OSGP04UFHs3ZP2ACaRpW1WyQGMHg,1624
|
|
9
|
+
telesign/voice.py,sha256=DJaWyQpun-T7LfNjpxpsUjupiv2ShW1jqoFQA-CE2-Y,1341
|
|
10
|
+
telesign-2.2.3.dist-info/LICENSE.txt,sha256=a--xZ4PCKUL5rpct8RrUC6ODU_8ZKIU51kJPfsA4HUs,1058
|
|
11
|
+
telesign-2.2.3.dist-info/METADATA,sha256=0XcO1v2ZEwFJt2yzWdUH_L6tc7zAXLJeRxZQ3WieMF0,4545
|
|
12
|
+
telesign-2.2.3.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
13
|
+
telesign-2.2.3.dist-info/top_level.txt,sha256=6LG7Jcr1jnpVhOWaIShoTdwYJn0QCfPhfudyVJNz1qg,9
|
|
14
|
+
telesign-2.2.3.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
telesign
|