Simple E-Mail sending working only from Thonny - python

I started a little Raspberry project and stuck with sending a simple E-Mail. Gmail smtp is set up. The code works fine from Thonny (although it sends the E-Mal only for the first receiver and not both), but when I trigger it from the terminal (python report.py), I get the following Error:
Traceback (most recent call last):
File "report.py", line 15, in <module>
with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
TypeError: __init__() got an unexpected keyword argument 'context'
As I mentioned above, from Thonny it is working. I plan to trigger some script like this time scheduled through Crontab. I set up the Crontab file, but it does nothing, I assume because it makes an error every time.
Thank you for help in advance!
The report.py content:
import smtplib, ssl
port = 465 # For SSL
smtp_server = "smtp.gmail.com"
sender_email = "****#gmail.com"
receiver_email = "****#gmail.com,xxxx#gmail.com"
password = "****"
message = """\
Subject: Hi there
This message is sent from Python."""
context = ssl.create_default_context()
with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message)

The context argument to smtplib.SMTP_SSL was added in Python 3.3.
Thonny uses a built-in Python3.7 interpreter, but many Unix-like operating systems' default Python interpreter is Python 2.x. Explicitly call the script with Python 3 to prevent the error:
python3 report.py

Related

Sending email via Gmail SMTP error: smtplib.SMTPServerDisconnected: please run connect() first

have been stuck on this for a few hours. Trying to send email from Python via Gmail SMTP
Gmail settings:
2 Step-Verification: Yes
App password created: Yes
Publishing status: Testing
User type: External
Code:
import smtplib
import ssl
port = 465 # For SSL
password = "example"
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
server.login("test#gmail.com", password)
sender_email = "test#gmail.com"
receiver_email = "test#gmail.com"
message = """\
Subject: Test
Test."""
server.sendmail(sender_email, receiver_email, message)
This is the error message I'm getting:
Traceback (most recent call last):
File "C:\Users\coopejo\PycharmProjects\pythonProject1\trawler\gmaillogin.py", line 20, in <module>
server.sendmail(sender_email, receiver_email, message)
File "C:\Users\coopejo\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 876, in sendmail
(code, resp) = self.mail(from_addr, esmtp_opts)
File "C:\Users\coopejo\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 540, in mail
self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
File "C:\Users\coopejo\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 373, in putcmd
self.send(str)
File "C:\Users\coopejo\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 365, in send
raise SMTPServerDisconnected('please run connect() first')
smtplib.SMTPServerDisconnected: please run connect() first
Any help would be greatly appreciated.Thanks!
So the error raised is asking you to run connect() first, so it looks like you aren't connecting to the server before trying to send the email.
I would put the server.sendemail() line directly under the server.login() line, with the same indent. That way, the already-connected server object is used for both. That's how it works in my code.
However, you're in bad luck here. As of May 30th, Google no longer allows insecure third-party apps to send emails this way. I'm looking into using a more secure auth method now and I'll update you if I find a working method.

python 3.9.0 smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server

