Connection Error SMTP python: smtplib.SMTPServerDisconnected: please run connect() first
Asked Answered
P

10

13

I've been using python for a bit now and have been using the email function without any errors in the past but on the latest program I have made I've been getting this error

 Traceback (most recent call last):
    File "daemon.py", line 62, in <module>
    scraper.run()
    File "c:\cfsresd\scraper.py", line 48, in run
    self.scrape()
    File "c:\cfsresd\scraper.py", line 44, in scrape
    handler(msg)
    File "daemon.py", line 57, in handler
    server.ehlo()
    File "C:\Python27\lib\smtplib.py", line 385, in ehlo
    self.putcmd(self.ehlo_msg, name or self.local_hostname)
    File "C:\Python27\lib\smtplib.py", line 318, in putcmd
    self.send(str) 
    File "C:\Python27\lib\smtplib.py", line 310, in send
    raise SMTPServerDisconnected('please run connect() first')
    smtplib.SMTPServerDisconnected: please run connect() first

I used the same email code for all my projects but this is first time is done it. I've tried adding the connect() but that made no difference. Below is email section of my script

msg = MIMEText ('%s - %s' % (msg.text, msg.channel))
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo()
    server.starttls()
    msg['Subject'] = "msg.channel"
    msg['From'] = ('removed')
    msg['To'] = ('removed')
    server.login('user','password')
    server.sendmail(msg.get('From'),msg["To"],msg.as_string())
    server.close()
    server.ehlo()
    server.quit()
    print('sent')
Peugia answered 10/5, 2015 at 3:34 Comment(6)
Is your connection failing? Is this the same connection string you typically use? I think smtplib.SMTP takes host and port as different arguments, though perhaps it also handles it as you specify it therePolice
email still get sent but then error come up and script stopsPeugia
here is one i made that works via my github linkPeugia
Yup, that makes me think my answer is probably right, that code in your link doesn't have the extra close() and ehlo() callsPolice
tried with close () and ehlo() no changePeugia
You could try the default of yagmail package (see answer below).Motherless
P
8

All sorted took a few idea and tried the code below:

msg = MIMEText ('%s - %s' % (msg.text, msg.channel))
server = smtplib.SMTP('smtp.gmail.com')
server.starttls()
server.login('user','pass')
msg['Subject'] = "msg.channel"
msg['From'] = ('from')
msg['To'] = ('to')
server.sendmail(msg.get('From'),msg["To"],msg.as_string())
server.quit()

So I removed ehlo(), close() and port number. Now I have to workout how to change the subject to msg.channel so it changes each time.

Peugia answered 10/5, 2015 at 5:39 Comment(1)
I removed ehlo(), close() and the port number like you did, but I still have this problem, how can I fix it?Bulter
S
3

Try using SMTP's empty constructor, then call connect(host, port):

    server = smtplib.SMTP()
    server.connect('smtp.gmail.com', '587')
    server.ehlo()
    server.starttls()
    server.login(username, password)
Shrovetide answered 10/5, 2015 at 3:39 Comment(3)
re-read post and tried forgot () in topline but sill same error disregard old comments sorryPeugia
Call connect('smtp.google.com', '587'), not connect('smtp.google.com:587')Shrovetide
i have all ways called smtp.gmail.com but tried with smtp.google.com and get error 11004 get addrinfo failPeugia
S
2

You can still have an encrypted connection with the smtp server by using the SMTP_SSL class without needing the starttls call (shorter). You don't need to be calling the ehlo every time, that's done automatically when needed, and when connecting to the default port, don't have to supply one when creating instances SMTP* classes.

msg = MIMEText ('%s - %s' % (msg.text, msg.channel))
msg['To'] = ','.join(receivers)
msg['Subject'] = 'msg.channel'
msg['From'] = '[email protected]'

Using SMTP with the starttls:

server = smtplib.SMTP('smtp.gmail.com')
server.starttls()
server.login('user', 'password')
server.sendmail(msg['From'], receivers, msg.as_string())

and now with the SMTP_SSL class

server = smtplib.SMTP_SSL('smtp.gmail.com')
server.login('user', 'password')
server.sendmail(msg['From'], receivers, msg.as_string())

and finally

server.quit()
Steppe answered 10/5, 2015 at 4:34 Comment(4)
says incorrect protocol i like the server.startttls () personallyPeugia
So what's this msg object in the MIMEText constructor? And what's channel?Groscr
Does sendmail() really require the headers to be populated in msg as well as specified in its params?Groscr
Oh. msg.channel is just a string. It's the subject header. The MIMEText constructor takes a single arg: the body of the message. The SSL version is the first of the many solutions I've run across that worked for me.Groscr
P
1

You have an ehlo after close. That seems unlikely to ever succeed. Also, quit does close so you can probably just get rid of the ehlo and close calls near the end

Police answered 10/5, 2015 at 3:47 Comment(0)
M
1

For Pyhton 3.6.*
Note : In gmail it will work only if 2-Step verification is turned off. Allow gmail to open via low secured app.

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from_addr = 'sender-email-id'
to_addr = 'receiver-email-id'
text = 'Hi Friend!!!'

username = 'sender-username'
password = 'password'

msg = MIMEMultipart()

msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = 'Test Mail'
msg.attach(MIMEText(text))


server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
server.ehlo()
server.login(username,password)
server.sendmail(from_addr,to_addr,msg.as_string())
server.quit()
Muslin answered 24/1, 2017 at 10:9 Comment(0)
M
0

I'm the maintainer of yagmail, a package that should make it really easy to send an email.

import yagmail
yag = yagmail.SMTP('user','password')
yag.send(to = '[email protected]', subject = 'msg.channel')

when yag leaves scope, it will auto-close.

I would also advise you to register in keyring once, so you'll never have to write the password in a script. Just run once:

yagmail.register('user', 'password')

You can then shorten it to this:

SMTP().send('[email protected]', 'msg.channel')

You can install it with pip or pip3 (for Python 3). You can also read more about it, with functionality as easily adding attachments, inline images/html, aliases etc.

Motherless answered 10/5, 2015 at 19:46 Comment(2)
yagmail.Connect(...): AttributeError: 'module' object has no attribute 'Connect' Importing yagmail from yagmail - same thing.Groscr
@TomRussell Has since been updated to SMTP. I updated the answer, thanks for taking the time to leave a comment.Motherless
S
0

I had a similar problem when I tried to send an e-mail from Celery (as a Docker container). I added env_file to the worker and beat containers in a docker compose file.

env_file: ./env/dev/.env

In that file I have an e-mail configuration.

EMAIL_HOST=smtp.gmail.com
EMAIL_HOST_USER=your_mail
EMAIL_HOST_PASSWORD=your_password
EMAIL_PORT=587
Silvanus answered 21/6, 2020 at 15:12 Comment(0)
T
0

I solved this error just by removing this line:

server.quit() 
Tenant answered 18/1, 2021 at 17:37 Comment(0)
S
0

raise SMTPServerDisconnected('please run connect() first')

if you had this error you my be want install this :

pip install django-smtp-ssl

this one to install smtp library and ssl protocol

its work perfecly for me

Significancy answered 20/2, 2021 at 14:7 Comment(0)
O
0

Believe me or not solution is very simple....

Simply just don't close the connection our in other words don't quit the server.

remove "server.quit()".

now you'll be able to send as many mails you need to.

Ogham answered 28/3, 2023 at 14:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.