diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7ccdf3f..3bf294daa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Change Log All notable changes to this project will be documented in this file. +## [3.0.1] - 2016-07-05 ## +### Fixed +- [Issue 185](https://github.com/sendgrid/sendgrid-python/issues/185): Getting HTTP Error 406 when getting bounces +### Updated +- Examples, USAGE.md and Unit Tests with updated content and new endpoints + ## [3.0.0] - 2016-06-13 ## ### Added - Breaking change to support the v3 Web API diff --git a/README.md b/README.md index 5616947bf..26504b952 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ **BREAKING CHANGE as of 2016.06.14** -Version `3.0.0` is a breaking change for the entire library. +Version `3.X.X` is a breaking change for the entire library. -Version 3.0.0 brings you full support for all Web API v3 endpoints. We +Version 3.X.X brings you full support for all Web API v3 endpoints. We have the following resources to get you started quickly: - [SendGrid @@ -17,6 +17,7 @@ have the following resources to get you started quickly: Documentation](https://github.com/sendgrid/sendgrid-python/tree/master/USAGE.md) - [Example Code](https://github.com/sendgrid/sendgrid-python/tree/master/examples) +- [Migration from v2 to v3](https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/how_to_migrate_from_v2_to_v3_mail_send.html) Thank you for your continued support! diff --git a/USAGE.md b/USAGE.md index 9b404b102..a9423c486 100644 --- a/USAGE.md +++ b/USAGE.md @@ -13,6 +13,7 @@ sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) # Table of Contents * [ACCESS SETTINGS](#access_settings) +* [ALERTS](#alerts) * [API KEYS](#api_keys) * [ASM](#asm) * [BROWSERS](#browsers) @@ -173,6 +174,115 @@ print response.status_code print response.body print response.headers ``` + +# ALERTS + +## Create a new Alert + +**This endpoint allows you to create a new alert.** + +Alerts allow you to specify an email address to receive notifications regarding your email usage or statistics. +* Usage alerts allow you to set the threshold at which an alert will be sent. +* Stats notifications allow you to set how frequently you would like to receive email statistics reports. For example, "daily", "weekly", or "monthly". + +For more information about alerts, please see our [User Guide](https://sendgrid.com/docs/User_Guide/Settings/alerts.html). + +### POST /alerts + + +```python +data = { + "email_to": "example@example.com", + "frequency": "daily", + "type": "stats_notification" +} +response = sg.client.alerts.post(request_body=data) +print response.status_code +print response.body +print response.headers +``` +## Retrieve all alerts + +**This endpoint allows you to retieve all of your alerts.** + +Alerts allow you to specify an email address to receive notifications regarding your email usage or statistics. +* Usage alerts allow you to set the threshold at which an alert will be sent. +* Stats notifications allow you to set how frequently you would like to receive email statistics reports. For example, "daily", "weekly", or "monthly". + +For more information about alerts, please see our [User Guide](https://sendgrid.com/docs/User_Guide/Settings/alerts.html). + +### GET /alerts + + +```python +response = sg.client.alerts.get() +print response.status_code +print response.body +print response.headers +``` +## Update an alert + +**This endpoint allows you to update an alert.** + +Alerts allow you to specify an email address to receive notifications regarding your email usage or statistics. +* Usage alerts allow you to set the threshold at which an alert will be sent. +* Stats notifications allow you to set how frequently you would like to receive email statistics reports. For example, "daily", "weekly", or "monthly". + +For more information about alerts, please see our [User Guide](https://sendgrid.com/docs/User_Guide/Settings/alerts.html). + +### PATCH /alerts/{alert_id} + + +```python +data = { + "email_to": "example@example.com" +} +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).patch(request_body=data) +print response.status_code +print response.body +print response.headers +``` +## Retrieve a specific alert + +**This endpoint allows you to retrieve a specific alert.** + +Alerts allow you to specify an email address to receive notifications regarding your email usage or statistics. +* Usage alerts allow you to set the threshold at which an alert will be sent. +* Stats notifications allow you to set how frequently you would like to receive email statistics reports. For example, "daily", "weekly", or "monthly". + +For more information about alerts, please see our [User Guide](https://sendgrid.com/docs/User_Guide/Settings/alerts.html). + +### GET /alerts/{alert_id} + + +```python +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).get() +print response.status_code +print response.body +print response.headers +``` +## Delete an alert + +**This endpoint allows you to delete an alert.** + +Alerts allow you to specify an email address to receive notifications regarding your email usage or statistics. +* Usage alerts allow you to set the threshold at which an alert will be sent. +* Stats notifications allow you to set how frequently you would like to receive email statistics reports. For example, "daily", "weekly", or "monthly". + +For more information about alerts, please see our [User Guide](https://sendgrid.com/docs/User_Guide/Settings/alerts.html). + +### DELETE /alerts/{alert_id} + + +```python +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).delete() +print response.status_code +print response.body +print response.headers +``` # API KEYS @@ -194,6 +304,7 @@ See the [API Key Permissions List](https://sendgrid.com/docs/API_Reference/Web_A ```python data = { "name": "My API Key", + "sample": "data", "scopes": [ "mail.send", "alerts.create", @@ -215,7 +326,8 @@ The API Keys feature allows customers to be able to generate an API Key credenti ```python -response = sg.client.api_keys.get() +params = {'limit': 1} +response = sg.client.api_keys.get(query_params=params) print response.status_code print response.body print response.headers @@ -347,6 +459,10 @@ print response.headers This endpoint will return information for each group ID that you include in your request. To add a group ID to your request, simply append `&id=` followed by the group ID. +Suppressions are a list of email addresses that will not receive content sent under a given [group](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html). + +Suppression groups, or [unsubscribe groups](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html), allow you to label a category of content that you regularly send. This gives your recipients the ability to opt out of a specific set of your email. For example, you might define a group for your transactional email, and one for your marketing email so that your users can continue recieving your transactional email witout having to receive your marketing content. + ### GET /asm/groups @@ -464,6 +580,31 @@ print response.status_code print response.body print response.headers ``` +## Search for suppressions within a group + +**This endpoint allows you to search a suppression group for multiple suppressions.** + +When given a list of email addresses and a group ID, this endpoint will return only the email addresses that have been unsubscribed from the given group. + +Suppressions are a list of email addresses that will not receive content sent under a given [group](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html). + +### POST /asm/groups/{group_id}/suppressions/search + + +```python +data = { + "recipient_emails": [ + "exists1@example.com", + "exists2@example.com", + "doesnotexists@example.com" + ] +} +group_id = "test_url_param" +response = sg.client.asm.groups._(group_id).suppressions.search.post(request_body=data) +print response.status_code +print response.body +print response.headers +``` ## Delete a suppression from a suppression group **This endpoint allows you to remove a suppressed email address from the given suppression group.** @@ -485,7 +626,7 @@ print response.headers **This endpoint allows you to retrieve a list of all suppressions.** -Suppressions are email addresses that can be added to [groups](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html) to prevent certain types of emails from being delivered to those addresses. +Suppressions are a list of email addresses that will not receive content sent under a given [group](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html). ### GET /asm/suppressions @@ -553,9 +694,9 @@ print response.headers ``` ## Retrieve all suppression groups for an email address -**This endpoint will return a list of all suppression groups, indicating if the given email address is suppressed for each group.** +**This endpoint returns the list of all groups that the given email address has been unsubscribed from.** -Suppressions are email addresses that can be added to [groups](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html) to prevent certain types of emails from being delivered to those addresses. +Suppressions are a list of email addresses that will not receive content sent under a given [group](https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html). ### GET /asm/suppressions/{email} @@ -648,7 +789,7 @@ For more information: ```python -params = {'limit': 0, 'offset': 0} +params = {'limit': 1, 'offset': 1} response = sg.client.campaigns.get(query_params=params) print response.status_code print response.body @@ -1083,7 +1224,7 @@ The Contacts API helps you manage your [Marketing Campaigns](https://sendgrid.co data = { "name": "newlistname" } -params = {'list_id': 0} +params = {'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).patch(request_body=data, query_params=params) print response.status_code @@ -1100,7 +1241,7 @@ The Contacts API helps you manage your [Marketing Campaigns](https://sendgrid.co ```python -params = {'list_id': 0} +params = {'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).get(query_params=params) print response.status_code @@ -1156,7 +1297,7 @@ The Contacts API helps you manage your [Marketing Campaigns](https://sendgrid.co ```python -params = {'page': 1, 'page_size': 1, 'list_id': 0} +params = {'page': 1, 'page_size': 1, 'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).recipients.get(query_params=params) print response.status_code @@ -1190,7 +1331,7 @@ The Contacts API helps you manage your [Marketing Campaigns](https://sendgrid.co ```python -params = {'recipient_id': 0, 'list_id': 0} +params = {'recipient_id': 1, 'list_id': 1} list_id = "test_url_param" recipient_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).recipients._(recipient_id).delete(query_params=params) @@ -1346,7 +1487,7 @@ The contactdb is a database of your contacts for [SendGrid Marketing Campaigns]( ```python -params = {'{field_name}': 'test_string'} +params = {'%7Bfield_name%7D': 'test_string', '{field_name}': 'test_string'} response = sg.client.contactdb.recipients.search.get(query_params=params) print response.status_code print response.body @@ -1536,7 +1677,7 @@ For more information about segments in Marketing Campaigns, please see our [User ```python -params = {'segment_id': 0} +params = {'segment_id': 1} segment_id = "test_url_param" response = sg.client.contactdb.segments._(segment_id).get(query_params=params) print response.status_code @@ -2054,13 +2195,8 @@ data = { "send_at": 1409348513, "subject": "Hello, World!", "substitutions": { - "sub": { - "%name%": [ - "John", - "Jane", - "Sam" - ] - } + "id": "substitutions", + "type": "object" }, "to": [ { @@ -2642,7 +2778,7 @@ For more information about Subusers: ```python -params = {'username': 'test_string', 'limit': 0, 'offset': 0} +params = {'username': 'test_string', 'limit': 1, 'offset': 1} response = sg.client.subusers.get(query_params=params) print response.status_code print response.body @@ -2866,7 +3002,7 @@ For more information, see our [User Guide](https://sendgrid.com/docs/User_Guide/ ```python -params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 0, 'sort_by_metric': 'test_string', 'offset': 1} +params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 1, 'sort_by_metric': 'test_string', 'offset': 1} subuser_name = "test_url_param" response = sg.client.subusers._(subuser_name).stats.monthly.get(query_params=params) print response.status_code @@ -2974,7 +3110,7 @@ For more information see: ```python -params = {'start_time': 0, 'end_time': 0} +params = {'start_time': 1, 'end_time': 1} response = sg.client.suppression.bounces.get(query_params=params) print response.status_code print response.body @@ -4061,11 +4197,32 @@ print response.status_code print response.body print response.headers ``` -## Retrieve Parse Webhook settings +## Create a parse setting + +**This endpoint allows you to create a new inbound parse setting.** + +The inbound parse webhook allows you to have incoming emails parsed, extracting some or all of the content, and then have that content POSTed by SendGrid to a URL of your choosing. For more information, please see our [User Guide](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). -**This endpoint allows you to retrieve your current inbound parse webhook settings.** +### POST /user/webhooks/parse/settings -SendGrid can parse the attachments and contents of incoming emails. The Parse API will POST the parsed email to a URL that you specify. For more information, see our Inbound [Parse Webhook documentation](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). + +```python +data = { + "hostname": "myhostname.com", + "send_raw": False, + "spam_check": True, + "url": "http://email.myhosthame.com" +} +response = sg.client.user.webhooks.parse.settings.post(request_body=data) +print response.status_code +print response.body +print response.headers +``` +## Retrieve all parse settings + +**This endpoint allows you to retrieve all of your current inbound parse settings.** + +The inbound parse webhook allows you to have incoming emails parsed, extracting some or all of the contnet, and then have that content POSTed by SendGrid to a URL of your choosing. For more information, please see our [User Guide](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). ### GET /user/webhooks/parse/settings @@ -4076,6 +4233,59 @@ print response.status_code print response.body print response.headers ``` +## Update a parse setting + +**This endpoint allows you to update a specific inbound parse setting.** + +The inbound parse webhook allows you to have incoming emails parsed, extracting some or all of the contnet, and then have that content POSTed by SendGrid to a URL of your choosing. For more information, please see our [User Guide](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). + +### PATCH /user/webhooks/parse/settings/{hostname} + + +```python +data = { + "send_raw": True, + "spam_check": False, + "url": "http://newdomain.com/parse" +} +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname).patch(request_body=data) +print response.status_code +print response.body +print response.headers +``` +## Retrieve a specific parse setting + +**This endpoint allows you to retrieve a specific inbound parse setting.** + +The inbound parse webhook allows you to have incoming emails parsed, extracting some or all of the contnet, and then have that content POSTed by SendGrid to a URL of your choosing. For more information, please see our [User Guide](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). + +### GET /user/webhooks/parse/settings/{hostname} + + +```python +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname).get() +print response.status_code +print response.body +print response.headers +``` +## Delete a parse setting + +**This endpoint allows you to delete a specific inbound parse setting.** + +The inbound parse webhook allows you to have incoming emails parsed, extracting some or all of the contnet, and then have that content POSTed by SendGrid to a URL of your choosing. For more information, please see our [User Guide](https://sendgrid.com/docs/API_Reference/Webhooks/parse.html). + +### DELETE /user/webhooks/parse/settings/{hostname} + + +```python +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname).delete() +print response.status_code +print response.body +print response.headers +``` ## Retrieves Inbound Parse Webhook statistics. **This endpoint allows you to retrieve the statistics for your Parse Webhook useage.** diff --git a/examples/alerts/alerts.py b/examples/alerts/alerts.py new file mode 100644 index 000000000..e30d48748 --- /dev/null +++ b/examples/alerts/alerts.py @@ -0,0 +1,63 @@ +import sendgrid +import json +import os + + +sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) + +################################################## +# Create a new Alert # +# POST /alerts # + +data = { + "email_to": "example@example.com", + "frequency": "daily", + "type": "stats_notification" +} +response = sg.client.alerts.post(request_body=data) +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Retrieve all alerts # +# GET /alerts # + +response = sg.client.alerts.get() +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Update an alert # +# PATCH /alerts/{alert_id} # + +data = { + "email_to": "example@example.com" +} +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).patch(request_body=data) +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Retrieve a specific alert # +# GET /alerts/{alert_id} # + +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).get() +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Delete an alert # +# DELETE /alerts/{alert_id} # + +alert_id = "test_url_param" +response = sg.client.alerts._(alert_id).delete() +print(response.status_code) +print(response.body) +print(response.headers) + diff --git a/examples/apikeys/apikeys.py b/examples/apikeys/apikeys.py index 97da4485f..42c3afa10 100644 --- a/examples/apikeys/apikeys.py +++ b/examples/apikeys/apikeys.py @@ -11,6 +11,7 @@ data = { "name": "My API Key", + "sample": "data", "scopes": [ "mail.send", "alerts.create", @@ -26,7 +27,8 @@ # Retrieve all API Keys belonging to the authenticated user # # GET /api_keys # -response = sg.client.api_keys.get() +params = {'limit': 1} +response = sg.client.api_keys.get(query_params=params) print(response.status_code) print(response.body) print(response.headers) diff --git a/examples/asm/asm.py b/examples/asm/asm.py index fd10755b5..43130cf06 100644 --- a/examples/asm/asm.py +++ b/examples/asm/asm.py @@ -90,6 +90,23 @@ print(response.body) print(response.headers) +################################################## +# Search for suppressions within a group # +# POST /asm/groups/{group_id}/suppressions/search # + +data = { + "recipient_emails": [ + "exists1@example.com", + "exists2@example.com", + "doesnotexists@example.com" + ] +} +group_id = "test_url_param" +response = sg.client.asm.groups._(group_id).suppressions.search.post(request_body=data) +print(response.status_code) +print(response.body) +print(response.headers) + ################################################## # Delete a suppression from a suppression group # # DELETE /asm/groups/{group_id}/suppressions/{email} # diff --git a/examples/campaigns/campaigns.py b/examples/campaigns/campaigns.py index 5a3cf960a..c77fc878b 100644 --- a/examples/campaigns/campaigns.py +++ b/examples/campaigns/campaigns.py @@ -38,7 +38,7 @@ # Retrieve all Campaigns # # GET /campaigns # -params = {'limit': 0, 'offset': 0} +params = {'limit': 1, 'offset': 1} response = sg.client.campaigns.get(query_params=params) print(response.status_code) print(response.body) diff --git a/examples/contactdb/contactdb.py b/examples/contactdb/contactdb.py index 340417e2b..07e8daa65 100644 --- a/examples/contactdb/contactdb.py +++ b/examples/contactdb/contactdb.py @@ -90,7 +90,7 @@ data = { "name": "newlistname" } -params = {'list_id': 0} +params = {'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).patch(request_body=data, query_params=params) print(response.status_code) @@ -101,7 +101,7 @@ # Retrieve a single list # # GET /contactdb/lists/{list_id} # -params = {'list_id': 0} +params = {'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).get(query_params=params) print(response.status_code) @@ -137,7 +137,7 @@ # Retrieve all recipients on a List # # GET /contactdb/lists/{list_id}/recipients # -params = {'page': 1, 'page_size': 1, 'list_id': 0} +params = {'page': 1, 'page_size': 1, 'list_id': 1} list_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).recipients.get(query_params=params) print(response.status_code) @@ -159,7 +159,7 @@ # Delete a Single Recipient from a Single List # # DELETE /contactdb/lists/{list_id}/recipients/{recipient_id} # -params = {'recipient_id': 0, 'list_id': 0} +params = {'recipient_id': 1, 'list_id': 1} list_id = "test_url_param" recipient_id = "test_url_param" response = sg.client.contactdb.lists._(list_id).recipients._(recipient_id).delete(query_params=params) @@ -251,7 +251,7 @@ # Retrieve recipients matching search criteria # # GET /contactdb/recipients/search # -params = {'{field_name}': 'test_string'} +params = {'%7Bfield_name%7D': 'test_string', '{field_name}': 'test_string'} response = sg.client.contactdb.recipients.search.get(query_params=params) print(response.status_code) print(response.body) @@ -365,7 +365,7 @@ # Retrieve a segment # # GET /contactdb/segments/{segment_id} # -params = {'segment_id': 0} +params = {'segment_id': 1} segment_id = "test_url_param" response = sg.client.contactdb.segments._(segment_id).get(query_params=params) print(response.status_code) diff --git a/examples/mail/mail.py b/examples/mail/mail.py index 56ea989d6..fef420e87 100644 --- a/examples/mail/mail.py +++ b/examples/mail/mail.py @@ -31,143 +31,138 @@ data = { "asm": { - "group_id": 1, + "group_id": 1, "groups_to_display": [ - 1, - 2, + 1, + 2, 3 ] - }, + }, "attachments": [ { - "content": "[BASE64 encoded content block here]", - "content_id": "ii_139db99fdb5c3704", - "disposition": "inline", - "filename": "file1.jpg", - "name": "file1", + "content": "[BASE64 encoded content block here]", + "content_id": "ii_139db99fdb5c3704", + "disposition": "inline", + "filename": "file1.jpg", + "name": "file1", "type": "jpg" } - ], - "batch_id": "[YOUR BATCH ID GOES HERE]", + ], + "batch_id": "[YOUR BATCH ID GOES HERE]", "categories": [ - "category1", + "category1", "category2" - ], + ], "content": [ { - "type": "text/html", + "type": "text/html", "value": "

