-
Notifications
You must be signed in to change notification settings - Fork 716
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #128 from sendgrid/v3_beta
V3 beta
- Loading branch information
Showing
25 changed files
with
903 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
SENDGRID_API_KEY=your_sendgrid_api_key | ||
SENDGRID_USERNAME=your_sendgrid_username | ||
SENDGRID_PASSWORD=your_sendgrid_password |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,5 +8,8 @@ sdist | |
*.egg | ||
*.egg-info | ||
*.pyc | ||
.idea/ | ||
venv/ | ||
.idea | ||
.env | ||
.python-version | ||
.tox/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ Announcements | |
|
||
For users of our `Web API v3 endpoints`_, we have begun integrating v3 endpoints into this library. As part of this process we have implemented a test automation tool, TOX_. We are also updating and enhancing the core library code. | ||
|
||
In no particular order, we have implemented a few of the v3 endpoints already and would appreciate your feedback. Please feel free to submit issues and pull requests on the `v3_beta branch`_. | ||
In no particular order, we have implemented a `few of the v3`_ endpoints already and would appreciate your feedback. | ||
|
||
Thank you for your continued support! | ||
|
||
|
@@ -232,6 +232,76 @@ add_content_id | |
message.add_attachment('image.png', open('./image.png', 'rb')) | ||
message.add_content_id('image.png', 'ID_IN_HTML') | ||
message.set_html('<html><body>TEXT BEFORE IMAGE<img src="cid:ID_IN_HTML"></img>AFTER IMAGE</body></html>') | ||
WEB API v3 | ||
---------- | ||
|
||
.. _APIKeysAnchor: | ||
|
||
`APIKeys`_ | ||
~~~~~~~~~~ | ||
|
||
List all API Keys belonging to the authenticated user. | ||
|
||
.. code:: python | ||
client = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) | ||
status, msg = client.apikeys.get() | ||
`Advanced Suppression Manager (ASM)`_ | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Advanced Suppression Manager gives your recipients more control over the types of emails they want to receive by letting them opt out of messages from a certain type of email. | ||
|
||
More information_. | ||
|
||
.. _information: https://sendgrid.com/docs/API_Reference/Web_API_v3/Advanced_Suppression_Manager/index.html | ||
|
||
ASM Groups | ||
~~~~~~~~~~ | ||
|
||
Retrieve all suppression groups associated with the user. | ||
|
||
.. code:: python | ||
client = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) | ||
status, msg = client.asm_groups.get() | ||
Get a single record. | ||
|
||
.. code:: python | ||
status, msg = client.asm_groups.get(record_id) | ||
ASM Suppressions | ||
~~~~~~~~~~~~~~~~ | ||
|
||
Suppressions are email addresses that can be added to groups to prevent certain types of emails from being delivered to those addresses. | ||
|
||
Add recipient addresses to the suppressions list for a given group. | ||
|
||
.. code:: python | ||
client = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) | ||
group_id = <group_id_number> # If no group_id_number, the emails will be added to the global suppression group | ||
emails = ['[email protected]', '[email protected]'] | ||
status, msg = client.asm_suppressions.post(group_id, emails) | ||
Get suppressed addresses for a given group. | ||
|
||
.. code:: python | ||
status, msg = client.asm_suppressions.get(<group_id>) | ||
Get suppression groups associated with a given recipient address. | ||
|
||
.. code:: python | ||
status, msg = client.asm_suppressions.get(None,<email_address>) | ||
Delete a recipient email from the suppressions list for a group. | ||
|
||
status, msg = client.asm_suppressions.delete(<group_id>,<email_address>) | ||
|
||
SendGrid's `X-SMTPAPI`_ | ||
----------------------- | ||
|
@@ -380,20 +450,48 @@ set_asm_group_id | |
Using Templates from the Template Engine | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
.. code:: python | ||
|
||
|
||
message.add_filter('templates', 'enable', '1') | ||
message.add_filter('templates', 'template_id', 'TEMPLATE-ALPHA-NUMERIC-ID') | ||
|
||
Tests | ||
~~~~~ | ||
|
||
**Prerequisites:** | ||
|
||
- Mac OS X Prerequisite: | ||
|
||
.. code:: python | ||
xcode-select --install | ||
- Install pyenv and tox | ||
|
||
.. code:: python | ||
brew update | ||
brew install pyenv | ||
pip install tox | ||
- Add `eval "$(pyenv init -)"` to your profile after installing tox, you only need to do this once. | ||
|
||
.. code:: python | ||
pyenv install 2.6.9 | ||
pyenv install 2.7.8 | ||
pyenv install 3.2.6 | ||
**Run the tests:** | ||
|
||
.. code:: python | ||
virtualenv venv | ||
source venv/bin/activate | ||
source venv/bin/activate #or . ./activate.sh | ||
python setup.py install | ||
python test/__init__.py | ||
pyenv local 3.2.6 2.7.8 2.6.9 | ||
pyenv rehash | ||
tox | ||
Deploying | ||
~~~~~~~~~ | ||
|
@@ -419,4 +517,4 @@ MIT License | |
.. _Filter: http://sendgrid.com/docs/API_Reference/SMTP_API/apps.html | ||
.. _`Web API v3 endpoints`: https://sendgrid.com/docs/API_Reference/Web_API_v3/index.html | ||
.. _TOX: https://testrun.org/tox/latest/ | ||
.. _`v3_beta branch`: https://github.com/sendgrid/sendgrid-python/tree/v3_beta | ||
.. _`few of the v3`: APIKeysAnchor_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/bash | ||
# Use this to activate the virtual environment, use the following to execute in current shell | ||
# . ./activate | ||
source venv/bin/activate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import sendgrid | ||
import os | ||
if os.path.exists('.env'): | ||
for line in open('.env'): | ||
var = line.strip().split('=') | ||
if len(var) == 2: | ||
os.environ[var[0]] = var[1] | ||
|
||
sg = sendgrid.SendGridClient(os.environ.get('SENDGRID_USERNAME'), os.environ.get('SENDGRID_PASSWORD')) | ||
|
||
message = sendgrid.Mail() | ||
message.add_to('Elmer Thomas <[email protected]>') | ||
message.set_subject('Testing from the Python library') | ||
message.set_html('<b>This was a successful test!</b>') | ||
message.set_text('This was a successful test!') | ||
message.set_from('Elmer Thomas <[email protected]>') | ||
status, msg = sg.send(message) | ||
print status | ||
print msg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import sendgrid | ||
import json | ||
|
||
import os | ||
if os.path.exists('.env'): | ||
for line in open('.env'): | ||
var = line.strip().split('=') | ||
if len(var) == 2: | ||
os.environ[var[0]] = var[1] | ||
|
||
|
||
|
||
client = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) | ||
|
||
status, msg = client.asm_suppressions.delete(67,'[email protected]') | ||
print status | ||
print msg | ||
|
||
""" | ||
status, msg = client.asm_suppressions.post(60, ['[email protected]', '[email protected]']) | ||
print status | ||
print msg | ||
status, msg = client.asm_suppressions.get(None,'[email protected]') | ||
print status | ||
print msg | ||
status, msg = client.asm_groups.get([66,67,50]) | ||
print status | ||
print msg | ||
name = "My Amazing API Key" | ||
status, msg = client.apikeys.post(name) | ||
msg = json.loads(msg) | ||
api_key_id = msg['api_key_id'] | ||
print status | ||
print msg | ||
name = "My NEW API Key 3000" | ||
status, msg = client.apikeys.patch(api_key_id, name) | ||
print status | ||
print msg | ||
status, msg = client.apikeys.delete(api_key_id) | ||
print status | ||
status, msg = client.apikeys.get() | ||
print status | ||
print msg | ||
# Get a list of all valid API Keys from your account | ||
status, msg = client.apikeys.get() | ||
print status | ||
print msg | ||
# Create a new API Key | ||
name = "My API Key 10" | ||
status, msg = client.apikeys.post(name) | ||
print status | ||
print msg | ||
# Delete an API Key with a given api_key_id | ||
api_key_id = "zc0r5sW5TTuBQGsMPMUx0A" | ||
status, msg = client.apikeys.delete(api_key_id) | ||
print status | ||
print msg | ||
# Update the name of an API Key, given an api_key_id | ||
api_key_id = "API_KEY" | ||
name = "My API Key 3" | ||
status, msg = client.apikeys.patch(api_key_id, name) | ||
print status | ||
print msg | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
from .version import __version__ | ||
from .sendgrid import SendGridClient | ||
from .exceptions import SendGridError, SendGridClientError, SendGridServerError | ||
#v2 API | ||
from .message import Mail | ||
#v3 API | ||
from .client import SendGridAPIClient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import json | ||
from .version import __version__ | ||
from socket import timeout | ||
try: | ||
import urllib.request as urllib_request | ||
from urllib.parse import urlencode | ||
from urllib.error import HTTPError | ||
except ImportError: # Python 2 | ||
import urllib2 as urllib_request | ||
from urllib2 import HTTPError | ||
from urllib import urlencode | ||
|
||
from .exceptions import SendGridClientError, SendGridServerError | ||
from .resources.apikeys import APIKeys | ||
from .resources.asm_groups import ASMGroups | ||
from .resources.asm_suppressions import ASMSuppressions | ||
|
||
class SendGridAPIClient(object): | ||
|
||
"""SendGrid API.""" | ||
|
||
def __init__(self, apikey, **opts): | ||
""" | ||
Construct SendGrid API object. | ||
Args: | ||
apikey: SendGrid API key | ||
opts: You can pass in host or proxies | ||
""" | ||
self._apikey = apikey | ||
self.useragent = 'sendgrid/' + __version__ + ';python_v3' | ||
self.host = opts.get('host', 'https://api.sendgrid.com') | ||
# urllib cannot connect to SSL servers using proxies | ||
self.proxies = opts.get('proxies', None) | ||
|
||
self.apikeys = APIKeys(self) | ||
self.asm_groups = ASMGroups(self) | ||
self.asm_suppressions = ASMSuppressions(self) | ||
|
||
@property | ||
def apikey(self): | ||
return self._apikey | ||
|
||
@apikey.setter | ||
def apikey(self, value): | ||
self._apikey = value | ||
|
||
def _build_request(self, url, json_header=False, method='GET', data=None): | ||
if self.proxies: | ||
proxy_support = urllib_request.ProxyHandler(self.proxies) | ||
opener = urllib_request.build_opener(proxy_support) | ||
urllib_request.install_opener(opener) | ||
req = urllib_request.Request(url) | ||
req.get_method = lambda: method | ||
req.add_header('User-Agent', self.useragent) | ||
req.add_header('Authorization', 'Bearer ' + self.apikey) | ||
if json_header: | ||
req.add_header('Content-Type', 'application/json') | ||
try: | ||
if data: | ||
response = urllib_request.urlopen(req, json.dumps(data)) | ||
else: | ||
response = urllib_request.urlopen(req, timeout=10) | ||
except HTTPError as e: | ||
if 400 <= e.code < 500: | ||
raise SendGridClientError(e.code, e.read()) | ||
elif 500 <= e.code < 600: | ||
raise SendGridServerError(e.code, e.read()) | ||
else: | ||
assert False | ||
except timeout as e: | ||
raise SendGridClientError(408, 'Request timeout') | ||
body = response.read() | ||
return response.getcode(), body | ||
|
||
def get(self, api): | ||
url = self.host + api.endpoint | ||
response, body = self._build_request(url, False, 'GET') | ||
return response, body | ||
|
||
def post(self, api, data): | ||
url = self.host + api.endpoint | ||
response, body = self._build_request(url, True, 'POST', data) | ||
return response, body | ||
|
||
def delete(self, api): | ||
url = self.host + api.endpoint | ||
response, body = self._build_request(url, False, 'DELETE') | ||
return response, body | ||
|
||
def patch(self, api, data): | ||
url = self.host + api.endpoint | ||
response, body = self._build_request(url, True, 'PATCH', data) | ||
return response, body |
Oops, something went wrong.