
Inbox.py: SMTP for Humans - dshah
https://github.com/kennethreitz/inbox.py
======
illumen
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))

~~~
seanp2k2
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.

~~~
kenneth_reitz
This is for receiving mail.

------
pan69
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?

~~~
nickrj
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.

~~~
pan69
Thanks for that. So what exactly would you be able to use this for?

~~~
sprobertson
Looks like it could be used in an application that needs to send email without
relying on a platform-specific SMTP server or external service.

edit: I'm wrong, listen to this guy ->

~~~
kenneth_reitz
It's actually for an application that needs to receive an email.

------
shuzchen
I've always wanted to make something with <http://lamsonproject.org/>, another
python based SMTP server. This appears to be more bare bones.

~~~
kenneth_reitz
That's exactly why I made this. Lamson looks fantastic and I've heard
_wonderful_ things about it, but my use case is far simpler.

~~~
mahmud
How did you evaluate Lamson if you only "heard" of it?

Non-Invenio Hic .. (bad) Latin for "Hack the good hack" ;-)

------
tocomment
Hey really dumb questions, but I'm wondering what some use cases are for this?

~~~
narag
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.

~~~
almost
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.

~~~
baudehlo
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.

------
Arelius
Am I missing something? It seems that most of the functionality is provided by
the smtpd lib:

[https://github.com/kennethreitz/inbox.py/blob/master/inbox.p...](https://github.com/kennethreitz/inbox.py/blob/master/inbox.py)

~~~
timClicks
Kenneth's work is always about simplifying APIs. Simple APIs lower barriers to
entry, which in turn drive adoption.

~~~
slurgfest
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.

~~~
kenneth_reitz
Who said anything about being rewritten? These are wrappers.

------
endlessvoid94
kenneth, you consistently make simple, badass tools.

thank you, and keep it up.

~~~
alagu
Highest authority on user-experience for APIs and libraries.

------
petermonsson
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.

~~~
kenneth_reitz
Thanks for the feedback :)

The dispatch method is for deferring to cli arguments for external
configuration (say, a Procfile).

The constructor is used for defaults.

------
codexon
I made something like this a long time ago.

No dependencies on third party libraries.

<http://codepad.org/sklZNXxM>

------
gouranga
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.

~~~
brass9
I'm interested. Will be waiting to review your code.

------
jhuckestein
An interesting similar project for nodejs is haraka:
<https://github.com/baudehlo/Haraka>

It's pretty fast. One benchmark (by the developer) clocked it at 5000
messages/s on his Macbook.

~~~
brass9
Haraka is the node.js port of the famous perl smtpd called Qpsmtpd. Haraka is
developed by the authors of qpsmtpd - and it seems pretty fast:
<http://baudehlo.wordpress.com/2011/09/13/node-js-is-fast/>

------
_pferreir_
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.

------
thrownaway2424
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?

------
brass9
I'd written a python smtpd for internal use a while back (with code borrowed
from tornado's ioloop, ideas from qpsmtpd, twisted etc.)... it's pretty fast
(though incomplete): [https://github.com/masroore/py-
cyclone/blob/master/cyclone.p...](https://github.com/masroore/py-
cyclone/blob/master/cyclone.py)

<https://github.com/masroore/py-cyclone>

------
driverdan
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?

------
rvkennedy
Is there a Python-based IMAP server?

~~~
emidln
Twisted has twisted.mail.imap4.IMAP4Server

------
skrebbel
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.

~~~
dpritchett
It's too late, he's already got a following. I saw the headline and thought "I
hope this is another awesome Python package by Kenneth Reitz!"

My only regret is that it's for receiving rather than sending. I use ugly
wrapper scripts for my most common attachment mailing scenarios right now.