I am trying to send emails with gmail using the smtp module for an amazon price tracker. A few days ago, it was working perfectly but today it came up with this error:
File "C:\Users\61409\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 755, in starttls
raise SMTPNotSupportedError(
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.
This is the code that originally worked but gives the error:
import smtplib
def send_email():
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login('xxxxxxxx#gmail.com', '*password*')
subject = f'The price of your product has fallen'
body = f'Check the amazon link - {URL}'
msg = f"Subject: {subject}\n\n{body}"
server.sendmail(
'xxxxxxx#gmail.com',
'xxxxxxx#gmail.com',
msg
)
print('The email has been sent')
server.quit()
I have tried making another gmail account and using SSL (importing ssl too) but the other gmail account comes up with the same problem and when using SSL, it comes up with a SMTP AUTH problem (unable to solve this too). I have allowed less secure apps but the same problem still occurs. I have also tried removing the first server.ehlo() and I have also tried using the server.set_debuglevel(1) but both do not work. I have also tried using with stmplib.SMTP(*Host*, *Port*) as server: and I have tried just using SMTP without using SSl and TLS at all but both answers do not work. Most of the answers removed the smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server. but other problems occured such as smtplib.SMTPServerDisconnected: Connection unexpectedly closed which happened numerous times with other answers. I tried researching on solutions to the connection unexpectedly closing but none of those answers worked too.
These are the answers I have tried:
SMTPException: STARTTLS extension not supported by server
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server
Python 2: SMTPServerDisconnected: Connection unexpectedly closed
Python3 SMTP 'Connection unexpectedly closed'
https://www.reddit.com/r/Python/comments/5grxy8/python_smtplib_connection_unexpectedly_closed/daumi2m/
How to send an email with Python?
How can I fix this problem?, am I missing something?? Will I need to use another module or library to send emails??? I apologise if this is a repeat question with a viable answer. I also apologise if one of the answers I mentioned as not working does actual work except I screwed up the code.
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.
The SMTP connection to the server does not seem to offer the STARTTLS extension, at least as seen from the perspective of the client. This extension is announced inside the response to the initial EHLO command of the client:
$ telnet smtp.gmail.com 587
...
Connected to smtp.gmail.com.
Escape character is '^]'.
220 smtp.gmail.com ESMTP h9sm19557267wre.24 - gsmtp
EHLO mail.example.com
250-smtp.gmail.com at your service, ...
250-SIZE 35882577
250-8BITMIME
250-STARTTLS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...
Given that smtp.gmail.com definitely supports this extension it is likely that there is some man in the middle somewhere in path of the connection, which rewrites the traffic to something like this:
220 smtp.gmail.com ESMTP h9sm19557267wre.24 - gsmtp
EHLO mail.example.com
250-smtp.gmail.com at your service, ...
250-SIZE 35882577
250-8BITMIME
250-XXXXXXXA <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...
Here the response of the server is changed to no longer show support for STARTTLS, in the hope that the client continues without encryption and thus the mail can be analyzed be the man in the middle. Such man in the middle are typically corporate firewalls like Cisco ASA but can also be ISP or local antivirus products.
A few days ago, it was working perfectly but today it came up with this error:
Check if there were any changes regarding local security products (antivirus) or its settings or if there are changes to your environment (corporate firewall, different network you use ...).
I had the same problem: smtplib working properly and then returning this same error, without any change in the server (outlook).
It just so happens that I had refactored my code, and the function that sent the email was deeper in the modules.
If I used the old way, it worked!
When I turned off the anti-virus (AVG in my case), all worked just fine!
So, for some reason, the code refactoring made the sending procedure to be caught by anti-virus.

Send email via Python/django on 1&1

I am developing a website with django framework. And I recently tried to release it on a 1&1 shared hosting.
I managed to make the project run well, except for one last “detail”: I can't send email from django.
I tried almost everything in settings (different emails, ports, etc.), but each time I got a beautiful '500 Internal Server Error' =/ (whereas it went fine on a free alwaysdata server)
In order to find the origin of this issue, I tried different things:
to test send_mail and EmailMessage via the python interpreter:
>>> send_mail('a subject', 'a test message', 'mymail#gmail.com', ['mymail#gmail.com'])
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: a subject
From: mymail#gmail.com
To: mymail#gmail.com
Date: Tue, 14 Jan 2014 22:12:48 -0000
Message-ID: <20140114221248.6718.86150#infong-fr25.kundenserver.de>
a test message
-------------------------------------------------------------------------------
1
But... I got nothing in my inbox.
My settings being:
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
DEFAULT_FROM_EMAIL = 'mymail#gmail.com'
EMAIL_HOST_USER = 'mymail#gmail.com'
EMAIL_PORT = 587
to connect to an SMTP server via the python interpreter:
./manage.py shell
>>> from smtplib import SMTP
>>> smtp_conn = SMTP()
>>> smtp_conn.connect('smtp.gmail.com', 25)
And nothing happens (I tried it with auth.smtp.1and1.fr, or port 587...); when I interrupt the process, it tells me:
^CTraceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.6/smtplib.py", line 295, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python2.6/smtplib.py", line 273, in _get_socket
return socket.create_connection((port, host), timeout)
File "/usr/lib/python2.6/socket.py", line 554, in create_connection
sock.connect(sa)
File "<string>", line 1, in connect
KeyboardInterrupt
to test with a php file:
With a basic:
<?php
if (mail("mymail#gmail.com", "a subject", "a test")) {
echo("<p>Email successfully sent!</p>");
}
else {
echo("<p>Email delivery failed…</p>");
}
?>
And the mail was sent! So, it seems that without SMTP connection, it is possible (at least, via php).
Conclusion
So, my questions are: do you think I can manage to correct this bug, and otherwise is it possible to send mail without smtp connection ("like php")?
1and1 does not allow SMTP within 1and1. To send an email when running on 1and1...
#!/usr/bin/python
import os
mail_to = "sam#comcast.net"
mail_from = "steve#example.com"
subject = "test message"
header = """From: {0}
To: {1}
Subject: {2}
""".format(mail_from, mail_to, subject)
msg = header + "a test from me"
sendmail = os.popen("/usr/lib/sendmail -t", "w")
sendmail.write(msg)
sendmail.close()
The blog post linked shows an example that sends mail using SMTP through 1and1 via an external machine. Perhaps you can override Django's send_mail (or maybe this gives you [or someone else] a hint as to why it doesn't work.) This should allow you to send email in the Python interpreter, anyway.
Source: https://flenniken.net/blog/send-email-using-python-and-1and1/

