77
88import six
99from django .conf import settings
10- from django .core .exceptions import ImproperlyConfigured
1110from django .core .mail .message import sanitize_address , DEFAULT_ATTACHMENT_MIME_TYPE
1211from django .utils .timezone import utc
1312
13+ from .exceptions import AnymailConfigurationError
1414
1515UNSET = object () # Used as non-None default value
1616
@@ -158,25 +158,42 @@ def get_content_disposition(mimeobj):
158158 return str (value ).partition (';' )[0 ].strip ().lower ()
159159
160160
161- def get_anymail_setting (setting , default = UNSET , allow_bare = False ):
162- """Returns a Django Anymail setting .
161+ def get_anymail_setting (name , default = UNSET , esp_name = None , kwargs = None , allow_bare = False ):
162+ """Returns an Anymail option from kwargs or Django settings .
163163
164164 Returns first of:
165- - settings.ANYMAIL[setting]
166- - settings.ANYMAIL_<setting>
167- - settings.<setting> (only if allow_bare)
168- - default if provided; else raises ImproperlyConfigured
165+ - kwargs[name] -- e.g., kwargs['api_key'] -- and name key will be popped from kwargs
166+ - settings.ANYMAIL['<ESP_NAME>_<NAME>'] -- e.g., settings.ANYMAIL['MAILGUN_API_KEY']
167+ - settings.ANYMAIL_<ESP_NAME>_<NAME> -- e.g., settings.ANYMAIL_MAILGUN_API_KEY
168+ - settings.<ESP_NAME>_<NAME> (only if allow_bare) -- e.g., settings.MAILGUN_API_KEY
169+ - default if provided; else raises AnymailConfigurationError
169170
170- ANYMAIL = { "MAILGUN_SEND_DEFAULTS" : { ... }, ... }
171- ANYMAIL_MAILGUN_SEND_DEFAULTS = { ... }
172-
173- If allow_bare, allows settings.<setting> without the ANYMAIL_ prefix:
171+ If allow_bare, allows settings.<ESP_NAME>_<NAME> without the ANYMAIL_ prefix:
174172 ANYMAIL = { "MAILGUN_API_KEY": "xyz", ... }
175173 ANYMAIL_MAILGUN_API_KEY = "xyz"
176174 MAILGUN_API_KEY = "xyz"
177175 """
178176
177+ try :
178+ value = kwargs .pop (name )
179+ if name in ['username' , 'password' ]:
180+ # Work around a problem in django.core.mail.send_mail, which calls
181+ # get_connection(... username=None, password=None) by default.
182+ # We need to ignore those None defaults (else settings like
183+ # 'SENDGRID_USERNAME' get unintentionally overridden from kwargs).
184+ if value is not None :
185+ return value
186+ else :
187+ return value
188+ except (AttributeError , KeyError ):
189+ pass
190+
191+ if esp_name is not None :
192+ setting = "{}_{}" .format (esp_name .upper (), name .upper ())
193+ else :
194+ setting = name .upper ()
179195 anymail_setting = "ANYMAIL_%s" % setting
196+
180197 try :
181198 return settings .ANYMAIL [setting ]
182199 except (AttributeError , KeyError ):
@@ -193,7 +210,7 @@ def get_anymail_setting(setting, default=UNSET, allow_bare=False):
193210 if allow_bare :
194211 message += " or %s" % setting
195212 message += " in your Django settings"
196- raise ImproperlyConfigured (message )
213+ raise AnymailConfigurationError (message )
197214 else :
198215 return default
199216
0 commit comments