From 7922352af04c885dd6b0d8efaf919ce5a21115d7 Mon Sep 17 00:00:00 2001 From: sethgrid Date: Tue, 18 Apr 2023 08:48:31 -0400 Subject: [PATCH 1/5] Multiple Webhook Support SendGrid now allows for multiple webhooks and this PR pulls in the non-breaking API changes to support it. Webhook resources will now take an ID parameter to target specific webhooks. When a webhook resource is NOT used with an ID, the API falls back to legacy behavior assuming there is only one webhook, and this defaults to the oldest webhook available. Users should update their services to reference webhooks by ID. --- examples/user/user.py | 10 +++++++--- test/integ/test_sendgrid.py | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/examples/user/user.py b/examples/user/user.py index 5160f9ff8..82961a78b 100644 --- a/examples/user/user.py +++ b/examples/user/user.py @@ -196,7 +196,8 @@ "unsubscribe": True, "url": "url" } -response = sg.client.user.webhooks.event.settings.patch(request_body=data) +webhook_id = "some-webhook-uuid" +response = sg.client.user.webhooks.event.settings._(webhook_id).patch(request_body=data) print(response.status_code) print(response.body) print(response.headers) @@ -205,7 +206,8 @@ # Retrieve Event Webhook settings # # GET /user/webhooks/event/settings # -response = sg.client.user.webhooks.event.settings.get() +webhook_id = "some-webhook-uuid" +response = sg.client.user.webhooks.event.settings._(webhook_id).get() print(response.status_code) print(response.body) print(response.headers) @@ -214,8 +216,10 @@ # Test Event Notification Settings # # POST /user/webhooks/event/test # +webhook_id = "some-webhook-uuid" data = { - "url": "url" + "url": "url", + "id": webhook_id } response = sg.client.user.webhooks.event.test.post(request_body=data) print(response.status_code) diff --git a/test/integ/test_sendgrid.py b/test/integ/test_sendgrid.py index 0c63851eb..dfaf0129c 100644 --- a/test/integ/test_sendgrid.py +++ b/test/integ/test_sendgrid.py @@ -1992,19 +1992,36 @@ def test_user_webhooks_event_settings_patch(self): "unsubscribe": True, "url": "url" } + webhook_id = "some-webhook-uuid" headers = {'X-Mock': 200} - response = self.sg.client.user.webhooks.event.settings.patch( + response = self.sg.client.user.webhooks.event.settings._(webhook_id).patch( request_body=data, request_headers=headers) self.assertEqual(response.status_code, 200) - def test_user_webhooks_event_settings_get(self): + # legacy webhook API only allowed for a single webhook. When no ID is provided, + # backwards compatiblity ensures we will get the oldest webhook back. + # Going forward, users should use settings._(webhook_id) in all calls. + def test_user_webhooks_event_settings_get_legacy_no_id(self): headers = {'X-Mock': 200} + webhook_id = "some-webhook-uuid" response = self.sg.client.user.webhooks.event.settings.get( request_headers=headers) + repr(response) + self.assertEqual(response.status_code, 200) + + def test_user_webhooks_event_settings_get(self): + headers = {'X-Mock': 200} + webhook_id = "some-webhook-uuid" + self.assertTrue(False, "not true") + response = self.sg.client.user.webhooks.event.settings._(webhook_id).get( + request_headers=headers) + self.assertEqual(repr(response), "I got a response") + self.assertEqual(response.status_code, 200) def test_user_webhooks_event_test_post(self): data = { + "id": "some-webhook-id", "url": "url" } headers = {'X-Mock': 204} From 3b0ec20cc5ff77c0f36fd7aadda607eb31acb25c Mon Sep 17 00:00:00 2001 From: sethgrid Date: Tue, 18 Apr 2023 09:03:32 -0400 Subject: [PATCH 2/5] update comment / doc, add entry for legacy behavior --- examples/user/user.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/user/user.py b/examples/user/user.py index 82961a78b..ccff07e69 100644 --- a/examples/user/user.py +++ b/examples/user/user.py @@ -179,7 +179,7 @@ ################################################## # Update Event Notification Settings # -# PATCH /user/webhooks/event/settings # +# PATCH /user/webhooks/event/settings/{webhook_id} # data = { "bounce": True, @@ -203,9 +203,19 @@ print(response.headers) ################################################## -# Retrieve Event Webhook settings # +# Retrieve Event Webhook settings (legacy, no id)# # GET /user/webhooks/event/settings # +webhook_id = "some-webhook-uuid" +response = sg.client.user.webhooks.event.settings.get() +print(response.status_code) +print(response.body) +print(response.headers) + +################################################## +# Retrieve Event Webhook settings # +# GET /user/webhooks/event/settings/{webhook_id} # + webhook_id = "some-webhook-uuid" response = sg.client.user.webhooks.event.settings._(webhook_id).get() print(response.status_code) From b1552a9dfeea74d75aeec0310b5abde06e55011c Mon Sep 17 00:00:00 2001 From: sethgrid Date: Tue, 18 Apr 2023 09:04:18 -0400 Subject: [PATCH 3/5] remove unused var --- examples/user/user.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/user/user.py b/examples/user/user.py index ccff07e69..cd1a5432a 100644 --- a/examples/user/user.py +++ b/examples/user/user.py @@ -206,7 +206,6 @@ # Retrieve Event Webhook settings (legacy, no id)# # GET /user/webhooks/event/settings # -webhook_id = "some-webhook-uuid" response = sg.client.user.webhooks.event.settings.get() print(response.status_code) print(response.body) From e02971abcf2819164aeaad03d21c806f0f6e69f8 Mon Sep 17 00:00:00 2001 From: sethgrid Date: Tue, 18 Apr 2023 09:16:18 -0400 Subject: [PATCH 4/5] CONTRIBUTING update to show example for running one specific test --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 890641059..a674702d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,7 +77,7 @@ All test files are in the [`test`](test) directory. For the purposes of contribu The integration tests require a Twilio SendGrid mock API in order to execute. We've simplified setting this up using Docker to run the tests. You will just need [Docker Desktop](https://docs.docker.com/get-docker/) and `make`. -Once these are available, simply execute the Docker test target to run all tests: `make test-docker`. This command can also be used to open an interactive shell into the container where this library is installed. To start a *bash* shell for example, use this command: `command=bash make test-docker`. +Once these are available, simply execute the Docker test target to run all tests: `make test-docker`. This command can also be used to open an interactive shell into the container where this library is installed. To start a *bash* shell for example, use this command: `command=bash make test-docker` and you can run a specific test like `source venv/bin/activate; python -m unittest test.integ.test_sendgrid.UnitTests.test_useragent`. ## Style Guidelines & Naming Conventions From f7c7e7f16a60cd162bc8ff87107b806afaf7dde8 Mon Sep 17 00:00:00 2001 From: sethgrid Date: Tue, 18 Apr 2023 10:54:42 -0400 Subject: [PATCH 5/5] remove debugging lines --- test/integ/test_sendgrid.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/integ/test_sendgrid.py b/test/integ/test_sendgrid.py index dfaf0129c..690e2405f 100644 --- a/test/integ/test_sendgrid.py +++ b/test/integ/test_sendgrid.py @@ -2006,7 +2006,6 @@ def test_user_webhooks_event_settings_get_legacy_no_id(self): webhook_id = "some-webhook-uuid" response = self.sg.client.user.webhooks.event.settings.get( request_headers=headers) - repr(response) self.assertEqual(response.status_code, 200) def test_user_webhooks_event_settings_get(self): @@ -2015,7 +2014,6 @@ def test_user_webhooks_event_settings_get(self): self.assertTrue(False, "not true") response = self.sg.client.user.webhooks.event.settings._(webhook_id).get( request_headers=headers) - self.assertEqual(repr(response), "I got a response") self.assertEqual(response.status_code, 200)