#35514: Dictionary based EMAIL_PROVIDERS settings
-----------------------------+--------------------------------------
Reporter: Jacob Rief | Owner: Jacob Rief
Type: New feature | Status: assigned
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------
Changes (by Natalia Bidart):
* cc: Jacob Rief (added)
Comment:
Hi Jacob R and Mike,
Thank you both for the work and discussion on this feature. As Django
Fellows, Jacob Walls and I want to encourage you to move this forward,
since we believe this work it's valuable and we'll do our best to help get
it merged for the 6.1 feature freeze (set to May 20th).
** About the implementation approach **
I'd like to propose aligning `EMAIL_PROVIDERS` with Django's existing
patterns for `DATABASES`, `CACHES`, and `STORAGES`. These all share a
consistent API:
{{{#!python
# Dict-like handler with named aliases for providers
from django.db import connections
from django.core.cache import caches
from django.core.files.storage import storages
from django.core.mail import providers # proposed
# Access by alias
db_conn = connections['analytics']
cache = caches['session']
storage = storages['s3']
provider = providers['marketing'] # proposed
# Lazy proxy for default provider
from django.db import connection
from django.core.cache import cache
from django.core.files.storage import default_storage
from django.core.mail import provider # proposed
}}}
This pattern would replace `get_connection(backend=...)` with
`providers["alias"]`, by having:
- Named provider configuration in `EMAIL_PROVIDERS`
- Consistent API across Django's connection systems
- Natural (?) solution for wrapper backends: configuration stays
declarative storing provider "alias" names in `OPTIONS`, then resolve them
via `providers["alias"]` at runtime, matching the pattern used with
multiple databases/caches/storages.
I think the wrapper backend issue (django-mailer, etc.) resolves cleanly
with this pattern (as far as I understand, let me know if I got that
wrong!). We can deprecate `get_connection(backend=...)` in favor of
`providers["alias"]` (hand-to-hand with `EMAIL_*` settings deprecation),
while MAYBE maintaining `get_connection()` with no arguments for backwards
compatibility. This may need further thinking.
For the ESP integration, and per Mike's feedback, I read that the
`OPTIONS` approach solved the `API_KEY` issue for `django-anymail` and
similar backends well. This appears resolved?
** PR and commit structure, next steps **
For the PR, we strongly recommend structuring commits as self-contained
units of functionality, each complete with relevant tests and
documentation. This allows:
- Reviewing each piece in isolation
- Merging incrementally when possible
- Easier identification of issues during review
For a feature this size, incremental review makes an enormous difference.
Think of commits as logical building blocks rather than chronological
changes.
So, concretely, next steps would be opening a fresh branch against current
`main` with a clean, well-structured commit history. That would help move
this forward efficiently. Jacob R, if you can prepare this, we'll
definitely try to prioritize review. Mike, your continued feedback on the
integration side would be highly appreciated. Please let us know if you
have questions about this approach!
--
Ticket URL: <
https://code.djangoproject.com/ticket/35514#comment:22>