Hello, world!

" } - ], + ], "custom_args": { - "New Argument 1": "New Value 1", - "activationAttempt": "1", + "New Argument 1": "New Value 1", + "activationAttempt": "1", "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]" - }, + }, "from": { - "email": "sam.smith@example.com", + "email": "sam.smith@example.com", "name": "Sam Smith" - }, - "headers": {}, - "ip_pool_name": "[YOUR POOL NAME GOES HERE]", + }, + "headers": {}, + "ip_pool_name": "[YOUR POOL NAME GOES HERE]", "mail_settings": { "bcc": { - "email": "ben.doe@example.com", + "email": "ben.doe@example.com", "enable": True - }, + }, "bypass_list_management": { "enable": True - }, + }, "footer": { - "enable": True, - "html": "

Thanks
The SendGrid Team

", + "enable": True, + "html": "

Thanks
The SendGrid Team

", "text": "Thanks,/n The SendGrid Team" - }, + }, "sandbox_mode": { "enable": False - }, + }, "spam_check": { - "enable": True, - "post_to_url": "http://example.com/compliance", + "enable": True, + "post_to_url": "http://example.com/compliance", "threshold": 3 } - }, + }, "personalizations": [ { "bcc": [ { - "email": "sam.doe@example.com", + "email": "sam.doe@example.com", "name": "Sam Doe" } - ], + ], "cc": [ { - "email": "jane.doe@example.com", + "email": "jane.doe@example.com", "name": "Jane Doe" } - ], + ], "custom_args": { - "New Argument 1": "New Value 1", - "activationAttempt": "1", + "New Argument 1": "New Value 1", + "activationAttempt": "1", "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]" - }, + }, "headers": { - "X-Accept-Language": "en", + "X-Accept-Language": "en", "X-Mailer": "MyApp" - }, - "send_at": 1409348513, - "subject": "Hello, World!", + }, + "send_at": 1409348513, + "subject": "Hello, World!", "substitutions": { - "sub": { - "%name%": [ - "John", - "Jane", - "Sam" - ] - } - }, + "id": "substitutions", + "type": "object" + }, "to": [ { - "email": "john.doe@example.com", + "email": "john.doe@example.com", "name": "John Doe" } ] } - ], + ], "reply_to": { - "email": "sam.smith@example.com", + "email": "sam.smith@example.com", "name": "Sam Smith" - }, + }, "sections": { "section": { - ":sectionName1": "section 1 text", + ":sectionName1": "section 1 text", ":sectionName2": "section 2 text" } - }, - "send_at": 1409348513, - "subject": "Hello, World!", - "template_id": "[YOUR TEMPLATE ID GOES HERE]", + }, + "send_at": 1409348513, + "subject": "Hello, World!", + "template_id": "[YOUR TEMPLATE ID GOES HERE]", "tracking_settings": { "click_tracking": { - "enable": True, + "enable": True, "enable_text": True - }, + }, "ganalytics": { - "enable": True, - "utm_campaign": "[NAME OF YOUR REFERRER SOURCE]", - "utm_content": "[USE THIS SPACE TO DIFFERENTIATE YOUR EMAIL FROM ADS]", - "utm_medium": "[NAME OF YOUR MARKETING MEDIUM e.g. email]", - "utm_name": "[NAME OF YOUR CAMPAIGN]", + "enable": True, + "utm_campaign": "[NAME OF YOUR REFERRER SOURCE]", + "utm_content": "[USE THIS SPACE TO DIFFERENTIATE YOUR EMAIL FROM ADS]", + "utm_medium": "[NAME OF YOUR MARKETING MEDIUM e.g. email]", + "utm_name": "[NAME OF YOUR CAMPAIGN]", "utm_term": "[IDENTIFY PAID KEYWORDS HERE]" - }, + }, "open_tracking": { - "enable": True, + "enable": True, "substitution_tag": "%opentrack" - }, + }, "subscription_tracking": { - "enable": True, - "html": "If you would like to unsubscribe and stop receiving these emails <% clickhere %>.", - "substitution_tag": "<%click here%>", + "enable": True, + "html": "If you would like to unsubscribe and stop receiving these emails <% clickhere %>.", + "substitution_tag": "<%click here%>", "text": "If you would like to unsubscribe and stop receiveing these emails <% click here %>." } } diff --git a/examples/subusers/subusers.py b/examples/subusers/subusers.py index aa4c78c6e..6aa91e535 100644 --- a/examples/subusers/subusers.py +++ b/examples/subusers/subusers.py @@ -27,7 +27,7 @@ # List all Subusers # # GET /subusers # -params = {'username': 'test_string', 'limit': 0, 'offset': 0} +params = {'username': 'test_string', 'limit': 1, 'offset': 1} response = sg.client.subusers.get(query_params=params) print(response.status_code) print(response.body) @@ -161,7 +161,7 @@ # Retrieve the monthly email statistics for a single subuser # # GET /subusers/{subuser_name}/stats/monthly # -params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 0, 'sort_by_metric': 'test_string', 'offset': 1} +params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 1, 'sort_by_metric': 'test_string', 'offset': 1} subuser_name = "test_url_param" response = sg.client.subusers._(subuser_name).stats.monthly.get(query_params=params) print(response.status_code) diff --git a/examples/suppression/suppression.py b/examples/suppression/suppression.py index 2a71e2458..abdaef76d 100644 --- a/examples/suppression/suppression.py +++ b/examples/suppression/suppression.py @@ -55,7 +55,7 @@ # Retrieve all bounces # # GET /suppression/bounces # -params = {'start_time': 0, 'end_time': 0} +params = {'start_time': 1, 'end_time': 1} response = sg.client.suppression.bounces.get(query_params=params) print(response.status_code) print(response.body) diff --git a/examples/user/user.py b/examples/user/user.py index 8a52b1df5..fa3da7401 100644 --- a/examples/user/user.py +++ b/examples/user/user.py @@ -224,7 +224,22 @@ print(response.headers) ################################################## -# Retrieve Parse Webhook settings # +# Create a parse setting # +# POST /user/webhooks/parse/settings # + +data = { + "hostname": "myhostname.com", + "send_raw": False, + "spam_check": True, + "url": "http://email.myhosthame.com" +} +response = sg.client.user.webhooks.parse.settings.post(request_body=data) +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Retrieve all parse settings # # GET /user/webhooks/parse/settings # response = sg.client.user.webhooks.parse.settings.get() @@ -232,6 +247,41 @@ print(response.body) print(response.headers) +################################################## +# Retrieve a specific parse setting # +# GET /user/webhooks/parse/settings/{hostname} # + +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname).get() +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Delete a parse setting # +# DELETE /user/webhooks/parse/settings/{hostname} # + +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname).delete() +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Update a parse setting # +# PATCH /user/webhooks/parse/settings/{hostname}/ # + +data = { + "send_raw": True, + "spam_check": False, + "url": "http://newdomain.com/parse" +} +hostname = "test_url_param" +response = sg.client.user.webhooks.parse.settings._(hostname)..patch(request_body=data) +print(response.status_code) +print(response.body) +print(response.headers) + ################################################## # Retrieves Inbound Parse Webhook statistics. # # GET /user/webhooks/parse/stats # diff --git a/sendgrid/sendgrid.py b/sendgrid/sendgrid.py index a4119cff4..ac043b002 100644 --- a/sendgrid/sendgrid.py +++ b/sendgrid/sendgrid.py @@ -20,7 +20,8 @@ def __init__(self, **opts): headers = { "Authorization": 'Bearer {0}'.format(self._apikey), - "User-agent": self.useragent + "User-agent": self.useragent, + "Accept": 'application/json' } self.client = python_http_client.Client(host=self.host, diff --git a/sendgrid/version.py b/sendgrid/version.py index 02bf5e2c6..54a233ce7 100644 --- a/sendgrid/version.py +++ b/sendgrid/version.py @@ -1,2 +1,2 @@ -version_info = (3, 0, 0) +version_info = (3, 0, 1) __version__ = '.'.join(str(v) for v in version_info) diff --git a/test/test_sendgrid.py b/test/test_sendgrid.py index 2b1e1115c..de7f8ee1b 100644 --- a/test/test_sendgrid.py +++ b/test/test_sendgrid.py @@ -81,9 +81,46 @@ def test_access_settings_whitelist__rule_id__delete(self): response = self.sg.client.access_settings.whitelist._(rule_id).delete(request_headers=headers) self.assertEqual(response.status_code, 204) + def test_alerts_post(self): + data = { + "email_to": "example@example.com", + "frequency": "daily", + "type": "stats_notification" +} + headers = {'X-Mock': 201} + response = self.sg.client.alerts.post(request_body=data, request_headers=headers) + self.assertEqual(response.status_code, 201) + + def test_alerts_get(self): + headers = {'X-Mock': 200} + response = self.sg.client.alerts.get(request_headers=headers) + self.assertEqual(response.status_code, 200) + + def test_alerts__alert_id__patch(self): + data = { + "email_to": "example@example.com" +} + alert_id = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.alerts._(alert_id).patch(request_body=data, request_headers=headers) + self.assertEqual(response.status_code, 200) + + def test_alerts__alert_id__get(self): + alert_id = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.alerts._(alert_id).get(request_headers=headers) + self.assertEqual(response.status_code, 200) + + def test_alerts__alert_id__delete(self): + alert_id = "test_url_param" + headers = {'X-Mock': 204} + response = self.sg.client.alerts._(alert_id).delete(request_headers=headers) + self.assertEqual(response.status_code, 204) + def test_api_keys_post(self): data = { "name": "My API Key", + "sample": "data", "scopes": [ "mail.send", "alerts.create", @@ -95,8 +132,9 @@ def test_api_keys_post(self): self.assertEqual(response.status_code, 201) def test_api_keys_get(self): + params = {'limit': 1} headers = {'X-Mock': 200} - response = self.sg.client.api_keys.get(request_headers=headers) + response = self.sg.client.api_keys.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) def test_api_keys__api_key_id__put(self): @@ -135,17 +173,18 @@ def test_api_keys__api_key_id__delete(self): def test_asm_groups_post(self): data = { - "description": "A group description", - "is_default": False, - "name": "A group name" + "description": "Suggestions for products our users might like.", + "is_default": True, + "name": "Product Suggestions" } - headers = {'X-Mock': 200} + headers = {'X-Mock': 201} response = self.sg.client.asm.groups.post(request_body=data, request_headers=headers) - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, 201) def test_asm_groups_get(self): + params = {'id': 1} headers = {'X-Mock': 200} - response = self.sg.client.asm.groups.get(request_headers=headers) + response = self.sg.client.asm.groups.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) def test_asm_groups__group_id__patch(self): @@ -189,6 +228,19 @@ def test_asm_groups__group_id__suppressions_get(self): response = self.sg.client.asm.groups._(group_id).suppressions.get(request_headers=headers) self.assertEqual(response.status_code, 200) + def test_asm_groups__group_id__suppressions_search_post(self): + data = { + "recipient_emails": [ + "exists1@example.com", + "exists2@example.com", + "doesnotexists@example.com" + ] +} + group_id = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.asm.groups._(group_id).suppressions.search.post(request_body=data, request_headers=headers) + self.assertEqual(response.status_code, 200) + def test_asm_groups__group_id__suppressions__email__delete(self): group_id = "test_url_param" email = "test_url_param" @@ -196,6 +248,11 @@ def test_asm_groups__group_id__suppressions__email__delete(self): response = self.sg.client.asm.groups._(group_id).suppressions._(email).delete(request_headers=headers) self.assertEqual(response.status_code, 204) + def test_asm_suppressions_get(self): + headers = {'X-Mock': 200} + response = self.sg.client.asm.suppressions.get(request_headers=headers) + self.assertEqual(response.status_code, 200) + def test_asm_suppressions_global_post(self): data = { "recipient_emails": [ @@ -219,6 +276,12 @@ def test_asm_suppressions_global__email__delete(self): response = self.sg.client.asm.suppressions._("global")._(email).delete(request_headers=headers) self.assertEqual(response.status_code, 204) + def test_asm_suppressions__email__get(self): + email = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.asm.suppressions._(email).get(request_headers=headers) + self.assertEqual(response.status_code, 200) + def test_browsers_stats_get(self): params = {'end_date': '2016-04-01', 'aggregated_by': 'day', 'browsers': 'test_string', 'limit': 'test_string', 'offset': 'test_string', 'start_date': '2016-01-01'} headers = {'X-Mock': 200} @@ -251,7 +314,7 @@ def test_campaigns_post(self): self.assertEqual(response.status_code, 201) def test_campaigns_get(self): - params = {'limit': 0, 'offset': 0} + params = {'limit': 1, 'offset': 1} headers = {'X-Mock': 200} response = self.sg.client.campaigns.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) @@ -413,14 +476,14 @@ def test_contactdb_lists__list_id__patch(self): data = { "name": "newlistname" } - params = {'list_id': 0} + params = {'list_id': 1} list_id = "test_url_param" headers = {'X-Mock': 200} response = self.sg.client.contactdb.lists._(list_id).patch(request_body=data, query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) def test_contactdb_lists__list_id__get(self): - params = {'list_id': 0} + params = {'list_id': 1} list_id = "test_url_param" headers = {'X-Mock': 200} response = self.sg.client.contactdb.lists._(list_id).get(query_params=params, request_headers=headers) @@ -444,7 +507,7 @@ def test_contactdb_lists__list_id__recipients_post(self): self.assertEqual(response.status_code, 201) def test_contactdb_lists__list_id__recipients_get(self): - params = {'page': 1, 'page_size': 1, 'list_id': 0} + params = {'page': 1, 'page_size': 1, 'list_id': 1} list_id = "test_url_param" headers = {'X-Mock': 200} response = self.sg.client.contactdb.lists._(list_id).recipients.get(query_params=params, request_headers=headers) @@ -458,7 +521,7 @@ def test_contactdb_lists__list_id__recipients__recipient_id__post(self): self.assertEqual(response.status_code, 201) def test_contactdb_lists__list_id__recipients__recipient_id__delete(self): - params = {'recipient_id': 0, 'list_id': 0} + params = {'recipient_id': 1, 'list_id': 1} list_id = "test_url_param" recipient_id = "test_url_param" headers = {'X-Mock': 204} @@ -522,7 +585,7 @@ def test_contactdb_recipients_count_get(self): self.assertEqual(response.status_code, 200) def test_contactdb_recipients_search_get(self): - params = {'{field_name}': 'test_string'} + params = {'%7Bfield_name%7D': 'test_string', '{field_name}': 'test_string'} headers = {'X-Mock': 200} response = self.sg.client.contactdb.recipients.search.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) @@ -604,7 +667,7 @@ def test_contactdb_segments__segment_id__patch(self): self.assertEqual(response.status_code, 200) def test_contactdb_segments__segment_id__get(self): - params = {'segment_id': 0} + params = {'segment_id': 1} segment_id = "test_url_param" headers = {'X-Mock': 200} response = self.sg.client.contactdb.segments._(segment_id).get(query_params=params, request_headers=headers) @@ -767,7 +830,7 @@ def test_mail_send_post(self): "content": [ { "type": "text/html", - "value": "

