Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support EU region endpoint #131

Merged
merged 9 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ jobs:
- name: Test with tox
env:
SENDGRID_API_KEY: ${{ secrets.SENDGRID_API_KEY }}
TESTING_SENDGRID_EU_API_KEY: ${{ secrets.TESTING_SENDGRID_EU_API_KEY }}
run: tox
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ To use the backend, simply install the package (using pip), set the `EMAIL_BACKE

1. To toggle sandbox mode (when django is running in DEBUG mode), set `SENDGRID_SANDBOX_MODE_IN_DEBUG = True/False`.
1. To err on the side of caution, this defaults to True, so emails sent in DEBUG mode will not be delivered, unless this setting is explicitly set to False.
2. `SENDGRID_ECHO_TO_STDOUT` will echo to stdout or any other file-like
1. `SENDGRID_ECHO_TO_STDOUT` will echo to stdout or any other file-like
object that is passed to the backend via the `stream` kwarg.
3. `SENDGRID_TRACK_EMAIL_OPENS` - defaults to true and tracks email open events via the Sendgrid service. These events are logged in the Statistics UI, Email Activity interface, and are reported by the Event Webhook.
4. `SENDGRID_TRACK_CLICKS_HTML` - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the HTML message sent.
5. `SENDGRID_TRACK_CLICKS_PLAIN` - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the plain text message sent.
1. `SENDGRID_TRACK_EMAIL_OPENS` - defaults to true and tracks email open events via the Sendgrid service. These events are logged in the Statistics UI, Email Activity interface, and are reported by the Event Webhook.
1. `SENDGRID_TRACK_CLICKS_HTML` - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the HTML message sent.
1. `SENDGRID_TRACK_CLICKS_PLAIN` - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the plain text message sent.
1. `SENDGRID_HOST_URL` - Allows changing the base API URI. Set to `https://api.eu.sendgrid.com` to use the EU region.

## Usage

Expand Down
17 changes: 14 additions & 3 deletions sendgrid_backend/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,24 @@ def __init__(self, *args, **kwargs):
# or passed as an argument to the init function, which takes precedence
# over the setting.

sg_args = {}
if "api_key" in kwargs:
self.sg = SendGridAPIClient(api_key=kwargs["api_key"])
sg_args["api_key"] = kwargs["api_key"]
elif hasattr(settings, "SENDGRID_API_KEY") and settings.SENDGRID_API_KEY:
self.sg = SendGridAPIClient(api_key=settings.SENDGRID_API_KEY)
sg_args["api_key"] = settings.SENDGRID_API_KEY
else:
raise ImproperlyConfigured(
"settings.py must contain a value for SENDGRID_API_KEY. "
+ "You may also pass a value to the api_key argument (optional)."
)

if "host" in kwargs:
sg_args["host"] = kwargs["host"]
elif hasattr(settings, "SENDGRID_HOST_URL") and settings.SENDGRID_HOST_URL:
sg_args["host"] = settings.SENDGRID_HOST_URL

self.sg = SendGridAPIClient(**sg_args)

# Configure sandbox mode based on settings
sandbox_mode_in_debug = get_django_setting(
"SENDGRID_SANDBOX_MODE_IN_DEBUG", True
Expand Down Expand Up @@ -212,7 +220,10 @@ def set_prop(attachment, prop_name, value):
filename = f"part-{uuid.uuid4().hex}{ext}"
set_prop(sg_attch, "filename", filename)
# todo: Read content if stream?
set_prop(sg_attch, "content", django_attch.get_payload().replace("\n", ""))
payload = django_attch.get_payload()
if isinstance(payload, str):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch

payload = payload.replace("\n", "")
set_prop(sg_attch, "content", payload)

# Content-type handling. Includes the 'method' param.
content_type = django_attch.get_content_type()
Expand Down
1 change: 0 additions & 1 deletion test/test_mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
Header,
MailSettings,
Personalization,
SpamCheck,
Substitution,
TrackingSettings,
)
Expand Down
33 changes: 32 additions & 1 deletion test/test_post_to_sendgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TestPostToSendgrid(SimpleTestCase):
)
def test_post(self):
"""
Sends a POST to sendgrid's live API using a private API key that is stored
Sends a POST to SendGrid's live API using a private API key that is stored
in github.
"""

Expand All @@ -35,3 +35,34 @@ def test_post(self):
)
val = msg.send()
self.assertEqual(val, 1)

# TESTING_SENDGRID_EU_API_KEY is only used for testing.
@pytest.mark.skipif(
not os.environ.get("TESTING_SENDGRID_EU_API_KEY"),
reason="requires TESTING_SENDGRID_EU_API_KEY env var",
)
def test_eu_post(self):
"""
Sends a POST to SendGrid's live EU API using a private API key that is stored
in GitHub.
"""

SENDGRID_API_KEY = os.environ.get("TESTING_SENDGRID_EU_API_KEY")

# Set DEBUG=True so sandbox mode is enabled
settings = {
"DEBUG": True,
"SENDGRID_API_KEY": SENDGRID_API_KEY,
"SENDGRID_HOST_URL": "https://api.eu.sendgrid.com",
"EMAIL_BACKEND": "sendgrid_backend.SendgridBackend",
}

with override_settings(**settings):
msg = EmailMessage(
subject="Hello, World!",
body="Hello, World!",
from_email="Sam Smith <[email protected]>",
to=["John Doe <[email protected]>"],
)
val = msg.send()
self.assertEqual(val, 1)