Page 1 of 2

uMail - A lightweight SMTP client for MicroPython

Posted: Tue Sep 18, 2018 3:03 pm
by shawwwn
I was trying to port smtplib but then found out it was too bloated, so I ended up writing my own.

https://github.com/shawwwn/uMail

The API was designed in a way so that it can accommodate sending long emails in a memory constrained system.

There is no pre-defined options for email headers(from/to/subject) so you have to draft up your own ;)

Code: Select all

import umail
smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port
smtp.login('bob@gmail.com', 'bobspassword')
smtp.to('alice@gmail.com')
smtp.write("From: Bob <bob@gmail.com>\n")
smtp.write("To: Alice <alice@gmail.com>\n")
smtp.write("Subject: Poem\n")
smtp.write("Roses are red.\n")
smtp.write("Violets are blue.\n")
smtp.write("...\n")
smtp.send()
smtp.quit()
The SMTP protocol is simple but be can be slow due to the back-and-forth ehlo. So far I am thinking of writing a non-blocking version with uasyncio.

UPDATE 1: Changed argument name 'email' to 'username' as brought up by @SpotlightKid

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Tue Sep 18, 2018 5:04 pm
by pythoncoder
That could be very useful, especially an asynchronous version.

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Wed Sep 19, 2018 8:23 pm
by bitninja
Hi!

I'm getting an

Code: Select all

   AssertionError: auth error 535
on line 73 of umail.py. My example is almost the same as yours.

Do I have to enable something in my gmail account to allow smtp access?

Thanks!

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Thu Sep 20, 2018 7:16 am
by loboris

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Thu Sep 20, 2018 8:46 pm
by bitninja
loboris wrote:
Thu Sep 20, 2018 7:16 am
Allow less secure apps
Ahh! Thank you. That did the trick!

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Fri Sep 21, 2018 12:31 am
by SpotlightKid
When Iooked at the source code, I noticed your module employs STARTTLS, if the server supports it. I think it would be good to mention that in the readme, for those where the server does not support a direct SSLL connection and who may be wondering if/how they can have a secure connection.

In your examples, you should end all header and body lines with '\r\n', not just newline, as the RFC prescribes.

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Fri Sep 21, 2018 9:08 am
by shawwwn
SpotlightKid wrote:
Fri Sep 21, 2018 12:31 am
When Iooked at the source code, I noticed your module employs STARTTLS, if the server supports it. I think it would be good to mention that in the readme, for those where the server does not support a direct SSLL connection and who may be wondering if/how they can have a secure connection.
SMTP server typically uses different ports for secure/unsecure connection(like HTTP). If client connect via an unsecure connection 'ssl=False', then it's up to the server to request whether or not the client should use encryption. If the server response(after the first ELHO) contains STARTTLS, and the client must switch to TLS protocol. If client connect via TLS 'ssl=True', then the STARTTLS won't even appear.
Take Gmail's SMTP for example, its unsecured port is 587. If you want to connect to this port, you must set 'ssl=False', but then Gmail will still request for TLS, otherwise it won't proceed -- that's when our client wraps the connection with TLS. It's all done in a transparent manner, so nothing to worry about.
SpotlightKid wrote:
Fri Sep 21, 2018 12:31 am
In your examples, you should end all header and body lines with '\r\n', not just newline, as the RFC prescribes.
I only tested it on Gmail, it seems to accept any kind of newline character. But yea, you are probably right. I will attach a notice in readme. Thanks for bring this up! :lol:

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Fri Sep 21, 2018 9:22 am
by SpotlightKid
shawwwn wrote:
Fri Sep 21, 2018 9:08 am

SMTP server typically uses different ports for secure/unsecure connection(like HTTP). If client connect via an unsecure connection 'ssl=False', then it's up to the server to request whether or not the client should use encryption. If the server response(after the first ELHO) contains STARTTLS, and the client must switch to TLS protocol.
I see. I thought that the server response would just indicate the support for STARTTLS.

Then you should probably add a boolean keyword arg starttls, to enforce use of STARTTLS with servers, which also allow unsecured connections.

Also, I would suggest, renaming the email argument for the init and login methods to user or username, which IMHO is more semantically correct, since the SMTP server account name doesn't need to be an email address.

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Fri Sep 21, 2018 9:35 am
by shawwwn
SpotlightKid wrote:
Fri Sep 21, 2018 9:22 am
Then you should probably add a boolean keyword arg starttls, to enforce use of STARTTLS with servers, which also allow unsecured connections.
'ssl=True|False' already does that -- if set True, then there is no need to STARTTLS; if set false, then client will switch to TLS upon server's request.
SpotlightKid wrote:
Fri Sep 21, 2018 9:22 am
Also, I would suggest, renaming the email argument for the init and login methods to user or username, which IMHO is more semantically correct, since the SMTP server account name doesn't need to be an email address.
For sure.

Re: uMail - A lightweight SMTP client for MicroPython

Posted: Fri Sep 21, 2018 9:42 am
by SpotlightKid
There are SMTP servers, which do not accept SSL connections on port 465, but support connections on port 587 either with using STARTTLS or without. For those the starttls arg would be useful. I.e. setting ssl=False and starttls=True, would enforce use of STARTTLS with those.