feat: add Django email backend, supporting Django 4.2 LTS through 6.1 - #26
Merged
Conversation
Add postmark.django.EmailBackend, a drop-in EMAIL_BACKEND gated behind a new optional `django` extra (pip install postmark-python[django]): - EmailBackend builds the Postmark payload from EmailMessage's high-level attributes (to/cc/bcc/subject/body/alternatives/attachments/extra_headers) rather than EmailMessage.message(), so it isn't affected by Django 6.0's modernized email API. - PostmarkEmailMessage / PostmarkEmailMultiAlternatives / PostmarkEmailMixin for setting tag, metadata, and message_stream. - pre_send / post_send / on_exception signals. - Settings: POSTMARK_SERVER_TOKEN, POSTMARK_TEST_MODE, POSTMARK_TRACK_OPENS, POSTMARK_MESSAGE_STREAM. Testing and CI: - tests/django_backend/ (32 tests: sending, batching/chunking, attachments, headers, Unicode round-trip, fail_silently, signals, a regression test proving .message() is never called). - New django-tests CI job matrixed across Django 4.2/5.2/6.0/6.1. - tests/conftest.py now skips collecting tests/django_backend/ gracefully when the django extra isn't installed, instead of failing collection for the whole suite. Docs and examples: - examples/django/ (simple send, batch, attachment, custom header, external image, tags/metadata, settings snippet). - README Django section with install/quickstart. Also included: PyPI keywords, CONTRIBUTING.md, and GitHub issue templates for discoverability and contribution ergonomics.
| import pytest | ||
|
|
||
| try: | ||
| import django # noqa: F401 |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() | ||
| except ImportError: |
| except ImportError: | ||
| # The `django` extra is optional; don't let its absence break collection | ||
| # of the rest of the suite. | ||
| collect_ignore = ["django_backend"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
postmark.django.EmailBackend, a drop-inEMAIL_BACKEND, gated behind a new optionaldjangoextra (pip install postmark-python[django]). Supports Django 4.2 LTS, 5.2 LTS, 6.0, and 6.1.EmailMessage's high-level attributes (to/cc/bcc/subject/body/alternatives/attachments/extra_headers) rather thanEmailMessage.message(), so it isn't affected by Django 6.0's modernized email API (message()now returns a different underlying type).PostmarkEmailMessage/PostmarkEmailMultiAlternatives/PostmarkEmailMixinfortag,metadata,message_stream, andpre_send/post_send/on_exceptionsignals.POSTMARK_SERVER_TOKEN,POSTMARK_TEST_MODE,POSTMARK_TRACK_OPENS,POSTMARK_MESSAGE_STREAM.CONTRIBUTING.md, and GitHub issue templates for discoverability/contribution ergonomics.Backward compatibility: zero changes to any pre-existing file under
postmark/(verified viagit diff), and the coredependencieslist inpyproject.tomlis untouched —djangoonly appears in the new optional extra and the dev group, so existing users get no new transitive dependency. Verifiedpyteststill passes in full with Django uninstalled (422 tests), and the whole suite (454 tests) passes with it installed against both Django 4.2 and 5.2 locally.Test plan
poetry run pytest— 454 passed, 96% coveragepoetry run ruff check ./ruff format --check .— cleanpoetry run mypy postmark/— cleantests/django_backend/(32 tests) run manually against Django 4.2 and 5.2 locally; CI's newdjango-testsjob matrixes 4.2/5.2/6.0/6.1 on Python 3.12 (the one Python version all four Django series support)import postmarknever importsdjango, and barepytestno longer crashes collection when thedjangoextra isn't installedtest,django-tests,lint)