Using Django SMTP - python

After reading the docs on the Django website, I'm a little confused on how to configure the SMTP backend with my Djagno application. I have a local exchange server that is running a business domain business.com that uses Outlook as the client. How do I configure the settings so that I am using a corporate email (local exchange) to send emails in the settings?
Thanks for you help!
EDIT:
Here is the connection error:
email.send()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\mail\message.py", line 342, in send
return self.get_connection(fail_silently).send_messages([self])
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\mail\backends\smtp.py", line 100, in send_messages
new_conn_created = self.open()
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\mail\backends\smtp.py", line 58, in open
self.connection = connection_class(self.host, self.port, **connection_params)
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py", line 335, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py", line 306, in _get_socket
self.source_address)
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\socket.py", line 711, in create_connection
raise err
File "C:\Users\Evan\AppData\Local\Programs\Python\Python35-32\lib\socket.py", line 702, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
And here is my code:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'business.com'
EMAIL_PORT = '25'
EMAIL_HOST_USER = 'purchases#business.com'
EMAIL_HOST_PASSWORD = 'password'

Raise a request to your SMTP services team to allow sending emails from your ip/domain name with a valid sender email id.
After it is approved, fetch the details of the EMAIL_HOST and EMAIL_PORT from smtp services team. And add it to settings.py as shown below:
EMAIL_USE_TLS = True
EMAIL_HOST = 'business.com'
EMAIL_PORT = '25' #or 587 or any others
EMAIL_HOST_USER = 'mailer#business.com' #Same as the sender email id
EMAIL_HOST_PASSWORD = 'yourpassword' #For exchange server pwd is not required
Run interactive mode:
python manage.py shell
Import the EmailMessage module:
from django.core.mail import EmailMessage
Now try to send an email with help of following code:
email = EmailMessage('Subject', 'Body', to=['your#email.com'])
email.send()

Related

Django send_mail not working while smtplib works

