Skip to content

Commit

Permalink
feat: geolocation setter in sendgrid-python for GDPR compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
manisha1997 committed Nov 14, 2023
1 parent 2fe1459 commit 30b1ca6
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 4 deletions.
36 changes: 36 additions & 0 deletions examples/dataresidency/set_region.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import sendgrid
import os

from sendgrid import Email, To, Content, Mail

# Example 1
# setting region to be "global"
sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
sg.set_region("global")
from_email = Email("[email protected]")
to_email = To("[email protected]")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
print(sg.host)
mail = Mail(from_email, to_email, subject, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response)
print(response.status_code)
print(response.body)
print(response.headers)

# Example 2
# setting region to "eu"
sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
sg.set_region("eu")
from_email = Email("[email protected]")
to_email = To("[email protected]")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
print(sg.host)
mail = Mail(from_email, to_email, subject, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response)
print(response.status_code)
print(response.body)
print(response.headers)
30 changes: 28 additions & 2 deletions sendgrid/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


class BaseInterface(object):
def __init__(self, auth, host, impersonate_subuser):
def __init__(self, auth, host, region, impersonate_subuser):
"""
Construct the Twilio SendGrid v3 API object.
Note that the underlying client is being set up during initialization,
Expand All @@ -19,10 +19,15 @@ def __init__(self, auth, host, impersonate_subuser):
:type impersonate_subuser: string
:param host: base URL for API calls
:type host: string
:param region: To determine the region which can only be 'global' or 'eu'
:type region: string
"""
from . import __version__
self.auth = auth
self.host = host
if host is not None and region == 'global':
self.set_host(host)
else:
self.set_region(region)
self.impersonate_subuser = impersonate_subuser
self.version = __version__
self.useragent = 'sendgrid/{};python'.format(self.version)
Expand Down Expand Up @@ -60,3 +65,24 @@ def send(self, message):
message = message.get()

return self.client.mail.send.post(request_body=message)

def set_host(self,host):
self.host = host

def set_region(self,region):
"""
* Client libraries contain setters for specifying region/edge.
* This allows support global and eu regions only. This set will likely expand in the future.
* Global should be the default
* Global region means the message should be sent through:
* HTTP: api.sendgrid.com
* EU region means the message should be sent through:
* HTTP: api.eu.sendgrid.com
:param region:
:return:
"""
region_host_dict = {'eu':'https://api.eu.sendgrid.com','global':'https://api.sendgrid.com'}
if region in region_host_dict.keys():
self.host = region_host_dict[region]
else:
raise ValueError("region can only be \"eu\" or \"global\"")
8 changes: 6 additions & 2 deletions sendgrid/sendgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class SendGridAPIClient(BaseInterface):
def __init__(
self,
api_key=None,
host='https://api.sendgrid.com',
host=None,
region='global',
impersonate_subuser=None):
"""
Construct the Twilio SendGrid v3 API object.
Expand All @@ -51,8 +52,11 @@ def __init__(
:type impersonate_subuser: string
:param host: base URL for API calls
:type host: string
:param region: To determine the region which can only be 'global' or 'eu'
:type region: string
"""
self.api_key = api_key or os.environ.get('SENDGRID_API_KEY')
auth = 'Bearer {}'.format(self.api_key)

super(SendGridAPIClient, self).__init__(auth, host, impersonate_subuser)
super(SendGridAPIClient, self).__init__(auth, host, region, impersonate_subuser)

43 changes: 43 additions & 0 deletions test/unit/test_sendgrid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import unittest
import sendgrid

class UnitTests(unittest.TestCase):
def test_host_with_no_region(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
self.assertEqual("https://api.sendgrid.com",sg.host)

def test_host_with_eu_region(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
sg.set_region("eu")
self.assertEqual("https://api.eu.sendgrid.com",sg.host)

def test_host_with_global_region(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
sg.set_region("global")
self.assertEqual("https://api.sendgrid.com",sg.host)

def test_host_with_host_first_eu_region_second(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
sg.set_host("https://sendgrid.com")
sg.set_region("eu")
self.assertEqual("https://api.eu.sendgrid.com",sg.host)

def test_host_with_eu_first_host_second(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
sg.set_region("eu")
sg.set_host("https://sendgrid.com")
self.assertEqual("https://sendgrid.com",sg.host)

def test_host_using_constructor(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY',host='https://sendgrid.com')
self.assertEqual("https://sendgrid.com",sg.host)

def test_with_region_is_none(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
with self.assertRaises(ValueError):
sg.set_region("")

def test_with_region_is_none(self):
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
with self.assertRaises(ValueError):
sg.set_region("abc")

0 comments on commit 30b1ca6

Please sign in to comment.