Hello, world!

" + "value": "

Hello, world!

" } ], "custom_args": { @@ -829,13 +892,8 @@ def test_mail_send_post(self): "send_at": 1409348513, "subject": "Hello, World!", "substitutions": { - "sub": { - "%name%": [ - "John", - "Jane", - "Sam" - ] - } + "id": "substitutions", + "type": "object" }, "to": [ { @@ -1077,7 +1135,7 @@ def test_subusers_post(self): self.assertEqual(response.status_code, 200) def test_subusers_get(self): - params = {'username': 'test_string', 'limit': 0, 'offset': 0} + params = {'username': 'test_string', 'limit': 1, 'offset': 1} headers = {'X-Mock': 200} response = self.sg.client.subusers.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) @@ -1163,7 +1221,7 @@ def test_subusers__subuser_name__monitor_delete(self): self.assertEqual(response.status_code, 204) def test_subusers__subuser_name__stats_monthly_get(self): - params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 0, 'sort_by_metric': 'test_string', 'offset': 1} + params = {'date': 'test_string', 'sort_by_direction': 'asc', 'limit': 1, 'sort_by_metric': 'test_string', 'offset': 1} subuser_name = "test_url_param" headers = {'X-Mock': 200} response = self.sg.client.subusers._(subuser_name).stats.monthly.get(query_params=params, request_headers=headers) @@ -1200,7 +1258,7 @@ def test_suppression_blocks__email__delete(self): self.assertEqual(response.status_code, 204) def test_suppression_bounces_get(self): - params = {'start_time': 0, 'end_time': 0} + params = {'start_time': 1, 'end_time': 1} headers = {'X-Mock': 200} response = self.sg.client.suppression.bounces.get(query_params=params, request_headers=headers) self.assertEqual(response.status_code, 200) @@ -1589,11 +1647,45 @@ def test_user_webhooks_event_test_post(self): response = self.sg.client.user.webhooks.event.test.post(request_body=data, request_headers=headers) self.assertEqual(response.status_code, 204) + def test_user_webhooks_parse_settings_post(self): + data = { + "hostname": "myhostname.com", + "send_raw": False, + "spam_check": True, + "url": "http://email.myhosthame.com" +} + headers = {'X-Mock': 201} + response = self.sg.client.user.webhooks.parse.settings.post(request_body=data, request_headers=headers) + self.assertEqual(response.status_code, 201) + def test_user_webhooks_parse_settings_get(self): headers = {'X-Mock': 200} response = self.sg.client.user.webhooks.parse.settings.get(request_headers=headers) self.assertEqual(response.status_code, 200) + def test_user_webhooks_parse_settings__hostname__patch(self): + data = { + "send_raw": True, + "spam_check": False, + "url": "http://newdomain.com/parse" +} + hostname = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.user.webhooks.parse.settings._(hostname).patch(request_body=data, request_headers=headers) + self.assertEqual(response.status_code, 200) + + def test_user_webhooks_parse_settings__hostname__get(self): + hostname = "test_url_param" + headers = {'X-Mock': 200} + response = self.sg.client.user.webhooks.parse.settings._(hostname).get(request_headers=headers) + self.assertEqual(response.status_code, 200) + + def test_user_webhooks_parse_settings__hostname__delete(self): + hostname = "test_url_param" + headers = {'X-Mock': 204} + response = self.sg.client.user.webhooks.parse.settings._(hostname).delete(request_headers=headers) + self.assertEqual(response.status_code, 204) + def test_user_webhooks_parse_stats_get(self): params = {'aggregated_by': 'day', 'limit': 'test_string', 'start_date': '2016-01-01', 'end_date': '2016-04-01', 'offset': 'test_string'} headers = {'X-Mock': 200}