customerio 2.1__tar.gz → 2.2__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.
- {customerio-2.1/customerio.egg-info → customerio-2.2}/PKG-INFO +1 -5
- {customerio-2.1 → customerio-2.2}/README.md +16 -16
- {customerio-2.1 → customerio-2.2}/customerio/__init__.py +1 -1
- {customerio-2.1 → customerio-2.2}/customerio/__version__.py +1 -1
- {customerio-2.1 → customerio-2.2}/customerio/api.py +53 -0
- {customerio-2.1 → customerio-2.2/customerio.egg-info}/PKG-INFO +1 -5
- {customerio-2.1 → customerio-2.2}/tests/server.py +9 -12
- {customerio-2.1 → customerio-2.2}/tests/test_api.py +17 -1
- {customerio-2.1 → customerio-2.2}/AUTHORS +0 -0
- {customerio-2.1 → customerio-2.2}/LICENSE +0 -0
- {customerio-2.1 → customerio-2.2}/customerio/client_base.py +0 -0
- {customerio-2.1 → customerio-2.2}/customerio/constants.py +0 -0
- {customerio-2.1 → customerio-2.2}/customerio/regions.py +0 -0
- {customerio-2.1 → customerio-2.2}/customerio/track.py +0 -0
- {customerio-2.1 → customerio-2.2}/customerio.egg-info/SOURCES.txt +0 -0
- {customerio-2.1 → customerio-2.2}/customerio.egg-info/dependency_links.txt +0 -0
- {customerio-2.1 → customerio-2.2}/customerio.egg-info/requires.txt +0 -0
- {customerio-2.1 → customerio-2.2}/customerio.egg-info/top_level.txt +0 -0
- {customerio-2.1 → customerio-2.2}/setup.cfg +0 -0
- {customerio-2.1 → customerio-2.2}/setup.py +0 -0
- {customerio-2.1 → customerio-2.2}/tests/__init__.py +0 -0
- {customerio-2.1 → customerio-2.2}/tests/test_customerio.py +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: customerio
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2
|
|
4
4
|
Summary: Customer.io Python bindings.
|
|
5
5
|
Home-page: https://github.com/customerio/customerio-python
|
|
6
6
|
Author: Peaberry Software Inc.
|
|
7
7
|
Author-email: support@customerio.com
|
|
8
8
|
License: BSD
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Classifier: Environment :: Web Environment
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: License :: OSI Approved :: BSD License
|
|
@@ -18,6 +17,3 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
License-File: LICENSE
|
|
20
19
|
License-File: AUTHORS
|
|
21
|
-
|
|
22
|
-
UNKNOWN
|
|
23
|
-
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
<p align=
|
|
1
|
+
<p align=center>
|
|
2
2
|
<a href="https://customer.io">
|
|
3
|
-
<img src="https://
|
|
3
|
+
<img src="https://avatars.githubusercontent.com/u/1152079?s=200&v=4" height="60">
|
|
4
4
|
</a>
|
|
5
|
-
<p align="center">Power automated communication that people like to receive.</p>
|
|
6
5
|
</p>
|
|
7
6
|
|
|
8
7
|
[](https://gitpod.io/#https://github.com/customerio/customerio-python/)
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
|
|
15
14
|
# Customer.io Python
|
|
16
15
|
|
|
17
|
-
This module has been tested with Python 3.6, 3.7, 3.8 and 3.9.
|
|
16
|
+
This module has been tested with Python 3.6, 3.7, 3.8 and 3.9. If you're new to Customer.io, we recommend that you integrate with our [Data Pipelines Python library](https://github.com/customerio/cdp-analytics-python) instead.
|
|
18
17
|
|
|
19
18
|
## Installing
|
|
20
19
|
|
|
@@ -54,7 +53,7 @@ values for that field.
|
|
|
54
53
|
|
|
55
54
|
You can pass any keyword arguments to the `identify` and `track` methods. These kwargs will be converted to custom attributes.
|
|
56
55
|
|
|
57
|
-
See original REST documentation [here](http://customer.io/docs/api/
|
|
56
|
+
See original REST documentation [here](http://customer.io/docs/api/track/#operation/identify)
|
|
58
57
|
|
|
59
58
|
### Track a custom event
|
|
60
59
|
|
|
@@ -70,7 +69,7 @@ cio.track(customer_id="5", name='purchased', price=23.45, product="widget")
|
|
|
70
69
|
|
|
71
70
|
You can pass any keyword arguments to the `identify` and `track` methods. These kwargs will be converted to custom attributes.
|
|
72
71
|
|
|
73
|
-
See original REST documentation [here](http://customer.io/docs/api/
|
|
72
|
+
See original REST documentation [here](http://customer.io/docs/api/track/#operation/track)
|
|
74
73
|
|
|
75
74
|
### Backfill a custom event
|
|
76
75
|
|
|
@@ -95,7 +94,7 @@ Event timestamp may be passed as a ```datetime.datetime``` object, an integer or
|
|
|
95
94
|
|
|
96
95
|
Keyword arguments to backfill work the same as a call to ```cio.track```.
|
|
97
96
|
|
|
98
|
-
See original REST documentation [here](http://customer.io/docs/api/
|
|
97
|
+
See original REST documentation [here](http://customer.io/docs/api/track/#operation/track)
|
|
99
98
|
|
|
100
99
|
### Track an anonymous event
|
|
101
100
|
|
|
@@ -107,7 +106,7 @@ An anonymous event is an event associated with a person you haven't identified.
|
|
|
107
106
|
|
|
108
107
|
#### Anonymous invite events
|
|
109
108
|
|
|
110
|
-
If you previously sent [invite events](https://customer.io/docs/anonymous-invite-emails/), you can achieve the same functionality by sending an anonymous event with the anonymous identifier set to `None`. To send anonymous invites, your event *must* include a `recipient` attribute.
|
|
109
|
+
If you previously sent [invite events](https://customer.io/docs/journeys/anonymous-invite-emails/), you can achieve the same functionality by sending an anonymous event with the anonymous identifier set to `None`. To send anonymous invites, your event *must* include a `recipient` attribute.
|
|
111
110
|
|
|
112
111
|
```python
|
|
113
112
|
cio.track_anonymous(anonymous_id=None, name="invite", first_name="alex", recipient="alex.person@example.com")
|
|
@@ -122,7 +121,7 @@ Deletes the customer profile for a specified customer.
|
|
|
122
121
|
|
|
123
122
|
This method returns nothing. Attempts to delete non-existent customers will not raise any errors.
|
|
124
123
|
|
|
125
|
-
See original REST documentation [here](
|
|
124
|
+
See original REST documentation [here](https://customer.io/docs/api/track/#operation/delete)
|
|
126
125
|
|
|
127
126
|
|
|
128
127
|
You can pass any keyword arguments to the `identify` and `track` methods. These kwargs will be converted to custom attributes.
|
|
@@ -175,7 +174,7 @@ cio.suppress(customer_id="1")
|
|
|
175
174
|
|
|
176
175
|
Suppresses the specified customer. They will be deleted from Customer.io, and we will ignore all further attempts to identify or track activity for the suppressed customer ID
|
|
177
176
|
|
|
178
|
-
See REST documentation [here](https://
|
|
177
|
+
See REST documentation [here](https://customer.io/docs/api/track/#operation/suppress)
|
|
179
178
|
|
|
180
179
|
### Unsuppress a customer
|
|
181
180
|
```python
|
|
@@ -184,22 +183,22 @@ cio.unsuppress(customer_id="1")
|
|
|
184
183
|
|
|
185
184
|
Unsuppresses the specified customer. We will remove the supplied id from our suppression list and start accepting new identify and track calls for the customer as normal
|
|
186
185
|
|
|
187
|
-
See REST documentation [here](https://
|
|
186
|
+
See REST documentation [here](https://customer.io/docs/api/track/#operation/unsuppress)
|
|
188
187
|
|
|
189
188
|
### Send Transactional Messages
|
|
190
189
|
|
|
191
|
-
To use the [Transactional API](https://customer.io/docs/transactional-api), instantiate the Customer.io object using an [app key](https://customer.io/docs/managing-credentials#app-api-keys) and create a request object for your message type.
|
|
190
|
+
To use the [Transactional API](https://customer.io/docs/journeys/transactional-api), instantiate the Customer.io object using an [app key](https://customer.io/docs/managing-credentials#app-api-keys) and create a request object for your message type.
|
|
192
191
|
|
|
193
192
|
## Email
|
|
194
193
|
|
|
195
194
|
SendEmailRequest requires:
|
|
196
|
-
* `transactional_message_id`: the ID of the transactional message you want to send, or the `body`, `
|
|
195
|
+
* `transactional_message_id`: the ID of the transactional message you want to send, or the `body`, `_from`, and `subject` of a new message.
|
|
197
196
|
* `to`: the email address of your recipients
|
|
198
197
|
* an `identifiers` object containing the `id` of your recipient. If the `id` does not exist, Customer.io will create it.
|
|
199
198
|
* a `message_data` object containing properties that you want reference in your message using Liquid.
|
|
200
199
|
* You can also send attachments with your message. Use `attach` to encode attachments.
|
|
201
200
|
|
|
202
|
-
Use `send_email` referencing your request to send a transactional message. [Learn more about transactional messages and `SendEmailRequest` properties](https://customer.io/docs/transactional-api).
|
|
201
|
+
Use `send_email` referencing your request to send a transactional message. [Learn more about transactional messages and `SendEmailRequest` properties](https://customer.io/docs/journeys/transactional-api).
|
|
203
202
|
|
|
204
203
|
```python
|
|
205
204
|
from customerio import APIClient, Regions, SendEmailRequest
|
|
@@ -207,6 +206,7 @@ client = APIClient("your API key", region=Regions.US)
|
|
|
207
206
|
|
|
208
207
|
request = SendEmailRequest(
|
|
209
208
|
to="person@example.com",
|
|
209
|
+
_from="override.sender@example.com",
|
|
210
210
|
transactional_message_id="3",
|
|
211
211
|
message_data={
|
|
212
212
|
"name": "person",
|
|
@@ -222,7 +222,7 @@ request = SendEmailRequest(
|
|
|
222
222
|
}
|
|
223
223
|
)
|
|
224
224
|
|
|
225
|
-
with open("
|
|
225
|
+
with open("receipt.pdf", "rb") as f:
|
|
226
226
|
request.attach('receipt.pdf', f.read())
|
|
227
227
|
|
|
228
228
|
response = client.send_email(request)
|
|
@@ -235,7 +235,7 @@ SendPushRequest requires:
|
|
|
235
235
|
* `transactional_message_id`: the ID of the transactional push message you want to send.
|
|
236
236
|
* an `identifiers` object containing the `id` or `email` of your recipient. If the profile does not exist, Customer.io will create it.
|
|
237
237
|
|
|
238
|
-
Use `send_push` referencing your request to send a transactional message. [Learn more about transactional messages and `SendPushRequest` properties](https://customer.io/docs/transactional-api).
|
|
238
|
+
Use `send_push` referencing your request to send a transactional message. [Learn more about transactional messages and `SendPushRequest` properties](https://customer.io/docs/journeys/transactional-api).
|
|
239
239
|
|
|
240
240
|
```python
|
|
241
241
|
from customerio import APIClient, Regions, SendPushRequest
|
|
@@ -2,5 +2,5 @@ import warnings
|
|
|
2
2
|
|
|
3
3
|
from customerio.client_base import CustomerIOException
|
|
4
4
|
from customerio.track import CustomerIO
|
|
5
|
-
from customerio.api import APIClient, SendEmailRequest, SendPushRequest
|
|
5
|
+
from customerio.api import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest
|
|
6
6
|
from customerio.regions import Regions
|
|
@@ -27,6 +27,12 @@ class APIClient(ClientBase):
|
|
|
27
27
|
request = request._to_dict()
|
|
28
28
|
resp = self.send_request('POST', self.url + "/v1/send/push", request)
|
|
29
29
|
return json.loads(resp)
|
|
30
|
+
|
|
31
|
+
def send_sms(self, request):
|
|
32
|
+
if isinstance(request, SendSMSRequest):
|
|
33
|
+
request = request._to_dict()
|
|
34
|
+
resp = self.send_request('POST', self.url + "/v1/send/sms", request)
|
|
35
|
+
return json.loads(resp)
|
|
30
36
|
|
|
31
37
|
# builds the session.
|
|
32
38
|
def _build_session(self):
|
|
@@ -211,3 +217,50 @@ class SendPushRequest(object):
|
|
|
211
217
|
data[name] = value
|
|
212
218
|
|
|
213
219
|
return data
|
|
220
|
+
|
|
221
|
+
class SendSMSRequest(object):
|
|
222
|
+
'''An object with all the options avaiable for triggering a transactional push message'''
|
|
223
|
+
def __init__(self,
|
|
224
|
+
transactional_message_id=None,
|
|
225
|
+
to=None,
|
|
226
|
+
identifiers=None,
|
|
227
|
+
disable_message_retention=None,
|
|
228
|
+
send_to_unsubscribed=None,
|
|
229
|
+
queue_draft=None,
|
|
230
|
+
message_data=None,
|
|
231
|
+
send_at=None,
|
|
232
|
+
language=None,
|
|
233
|
+
):
|
|
234
|
+
|
|
235
|
+
self.transactional_message_id = transactional_message_id
|
|
236
|
+
self.to = to
|
|
237
|
+
self.identifiers = identifiers
|
|
238
|
+
self.disable_message_retention = disable_message_retention
|
|
239
|
+
self.send_to_unsubscribed = send_to_unsubscribed
|
|
240
|
+
self.queue_draft = queue_draft
|
|
241
|
+
self.message_data = message_data
|
|
242
|
+
self.send_at = send_at
|
|
243
|
+
self.language = language
|
|
244
|
+
|
|
245
|
+
def _to_dict(self):
|
|
246
|
+
'''Build a request payload from the object'''
|
|
247
|
+
field_map = dict(
|
|
248
|
+
# field name is the same as the payload field name
|
|
249
|
+
transactional_message_id="transactional_message_id",
|
|
250
|
+
to="to",
|
|
251
|
+
identifiers="identifiers",
|
|
252
|
+
disable_message_retention="disable_message_retention",
|
|
253
|
+
send_to_unsubscribed="send_to_unsubscribed",
|
|
254
|
+
queue_draft="queue_draft",
|
|
255
|
+
message_data="message_data",
|
|
256
|
+
send_at="send_at",
|
|
257
|
+
language="language",
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
data = {}
|
|
261
|
+
for field, name in field_map.items():
|
|
262
|
+
value = getattr(self, field, None)
|
|
263
|
+
if value is not None:
|
|
264
|
+
data[name] = value
|
|
265
|
+
|
|
266
|
+
return data
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: customerio
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2
|
|
4
4
|
Summary: Customer.io Python bindings.
|
|
5
5
|
Home-page: https://github.com/customerio/customerio-python
|
|
6
6
|
Author: Peaberry Software Inc.
|
|
7
7
|
Author-email: support@customerio.com
|
|
8
8
|
License: BSD
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Classifier: Environment :: Web Environment
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: License :: OSI Approved :: BSD License
|
|
@@ -18,6 +17,3 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
License-File: LICENSE
|
|
20
19
|
License-File: AUTHORS
|
|
21
|
-
|
|
22
|
-
UNKNOWN
|
|
23
|
-
|
|
@@ -3,7 +3,6 @@ try:
|
|
|
3
3
|
except ImportError:
|
|
4
4
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
5
5
|
|
|
6
|
-
from functools import wraps
|
|
7
6
|
from random import randint
|
|
8
7
|
import json
|
|
9
8
|
import ssl
|
|
@@ -11,12 +10,11 @@ import time
|
|
|
11
10
|
import threading
|
|
12
11
|
import unittest
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return bar
|
|
13
|
+
def create_ssl_context():
|
|
14
|
+
"""Create SSL context for Python 3.12+ compatibility"""
|
|
15
|
+
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
|
16
|
+
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
|
17
|
+
return context
|
|
20
18
|
|
|
21
19
|
request_counts = dict()
|
|
22
20
|
|
|
@@ -75,12 +73,11 @@ class HTTPSTestCase(unittest.TestCase):
|
|
|
75
73
|
def setUpClass(cls):
|
|
76
74
|
# create a server
|
|
77
75
|
cls.server = HTTPServer(("localhost", 0), Handler)
|
|
78
|
-
#
|
|
79
|
-
|
|
76
|
+
# create SSL context for Python 3.12+ compatibility
|
|
77
|
+
context = create_ssl_context()
|
|
78
|
+
context.load_cert_chain('./tests/server.pem')
|
|
80
79
|
# upgrade to https
|
|
81
|
-
cls.server.socket =
|
|
82
|
-
certfile='./tests/server.pem',
|
|
83
|
-
server_side=True)
|
|
80
|
+
cls.server.socket = context.wrap_socket(cls.server.socket, server_side=True)
|
|
84
81
|
# start server instance in new thread
|
|
85
82
|
cls.server_thread = threading.Thread(target=cls.server.serve_forever)
|
|
86
83
|
cls.server_thread.start()
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import sys
|
|
6
6
|
import unittest
|
|
7
7
|
|
|
8
|
-
from customerio import APIClient, SendEmailRequest, SendPushRequest, Regions, CustomerIOException
|
|
8
|
+
from customerio import APIClient, SendEmailRequest, SendPushRequest, SendSMSRequest, Regions, CustomerIOException
|
|
9
9
|
from customerio.__version__ import __version__ as ClientVersion
|
|
10
10
|
from tests.server import HTTPSTestCase
|
|
11
11
|
|
|
@@ -95,5 +95,21 @@ class TestAPIClient(HTTPSTestCase):
|
|
|
95
95
|
|
|
96
96
|
self.client.send_push(push)
|
|
97
97
|
|
|
98
|
+
def test_send_sms(self):
|
|
99
|
+
self.client.http.hooks = dict(response=partial(self._check_request, rq={
|
|
100
|
+
'method': 'POST',
|
|
101
|
+
'authorization': "Bearer app_api_key",
|
|
102
|
+
'content_type': 'application/json',
|
|
103
|
+
'url_suffix': '/v1/send/sms',
|
|
104
|
+
'body': {"identifiers": {"id":"customer_1"}, "transactional_message_id": 100}
|
|
105
|
+
}))
|
|
106
|
+
|
|
107
|
+
sms = SendSMSRequest(
|
|
108
|
+
identifiers={"id":"customer_1"},
|
|
109
|
+
transactional_message_id=100,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
self.client.send_sms(sms)
|
|
113
|
+
|
|
98
114
|
if __name__ == '__main__':
|
|
99
115
|
unittest.main()
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|