Django Email Backend - python

I'm developing a django app locally and trying to configure it to use the Amazone SES service to send emails. I've installed django-ses and added this to my settings.py:
EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_SES_REGION_NAME = 'us-west-2'
AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'
AWS_ACCESS_KEY_ID = '...'
AWS_SECRET_ACCESS_KEY = '...'
Unfortunately, mail.get_connection() returns that it's still using django.core.mail.backends.console.EmailBackend; both in the shell and when the development server is running.
It behaved the same when I was attempting to go the normal smtp configuration route with django.core.mail.backends.smtp.EmailBackend too...
Any ideas as to why it's not making the switch?

According to the django docs the default value for EMAIL_BACKEND is django.core.mail.backends.smtp.EmailBackend, not django.core.mail.backends.console.EmailBackend, so it has probably been set again later in the settings file.
You can also print the value of EMAIL_BACKEND to make sure if the problem is in the function or the variable.
from django.conf import settings
print(settings.EMAIL_BACKEND)

Related

smtplib.SMTPNotSupportedError: SMTP AUTH extension not supported by server - trying to send email via Django

I have a Docker container where I am trying to send an email via Django.
I have a separate email server on another domain that I want to use for this purpose. I have other applications connect with it with no problem.
My Django production email setup looks like this (I intend to replace username and password with Kubernetes secrets in the future, but for testing I am just putting them inside the file):
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mail.mydomain.io'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = "<username>"
EMAIL_HOST_PASSWORD = "<password>"
In my module, I have the following code:
from rest_framework.views import APIView
from django.core.mail import send_mail
class MailView(APIView):
def post(self, request):
subject = request.data.get("subject")
message = request.data.get("message")
sender = request.data.get("sender")
receipients = request.data.get("receipients")
send_mail(subject,message,sender,receipients,fail_silently=False,)
... more
This works locally, however when I try to run it inside the container, I get the following error:
smtplib.SMTPNotSupportedError: SMTP AUTH extension not supported by server.
Do I need to install some sort of SMTP relay or server to my Docker container?
My Docker container is based on the python:3.7 container and I am not currently installing any SMTP extensions or anything to it.
EMAIL_USE_TLS needs to be set to True
EMAIL_USE_TLS = True

python django email set correct sender gunicorn