SSL error on Raspberry Pi

I recently purchased a Raspberry Pi to run some Python scripts, but when I ported it the function I wrote to send emails through Windows Live suddenly started handing out an SSL error after successful handshake, specifically:
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
After extensive searching around, I found many people with the same error, but all in vastly different situations. The most relevant thing I could find was that it seemed to be an issue with a specific version of OpenSSL, but I could find nothing about the version running on my Pi (1.0.1e).
The function (which works perfectly fine on Win7):
def wlive(adr_to, adr_fro, adr_pass, adr_subj, adr_file):
saveout = smtplib.stderr
logger = open('wlive.log', 'w')
smtplib.stderr = logger
msg = MIMEMultipart()
msg['Subject'] = adr_subj
msg['From'] = adr_fro
msg['To'] = adr_to
if adr_file != None:
# subtype recognition based on extension
filext = os.path.splitext(adr_file)[1]
if filext == '.png':
subt = 'png'
else:
subt = 'jpeg'
fp = open(adr_file, 'rb')
img = MIMEImage(fp.read(), subt)
fp.close()
msg.attach(img)
try:
server = smtplib.SMTP('smtp.live.com', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login(adr_fro, adr_pass)
server.sendmail(adr_fro, adr_to, msg.as_string())
server.quit()
return True
except Exception, e:
print 'wlive exception:\n\n', str(e)
return False
smtplib.stderr = saveout
logger.close()
I'm running the fully updated and upgraded Raspbian "Wheezy" image, and Python 2.7.3
I encountered this problem yesterday. First thing to try is to change the account from which you want to send an email to some other provider: try gmail, for instance. In my case it started working instantly.
If it's also the case for you (Microsoft's fault?), try another thing with windows live account (similar to the one suggested in the comment):openssl s_client -connect smtp.live.com:587 -starttls smtp -crlf -ign_eof
then type:
ehlo
auth login
In my case nothing happened. No answer, only read timeout. This time try:
openssl s_client -connect smtp.live.com:587 -starttls smtp -crlf -ign_eof -no_tls1_2
Then:
ehlo
auth login
I got an answer immediately. If it's still your case, there's a little problem. I haven't found any way to specify such a parameter (which versions of tls to prevent from being used). What I found is that in python 3.3 you can give an additional context argument instarttls and you should be able to define some cipher parameters in this context. List of options can be found here.
I must admit that it was easier for me to just use the gmail account than to get python 3.3 (on rpi you've got 3.2 with no possibility of specifying the context), not being even sure if it will help. However, I hope that this information helps you somehow.

Sending an email via gmail through a python application

as indicated by the title I am having trouble sending an email via my gmail account through a python application.I have searched online for a solution but nothing seems to solve it and I thought I might ask here.
My code is the following:
FROMADDR = "myemail#gmail.com"
LOGIN = FROMADDR
PASSWORD = "mypass"
TOADDRS = "varis81#hotmail.com"
msg = "Test message"
server = smtplib.SMTP('smtp.gmail.com', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login(LOGIN, PASSWORD)
server.sendmail(FROMADDR, TOADDRS, msg)
server.quit()
print "E-mail succesfully sent"
I get the message:
socket.error: [Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I tried different ports but it doesn't work also.I also tried hotmail but it causes the same problem.I am using Python 2.7 (don't ask :) ) on a Windows 7 machine developing on Eclipse using PyDev.
Any help would be great!
Thank you in advance.
I'm using the same construct on one of my servers. My code is below.
The only difference is the extra .ehlo() after '.starttls()`. This should not be the issue; from the RFC:
5.2 Result of the STARTTLS Command
The client SHOULD send an EHLO command as the first
command after a successful TLS negotiation.
According to the RFC, the server should not sever a connection if the client does not send ehlo after starttls, but Google could be more restrictive on their SMTP server. I'd check that first. (I've seen providers tighten down on these kinds of conditions to reduce spam, see Mailinator's 2007 writeup for instance.)
It could also be filtered ports - try running the code in the REPL and confirm which line is exceptioning, if it's the connect() you'll know it's network. If it's after, it's likely your usage of smtplib.
Of note, I also experienced occasional unclean shutdowns, resulting in the try/except around .close().
import smtplib
s = smtplib.SMTP()
s.connect("smtp.gmail.com")
s.ehlo()
s.starttls()
s.ehlo()
s.login("from#gmail.com", "frompass")
s.sendmail("fromname#gmail.com", toAddr, bytes)
try:
s.close()
except: pass
Well, since I cant post comments yet I'll have to attempt an answer..
Judging by this: Python SMTP Errno 10060
Perhaps a timeout would help?

Categories