summaryrefslogtreecommitdiff
path: root/python-trycourier.spec
diff options
context:
space:
mode:
Diffstat (limited to 'python-trycourier.spec')
-rw-r--r--python-trycourier.spec2092
1 files changed, 2092 insertions, 0 deletions
diff --git a/python-trycourier.spec b/python-trycourier.spec
new file mode 100644
index 0000000..1f36f06
--- /dev/null
+++ b/python-trycourier.spec
@@ -0,0 +1,2092 @@
+%global _empty_manifest_terminate_build 0
+Name: python-trycourier
+Version: 4.4.0
+Release: 1
+Summary: A Python Package for communicating with the Courier REST API.
+License: MIT License
+URL: https://github.com/trycourier/courier-python
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/4f/8f/7fe6e1738d8db5822f24b62872e9a52adaac0474a553863f8e18b3b38396/trycourier-4.4.0.tar.gz
+BuildArch: noarch
+
+Requires: python3-requests
+
+%description
+# `trycourier`
+
+This Python Package helps you send notifications through [Courier](https://www.courier.com/), the smartest way to design & deliver notifications. Design your notifications once using our drag & drop editor, then deliver to any channel through one API. Email, mobile push, SMS, Slack — you name it!
+
+## Installation
+
+Install from PyPI using [pip](http://www.pip-installer.org/en/latest/):
+
+```shell
+$ pip install trycourier
+```
+
+Python 3.5 or later is required.
+
+## Usage
+
+### Using Token Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token") #or set via COURIER_AUTH_TOKEN env var
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Using Basic Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(username="your-username", password="your-password")
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Timeouts
+
+As of v1.4.0, the timeout is defaulted to 5 seconds. This is configurable using the `timeout` parameter when creating a client. You can specify the time in seconds using a `float` value for both Connect and Read or use a tuple to set them for each individual one `(Connect, Read)`.
+
+```python
+client = Courier(auth_token="your-auth-token",
+ timeout=3.5)
+
+client = Courier(auth_token="your-auth-token",
+ timeout=(3.2, 3.3))
+```
+
+## Advanced Usage
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token")
+
+"""
+Example: send a message to a recipient
+"""
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={}, # optional
+ brand="your-brand-id", # optional
+ data={}, # optional
+ preferences={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send message using a message object that unlocks enhanced power features
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': {'email': 'foo@bar.com'}}
+)
+print(resp['requestId'])
+"""
+
+Example: send UTM metadata with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send granular UTM metadata with message object
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ },
+ 'channels': {
+ 'email': {
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ },
+ 'providers':['sendgrid','sns']
+ }
+ },
+ 'providers': {
+ 'sendgrid':{
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ }
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set trace_id with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ "trace_id": "feed-me-seemore",
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set tags with message object - V2
+"""
+resp = client.send_message(
+ message={
+ "to": {
+ "email": "foo@bar.com",
+ },
+ "template": "my-template",
+ "metadata": {
+ "tags": ["tag-1", "tag-2"]
+ }
+ })
+print(resp['requestId'])
+"""
+
+Example: send a message to a list, pattern and user
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': [
+ {
+ "list_pattern": "<PATTERN>", #e.g. example.list.*
+ },
+ {
+ "list_id": "<LIST_ID>", #e.g. your Courier List Id
+ },
+ {
+ "email": "test@email.com"
+ }
+ ]
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send a message to a list
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ list="your.list.id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send a message to a list pattern
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ pattern="your.list.*",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: create a recipient's profile
+"""
+resp = client.profiles.add(
+ recipient_id,
+ {
+ "email":"example@example.com",
+ "name":"Example Name"
+ }
+)
+
+"""
+Example: replace or create a recipient's profile
+"""
+resp = client.profiles.replace(
+ recipient_id,
+ {
+ "email": "example@example.com"
+ }
+)
+print(resp['status'])
+
+"""
+Example: merge or create a recipient's profile
+"""
+resp = client.profiles.merge(
+ recipient_id,
+ {
+ "phone_number": "+15555555555"
+ }
+)
+print(resp['status'])
+
+"""
+Example: get the subscribed lists of a recipient
+"""
+resp = client.profiles.get_subscriptions(
+ recipient_id,
+ cursor #optional
+)
+print(resp)
+
+"""
+Example: edit the contents of a recipient's profile with a patch operation
+(follows JSON Patch conventions: RFC 6902).
+"""
+resp = client.profiles.patch(
+ recipient_id,
+ [
+ {
+ "op": "add", #operation 1: add this email to profile
+ "path": "/parent",
+ "value": "example@example.com"
+ }
+ {
+ "op": "replace", #operation 2: update with new email
+ "path": "/parent",
+ "value": "jane@doe.com"
+ }
+ {
+ "op": "copy", #operation 3: copy that email to /emergency_contact
+ "from": "/parent",
+ "path": "/emergency_contact"
+ }
+ ...
+ ]
+)
+print(resp)
+
+
+"""
+Example: get a recipient's profile
+"""
+resp = client.profiles.get(recipient_id)
+print(resp)
+
+
+"""
+Example: fetch the statuses of messages you've previously sent.
+"""
+resp = client.messages.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+ event="your-event-id", # optional
+ list="your-list-id", #optional
+ message_id="your-message-id", #optional
+ notification=["message-status-1", "message-status-2",...], #optional
+ recipient="recipient-id" # optional
+)
+print(resp)
+
+"""
+Example: fetch the status of a message you've previously sent
+"""
+resp = client.messages.get(message_id)
+print(resp)
+
+"""
+Example: fetch the array of events of a message you've previously sent.
+"""
+resp = client.messages.get_history(
+message_id="your-message-id",
+type="list-type" #optional ("FILTERED", "RENDERED", "MAPPED", "PROFILE_LOADED")
+)
+print(resp)
+
+"""
+Example: fetch the list of events
+"""
+resp = client.get_events()
+print(resp)
+
+"""
+Example: fetch a specific event by event ID
+"""
+resp = client.get_event(event_id)
+print(resp)
+
+"""
+Example: create or replace an event
+"""
+resp = client.replace_event(
+ event_id,
+ notification_id="GRPVB5P0BHMEZSNY6TP2X7TQHEBF",
+ type="notificaton" ## optional, defaults to notification
+)
+print(resp)
+
+"""
+Example: get all brands
+"""
+resp = client.get_brands(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print(resp)
+
+"""
+Example: get a specific brand
+"""
+resp = client.get_brand(brand_id)
+print(resp)
+
+"""
+Example: create a brand
+"""
+resp = client.create_brand({
+ name="My Brand",
+ settings={
+ "color": {
+ "primary": "#0000FF",
+ "secondary": "#FF0000",
+ "tertiary": "#00FF00"
+ }
+ }
+})
+print resp
+
+"""
+Example: replace a brand
+"""
+resp = client.replace_brand(
+ brand_id,
+ name="My New Brand",
+ settings={
+ "color": {
+ "primary": "#FF0000",
+ "secondary": "#00FF00",
+ "tertiary": "#0000FF"
+ }
+ }
+)
+print resp
+
+"""
+Example: delete a brand
+"""
+client.delete_brand(brand_id)
+
+"""
+Example: get all lists
+"""
+resp = client.lists.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: get a specific list
+"""
+resp = client.lists.get(list_id)
+print resp
+
+"""
+Example: create or replace a list
+"""
+client.lists.put(list_id, name="My List")
+
+"""
+Example: delete a list
+"""
+client.lists.delete(list_id)
+
+"""
+Example: restore a list
+"""
+client.lists.restore(list_id)
+
+"""
+Example: get a list's subscribptions
+"""
+resp = client.lists.get_subscriptions(list_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: replace many recipients to a new or existing list
+"""
+client.lists.put_subscriptions(list_id, [
+ "RECIPIENT_ID_1",
+ "RECIPIENT_ID_2"
+])
+
+"""
+Example: Example: subscribe single recipient to a new or existing list
+"""
+client.lists.subscribe(list_id, recipient_id)
+
+"""
+Example: unsubscribe recipient from list
+"""
+client.lists.unsubscribe(list_id, recipient_id)
+
+"""
+Example: get a recipient's subscribed lists
+"""
+resp = client.lists.find_by_recipient_id(recipient_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: Invoke an ad-hoc automation
+"""
+
+resp = client.automations.invoke(
+ automation={'steps': [{ 'action': 'send' }]},
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Example: Invoke an automation template
+"""
+resp = client.automations.invoke_template(
+ template_id="your-automation-template-id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Bulk Processing:
+"""
+
+"""
+Example: Create a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'event': 'foo'},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Create a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'message': { 'template': 'RR4NDQ7NZ24A8TKPWVBEDGE15E9A' }},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Ingest users into a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'profile': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Ingest users into a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'to': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Run a bulk processing job
+"""
+client.bulk.run_job(
+ job_id='12345',
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+
+"""
+Example: Get bulk processing job
+"""
+resp = client.bulk.get_job('12345')
+print(resp)
+
+"""
+Example: Get bulk processing job user details
+"""
+resp = client.bulk.get_job_users('12345', cursor='abc') # cursor is optional
+print(resp)
+
+"""
+Example: Get audit event
+"""
+resp = client.audit_events.get_audit_event('12345')
+print(resp)
+
+"""
+Example: List audit events
+"""
+resp = client.audit_events.list_audit_events(cursor='abc') # cursor is optional
+print(resp)
+```
+
+### Idempotency
+
+For `POST` methods, you can supply an `idempotency_key` to ensure the idempotency of the API Call. We recommend that you use a `V4 UUID` for the key. By default, keys are eligible to be removed from the system after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been removed.
+
+Also, the expiration of an idempotency key can be altered by setting a `idempotency_expiration` header value. The value of this header can be either epoch milliseconds or an ISO-8601 formatted date string. The minimum value that can be set is 24 hours. The maximum value that can be set is 1 year.
+
+```python
+import uuid
+from datetime import datetime, timedelta
+from trycourier import Courier
+
+client = Courier()
+
+idempotency_key = uuid.uuid4()
+expiration = (datetime.now()+timedelta(days=7)).isoformat()
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ },
+ idempotency_key=idempotency_key,
+ idempotency_expiration=expiration
+)
+print(resp['messageId'])
+```
+
+## Contributing
+
+Bug reports and pull requests are welcome on GitHub at https://github.com/trycourier/courier-python. See [CONTRIBUTING.md](CONTRIBUTING.md) for more info.
+
+## License
+
+The package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
+
+
+
+
+%package -n python3-trycourier
+Summary: A Python Package for communicating with the Courier REST API.
+Provides: python-trycourier
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-trycourier
+# `trycourier`
+
+This Python Package helps you send notifications through [Courier](https://www.courier.com/), the smartest way to design &amp; deliver notifications. Design your notifications once using our drag &amp; drop editor, then deliver to any channel through one API. Email, mobile push, SMS, Slack &mdash; you name it!
+
+## Installation
+
+Install from PyPI using [pip](http://www.pip-installer.org/en/latest/):
+
+```shell
+$ pip install trycourier
+```
+
+Python 3.5 or later is required.
+
+## Usage
+
+### Using Token Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token") #or set via COURIER_AUTH_TOKEN env var
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Using Basic Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(username="your-username", password="your-password")
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Timeouts
+
+As of v1.4.0, the timeout is defaulted to 5 seconds. This is configurable using the `timeout` parameter when creating a client. You can specify the time in seconds using a `float` value for both Connect and Read or use a tuple to set them for each individual one `(Connect, Read)`.
+
+```python
+client = Courier(auth_token="your-auth-token",
+ timeout=3.5)
+
+client = Courier(auth_token="your-auth-token",
+ timeout=(3.2, 3.3))
+```
+
+## Advanced Usage
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token")
+
+"""
+Example: send a message to a recipient
+"""
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={}, # optional
+ brand="your-brand-id", # optional
+ data={}, # optional
+ preferences={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send message using a message object that unlocks enhanced power features
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': {'email': 'foo@bar.com'}}
+)
+print(resp['requestId'])
+"""
+
+Example: send UTM metadata with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send granular UTM metadata with message object
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ },
+ 'channels': {
+ 'email': {
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ },
+ 'providers':['sendgrid','sns']
+ }
+ },
+ 'providers': {
+ 'sendgrid':{
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ }
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set trace_id with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ "trace_id": "feed-me-seemore",
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set tags with message object - V2
+"""
+resp = client.send_message(
+ message={
+ "to": {
+ "email": "foo@bar.com",
+ },
+ "template": "my-template",
+ "metadata": {
+ "tags": ["tag-1", "tag-2"]
+ }
+ })
+print(resp['requestId'])
+"""
+
+Example: send a message to a list, pattern and user
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': [
+ {
+ "list_pattern": "<PATTERN>", #e.g. example.list.*
+ },
+ {
+ "list_id": "<LIST_ID>", #e.g. your Courier List Id
+ },
+ {
+ "email": "test@email.com"
+ }
+ ]
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send a message to a list
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ list="your.list.id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send a message to a list pattern
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ pattern="your.list.*",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: create a recipient's profile
+"""
+resp = client.profiles.add(
+ recipient_id,
+ {
+ "email":"example@example.com",
+ "name":"Example Name"
+ }
+)
+
+"""
+Example: replace or create a recipient's profile
+"""
+resp = client.profiles.replace(
+ recipient_id,
+ {
+ "email": "example@example.com"
+ }
+)
+print(resp['status'])
+
+"""
+Example: merge or create a recipient's profile
+"""
+resp = client.profiles.merge(
+ recipient_id,
+ {
+ "phone_number": "+15555555555"
+ }
+)
+print(resp['status'])
+
+"""
+Example: get the subscribed lists of a recipient
+"""
+resp = client.profiles.get_subscriptions(
+ recipient_id,
+ cursor #optional
+)
+print(resp)
+
+"""
+Example: edit the contents of a recipient's profile with a patch operation
+(follows JSON Patch conventions: RFC 6902).
+"""
+resp = client.profiles.patch(
+ recipient_id,
+ [
+ {
+ "op": "add", #operation 1: add this email to profile
+ "path": "/parent",
+ "value": "example@example.com"
+ }
+ {
+ "op": "replace", #operation 2: update with new email
+ "path": "/parent",
+ "value": "jane@doe.com"
+ }
+ {
+ "op": "copy", #operation 3: copy that email to /emergency_contact
+ "from": "/parent",
+ "path": "/emergency_contact"
+ }
+ ...
+ ]
+)
+print(resp)
+
+
+"""
+Example: get a recipient's profile
+"""
+resp = client.profiles.get(recipient_id)
+print(resp)
+
+
+"""
+Example: fetch the statuses of messages you've previously sent.
+"""
+resp = client.messages.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+ event="your-event-id", # optional
+ list="your-list-id", #optional
+ message_id="your-message-id", #optional
+ notification=["message-status-1", "message-status-2",...], #optional
+ recipient="recipient-id" # optional
+)
+print(resp)
+
+"""
+Example: fetch the status of a message you've previously sent
+"""
+resp = client.messages.get(message_id)
+print(resp)
+
+"""
+Example: fetch the array of events of a message you've previously sent.
+"""
+resp = client.messages.get_history(
+message_id="your-message-id",
+type="list-type" #optional ("FILTERED", "RENDERED", "MAPPED", "PROFILE_LOADED")
+)
+print(resp)
+
+"""
+Example: fetch the list of events
+"""
+resp = client.get_events()
+print(resp)
+
+"""
+Example: fetch a specific event by event ID
+"""
+resp = client.get_event(event_id)
+print(resp)
+
+"""
+Example: create or replace an event
+"""
+resp = client.replace_event(
+ event_id,
+ notification_id="GRPVB5P0BHMEZSNY6TP2X7TQHEBF",
+ type="notificaton" ## optional, defaults to notification
+)
+print(resp)
+
+"""
+Example: get all brands
+"""
+resp = client.get_brands(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print(resp)
+
+"""
+Example: get a specific brand
+"""
+resp = client.get_brand(brand_id)
+print(resp)
+
+"""
+Example: create a brand
+"""
+resp = client.create_brand({
+ name="My Brand",
+ settings={
+ "color": {
+ "primary": "#0000FF",
+ "secondary": "#FF0000",
+ "tertiary": "#00FF00"
+ }
+ }
+})
+print resp
+
+"""
+Example: replace a brand
+"""
+resp = client.replace_brand(
+ brand_id,
+ name="My New Brand",
+ settings={
+ "color": {
+ "primary": "#FF0000",
+ "secondary": "#00FF00",
+ "tertiary": "#0000FF"
+ }
+ }
+)
+print resp
+
+"""
+Example: delete a brand
+"""
+client.delete_brand(brand_id)
+
+"""
+Example: get all lists
+"""
+resp = client.lists.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: get a specific list
+"""
+resp = client.lists.get(list_id)
+print resp
+
+"""
+Example: create or replace a list
+"""
+client.lists.put(list_id, name="My List")
+
+"""
+Example: delete a list
+"""
+client.lists.delete(list_id)
+
+"""
+Example: restore a list
+"""
+client.lists.restore(list_id)
+
+"""
+Example: get a list's subscribptions
+"""
+resp = client.lists.get_subscriptions(list_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: replace many recipients to a new or existing list
+"""
+client.lists.put_subscriptions(list_id, [
+ "RECIPIENT_ID_1",
+ "RECIPIENT_ID_2"
+])
+
+"""
+Example: Example: subscribe single recipient to a new or existing list
+"""
+client.lists.subscribe(list_id, recipient_id)
+
+"""
+Example: unsubscribe recipient from list
+"""
+client.lists.unsubscribe(list_id, recipient_id)
+
+"""
+Example: get a recipient's subscribed lists
+"""
+resp = client.lists.find_by_recipient_id(recipient_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: Invoke an ad-hoc automation
+"""
+
+resp = client.automations.invoke(
+ automation={'steps': [{ 'action': 'send' }]},
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Example: Invoke an automation template
+"""
+resp = client.automations.invoke_template(
+ template_id="your-automation-template-id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Bulk Processing:
+"""
+
+"""
+Example: Create a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'event': 'foo'},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Create a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'message': { 'template': 'RR4NDQ7NZ24A8TKPWVBEDGE15E9A' }},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Ingest users into a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'profile': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Ingest users into a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'to': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Run a bulk processing job
+"""
+client.bulk.run_job(
+ job_id='12345',
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+
+"""
+Example: Get bulk processing job
+"""
+resp = client.bulk.get_job('12345')
+print(resp)
+
+"""
+Example: Get bulk processing job user details
+"""
+resp = client.bulk.get_job_users('12345', cursor='abc') # cursor is optional
+print(resp)
+
+"""
+Example: Get audit event
+"""
+resp = client.audit_events.get_audit_event('12345')
+print(resp)
+
+"""
+Example: List audit events
+"""
+resp = client.audit_events.list_audit_events(cursor='abc') # cursor is optional
+print(resp)
+```
+
+### Idempotency
+
+For `POST` methods, you can supply an `idempotency_key` to ensure the idempotency of the API Call. We recommend that you use a `V4 UUID` for the key. By default, keys are eligible to be removed from the system after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been removed.
+
+Also, the expiration of an idempotency key can be altered by setting a `idempotency_expiration` header value. The value of this header can be either epoch milliseconds or an ISO-8601 formatted date string. The minimum value that can be set is 24 hours. The maximum value that can be set is 1 year.
+
+```python
+import uuid
+from datetime import datetime, timedelta
+from trycourier import Courier
+
+client = Courier()
+
+idempotency_key = uuid.uuid4()
+expiration = (datetime.now()+timedelta(days=7)).isoformat()
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ },
+ idempotency_key=idempotency_key,
+ idempotency_expiration=expiration
+)
+print(resp['messageId'])
+```
+
+## Contributing
+
+Bug reports and pull requests are welcome on GitHub at https://github.com/trycourier/courier-python. See [CONTRIBUTING.md](CONTRIBUTING.md) for more info.
+
+## License
+
+The package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
+
+
+
+
+%package help
+Summary: Development documents and examples for trycourier
+Provides: python3-trycourier-doc
+%description help
+# `trycourier`
+
+This Python Package helps you send notifications through [Courier](https://www.courier.com/), the smartest way to design &amp; deliver notifications. Design your notifications once using our drag &amp; drop editor, then deliver to any channel through one API. Email, mobile push, SMS, Slack &mdash; you name it!
+
+## Installation
+
+Install from PyPI using [pip](http://www.pip-installer.org/en/latest/):
+
+```shell
+$ pip install trycourier
+```
+
+Python 3.5 or later is required.
+
+## Usage
+
+### Using Token Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token") #or set via COURIER_AUTH_TOKEN env var
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Using Basic Auth
+
+```python
+from trycourier import Courier
+
+client = Courier(username="your-username", password="your-password")
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ }
+)
+print(resp['messageId'])
+```
+
+### Timeouts
+
+As of v1.4.0, the timeout is defaulted to 5 seconds. This is configurable using the `timeout` parameter when creating a client. You can specify the time in seconds using a `float` value for both Connect and Read or use a tuple to set them for each individual one `(Connect, Read)`.
+
+```python
+client = Courier(auth_token="your-auth-token",
+ timeout=3.5)
+
+client = Courier(auth_token="your-auth-token",
+ timeout=(3.2, 3.3))
+```
+
+## Advanced Usage
+
+```python
+from trycourier import Courier
+
+client = Courier(auth_token="your-auth-token")
+
+"""
+Example: send a message to a recipient
+"""
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={}, # optional
+ brand="your-brand-id", # optional
+ data={}, # optional
+ preferences={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send message using a message object that unlocks enhanced power features
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': {'email': 'foo@bar.com'}}
+)
+print(resp['requestId'])
+"""
+
+Example: send UTM metadata with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send granular UTM metadata with message object
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ 'utm': {
+ 'source': 'python'
+ }
+ },
+ 'channels': {
+ 'email': {
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ },
+ 'providers':['sendgrid','sns']
+ }
+ },
+ 'providers': {
+ 'sendgrid':{
+ 'metadata': {
+ 'utm': {
+ 'medium': 'email'
+ }
+ }
+ }
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set trace_id with message object - V2
+"""
+resp = client.send_message(
+ message={
+ 'to': [
+ {
+ "email": "foo@bar.com"
+ }
+ ],
+ 'content': {
+ 'version': '2020-01-01',
+ 'elements': [
+ {
+ 'type': 'action',
+ 'content': 'ELEMENTAL',
+ 'href': 'courier.com',
+ 'style': 'button',
+ 'align': 'center'
+ }
+ ]
+ },
+ 'routing': {
+ 'method': 'single',
+ 'channels': [
+ 'email'
+ ]
+ },
+ 'metadata': {
+ "trace_id": "feed-me-seemore",
+ }
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: set tags with message object - V2
+"""
+resp = client.send_message(
+ message={
+ "to": {
+ "email": "foo@bar.com",
+ },
+ "template": "my-template",
+ "metadata": {
+ "tags": ["tag-1", "tag-2"]
+ }
+ })
+print(resp['requestId'])
+"""
+
+Example: send a message to a list, pattern and user
+"""
+resp = client.send_message(
+ message={'template': 'my-template', 'to': [
+ {
+ "list_pattern": "<PATTERN>", #e.g. example.list.*
+ },
+ {
+ "list_id": "<LIST_ID>", #e.g. your Courier List Id
+ },
+ {
+ "email": "test@email.com"
+ }
+ ]
+ }
+)
+print(resp['requestId'])
+"""
+
+Example: send a message to a list
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ list="your.list.id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: send a message to a list pattern
+"""
+resp = client.lists.send(
+ event="your-event-id",
+ pattern="your.list.*",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ override={} # optional
+)
+print(resp['messageId'])
+
+"""
+Example: create a recipient's profile
+"""
+resp = client.profiles.add(
+ recipient_id,
+ {
+ "email":"example@example.com",
+ "name":"Example Name"
+ }
+)
+
+"""
+Example: replace or create a recipient's profile
+"""
+resp = client.profiles.replace(
+ recipient_id,
+ {
+ "email": "example@example.com"
+ }
+)
+print(resp['status'])
+
+"""
+Example: merge or create a recipient's profile
+"""
+resp = client.profiles.merge(
+ recipient_id,
+ {
+ "phone_number": "+15555555555"
+ }
+)
+print(resp['status'])
+
+"""
+Example: get the subscribed lists of a recipient
+"""
+resp = client.profiles.get_subscriptions(
+ recipient_id,
+ cursor #optional
+)
+print(resp)
+
+"""
+Example: edit the contents of a recipient's profile with a patch operation
+(follows JSON Patch conventions: RFC 6902).
+"""
+resp = client.profiles.patch(
+ recipient_id,
+ [
+ {
+ "op": "add", #operation 1: add this email to profile
+ "path": "/parent",
+ "value": "example@example.com"
+ }
+ {
+ "op": "replace", #operation 2: update with new email
+ "path": "/parent",
+ "value": "jane@doe.com"
+ }
+ {
+ "op": "copy", #operation 3: copy that email to /emergency_contact
+ "from": "/parent",
+ "path": "/emergency_contact"
+ }
+ ...
+ ]
+)
+print(resp)
+
+
+"""
+Example: get a recipient's profile
+"""
+resp = client.profiles.get(recipient_id)
+print(resp)
+
+
+"""
+Example: fetch the statuses of messages you've previously sent.
+"""
+resp = client.messages.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+ event="your-event-id", # optional
+ list="your-list-id", #optional
+ message_id="your-message-id", #optional
+ notification=["message-status-1", "message-status-2",...], #optional
+ recipient="recipient-id" # optional
+)
+print(resp)
+
+"""
+Example: fetch the status of a message you've previously sent
+"""
+resp = client.messages.get(message_id)
+print(resp)
+
+"""
+Example: fetch the array of events of a message you've previously sent.
+"""
+resp = client.messages.get_history(
+message_id="your-message-id",
+type="list-type" #optional ("FILTERED", "RENDERED", "MAPPED", "PROFILE_LOADED")
+)
+print(resp)
+
+"""
+Example: fetch the list of events
+"""
+resp = client.get_events()
+print(resp)
+
+"""
+Example: fetch a specific event by event ID
+"""
+resp = client.get_event(event_id)
+print(resp)
+
+"""
+Example: create or replace an event
+"""
+resp = client.replace_event(
+ event_id,
+ notification_id="GRPVB5P0BHMEZSNY6TP2X7TQHEBF",
+ type="notificaton" ## optional, defaults to notification
+)
+print(resp)
+
+"""
+Example: get all brands
+"""
+resp = client.get_brands(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print(resp)
+
+"""
+Example: get a specific brand
+"""
+resp = client.get_brand(brand_id)
+print(resp)
+
+"""
+Example: create a brand
+"""
+resp = client.create_brand({
+ name="My Brand",
+ settings={
+ "color": {
+ "primary": "#0000FF",
+ "secondary": "#FF0000",
+ "tertiary": "#00FF00"
+ }
+ }
+})
+print resp
+
+"""
+Example: replace a brand
+"""
+resp = client.replace_brand(
+ brand_id,
+ name="My New Brand",
+ settings={
+ "color": {
+ "primary": "#FF0000",
+ "secondary": "#00FF00",
+ "tertiary": "#0000FF"
+ }
+ }
+)
+print resp
+
+"""
+Example: delete a brand
+"""
+client.delete_brand(brand_id)
+
+"""
+Example: get all lists
+"""
+resp = client.lists.list(
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: get a specific list
+"""
+resp = client.lists.get(list_id)
+print resp
+
+"""
+Example: create or replace a list
+"""
+client.lists.put(list_id, name="My List")
+
+"""
+Example: delete a list
+"""
+client.lists.delete(list_id)
+
+"""
+Example: restore a list
+"""
+client.lists.restore(list_id)
+
+"""
+Example: get a list's subscribptions
+"""
+resp = client.lists.get_subscriptions(list_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: replace many recipients to a new or existing list
+"""
+client.lists.put_subscriptions(list_id, [
+ "RECIPIENT_ID_1",
+ "RECIPIENT_ID_2"
+])
+
+"""
+Example: Example: subscribe single recipient to a new or existing list
+"""
+client.lists.subscribe(list_id, recipient_id)
+
+"""
+Example: unsubscribe recipient from list
+"""
+client.lists.unsubscribe(list_id, recipient_id)
+
+"""
+Example: get a recipient's subscribed lists
+"""
+resp = client.lists.find_by_recipient_id(recipient_id,
+ cursor="MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA", # optional
+)
+print resp
+
+"""
+Example: Invoke an ad-hoc automation
+"""
+
+resp = client.automations.invoke(
+ automation={'steps': [{ 'action': 'send' }]},
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Example: Invoke an automation template
+"""
+resp = client.automations.invoke_template(
+ template_id="your-automation-template-id",
+ brand="your-brand-id", # optional
+ data={}, # optional
+ profile={}, # optional
+ recipient="your-recipient-id", # optional
+ template="your-notification-template-id" # optional
+)
+print(resp['runId'])
+
+"""
+Bulk Processing:
+"""
+
+"""
+Example: Create a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'event': 'foo'},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Create a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.create_job(
+ message={'message': { 'template': 'RR4NDQ7NZ24A8TKPWVBEDGE15E9A' }},
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp['jobId'])
+
+"""
+Example: Ingest users into a bulk processing job (API v1 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'profile': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Ingest users into a bulk processing job (API v2 semantics)
+"""
+resp = client.bulk.ingest_users(
+ job_id='12345',
+ users=[{ 'to': { 'email': 'foo@bar.com' } }],
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+print(resp)
+
+"""
+Example: Run a bulk processing job
+"""
+client.bulk.run_job(
+ job_id='12345',
+ idempotency_key='1234ABCD', # optional
+ idempotency_expiration='expiration-date' # optional
+)
+
+"""
+Example: Get bulk processing job
+"""
+resp = client.bulk.get_job('12345')
+print(resp)
+
+"""
+Example: Get bulk processing job user details
+"""
+resp = client.bulk.get_job_users('12345', cursor='abc') # cursor is optional
+print(resp)
+
+"""
+Example: Get audit event
+"""
+resp = client.audit_events.get_audit_event('12345')
+print(resp)
+
+"""
+Example: List audit events
+"""
+resp = client.audit_events.list_audit_events(cursor='abc') # cursor is optional
+print(resp)
+```
+
+### Idempotency
+
+For `POST` methods, you can supply an `idempotency_key` to ensure the idempotency of the API Call. We recommend that you use a `V4 UUID` for the key. By default, keys are eligible to be removed from the system after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been removed.
+
+Also, the expiration of an idempotency key can be altered by setting a `idempotency_expiration` header value. The value of this header can be either epoch milliseconds or an ISO-8601 formatted date string. The minimum value that can be set is 24 hours. The maximum value that can be set is 1 year.
+
+```python
+import uuid
+from datetime import datetime, timedelta
+from trycourier import Courier
+
+client = Courier()
+
+idempotency_key = uuid.uuid4()
+expiration = (datetime.now()+timedelta(days=7)).isoformat()
+
+resp = client.send(
+ event="your-event-id",
+ recipient="your-recipient-id",
+ profile={
+ "email": "example@example.com",
+ "phone_number": "555-867-5309"
+ },
+ data={
+ "world": "Python!"
+ },
+ idempotency_key=idempotency_key,
+ idempotency_expiration=expiration
+)
+print(resp['messageId'])
+```
+
+## Contributing
+
+Bug reports and pull requests are welcome on GitHub at https://github.com/trycourier/courier-python. See [CONTRIBUTING.md](CONTRIBUTING.md) for more info.
+
+## License
+
+The package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
+
+
+
+
+%prep
+%autosetup -n trycourier-4.4.0
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-trycourier -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 4.4.0-1
+- Package Spec generated