7 ms·
Inbox.py: SMTP for Humans
- pan69 14y agoOK. 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?
- andrewaylett 14y agoIf 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.
- nickrj 14y agoSMTP 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 14y agoThanks for that. So what exactly would you be able to use this for?
- sprobertson 14y agoLooks 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 14y agoIt's actually for an application that needs to receive an email.
- tdfx 14y agoFor one example, this would certainly take care of a lot of the work necessary for creating a disposable email service.
- FuzzyDunlop 14y agoOne existing use-case is Facebook's 'reply to this email to post a comment' feature.
- seigenblues 14y agoI think it could probably be called "outbox" instead -- it might make a bit more sense?
- KenCochrane 14y agoThis 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. :)
- codexon 14y agoI made something like this a long time ago. No dependencies on third party libraries. http://codepad.org/sklZNXxM http://codepad.org/sklZNXxM
- Arelius 14y agoAm 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.py https://github.com/kennethreitz/inbox.py/blob/master/inbox.p...
- timClicks 14y agoKenneth's work is always about simplifying APIs. Simple APIs lower barriers to entry, which in turn drive adoption.
- dpritchett 14y agoToo 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.
- slurgfest 14y agoDoes 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 14y agoWho said anything about being rewritten? These are wrappers.
- shuzchen 14y agoI've always wanted to make something with http://lamsonproject.org/ http://lamsonproject.org/, another python based SMTP server. This appears to be more bare bones.
- kenneth_reitz 14y agoThat'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 14y agoHow did you evaluate Lamson if you only "heard" of it? Non-Invenio Hic .. (bad) Latin for "Hack the good hack" ;-)
- nmcfarl 14y agoWorking with Lamson is a very good experience. 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 :)
- petermonsson 14y agoI 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 14y agoThanks for the feedback :) The dispatch method is for deferring to cli arguments for external configuration (say, a Procfile). The constructor is used for defaults.
- endlessvoid94 14y agokenneth, you consistently make simple, badass tools. thank you, and keep it up.
- alagu 14y agoHighest authority on user-experience for APIs and libraries.
- jhuckestein 14y agoAn interesting similar project for nodejs is haraka: https://github.com/baudehlo/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 14y agoHaraka 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/ http://baudehlo.wordpress.com/2011/09/13/node-js-is-fast/
- baudehlo 14y agoNote 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.
- gouranga 14y agoI 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 14y agoI'm interested. Will be waiting to review your code.
- rvkennedy 14y agoIs there a Python-based IMAP server?
- emidln 14y agoTwisted has twisted.mail.imap4.IMAP4Server
- _pferreir_ 14y agoGreat. 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.
- illumen 14y agoI'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))
- mmerickel 14y agoI 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.
- jonknee 14y agoIt's to monkey patch the socket code of smtpd to make it async. Apparently that nets a nifty speed bump: > "One instance should handle over one thousand emails per second, thanks to Gevent." Take a look at the code, it's very small.
- seanp2k2 14y agoSeconded. 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.
- brass9 14y agoI'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.py https://github.com/masroore/py-cyclone/blob/master/cyclone.p... https://github.com/masroore/py-cyclone https://github.com/masroore/py-cyclone
- tocomment 14y agoHey really dumb questions, but I'm wondering what some use cases are for this?
- narag 14y agoYours 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 14y agoThe 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 14y agoIf 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.
- skrebbel 14y agoA 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 14y agoIt'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.
- thrownaway2424 14y agoAnyone 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?
- driverdan 14y agoCan 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?