Skip to content

Commit b5afcca

Browse files
authored
feat: geolocation setter in sendgrid-python for GDPR compliance (#1073)
1 parent d3ddc8a commit b5afcca

File tree

4 files changed

+87
-2
lines changed

4 files changed

+87
-2
lines changed

.github/workflows/lint-python.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ jobs:
1313
steps:
1414
- uses: actions/checkout@v3
1515
- run: pip install --user ruff
16-
- run: ruff --format=github --ignore="E722,F40,F841" --line-length=681 --target-version=py37 .
16+
- run: ruff --ignore="E722,F40,F841" --line-length=320 --target-version=py37 .

examples/dataresidency/set_region.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import sendgrid
2+
import os
3+
4+
from sendgrid import Email, To, Content, Mail
5+
6+
# Example 1
7+
# setting region to be "global"
8+
9+
sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
10+
from_email = Email("[email protected]")
11+
to_email = To("[email protected]")
12+
subject = "Sending with SendGrid is Fun"
13+
content = Content("text/plain", "and easy to do anywhere, even with Python")
14+
mail = Mail(from_email, to_email, subject, content)
15+
sg.set_sendgrid_data_residency("global")
16+
print(sg.client.host)
17+
response = sg.client.mail.send.post(request_body=mail.get())
18+
print(response)
19+
print(response.status_code)
20+
print(response.body)
21+
print(response.headers)
22+
23+
# Example 2
24+
# setting region to "eu"
25+
sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY_EU'))
26+
sg.set_sendgrid_data_residency("eu")
27+
from_email = Email("[email protected]")
28+
to_email = To("[email protected]")
29+
subject = "Sending with SendGrid is Fun"
30+
content = Content("text/plain", "and easy to do anywhere, even with Python")
31+
print(sg.client.host)
32+
mail = Mail(from_email, to_email, subject, content)
33+
response = sg.client.mail.send.post(request_body=mail.get())
34+
print(response)
35+
print(response.status_code)
36+
print(response.body)
37+
print(response.headers)

sendgrid/base_interface.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import python_http_client
22

3+
region_host_dict = {'eu':'https://api.eu.sendgrid.com','global':'https://api.sendgrid.com'}
34

45
class BaseInterface(object):
56
def __init__(self, auth, host, impersonate_subuser):
@@ -22,10 +23,10 @@ def __init__(self, auth, host, impersonate_subuser):
2223
"""
2324
from . import __version__
2425
self.auth = auth
25-
self.host = host
2626
self.impersonate_subuser = impersonate_subuser
2727
self.version = __version__
2828
self.useragent = 'sendgrid/{};python'.format(self.version)
29+
self.host = host
2930

3031
self.client = python_http_client.Client(
3132
host=self.host,
@@ -60,3 +61,23 @@ def send(self, message):
6061
message = message.get()
6162

6263
return self.client.mail.send.post(request_body=message)
64+
65+
def set_sendgrid_data_residency(self, region):
66+
"""
67+
Client libraries contain setters for specifying region/edge.
68+
This supports global and eu regions only. This set will likely expand in the future.
69+
Global is the default residency (or region)
70+
Global region means the message will be sent through https://api.sendgrid.com
71+
EU region means the message will be sent through https://api.eu.sendgrid.com
72+
:param region: string
73+
:return:
74+
"""
75+
if region in region_host_dict.keys():
76+
self.host = region_host_dict[region]
77+
if self._default_headers is not None:
78+
self.client = python_http_client.Client(
79+
host=self.host,
80+
request_headers=self._default_headers,
81+
version=3)
82+
else:
83+
raise ValueError("region can only be \"eu\" or \"global\"")

test/unit/test_sendgrid.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import unittest
2+
import sendgrid
3+
4+
class UnitTests(unittest.TestCase):
5+
def test_host_with_no_region(self):
6+
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
7+
self.assertEqual("https://api.sendgrid.com",sg.client.host)
8+
9+
def test_host_with_eu_region(self):
10+
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
11+
sg.set_sendgrid_data_residency("eu")
12+
self.assertEqual("https://api.eu.sendgrid.com",sg.client.host)
13+
14+
def test_host_with_global_region(self):
15+
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
16+
sg.set_sendgrid_data_residency("global")
17+
self.assertEqual("https://api.sendgrid.com",sg.client.host)
18+
19+
def test_with_region_is_none(self):
20+
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
21+
with self.assertRaises(ValueError):
22+
sg.set_sendgrid_data_residency(None)
23+
24+
def test_with_region_is_invalid(self):
25+
sg = sendgrid.SendGridAPIClient(api_key='MY_API_KEY')
26+
with self.assertRaises(ValueError):
27+
sg.set_sendgrid_data_residency("abc")

0 commit comments

Comments
 (0)