This is my settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com' # mail service smtp
EMAIL_HOST_USER = 'xx#xx.com' # email id
EMAIL_HOST_PASSWORD = 'sdjlfkjdskjfdsjkjfkds' #password
EMAIL_PORT = 587
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = 'xx#xx.com'
I am sending password reset email
It works fine on localhost but on production server as sender I get webmaster#localhost
What do I do?
This is my urls.py
url(r'^password_reset/$', auth_views.PasswordResetView.as_view(
template_name='accounts/password_reset.html',
email_template_name = 'accounts/email/password_reset.html',
html_email_template_name = 'accounts/email/password_reset.html',
subject_template_name = 'accounts/email/password_reset_subject.html'),
First I want to explain why you get specifically webmaster#localhost email.
Explanation
django.contrib.auth.forms.PasswordResetForm.save() function uses None as a from email address, webmaster#localhost is used by default, so you should just need to add DEFAULT_FROM_EMAIL property to your settings.py.
Solution
Connect to your production enviroment and run the django shell with python manage.py shell.
Now run the following commands.
# Check your enviroment, should say something like production.
import os
os.environ.get('DJANGO_SETTINGS_MODULE')
# Check if the DEFAULT_FROM_EMAIL property is set.
from django.conf import settings
settings.DEFAULT_FROM_EMAIL
With os.environ.get('DJANGO_SETTINGS_MODULE') you will get the settings file you are using for production, so if settings.DEFAULT_FROM_EMAIL isn't set just edit that file and add it with your email.
Recomendations
Use another email backend (mandrill, sendgrid, etc...) to ensure that your mails will reach the inbox and not the spam folder.
For this you can use django-anymail package.
References
How to create a password reset view in Django - simpleisbetterthancomplex.com

Django REST framework: Basic Auth without debug

Got a problem with Basic authentication in Django REST framework when debug mode is turned off. I am using Django 1.8.4 and Django REST Framework 3.2.2.
Looks like it saves credentials for all computers with the same IP address when the first is logged in. But after some time it prompts for the username and password again.
However, this problem does not occur when the debug mode in Django REST framework settings is set to True. I would like to have the same behaviour when debug is turned off. What is causing the problem?
In settings.py file add the host/domain-name of the system to which django is allowed to serve.
Use:
ALLOWED_HOSTS = ['127.0.0.1'] or ALLOWED_HOSTS = ['localhost'] so that django can serve the localhost.
You may also add other IP address as you wish.
Example:
ALLOWED_HOSTS = ['127.0.0.1', '192.1.12.23']
Domain names can also be accepted:
ALLOWED_HOSTS = ['www.example.com']
If you wish to serve many hosts, you may simply use *, as shown:
ALLOWED_HOSTS = ['*']
This will serve Django to any host in the world.

Duplication of settings for multi-site django setup

I'm using the same django codebase on multiple apps on heroku. My set up is using a git master branch and individual branches for each separate domain. However I'm struggling with the ideal solution of storing setting variables which are different for each app.
I was going down the route of storing them in environment variables, separate for each app on heroku. This would of been the ideal solution. However there are one or two admin functions which I currently only run locally in my app which needs to know the settings for each app. This means I'd have to store all the settings for each app in every apps environment. For instance:
instead of
site_email=blah#site.com
I'd end up with:
site1_email=blah#site1.com
site2_email=blah#site2.com
and so on...
I could do this but it just seems pretty messy to me. Are there any alternatives? I could rip out the offending functions and build them into their own app, but this seems alot of work just to hide app settings from each other.
given the following app setup:
/Project/
/app1/
/app2/
/project/ (the project app that gets auto created in Django 1.4+)
/settings/
__init__.py <- general site inspecific settings
sitea.py <- site A's specific settings
siteb.py <- site B's specific settings
inside sitea.py put Site specific settings (you can still use the os.environ.get() calls to use heroku stored settings).
# Default Django settings for project.
from project.settings import *
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email#example.com'),
)
MANAGERS = ADMINS
ALLOWED_HOSTS = []
MEDIA_ROOT = ''
STATIC_ROOT = ''
then in your heroku run/startup script do the equivalent of (I assume you'll be using gunicorn or some other production django server)
python manage.py runserver --settings=project.settings.sitea
Update - an example Project/project/settings/production.py file, note: all sensitive info reads from environment not from file.
from project.settings import *
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
('Francis', 'francis#teamcolab.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': os.environ.get('MYSQL_DATABASE'), # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': os.environ.get('MYSQL_USER'),
'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
'HOST': os.environ.get('MYSQL_HOST'), # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': os.environ.get('MYSQL_PORT'), # Set to empty string for default.
}
}
REDIS = {
'HOST' : os.environ.get('REDIS_HOST'),
'PASSWORD' : os.environ.get('REDIS_PASSWORD', None),
'PORT' : int(os.environ.get('REDIS_PORT', 6379)),
'DB' : int(os.environ.get('REDIS_DB', 0)),
}
WEBSOCKET_URL = os.environ.get('WEBSOCKET_URL')
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ['XX.com','production.XX.com','www.XX.com',]
SESSION_COOKIE_DOMAIN = '.XX.com'
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = os.environ.get('MEDIA_ROOT')
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = os.environ.get('STATIC_ROOT')
Here's how we do it at The Motley Fool.
We have multiple settings files, one for each environment.
We have a defaults.py settings file which is the 'stock' for all environments.
We have settings files for each environment: testing.py, live.py etc.
These contain the changes from default (or completely different settings as needed).
We use Fabric + an internal deployer to deploy the right settings file to the right environment.
We have a fabfile that looks like this (simplified):
#task #def test():
"""sets environment to test"""
set_hosts(['testserver01.test.com', 'testserver02.test.com']) #servers to deploy to
env.environment = 'testing'
We have an internal deployer that scripts the creation of the environment:
def setup():
from fabric.api import cd, env
with cd(env.checkout):
env.run('python create_manage_script.py %s' % env.environment)
So when we deploy, here's what happens:
User runs fab {{environment}} deploy
Our deployer looks at the settings directory, and looks for a settings file that matches the environment name (testing/live/etc)
The deployer sends the appropriate commands to fabric,
Fabric deploys the code to that server and points the server to the correct settings file
It's important to note that we have three different environments (dev, test, live), and we have three different apps that use these three different environments.

Django mail sending error

I have separate django project and one python script file. The script file will not depends on project(that was available in different path).
The script file will generate some data and need to send mail to corresponding user. In this case i am trying to use django mail:-
from django.core.mail import EmailMessage, SMTPConnection
I enabled the django environment in my python script file and added the sys.path to my django project settings(So i can able to use django mail).
# setting a django environment
os.environ['DJANGO_SETTINGS_MODULE'] = "settings"
sys.path = sys.path + [PROJECT_PATH]
And the mail config code added in my script:-
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxxx#gmail.com'
EMAIL_HOST_PASSWORD = 'xxx'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
After all this mail not working properly. Because the above parameters not in settings file(The actual problem is if i added this "EMAIL_USE_TLS" parameter itself in settings means it works properly other parameters taking from my script file.
My question is why "EMAIL_USE_TLS" this parameter is not taking from my script file like other parameters?
or
Is mandatory one "EMAIL_USE_TLS" this needs to specify in settings file?
If i not specified EMAIL_USE_TLS = True in settings means got below error:-
SMTP AUTH extension not supported by server
Please anyone advise on this.

Categories