From ec22dcf5df6662ec81e068d8edb5f3df23ee16d0 Mon Sep 17 00:00:00 2001 From: koenoki Date: Mon, 25 Jan 2016 17:23:53 -0800 Subject: [PATCH 1/8] Add V3 Subusers API support --- sendgrid/client.py | 2 ++ sendgrid/resources/subusers.py | 66 ++++++++++++++++++++++++++++++++++ test/test_subusers.py | 56 +++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 sendgrid/resources/subusers.py create mode 100644 test/test_subusers.py diff --git a/sendgrid/client.py b/sendgrid/client.py index 6b220b50c..7b1df4410 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -17,6 +17,7 @@ from .resources.asm_global_suppressions import ASMGlobalSuppressions from .resources.suppressions import Suppressions from .resources.stats import Stats +from .resources.subusers import Subusers class SendGridAPIClient(object): @@ -42,6 +43,7 @@ def __init__(self, apikey, **opts): self.asm_global_suppressions = ASMGlobalSuppressions(self) self.suppressions = Suppressions(self) self.stats = Stats(self) + self.subusers = Subusers(self) @property def apikey(self): diff --git a/sendgrid/resources/subusers.py b/sendgrid/resources/subusers.py new file mode 100644 index 000000000..7ff4f6a66 --- /dev/null +++ b/sendgrid/resources/subusers.py @@ -0,0 +1,66 @@ +class Subusers(object): + + def __init__(self, client, **opts): + """ + Constructs SendGrid Subusers object. + + See https://sendgrid.com/docs/API_Reference/Web_API_v3/subusers.html + """ + self._name = None + self._base_endpoint = "/v3/subusers" + self._endpoint = "/v3/subusers" + self._client = client + + @property + def name(self): + return self._name + + @name.setter + def name(self, value): + self._name = value + + @property + def base_endpoint(self): + return self._base_endpoint + + @property + def endpoint(self): + endpoint = self._endpoint + return endpoint + + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + + @property + def client(self): + return self._client + + # Get a list of active API keys + def get(self): + return self.client.get(self) + + # Create a new subuser with username, email, password (string) and IP list (string[]) + def post(self, username, email, password, ips = []): + data = {} + self.username = username + self.email = email + self.password = password + data['username'] = self.username + data['email'] = self.email + data['password'] = self.password + data['ips'] = ips + return self.client.post(self, data) + + # Delete a subuser + def delete(self, username): + self.endpoint = self._base_endpoint + "/" + username + return self.client.delete(self) + + # Enable/disable a subuser + def patch(self, username, disabled): + data = {} + self.disabled = disabled + data['disabled'] = self.disabled + self.endpoint = self._base_endpoint + "/" + username + return self.client.patch(self, data) diff --git a/test/test_subusers.py b/test/test_subusers.py new file mode 100644 index 000000000..bab1ebf5d --- /dev/null +++ b/test/test_subusers.py @@ -0,0 +1,56 @@ +from .base_test import BaseTest, MockSendGridAPIClientRequest +import os +try: + import unittest2 as unittest +except ImportError: + import unittest +try: + from StringIO import StringIO +except ImportError: # Python 3 + from io import StringIO + +import sendgrid +from sendgrid.client import SendGridAPIClient +from sendgrid.version import __version__ + +SG_KEY = os.getenv('SG_KEY') or 'SENDGRID_APIKEY' + +class TestSubusers(unittest.TestCase): + def setUp(self): + SendGridAPIClient = MockSendGridAPIClientRequest + self.client = SendGridAPIClient(SG_KEY) + + def test_subusers_init(self): + self.subusers = self.client.subusers + self.assertEqual(self.subusers.name, None) + self.assertEqual(self.subusers.base_endpoint, "/v3/subusers") + self.assertEqual(self.subusers.endpoint, "/v3/subusers") + self.assertEqual(self.subusers.client, self.client) + + def test_subusers_post(self): + username = "test-subuser1" + email = "keiji+test-subuser1@nextdoor.com" + password = "password" + status, msg = self.client.subusers.post(username, email, password) + self.assertEqual(status, 201) + self.assertEqual(msg['username'], username) + self.assertEqual(msg['email'], email) + self.assertEqual(msg['password'], password) + + def test_subusers_patch(self): + username = "test-subuser1" + disabled = True + status, msg = self.client.subusers.patch(username, disabled) + self.assertEqual(status, 200) + + def test_subusers_delete(self): + username = "test-subuser1" + status, msg = self.client.subusers.delete(username) + self.assertEqual(status, 204) + + def test_subusers_get(self): + status, msg = self.client.subusers.get() + self.assertEqual(status, 200) + +if __name__ == '__main__': + unittest.main() From 84dca5d280273ebf0e9fb1d7fc5e1db801d2a07a Mon Sep 17 00:00:00 2001 From: koenoki Date: Mon, 25 Jan 2016 17:56:14 -0800 Subject: [PATCH 2/8] Add Basic auth support --- sendgrid/client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sendgrid/client.py b/sendgrid/client.py index 7b1df4410..4faf5ce20 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -36,6 +36,7 @@ def __init__(self, apikey, **opts): self.host = opts.get('host', 'https://api.sendgrid.com') # urllib cannot connect to SSL servers using proxies self.proxies = opts.get('proxies', None) + self._basic = opts.get('basic', False) self.apikeys = APIKeys(self) self.asm_groups = ASMGroups(self) @@ -61,7 +62,7 @@ def _build_request(self, url, json_header=False, method='GET', data=None): req = urllib_request.Request(url) req.get_method = lambda: method req.add_header('User-Agent', self.useragent) - req.add_header('Authorization', 'Bearer ' + self.apikey) + req.add_header('Authorization', ('Basic ' if self._basic else 'Bearer ') + self.apikey) if json_header: req.add_header('Content-Type', 'application/json') try: From b1e4acaf9419a2611267bfe0fb2b82d648b56f36 Mon Sep 17 00:00:00 2001 From: koenoki Date: Tue, 26 Jan 2016 10:24:26 -0800 Subject: [PATCH 3/8] Fix endpoint in API_keys and Subusers API --- sendgrid/resources/api_keys.py | 10 +++++-- sendgrid/resources/subusers.py | 53 ++++++++++++++++++++-------------- test/test_api_keys.py | 8 ++++- test/test_subusers.py | 6 +++- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/sendgrid/resources/api_keys.py b/sendgrid/resources/api_keys.py index e5de418b8..6ba2a409a 100644 --- a/sendgrid/resources/api_keys.py +++ b/sendgrid/resources/api_keys.py @@ -40,24 +40,30 @@ def client(self): # Get a list of active API keys def get(self): + self.name = None + self.endpoint = self._base_endpoint return self.client.get(self) # Create a new API key with name (string) def post(self, name): data = {} + data['name'] = name + self.name = name - data['name'] = self.name + self.endpoint = self._base_endpoint return self.client.post(self, data) # Delete a API key def delete(self, api_key_id): + self.name = None self.endpoint = self._base_endpoint + "/" + api_key_id return self.client.delete(self) # Update a API key's name def patch(self, api_key_id, name): data = {} + data['name'] = name + self.name = name - data['name'] = self.name self.endpoint = self._base_endpoint + "/" + api_key_id return self.client.patch(self, data) \ No newline at end of file diff --git a/sendgrid/resources/subusers.py b/sendgrid/resources/subusers.py index 7ff4f6a66..7f6f7ce5c 100644 --- a/sendgrid/resources/subusers.py +++ b/sendgrid/resources/subusers.py @@ -4,21 +4,12 @@ def __init__(self, client, **opts): """ Constructs SendGrid Subusers object. - See https://sendgrid.com/docs/API_Reference/Web_API_v3/subusers.html + https://sendgrid.com/docs/API_Reference/Web_API_v3/subusers.html """ - self._name = None self._base_endpoint = "/v3/subusers" self._endpoint = "/v3/subusers" self._client = client - @property - def name(self): - return self._name - - @name.setter - def name(self, value): - self._name = value - @property def base_endpoint(self): return self._base_endpoint @@ -36,31 +27,49 @@ def endpoint(self, value): def client(self): return self._client - # Get a list of active API keys def get(self): + """ + Get a list of subusers + """ + self.endpoint = self._base_endpoint return self.client.get(self) - # Create a new subuser with username, email, password (string) and IP list (string[]) def post(self, username, email, password, ips = []): + """ + Create a new subuser + + :param username: string + :param email: string + :param password: string + :param ips: string[] + """ data = {} - self.username = username - self.email = email - self.password = password - data['username'] = self.username - data['email'] = self.email - data['password'] = self.password + data['username'] = username + data['email'] = email + data['password'] = password data['ips'] = ips + + self.endpoint = self._base_endpoint return self.client.post(self, data) - # Delete a subuser def delete(self, username): + """ + Delete a subuser + + :param username: string + """ self.endpoint = self._base_endpoint + "/" + username return self.client.delete(self) - # Enable/disable a subuser def patch(self, username, disabled): + """ + Enable/disable a subuser + + :param username: string + :param disabled: bool + """ data = {} - self.disabled = disabled - data['disabled'] = self.disabled + data['disabled'] = disabled + self.endpoint = self._base_endpoint + "/" + username return self.client.patch(self, data) diff --git a/test/test_api_keys.py b/test/test_api_keys.py index c7a0cc96f..efc4c9495 100644 --- a/test/test_api_keys.py +++ b/test/test_api_keys.py @@ -38,13 +38,19 @@ def test_apikeys_patch(self): status, msg = self.client.apikeys.patch(SG_KEY, name) self.assertEqual(status, 200) self.assertEqual(msg['name'], name) - + + self.test_apikeys_get() + def test_apikeys_delete(self): status, msg = self.client.apikeys.delete(SG_KEY) self.assertEqual(status, 204) + self.test_apikeys_get() + def test_apikeys_get(self): status, msg = self.client.apikeys.get() + self.assertEqual(self.client.apikeys.name, None) + self.assertEqual(self.client.apikeys.endpoint, "/v3/api_keys") self.assertEqual(status, 200) if __name__ == '__main__': diff --git a/test/test_subusers.py b/test/test_subusers.py index bab1ebf5d..57ea753c0 100644 --- a/test/test_subusers.py +++ b/test/test_subusers.py @@ -22,7 +22,6 @@ def setUp(self): def test_subusers_init(self): self.subusers = self.client.subusers - self.assertEqual(self.subusers.name, None) self.assertEqual(self.subusers.base_endpoint, "/v3/subusers") self.assertEqual(self.subusers.endpoint, "/v3/subusers") self.assertEqual(self.subusers.client, self.client) @@ -43,13 +42,18 @@ def test_subusers_patch(self): status, msg = self.client.subusers.patch(username, disabled) self.assertEqual(status, 200) + self.test_subusers_get() + def test_subusers_delete(self): username = "test-subuser1" status, msg = self.client.subusers.delete(username) self.assertEqual(status, 204) + self.test_subusers_get() + def test_subusers_get(self): status, msg = self.client.subusers.get() + self.assertEqual(self.client.subusers.endpoint, "/v3/subusers") self.assertEqual(status, 200) if __name__ == '__main__': From c65c6e7aad40f5409382f2d1607cfa8d1c53fc6d Mon Sep 17 00:00:00 2001 From: koenoki Date: Tue, 26 Jan 2016 10:24:50 -0800 Subject: [PATCH 4/8] Add whitelabel domains API --- sendgrid/client.py | 2 + sendgrid/resources/whitelabel_domains.py | 75 ++++++++++++++++++++++++ test/test_whitelabel_domains.py | 62 ++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 sendgrid/resources/whitelabel_domains.py create mode 100644 test/test_whitelabel_domains.py diff --git a/sendgrid/client.py b/sendgrid/client.py index 4faf5ce20..7f54dfd82 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -18,6 +18,7 @@ from .resources.suppressions import Suppressions from .resources.stats import Stats from .resources.subusers import Subusers +from .resources.whitelabel_domains import WhitelabelDomains class SendGridAPIClient(object): @@ -45,6 +46,7 @@ def __init__(self, apikey, **opts): self.suppressions = Suppressions(self) self.stats = Stats(self) self.subusers = Subusers(self) + self.whitelabel_domains = WhitelabelDomains(self) @property def apikey(self): diff --git a/sendgrid/resources/whitelabel_domains.py b/sendgrid/resources/whitelabel_domains.py new file mode 100644 index 000000000..5c5f45329 --- /dev/null +++ b/sendgrid/resources/whitelabel_domains.py @@ -0,0 +1,75 @@ +class WhitelabelDomains(object): + + def __init__(self, client, **opts): + """ + Constructs SendGrid WhitelabelDomains object. + + See https://sendgrid.com/docs/API_Reference/Web_API_v3/Whitelabel/domains.html + """ + self._base_endpoint = '/v3/whitelabel/domains' + self._endpoint = '/v3/whitelabel/domains' + self._client = client + + @property + def base_endpoint(self): + return self._base_endpoint + + @property + def endpoint(self): + endpoint = self._endpoint + return endpoint + + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + + @property + def client(self): + return self._client + + def get(self): + """ + Get a list of whitelabel domains + """ + self.endpoint = self._base_endpoint + return self.client.get(self) + + def post(self, domain, subdomain, username, default): + """ + Create a new whitelabel domain + + :param domain: string + :param subdomain: string + :param username: string + :param default: bool + """ + data = {} + data['domain'] = domain + data['subdomain'] = subdomain + data['username'] = username + data['default'] = default + + self.endpoint = self._base_endpoint + return self.client.post(self, data) + + def delete(self, id): + """ + Delete a whitelabel domain + + :param id: int + """ + self.endpoint = self._base_endpoint + '/' + str(id) + return self.client.delete(self) + + def patch(self, id, default): + """ + Update a whitelabel domain + + :param id: int + :param default: bool + """ + data = {} + data['default'] = default + + self.endpoint = self._base_endpoint + '/' + str(id) + return self.client.patch(self, data) diff --git a/test/test_whitelabel_domains.py b/test/test_whitelabel_domains.py new file mode 100644 index 000000000..c4c20838f --- /dev/null +++ b/test/test_whitelabel_domains.py @@ -0,0 +1,62 @@ +from .base_test import BaseTest, MockSendGridAPIClientRequest +import os +try: + import unittest2 as unittest +except ImportError: + import unittest +try: + from StringIO import StringIO +except ImportError: # Python 3 + from io import StringIO + +import sendgrid +from sendgrid.client import SendGridAPIClient +from sendgrid.version import __version__ + +SG_KEY = os.getenv('SG_KEY') or 'SENDGRID_APIKEY' + +class TestWhitelabelDomains(unittest.TestCase): + def setUp(self): + SendGridAPIClient = MockSendGridAPIClientRequest + self.client = SendGridAPIClient(SG_KEY) + + def test_whitelabel_domains_init(self): + self.whitelabel_domains = self.client.whitelabel_domains + self.assertEqual(self.whitelabel_domains.base_endpoint, "/v3/whitelabel/domains") + self.assertEqual(self.whitelabel_domains.endpoint, "/v3/whitelabel/domains") + self.assertEqual(self.whitelabel_domains.client, self.client) + + def test_whitelabel_domains_post(self): + domain = "nextdoor-test-whitelabel.com" + subdomain = "test" + username = "test-subuser1" + default = True + status, msg = self.client.whitelabel_domains.post(domain, subdomain, username, default) + self.assertEqual(status, 201) + self.assertEqual(msg['domain'], domain) + self.assertEqual(msg['subdomain'], subdomain) + self.assertEqual(msg['username'], username) + self.assertEqual(msg['default'], default) + + def test_whitelabel_domains_patch(self): + id = 1 + default = False + status, msg = self.client.whitelabel_domains.patch(id, default) + self.assertEqual(status, 200) + + self.test_whitelabel_domains_get() + + def test_whitelabel_domains_delete(self): + id = 1 + status, msg = self.client.whitelabel_domains.delete(id) + self.assertEqual(status, 204) + + self.test_whitelabel_domains_get() + + def test_whitelabel_domains_get(self): + status, msg = self.client.whitelabel_domains.get() + self.assertEqual(self.client.whitelabel_domains.endpoint, "/v3/whitelabel/domains") + self.assertEqual(status, 200) + +if __name__ == '__main__': + unittest.main() From 26d9a149443edc0e6a7ddc2f18449547c2d86d09 Mon Sep 17 00:00:00 2001 From: koenoki Date: Wed, 27 Jan 2016 17:11:01 -0800 Subject: [PATCH 5/8] Add whitelabel IPs API --- sendgrid/client.py | 2 + sendgrid/resources/whitelabel_ips.py | 60 ++++++++++++++++++++++++++++ test/test_whitelabel_ips.py | 52 ++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 sendgrid/resources/whitelabel_ips.py create mode 100644 test/test_whitelabel_ips.py diff --git a/sendgrid/client.py b/sendgrid/client.py index 7f54dfd82..384106279 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -19,6 +19,7 @@ from .resources.stats import Stats from .resources.subusers import Subusers from .resources.whitelabel_domains import WhitelabelDomains +from .resources.whitelabel_ips import WhitelabelIPs class SendGridAPIClient(object): @@ -47,6 +48,7 @@ def __init__(self, apikey, **opts): self.stats = Stats(self) self.subusers = Subusers(self) self.whitelabel_domains = WhitelabelDomains(self) + self.whitelabel_ips = WhitelabelIPs(self) @property def apikey(self): diff --git a/sendgrid/resources/whitelabel_ips.py b/sendgrid/resources/whitelabel_ips.py new file mode 100644 index 000000000..2cdace4e9 --- /dev/null +++ b/sendgrid/resources/whitelabel_ips.py @@ -0,0 +1,60 @@ +class WhitelabelIPs(object): + + def __init__(self, client, **opts): + """ + Constructs SendGrid WhitelabelIPs object. + + See https://sendgrid.com/docs/API_Reference/Web_API_v3/Whitelabel/ips.html + """ + self._base_endpoint = '/v3/whitelabel/ips' + self._endpoint = '/v3/whitelabel/ips' + self._client = client + + @property + def base_endpoint(self): + return self._base_endpoint + + @property + def endpoint(self): + endpoint = self._endpoint + return endpoint + + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + + @property + def client(self): + return self._client + + def get(self): + """ + Get a list of whitelabel IPs + """ + self.endpoint = self._base_endpoint + return self.client.get(self) + + def post(self, ip, domain, subdomain): + """ + Create a new whitelabel IP + + :param ip: string + :param domain: string + :param subdomain: string + """ + data = {} + data['ip'] = ip + data['domain'] = domain + data['subdomain'] = subdomain + + self.endpoint = self._base_endpoint + return self.client.post(self, data) + + def delete(self, id): + """ + Delete a whitelabel IP + + :param id: int + """ + self.endpoint = self._base_endpoint + '/' + str(id) + return self.client.delete(self) diff --git a/test/test_whitelabel_ips.py b/test/test_whitelabel_ips.py new file mode 100644 index 000000000..47b3ca9b3 --- /dev/null +++ b/test/test_whitelabel_ips.py @@ -0,0 +1,52 @@ +from .base_test import BaseTest, MockSendGridAPIClientRequest +import os +try: + import unittest2 as unittest +except ImportError: + import unittest +try: + from StringIO import StringIO +except ImportError: # Python 3 + from io import StringIO + +import sendgrid +from sendgrid.client import SendGridAPIClient +from sendgrid.version import __version__ + +SG_KEY = os.getenv('SG_KEY') or 'SENDGRID_APIKEY' + +class TestWhitelabelIPs(unittest.TestCase): + def setUp(self): + SendGridAPIClient = MockSendGridAPIClientRequest + self.client = SendGridAPIClient(SG_KEY) + + def test_whitelabel_ips_init(self): + self.whitelabel_ips = self.client.whitelabel_ips + self.assertEqual(self.whitelabel_ips.base_endpoint, "/v3/whitelabel/ips") + self.assertEqual(self.whitelabel_ips.endpoint, "/v3/whitelabel/ips") + self.assertEqual(self.whitelabel_ips.client, self.client) + + def test_whitelabel_ips_post(self): + domain = "nextdoor-test-whitelabel.com" + subdomain = "test" + ip = '10.1.2.3' + status, msg = self.client.whitelabel_ips.post(ip, domain, subdomain) + self.assertEqual(status, 201) + self.assertEqual(msg['ip'], ip) + self.assertEqual(msg['domain'], domain) + self.assertEqual(msg['subdomain'], subdomain) + + def test_whitelabel_ips_delete(self): + id = 1 + status, msg = self.client.whitelabel_ips.delete(id) + self.assertEqual(status, 204) + + self.test_whitelabel_ips_get() + + def test_whitelabel_ips_get(self): + status, msg = self.client.whitelabel_ips.get() + self.assertEqual(self.client.whitelabel_ips.endpoint, "/v3/whitelabel/ips") + self.assertEqual(status, 200) + +if __name__ == '__main__': + unittest.main() From 8105c5af792eb086be30c0d41ca45ded8c7ce823 Mon Sep 17 00:00:00 2001 From: koenoki Date: Tue, 2 Feb 2016 11:41:14 -0800 Subject: [PATCH 6/8] Add IP Pools API --- sendgrid/client.py | 2 ++ sendgrid/resources/ip_pools.py | 58 ++++++++++++++++++++++++++++++++++ test/test_ip_pools.py | 48 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 sendgrid/resources/ip_pools.py create mode 100644 test/test_ip_pools.py diff --git a/sendgrid/client.py b/sendgrid/client.py index 384106279..467b2ce95 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -20,6 +20,7 @@ from .resources.subusers import Subusers from .resources.whitelabel_domains import WhitelabelDomains from .resources.whitelabel_ips import WhitelabelIPs +from .resources.ip_pools import IPPools class SendGridAPIClient(object): @@ -49,6 +50,7 @@ def __init__(self, apikey, **opts): self.subusers = Subusers(self) self.whitelabel_domains = WhitelabelDomains(self) self.whitelabel_ips = WhitelabelIPs(self) + self.ip_pools = IPPools(self) @property def apikey(self): diff --git a/sendgrid/resources/ip_pools.py b/sendgrid/resources/ip_pools.py new file mode 100644 index 000000000..2773e3055 --- /dev/null +++ b/sendgrid/resources/ip_pools.py @@ -0,0 +1,58 @@ +import urllib + +class IPPools(object): + + def __init__(self, client, **opts): + """ + Constructs SendGrid IP Pools object. + + See https://sendgrid.com/docs/API_Reference/Web_API_v3/IP_Management/ip_pools.html + """ + self._base_endpoint = '/v3/ips/pools' + self._endpoint = '/v3/ips/pools' + self._client = client + + @property + def base_endpoint(self): + return self._base_endpoint + + @property + def endpoint(self): + endpoint = self._endpoint + return endpoint + + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + + @property + def client(self): + return self._client + + def get(self): + """ + List all IP pools + """ + self.endpoint = self._base_endpoint + return self.client.get(self) + + def post(self, name): + """ + Create a new IP pool + + :param name: str + """ + data = {} + data['name'] = name + + self.endpoint = self._base_endpoint + return self.client.post(self, data) + + def delete(self, name): + """ + Delete an IP pool + + :param name: str + """ + self.endpoint = self._base_endpoint + '/' + urllib.quote_plus(name) + return self.client.delete(self) diff --git a/test/test_ip_pools.py b/test/test_ip_pools.py new file mode 100644 index 000000000..4d87be68b --- /dev/null +++ b/test/test_ip_pools.py @@ -0,0 +1,48 @@ +from .base_test import BaseTest, MockSendGridAPIClientRequest +import os +try: + import unittest2 as unittest +except ImportError: + import unittest +try: + from StringIO import StringIO +except ImportError: # Python 3 + from io import StringIO + +import sendgrid +from sendgrid.client import SendGridAPIClient +from sendgrid.version import __version__ + +SG_KEY = os.getenv('SG_KEY') or 'SENDGRID_APIKEY' + +class TestIPPools(unittest.TestCase): + def setUp(self): + SendGridAPIClient = MockSendGridAPIClientRequest + self.client = SendGridAPIClient(SG_KEY) + + def test_ip_pools_init(self): + self.ip_pools = self.client.ip_pools + self.assertEqual(self.ip_pools.base_endpoint, "/v3/ips/pools") + self.assertEqual(self.ip_pools.endpoint, "/v3/ips/pools") + self.assertEqual(self.ip_pools.client, self.client) + + def test_ip_pools_post(self): + name = 'test-pool' + status, msg = self.client.ip_pools.post(name) + self.assertEqual(status, 201) + self.assertEqual(msg['name'], name) + + def test_ip_pools_delete(self): + id = 'test-pools' + status, msg = self.client.ip_pools.delete(id) + self.assertEqual(status, 204) + + self.test_ip_pools_get() + + def test_ip_pools_get(self): + status, msg = self.client.ip_pools.get() + self.assertEqual(self.client.ip_pools.endpoint, "/v3/ips/pools") + self.assertEqual(status, 200) + +if __name__ == '__main__': + unittest.main() From b2c4625648fac352c4b03a3b1b2c4cef3d839d70 Mon Sep 17 00:00:00 2001 From: koenoki Date: Wed, 3 Feb 2016 18:05:21 -0800 Subject: [PATCH 7/8] Add IP Addresses API --- sendgrid/client.py | 2 + sendgrid/resources/ip_addresses.py | 63 ++++++++++++++++++++++++++++++ test/test_ip_addresses.py | 50 ++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 sendgrid/resources/ip_addresses.py create mode 100644 test/test_ip_addresses.py diff --git a/sendgrid/client.py b/sendgrid/client.py index 467b2ce95..7f7707c98 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -21,6 +21,7 @@ from .resources.whitelabel_domains import WhitelabelDomains from .resources.whitelabel_ips import WhitelabelIPs from .resources.ip_pools import IPPools +from .resources.ip_addresses import IPAddresses class SendGridAPIClient(object): @@ -51,6 +52,7 @@ def __init__(self, apikey, **opts): self.whitelabel_domains = WhitelabelDomains(self) self.whitelabel_ips = WhitelabelIPs(self) self.ip_pools = IPPools(self) + self.ips = IPAddresses(self) @property def apikey(self): diff --git a/sendgrid/resources/ip_addresses.py b/sendgrid/resources/ip_addresses.py new file mode 100644 index 000000000..73ce58bad --- /dev/null +++ b/sendgrid/resources/ip_addresses.py @@ -0,0 +1,63 @@ +import urllib + +class IPAddresses(object): + + def __init__(self, client, **opts): + """ + Constructs SendGrid IP Pools object. + + See https://sendgrid.com/docs/API_Reference/Web_API_v3/IP_Management/ip_addresses.html + """ + self._base_endpoint = '/v3/ips' + self._endpoint = '/v3/ips' + self._client = client + + @property + def base_endpoint(self): + return self._base_endpoint + + @property + def endpoint(self): + endpoint = self._endpoint + return endpoint + + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + + @property + def client(self): + return self._client + + def get(self): + """ + List all IP addresses + """ + self.endpoint = self._base_endpoint + return self.client.get(self) + + def post(self, ip_pool, ip): + """ + Add an IP address to the specified IP Pool + + :param ip_pool: str + :param ip: str + """ + data = {} + data['ip'] = ip + + self.endpoint = self._base_endpoint + '/pools/' + urllib.quote_plus(ip_pool) + '/ips' + return self.client.post(self, data) + + def delete(self, ip_pool, ip): + """ + Delete an IP address from the specified IP Pool + + :param ip_pool: str + :param ip: str + """ + self.endpoint = ( + self._base_endpoint + + '/pools/' + urllib.quote_plus(ip_pool) + + '/ips/' + urllib.quote_plus(ip)) + return self.client.delete(self) diff --git a/test/test_ip_addresses.py b/test/test_ip_addresses.py new file mode 100644 index 000000000..f5c60c573 --- /dev/null +++ b/test/test_ip_addresses.py @@ -0,0 +1,50 @@ +from .base_test import BaseTest, MockSendGridAPIClientRequest +import os +try: + import unittest2 as unittest +except ImportError: + import unittest +try: + from StringIO import StringIO +except ImportError: # Python 3 + from io import StringIO + +import sendgrid +from sendgrid.client import SendGridAPIClient +from sendgrid.version import __version__ + +SG_KEY = os.getenv('SG_KEY') or 'SENDGRID_APIKEY' + +class TestIPAddresses(unittest.TestCase): + def setUp(self): + SendGridAPIClient = MockSendGridAPIClientRequest + self.client = SendGridAPIClient(SG_KEY) + + def test_ips_init(self): + self.ips = self.client.ips + self.assertEqual(self.ips.base_endpoint, "/v3/ips") + self.assertEqual(self.ips.endpoint, "/v3/ips") + self.assertEqual(self.ips.client, self.client) + + def test_ips_post(self): + ip_pool = 'test-pool' + ip = '10.1.2.3' + status, msg = self.client.ips.post(ip_pool, ip) + self.assertEqual(status, 201) + self.assertEqual(msg['ip'], ip) + + def test_ips_delete(self): + ip_pool = 'test-pools' + ip = '10.1.2.3' + status, msg = self.client.ips.delete(ip_pool, ip) + self.assertEqual(status, 204) + + self.test_ips_get() + + def test_ips_get(self): + status, msg = self.client.ips.get() + self.assertEqual(self.client.ips.endpoint, "/v3/ips") + self.assertEqual(status, 200) + +if __name__ == '__main__': + unittest.main() From 839c579679f186d19029d934ecf0139338d709e4 Mon Sep 17 00:00:00 2001 From: Keiji Oenoki Date: Fri, 19 Feb 2016 08:48:23 -0800 Subject: [PATCH 8/8] Fix urllib import in Python 3 --- sendgrid/resources/ip_addresses.py | 11 +++++++---- sendgrid/resources/ip_pools.py | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sendgrid/resources/ip_addresses.py b/sendgrid/resources/ip_addresses.py index 73ce58bad..242fc0fd9 100644 --- a/sendgrid/resources/ip_addresses.py +++ b/sendgrid/resources/ip_addresses.py @@ -1,4 +1,7 @@ -import urllib +try: + from urllib.parse import quote_plus +except ImportError: # Python 2 + from urllib import quote_plus class IPAddresses(object): @@ -46,7 +49,7 @@ def post(self, ip_pool, ip): data = {} data['ip'] = ip - self.endpoint = self._base_endpoint + '/pools/' + urllib.quote_plus(ip_pool) + '/ips' + self.endpoint = self._base_endpoint + '/pools/' + quote_plus(ip_pool) + '/ips' return self.client.post(self, data) def delete(self, ip_pool, ip): @@ -58,6 +61,6 @@ def delete(self, ip_pool, ip): """ self.endpoint = ( self._base_endpoint + - '/pools/' + urllib.quote_plus(ip_pool) + - '/ips/' + urllib.quote_plus(ip)) + '/pools/' + quote_plus(ip_pool) + + '/ips/' + quote_plus(ip)) return self.client.delete(self) diff --git a/sendgrid/resources/ip_pools.py b/sendgrid/resources/ip_pools.py index 2773e3055..4e3b00acc 100644 --- a/sendgrid/resources/ip_pools.py +++ b/sendgrid/resources/ip_pools.py @@ -1,4 +1,7 @@ -import urllib +try: + from urllib.parse import quote_plus +except ImportError: # Python 2 + from urllib import quote_plus class IPPools(object): @@ -54,5 +57,5 @@ def delete(self, name): :param name: str """ - self.endpoint = self._base_endpoint + '/' + urllib.quote_plus(name) + self.endpoint = self._base_endpoint + '/' + quote_plus(name) return self.client.delete(self)