I'm guessing this is not complete? I'll review it like it is complete though, since it doesn't say anywhere if it is or not.
I hope no one uses this in production. Handling SMTP well is all about the edge cases, and this doesn't seem to handle any of them.
This is just a thin wrapper on python stdlib smtpd.SMTPServer, which is itself not production ready. It also doesn't really make it easier. The original API is better. Why are magic decorators better than inheritance again?
Also, monkey patching? Hidden side effects make sad pandas cry. Let me throw up a little in my mouth.
There are zero unit tests for this, and no functional tests.
The original API has better documentation. What are the to, sender, and body arguments?
Below seems a simpler API, and gives you the subject too. I thought humans would be interested in the subject... but I guess not.
import inbox
for m in inbox:
toprint = m.to, m.from, m.subject, m.body
print ("to:{} from:{} subject:{} body:{}".format(toprint))
You're right, it's a trivial wrapper with a subjective/opinionated usability improvement.
I think the biggest service here is
1. Education about Python's pretty decent standard smtpd lib.
2. Food for thought about making thin custom interfaces over standard libraries.
3. Perhaps inspiration to do more?
It's no Linux kernel, but I enjoyed reading through the source and I feel like I have a better understanding of Python's smtpd lib and I've some of my own ideas for future API design.
Additionally, I like your generator-based API proposal. Also inspiring. Need to think more about routing in that context, though.
I don't understand why the library chooses to require gevent. That's a large dependency for an API that might be useful otherwise. That should really be up to the user since it looks like it'd work fine in its own thread or standalone.
Seconded. Also, why re-invent the wheel? You're not DJB, an even if you were, qmail kinda sucks these days. With exim and postfix already out there...I'm struggling to see a point to this.
Want your app to send some mail? Please please please don't try delivering directly. The only people great at this are spammers. Use a real MTA and the mail() function that is built into basically every language.
OK. When it comes to email I'm a complete noob. The Github page indicates this is an SMTP server. SMTP is for sending email, right? The examples then goes into an example of creating an inbox, which indicates receiving email. Maybe someone who knows more about this might want to explain?
SMTP is the protocol that mail servers use to send messages between each other, both sending and receiving.
POP3/IMAP are protocols that your email client will use between itself and the mail server which allow you to view messages.
edit: I should note that you're correct in that SMTP is used by the client to relay email messages to the server also.
If you run your own mail server, you can usually configure it to forward mail over SMTP to a specific port, rather than delivering it to a mailbox for a client to pick up using IMAP. If you send the mail (using SMTP) to inbox.py, you'll get callbacks as soon as the mail is received, without having to worry about mailbox management and the complexity of an IMAP client.
This library is for receiving email, new email that you get, is put in your inbox. Email that you are sending goes in your outbox before it is sent. So I think it is named correctly. :)
Our Lamson project has been running for 3 years. It was fun to write, it stays up when we need it to - and it’s easy to modify when we need new features.
This is the only piece of python we have running in-house - we’re a pair of coders and both of us had had very bad experiences with Python (in the distant past - 2002 for me). It’s done quite a lot to rehabilitate python’s reputation here :)
Yours is the top voted comment at the moment, so dumb or not, it seems a common question.
Looking just at the two examples on the main page, it's an implementation of the SMTP protocol so you can either send mail directly to recipients' servers, or run a mail server.
Sending mail directly is often useful when you need to deliver a message to a lot of recipients. IIRC, this doesn't always work, because many servers reject messages unless they can reverse resolve the ip to the sender's domain.
A server for receiving messages is basic infrastructure. The reason for using a simple solution with clear source code, instead of established daemons, like postfix, is that you can tune it to implement filters or notifications.
As an example: some time ago I had the idea of putting a bayesian spam filter directly in the server code, eliminating the problem of false positives: the mail is either accepted or rejected, in which case the sender gets to know that the message has not arrived its recipient, instead of silently trashing it as spam.
The problem with rejecting mail as spam explicitly rather than silently dropping it into the spam bin is that it makes it really easy to tune spam so that it gets past your filter. Maybe it doesn't matter so much if it's just for a few people, but if something like that was popular there would be people figuring out how to work around it.
If this were even a tiny bit of an issue then way more spam would hit people's inboxes. Rejecting explicitly is the right thing to do. It's not always possible, but it's definitely preferred.
Source: I wrote some of the original SpamAssassin and worked in anti-spam for over 10 years.
Too right! I haven't touched 'urllib' since I discovered 'requests', and now I toss off helpful little scrapers and web API-consuming services without a moment's thought.
Does every single part of the standard library need to be rewritten "for humans" (read: in a certain style)? It seems that there are really better and worse cases for doing this.
I am puzzled as to why there is a a dispatch() method. Isn't the serve() method enough?
Also, both the Inbox constructor and the serve() method takes the listening port and address. Now I need to read the source code in order to figure out where I should put the port number and what happens if I put in two different port numbers. (insert appropriate sort of unhappy smiley)
I believe my feedback to Kenneth (if he even sees this) is that this SMTP server can be even simpler.
I wrote an extensive C# version of this that runs as a service, includes a MIME parser, filter pipeline and WCF bridge (so you can recieve mail via a net.tcp).
I will clean it up and chuck it on bitbucket.org some time this month.
You just publish an endpoint on your app, fire up the service and emails come in as WCF messages ready parsed.
Note that Haraka does MUCH more than this simple library. It has a full outbound queue built into it which will send to appropriate MX records for outbound. It has many plugins for processing inbound mail. And yes it is fast - faster than exim or postfix.
Great. I've always wanted to have a simple SMTP server that I could integrate in my projects/unit tests without having to re-invent the wheel. fakemail.py is too old and can't be installed from PyPI.
Anyone else tired of software released with meaningless performance claims? What could it possibly mean to "handle over 1000 emails per second"? Trivial 1-recipient emails?
Can someone explain why this has gotten so many votes? Is it because the author is well known in the Python world? Are other Python SMTP libraries terrible?
A somewhat off topic request: could the friendly people writing libraries "for humans" alter their titles to "for humans who like to write Python"?
This particular one isn't so bad, since ".py" is part of the headline, but it's fooled me so many times that it's getting boring. I'm a human. I think SMTP a big hassle. The headline made me think someone somehow reimplemented what SMTP does for us in a modern way. Instead, it's a client library for a programming language that I don't use.
I hope no one uses this in production. Handling SMTP well is all about the edge cases, and this doesn't seem to handle any of them.
This is just a thin wrapper on python stdlib smtpd.SMTPServer, which is itself not production ready. It also doesn't really make it easier. The original API is better. Why are magic decorators better than inheritance again?
Also, monkey patching? Hidden side effects make sad pandas cry. Let me throw up a little in my mouth.
There are zero unit tests for this, and no functional tests.
The original API has better documentation. What are the to, sender, and body arguments?
Below seems a simpler API, and gives you the subject too. I thought humans would be interested in the subject... but I guess not.