mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Rename EmailBackends for Django consistency
* **Future breaking change:** Rename all Anymail backends to just `EmailBackend`, matching Django's naming convention. (E.g., switch to "anymail.backends.mailgun.EmailBackend" rather than "anymail.backends.mailgun.MailgunBackend".) The old names still work, but will issue a DeprecationWarning and will be removed in some future release. (Apologies for this change; the old naming convention was a holdover from Djrill, and I wanted consistency with other Django EmailBackends before hitting 1.0.) Fixes #49.
This commit is contained in:
@@ -190,9 +190,12 @@ class AnymailBaseBackend(BaseEmailBackend):
|
||||
"""
|
||||
Read-only name of the ESP for this backend.
|
||||
|
||||
(E.g., MailgunBackend will return "Mailgun")
|
||||
Concrete backends must override with class attr. E.g.:
|
||||
esp_name = "Postmark"
|
||||
esp_name = "SendGrid" # (use ESP's preferred capitalization)
|
||||
"""
|
||||
return self.__class__.__name__.replace("Backend", "")
|
||||
raise NotImplementedError("%s.%s must declare esp_name class attr" %
|
||||
(self.__class__.__module__, self.__class__.__name__))
|
||||
|
||||
|
||||
class BasePayload(object):
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailError
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailError, AnymailDeprecationWarning
|
||||
from ..message import AnymailRecipientStatus
|
||||
from ..utils import get_anymail_setting, rfc2822date
|
||||
|
||||
from .base_requests import AnymailRequestsBackend, RequestsPayload
|
||||
|
||||
|
||||
class MailgunBackend(AnymailRequestsBackend):
|
||||
class EmailBackend(AnymailRequestsBackend):
|
||||
"""
|
||||
Mailgun API Email Backend
|
||||
"""
|
||||
|
||||
esp_name = "Mailgun"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
esp_name = self.esp_name
|
||||
@@ -22,7 +25,7 @@ class MailgunBackend(AnymailRequestsBackend):
|
||||
default="https://api.mailgun.net/v3")
|
||||
if not api_url.endswith("/"):
|
||||
api_url += "/"
|
||||
super(MailgunBackend, self).__init__(api_url, **kwargs)
|
||||
super(EmailBackend, self).__init__(api_url, **kwargs)
|
||||
|
||||
def build_message_payload(self, message, defaults):
|
||||
return MailgunPayload(message, defaults, self)
|
||||
@@ -52,6 +55,15 @@ class MailgunBackend(AnymailRequestsBackend):
|
||||
return {recipient.email: status for recipient in payload.all_recipients}
|
||||
|
||||
|
||||
# Pre-v0.8 naming (deprecated)
|
||||
class MailgunBackend(EmailBackend):
|
||||
def __init__(self, **kwargs):
|
||||
warnings.warn(AnymailDeprecationWarning(
|
||||
"Please update your EMAIL_BACKEND setting to "
|
||||
"'anymail.backends.mailgun.EmailBackend'"))
|
||||
super(MailgunBackend, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class MailgunPayload(RequestsPayload):
|
||||
|
||||
def __init__(self, message, defaults, backend, *args, **kwargs):
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailWarning
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailWarning, AnymailDeprecationWarning
|
||||
from ..message import AnymailRecipientStatus, ANYMAIL_STATUSES
|
||||
from ..utils import last, combine, get_anymail_setting
|
||||
|
||||
from .base_requests import AnymailRequestsBackend, RequestsPayload
|
||||
|
||||
|
||||
class MandrillBackend(AnymailRequestsBackend):
|
||||
class EmailBackend(AnymailRequestsBackend):
|
||||
"""
|
||||
Mandrill API Email Backend
|
||||
"""
|
||||
|
||||
esp_name = "Mandrill"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
esp_name = self.esp_name
|
||||
@@ -21,7 +23,7 @@ class MandrillBackend(AnymailRequestsBackend):
|
||||
default="https://mandrillapp.com/api/1.0")
|
||||
if not api_url.endswith("/"):
|
||||
api_url += "/"
|
||||
super(MandrillBackend, self).__init__(api_url, **kwargs)
|
||||
super(EmailBackend, self).__init__(api_url, **kwargs)
|
||||
|
||||
def build_message_payload(self, message, defaults):
|
||||
return MandrillPayload(message, defaults, self)
|
||||
@@ -44,6 +46,15 @@ class MandrillBackend(AnymailRequestsBackend):
|
||||
return recipient_status
|
||||
|
||||
|
||||
# Pre-v0.8 naming (deprecated)
|
||||
class MandrillBackend(EmailBackend):
|
||||
def __init__(self, **kwargs):
|
||||
warnings.warn(AnymailDeprecationWarning(
|
||||
"Please update your EMAIL_BACKEND setting to "
|
||||
"'anymail.backends.mandrill.EmailBackend'"))
|
||||
super(MandrillBackend, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class DjrillDeprecationWarning(AnymailWarning, DeprecationWarning):
|
||||
"""Warning for features carried over from Djrill that will be removed soon"""
|
||||
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
from ..exceptions import AnymailRequestsAPIError
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailDeprecationWarning
|
||||
from ..message import AnymailRecipientStatus
|
||||
from ..utils import get_anymail_setting
|
||||
|
||||
from .base_requests import AnymailRequestsBackend, RequestsPayload
|
||||
|
||||
|
||||
class PostmarkBackend(AnymailRequestsBackend):
|
||||
class EmailBackend(AnymailRequestsBackend):
|
||||
"""
|
||||
Postmark API Email Backend
|
||||
"""
|
||||
|
||||
esp_name = "Postmark"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
esp_name = self.esp_name
|
||||
@@ -22,7 +25,7 @@ class PostmarkBackend(AnymailRequestsBackend):
|
||||
default="https://api.postmarkapp.com/")
|
||||
if not api_url.endswith("/"):
|
||||
api_url += "/"
|
||||
super(PostmarkBackend, self).__init__(api_url, **kwargs)
|
||||
super(EmailBackend, self).__init__(api_url, **kwargs)
|
||||
|
||||
def build_message_payload(self, message, defaults):
|
||||
return PostmarkPayload(message, defaults, self)
|
||||
@@ -30,7 +33,7 @@ class PostmarkBackend(AnymailRequestsBackend):
|
||||
def raise_for_status(self, response, payload, message):
|
||||
# We need to handle 422 responses in parse_recipient_status
|
||||
if response.status_code != 422:
|
||||
super(PostmarkBackend, self).raise_for_status(response, payload, message)
|
||||
super(EmailBackend, self).raise_for_status(response, payload, message)
|
||||
|
||||
def parse_recipient_status(self, response, payload, message):
|
||||
parsed_response = self.deserialize_json_response(response, payload, message)
|
||||
@@ -89,6 +92,15 @@ class PostmarkBackend(AnymailRequestsBackend):
|
||||
return []
|
||||
|
||||
|
||||
# Pre-v0.8 naming (deprecated)
|
||||
class PostmarkBackend(EmailBackend):
|
||||
def __init__(self, **kwargs):
|
||||
warnings.warn(AnymailDeprecationWarning(
|
||||
"Please update your EMAIL_BACKEND setting to "
|
||||
"'anymail.backends.postmark.EmailBackend'"))
|
||||
super(PostmarkBackend, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class PostmarkPayload(RequestsPayload):
|
||||
|
||||
def __init__(self, message, defaults, backend, *args, **kwargs):
|
||||
|
||||
@@ -5,16 +5,18 @@ from django.core.mail import make_msgid
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
from .base_requests import AnymailRequestsBackend, RequestsPayload
|
||||
from ..exceptions import AnymailConfigurationError, AnymailRequestsAPIError, AnymailWarning
|
||||
from ..exceptions import AnymailConfigurationError, AnymailRequestsAPIError, AnymailWarning, AnymailDeprecationWarning
|
||||
from ..message import AnymailRecipientStatus
|
||||
from ..utils import get_anymail_setting, timestamp, update_deep
|
||||
|
||||
|
||||
class SendGridBackend(AnymailRequestsBackend):
|
||||
class EmailBackend(AnymailRequestsBackend):
|
||||
"""
|
||||
SendGrid v3 API Email Backend
|
||||
"""
|
||||
|
||||
esp_name = "SendGrid"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
esp_name = self.esp_name
|
||||
@@ -46,7 +48,7 @@ class SendGridBackend(AnymailRequestsBackend):
|
||||
default="https://api.sendgrid.com/v3/")
|
||||
if not api_url.endswith("/"):
|
||||
api_url += "/"
|
||||
super(SendGridBackend, self).__init__(api_url, **kwargs)
|
||||
super(EmailBackend, self).__init__(api_url, **kwargs)
|
||||
|
||||
def build_message_payload(self, message, defaults):
|
||||
return SendGridPayload(message, defaults, self)
|
||||
@@ -64,6 +66,15 @@ class SendGridBackend(AnymailRequestsBackend):
|
||||
return {recipient.email: status for recipient in payload.all_recipients}
|
||||
|
||||
|
||||
# Pre-v0.8 naming (deprecated)
|
||||
class SendGridBackend(EmailBackend):
|
||||
def __init__(self, **kwargs):
|
||||
warnings.warn(AnymailDeprecationWarning(
|
||||
"Please update your EMAIL_BACKEND setting to "
|
||||
"'anymail.backends.sendgrid.EmailBackend'"))
|
||||
super(SendGridBackend, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class SendGridPayload(RequestsPayload):
|
||||
|
||||
def __init__(self, message, defaults, backend, *args, **kwargs):
|
||||
|
||||
@@ -260,7 +260,7 @@ class SendGridPayload(RequestsPayload):
|
||||
if files_field in self.files:
|
||||
# It's possible SendGrid could actually handle this case (needs testing),
|
||||
# but requests doesn't seem to accept a list of tuples for a files field.
|
||||
# (See the MailgunBackend version for a different approach that might work.)
|
||||
# (See the Mailgun EmailBackend version for a different approach that might work.)
|
||||
self.unsupported_feature(
|
||||
"multiple attachments with the same filename ('%s')" % filename if filename
|
||||
else "multiple unnamed attachments")
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from __future__ import absolute_import # we want the sparkpost package, not our own module
|
||||
|
||||
import warnings
|
||||
|
||||
from .base import AnymailBaseBackend, BasePayload
|
||||
from ..exceptions import AnymailAPIError, AnymailImproperlyInstalled, AnymailConfigurationError
|
||||
from ..exceptions import (AnymailAPIError, AnymailImproperlyInstalled,
|
||||
AnymailConfigurationError, AnymailDeprecationWarning)
|
||||
from ..message import AnymailRecipientStatus
|
||||
from ..utils import get_anymail_setting
|
||||
|
||||
@@ -11,14 +14,16 @@ except ImportError:
|
||||
raise AnymailImproperlyInstalled(missing_package='sparkpost', backend='sparkpost')
|
||||
|
||||
|
||||
class SparkPostBackend(AnymailBaseBackend):
|
||||
class EmailBackend(AnymailBaseBackend):
|
||||
"""
|
||||
SparkPost Email Backend (using python-sparkpost client)
|
||||
"""
|
||||
|
||||
esp_name = "SparkPost"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
super(SparkPostBackend, self).__init__(**kwargs)
|
||||
super(EmailBackend, self).__init__(**kwargs)
|
||||
# SPARKPOST_API_KEY is optional - library reads from env by default
|
||||
self.api_key = get_anymail_setting('api_key', esp_name=self.esp_name,
|
||||
kwargs=kwargs, allow_bare=True, default=None)
|
||||
@@ -77,6 +82,15 @@ class SparkPostBackend(AnymailBaseBackend):
|
||||
return {recipient.email: recipient_status for recipient in payload.all_recipients}
|
||||
|
||||
|
||||
# Pre-v0.8 naming (deprecated)
|
||||
class SparkPostBackend(EmailBackend):
|
||||
def __init__(self, **kwargs):
|
||||
warnings.warn(AnymailDeprecationWarning(
|
||||
"Please update your EMAIL_BACKEND setting to "
|
||||
"'anymail.backends.sparkpost.EmailBackend'"))
|
||||
super(SparkPostBackend, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class SparkPostPayload(BasePayload):
|
||||
def init_payload(self):
|
||||
self.params = {}
|
||||
|
||||
@@ -5,13 +5,15 @@ from .base import AnymailBaseBackend, BasePayload
|
||||
from ..utils import get_anymail_setting
|
||||
|
||||
|
||||
class TestBackend(AnymailBaseBackend):
|
||||
class EmailBackend(AnymailBaseBackend):
|
||||
"""
|
||||
Anymail backend that doesn't do anything.
|
||||
|
||||
Used for testing Anymail common backend functionality.
|
||||
"""
|
||||
|
||||
esp_name = "Test"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Init options from Django settings
|
||||
esp_name = self.esp_name
|
||||
@@ -19,7 +21,7 @@ class TestBackend(AnymailBaseBackend):
|
||||
kwargs=kwargs, allow_bare=True)
|
||||
self.recorded_send_params = get_anymail_setting('recorded_send_params', default=[],
|
||||
esp_name=esp_name, kwargs=kwargs)
|
||||
super(TestBackend, self).__init__(*args, **kwargs)
|
||||
super(EmailBackend, self).__init__(*args, **kwargs)
|
||||
|
||||
def build_message_payload(self, message, defaults):
|
||||
return TestPayload(backend=self, message=message, defaults=defaults)
|
||||
@@ -47,6 +49,14 @@ class TestBackend(AnymailBaseBackend):
|
||||
raise AnymailAPIError('Unparsable test response')
|
||||
|
||||
|
||||
# Pre-v0.8 naming (immediately deprecated for this undocumented test feature)
|
||||
class TestBackend(object):
|
||||
def __init__(self, **kwargs):
|
||||
raise NotImplementedError(
|
||||
"Anymail's (undocumented) TestBackend has been renamed to "
|
||||
"'anymail.backends.test.EmailBackend'")
|
||||
|
||||
|
||||
class TestPayload(BasePayload):
|
||||
# For test purposes, just keep a dict of the params we've received.
|
||||
# (This approach is also useful for native API backends -- think of
|
||||
|
||||
@@ -175,3 +175,7 @@ class AnymailWarning(Warning):
|
||||
|
||||
class AnymailInsecureWebhookWarning(AnymailWarning):
|
||||
"""Warns when webhook configured without any validation"""
|
||||
|
||||
|
||||
class AnymailDeprecationWarning(AnymailWarning, DeprecationWarning):
|
||||
"""Warning for deprecated Anymail features"""
|
||||
|
||||
Reference in New Issue
Block a user