I have a setup where I am using "send_mail" to send emails to the users using a gmail account. For some reason this function returns "smtplib.SMTPServerDisconnected: Connection unexpectedly closed".
I am using a gmail account with 2 factor security enabled and an app password.
If I just build a script using smtplib, it works. I am not sure how exactly to debug this issue.
Edit 1:
'send_mail' Seems to work if I remove "**connection_params" from being passed to "self.connection_class" on line 81 in 'django/core/mail/backends/smtp.py'
Edit 2:
Changing "smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587)" to "smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587, local_hostname='localhost')" results in the same error in case of smtplib
The problems seems to lie in the following:
value "localhost" is assigned to "connection_params" on line 69 in 'django/core/mail/backends/smtp.py' in the following manner (you may notice, there is no 'if' check, as the comment states):
...
# If local_hostname is not specified, socket.getfqdn() gets used.
# For performance, we use the cached FQDN for local_hostname.
connection_params = {"local_hostname": DNS_NAME.get_fqdn()}
...
The problem is, there is no way to assign 'local_hostname', as far as I can see, nor is there a way to set it to None
Edit 3:
It looks like Django is trying to do a 'socket.getfqdn()', which returns 'localhost', but 'localhost' is not fully qualified. Smtplib does the same 'socket.getfqdn()', but check for localhost and sets it to '127.0.0.1' instead.
This seems like a bug, with no way to set the 'local_hostname' value, and automatically setting it to 'localhost' which is not fully qualified.
Code snippets below:
settings.py
...
EMAIL_HOST = 'smtp-relay.gmail.com'
EMAIL_HOST_USER = "myemail#costumgmail.com"
EMAIL_HOST_PASSWORD = "mypass"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
...
djangotest.py
from django.core.mail import send_mail
send_mail('Django mail', 'This e-mail was sent with Django.', "myemail#costumgmail.com" , ['some.other#mail.com'], fail_silently=False)
# smtplib.SMTPServerDisconnected: Connection unexpectedly closed
smtplibtest.py
from email.message import EmailMessage
import smtplib
email_sender = "myemail#costumgmail.com"
email_password="mypass"
email_reciever ='some.other#mail.com'
subject = "test"
body = "test"
em = EmailMessage()
em['sender'] = email_sender
em['to'] = email_reciever
em['subject'] = subject
em.set_content(body)
smtpObj = smtplib.SMTP('smtp-relay.gmail.com', 587)
smtpObj.ehlo() # (250, b'smtp-relay.gmail.com at your service, [188.26.233.149]\nSIZE 157286400\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES\nPIPELINING\nCHUNKING\nSMTPUTF8')
smtpObj.starttls() # (220, b'2.0.0 Ready to start TLS')
smtpObj.login(email_sender, email_password) # (235, b'2.7.0 Accepted')
smtpObj.sendmail(email_sender, email_reciever, em.as_string()) # OK
traceback from django:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/__init__.py", line 87, in send_mail
return mail.send()
File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/message.py", line 298, in send
return self.get_connection(fail_silently).send_messages([self])
File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
new_conn_created = self.open()
File "/root/.virtualenvs/myenv/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 87, in open
self.connection.starttls(
File "/usr/lib/python3.10/smtplib.py", line 769, in starttls
self.ehlo_or_helo_if_needed()
File "/usr/lib/python3.10/smtplib.py", line 612, in ehlo_or_helo_if_needed
(code, resp) = self.helo()
File "/usr/lib/python3.10/smtplib.py", line 441, in helo
(code, msg) = self.getreply()
File "/usr/lib/python3.10/smtplib.py", line 405, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed

Connection timed out when trying to send an email using the send_mail method

I am having trouble when it comes to sending emails using the send_mail method from the django.core.mail module.
The contents of the project email settings are as follows.
# --snip--
# Email Settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'mukukachilu#gmail.com'
EMAIL_HOST_PASSWORD = 'myfakepassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = False
EMAIL_USE_SSL = False
# --snip--
This is what I am doing in the Django shell.
Python 3.9.7 (default, Sep 10 2021, 14:59:43)
[GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.mail import send_mail
>>> from django.conf import settings
>>> send_mail('Test Subject', 'Test message', settings.EMAIL_HOST_USER, ['c.mukuka#makeitworkds.com'], fail_silently=False)
After the send_mail method hangs for a long time, I am getting this Traceback below.
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/__init__.py", line 61, in send_mail
return mail.send()
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/message.py", line 284, in send
return self.get_connection(fail_silently).send_messages([self])
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 102, in send_messages
new_conn_created = self.open()
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 62, in open
self.connection = self.connection_class(self.host, self.port, **connection_params)
File "/usr/lib/python3.9/smtplib.py", line 255, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.9/smtplib.py", line 341, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.9/smtplib.py", line 312, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/lib/python3.9/socket.py", line 844, in create_connection
raise err
File "/usr/lib/python3.9/socket.py", line 832, in create_connection
sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out
I also did a telnet command on the Gmail smtp server like so
# telnet smtp.gmail.com 25
Trying 2a00:1450:400c:c0c::6d...
But Getting this response from telnet
telnet unable to connect to remote host: Connection timed out
I have also enabled two-factor authentication on my Gmail account and I singing in using the App password. I also tried using the method of signing in using less secure apps but it is still the same thing.
So where could I be possibly going wrong?
The SMTP protocol makes use of a TCP socket connection to send the email. There can only be one TCP socket for each port on the client side.
In your case, Django will bind a TCP socket to the EMAIL_PORT you specified on the client side to send the email. That socket by default has an EMAIL_TIMEOUT of None according to the documentation, so the socket will persist indefinitely. You will be able to send the message the first time, but the second time you run your code you will get the above error since the port is already in use.
You should specify an EMAIL_TIMEOUT in your settings to close the sockets after some time interval. You should also free up the used TCP port before you try to send an email again following the steps of this thread (or just restart your PC).

How to reslove "socket.gaierror" error of python-smtplib?

Few hours back I have posted a post related to "Django email sending API" and its error. So I thought that first I should try something with "smtplib". Unfortunately, after struggling with "smtplib", I realise that it will also not work, because something is wrong with my code or my network or my machine which I am not able to figure out.
Can any body help me regarding to this?
As of now, after struggling a lot, I have tried hundreds of solution posted here and there and also I have tried to resolve with myself but nothing is working in my case kindly help.
Code is given bellow.
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
import socks
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, "172.16.0.2", '8084')
socks.wrapmodule(smtplib)
#smtp = smtplib.SMTP()
msg = MIMEMultipart()
msg['From'] = 'my#yahoo.com'
msg['To'] = 'example#gmail.com'
msg['Subject'] = 'simple email in python'
message = 'here is the email'
msg.attach(MIMEText(message))
mailserver = smtplib.SMTP('smtp.mail.yahoo.com',465)
# identify ourselves to smtp gmail client
mailserver.ehlo()
# secure our email with tls encryption
mailserver.starttls()
# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('my#yahoo.com', 'pswd12345678')
mailserver.sendmail('my#yahoo.com','example#gmail.com',msg.as_string())
mailserver.quit()
This is the error coming again and again:
Traceback (most recent call last):
File "import_mail.py", line 21, in <module>
mailserver = smtplib.SMTP('smtp.mail.yahoo.com',465)
File "/usr/lib/python2.7/smtplib.py", line 256, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python2.7/smtplib.py", line 316, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python2.7/smtplib.py", line 291, in _get_socket
return socket.create_connection((host, port), timeout)
File "/usr/lib/python2.7/socket.py", line 557, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno -3] Temporary failure in name resolution
This error is raised as the 'EMAIL_BACKEND' definition is missing from the settings file. Make sure that the settings.py file contains the following line:-
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
IF you`re using the gmail account to set up a default interactive mail, use the following values:-
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587 #PORT NO
EMAIL_HOST_USER = #e-MAIL ID
EMAIL_HOST_PASSWORD = #PASSWORD
My system had not a DNS configured and I resolved this issue configuring a google DNS or an openDNS.

Django Email Error: raise err socket.error: [Errno 111] Connection refused [duplicate]

This question already has answers here:
How to execute a Python script from the Django shell?
(26 answers)
Closed 4 years ago.
I saw this question being asked at a number of places but no solutions have worked for me so far, or may be I am unable to understand what to do exactly (newbie traits). Please help if you can.
Email Settings/ settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'xyz#gmail.com'
EMAIL_HOST_PASSWORD = 'pwd'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
Error I am receiving while sending test email from the Django Python Shell:
First I ran the send mail command - Gave me Error1: django.core.exceptions.ImproperlyConfigured:
>>> from django.core.mail import send_mail
>>> send_mail('Test', 'Test', 'xyz#gmail.com', ['abc#hotmail.com'], fail_silently=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site- packages/Django-1.8.2-py2.7.egg/django/core/mail/__init__.py", line 56, in send_mail
fail_silently=fail_silently)
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/mail/__init__.py", line 37, in get_connection
klass = import_string(backend or settings.EMAIL_BACKEND)
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/conf/__init__.py", line 48, in __getattr__
self._setup(name)
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/conf/__init__.py", line 42, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting EMAIL_BACKEND, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
To Overcome Error1- I ran the below commands
>>> from django.conf import settings
>>> settings.configure()
Secondly I ran the send mail again - Gave Error2: Emails not going out!
socket.error: [Errno 111] Connection refused
>>> from django.core.mail import send_mail
>>> send_mail('Test', 'Test', 'xyz#gmail.com', ['abc#hotmail.com'], fail_silently=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/mail/__init__.py", line 62, in send_mail
return mail.send()
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/mail/message.py", line 303, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/mail/backends/smtp.py", line 100, in send_messages
new_conn_created = self.open()
File "/home/django_admin1/venv-tile-prod/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/mail/backends/smtp.py", line 58, in open
self.connection = connection_class(self.host, self.port, **connection_params)
File "/usr/local/lib/python2.7/smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "/usr/local/lib/python2.7/smtplib.py", line 311, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/local/lib/python2.7/smtplib.py", line 286, in _get_socket
return socket.create_connection((host, port), timeout)
File "/usr/local/lib/python2.7/socket.py", line 571, in create_connection
raise err
socket.error: [Errno 111] Connection refused
All this while I was attempting to send the email from the normal python prompt which is invoked as:
(venv)[user#server django_project]$ python
The emails never went. Actually they have to be run from
(venv)[user#server django_project]$ python manage.py shell
>>> from django.core.mail import send_mail
>>> send_mail('Test', 'This is test email', 'xyz#gmail.com', ['recipientemail#hotmail.com'], fail_silently=False)
That resolved the issue for me. The email went out perfectly. So there was no problem with my email setup, there was a problem in the way i was sending it.

Django throws this error: SMTPException: STARTTLS extension not supported by server

Due to limitation of outgoing mail in gmail, I installed exim4 on one of my server with the following settings:
dc_eximconfig_configtype='internet'
dc_other_hostnames='mydomain.com, localhost, localhost.localdomain, mail.mydomain.com'
dc_local_interfaces=''
dc_readhost='mydomain.com'
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='mydomain.com'
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname='true'
dc_mailname_in_oh='true'
dc_localdelivery='maildir_home'
I also changed my firewall settings to allow SMTP connection.
Now I can send mail from this server with some command like this:
echo "TEST" | mail -s testing user#example.com
Now I want to use this server to send mail for my another remote server say mydomain2.com.
I am using django on this second server.
The current settings of settings.py file are following:
EMAIL_HOST = 'mail.mydomain.com'
EMAIL_HOST_USER = 'username' # username of one of my user on the first server
EMAIL_HOST_PASSWORD = 'password'
EMAIL_PORT = 25
EMAIL_USE_TLS = True
When I try to send mail from this server using above settings and the following code:
from django.core.mail import send_mail
send_mail('testing','test','from#example.com',['to#example.com'])
I get the following error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/django/core/mail/__init__.py", line 61, in send_mail
connection=connection).send()
File "/usr/local/lib/python2.7/dist-packages/django/core/mail/message.py", line 248, in send
return self.get_connection(fail_silently).send_messages([self])
File "/usr/local/lib/python2.7/dist-packages/django/core/mail/backends/smtp.py", line 85, in send_messages
new_conn_created = self.open()
File "/usr/local/lib/python2.7/dist-packages/django/core/mail/backends/smtp.py", line 51, in open
self.connection.starttls()
File "/usr/lib/python2.7/smtplib.py", line 635, in starttls
raise SMTPException("STARTTLS extension not supported by server.")
SMTPException: STARTTLS extension not supported by server.
I think there is some problem in the settings of exim4.
So how I do solve this tls error.
Thanks in Advance.
Thanks Reto,
I installed the exim4 now on the second server and
I tried your suggestion and then it was throwing error 'AUTHException:' .
So finally I figured out that I had to comment out two more lines. So now my setting.py file looks like this:
EMAIL_HOST = 'localhost'
#EMAIL_HOST_USER = 'username' # username of one of my user on the first server
#EMAIL_HOST_PASSWORD = 'password'
EMAIL_PORT = 25
#EMAIL_USE_TLS = True
and Now it's working!!!
Thanks again Reto.

Categories