6 ms·
Envelopes - Python email for humans
- ghc 13y agoIf this works as well as Python's requests library, then you are my hero. I hate dealing with email in Python, because the standard library interfaces to email are horrible. I have a have a project that could use this now, so I will give it a shot. I will report back with my findings.
- fsckin 13y agoAnyone who calls their project "Library_Name for Humans" has big shoes to fill. Looking at the examples, it appears to be exactly that.
- Chris2048 13y agoperhaps there should be an official group for 'for humans' projects?
- tomekwojcik 13y agoI'm aiming at Requests' robustness, but it's still a long way to go for Envelopes. Good news is - it works and sends e-mails :). If you find any issues please report them at GitHub. Thanks and have fun.
- codegeek 13y agoLooks pretty good. Being a Flask user, happy to see the flask example as well. Would definitely try and use it in side projects of mine. You open to any forks and/or pull requests ?
- bobbyi_settv 13y agoWe use boto to send email via Amazon's Simple Email Service and it is fairly simple. SES allows you to send up to 2000 emails per day for free.
- jp_sc 13y agoWould you be willing to collaborate a SES mailer wrapper for this similar project? https://github.com/lucuma/MailShake https://github.com/lucuma/MailShake
- tghw 13y agoIf they can add IMAP, POP, possibly Exchange, and good email parsing (it's truly a pain in the ass to do yourself) this will be a killer library.
- anonymoushn 13y agoI'd also be interested in an email parsing library for Python. Last time I used Twisted to read email the parser was completely worthless and could not be fixed other than by rewriting it from scratch.
- ianstormtaylor 13y agoFrom an API standpoint: (1) I feel like sending emails isn't a task that's going to be repeated endlessly across a codebase, so is it really necessary to save three characters by truncating "from_address" to "from_addr"? You lose clarity for very little gain. (2) If truncating the above was so important, why is it "text_body" instead of just plain "body"? In this case, you'd lose almost no clarity. I prefer APIs to not have unnecessarily abbreviated words—especially when, realistically, I'm going to type them once per file. (Sorry, pet peeve.)
- ihuman 13y agoIt is called text_body because there is also an html_body. http://tomekwojcik.github.io/envelopes/api/envelope.html http://tomekwojcik.github.io/envelopes/api/envelope.html
- mey 13y agoSo if you set both, will it auto-magically do multipart/mime/alt? That is pretty nice.
- ianstormtaylor 13y agoAh good call. Maybe it's just my very maleable Javascript side talking, but if I were making this API in Javascript I'd probably have a "body" and do a super simple check if the first character is a "<", which will solve the 99.999% case for HTML vs. text emails.
- ihuman 13y agoBut then your emails can't have HTML and a plaintext backup.
- ianstormtaylor 13y agoAh I should have clarified that "body" would be a shorthand of sorts. I'd still have an "html" and "text" alternative to satisfy the case where you want to set both, and in that case "text" and "html" are very meaningful. But the "body" makes the simple case, and the examples extremely clean too.
- gpsarakis 13y agoSeems really nice with a first glance. Are you considering any Django support in the future?
- mattoc 13y agoDjango's Email API is already pretty solid, see the EmailMessage[0] class. Attachments and multiple MIME types are handled for sending text & html versions of the email body. However, given that Django is just Python there's nothing precluding you from using the library as a drop-in replacement. [0] https://docs.djangoproject.com/en/dev/topics/email/#emailmessage-objects https://docs.djangoproject.com/en/dev/topics/email/#emailmes...
- tomekwojcik 13y agoI don't generally do Django, but I don't think it should be a problem. Just a word of warning - if you're going to use a global per-app SMTP connection remember to wrap it in connstack. The Flask example shows this and it shouldn't be hard to do the same in Django.
- ajaxaddicted 13y agoEnvelopes looks very good for sending emails and for reading emails there is another cool library - Imbox https://github.com/martinrusev/imbox https://github.com/martinrusev/imbox
- omaranto 13y agoWhat is the advantage of having an Envelope class? Why not just have a send function?
- YokoZar 13y agoMaybe so you can more deliberately build different parts of the email in different parts of the code without having to create your own set of variables for that.
- TemporalAnomaly 13y agoI find it a little weird that you would create the email in one part of the code and then send it somewhere else though. The only advantage I can think off is something like falling back to another connection if the primary one fails. But it's strange to support reuse of messages while at the same time not being able to reuse a connection. Why not have a set of classes for flexibility and simple helper functions for the most common cases? Requests is so great to use because the API matches the expectations of its users (how do I make a GET request? oh, use the get function...) and I think for email a single send function does what people want most of the time. send( 'smtp.googlemail.com', login='from@example.com', password='password', from_address=u'from@example.com', from_name=u'From Example', to_address=u'to@example.com', to_name=u'To Example', subject=u'Envelopes demo', text=u"I'm a helicopter!" ) connection = Connection( 'smtp.googlemail.com', login='from@example.com', password='password' ) message = Envelope( from_address=u'from@example.com', from_name=u'From Example', to_address=u'to@example.com', to_name=u'To Example', subject=u'Envelopes demo', text=u"I'm a helicopter!" ) message.add_attachment('/Users/bilbo/Pictures/helicopter.jpg') connection.send(message)
- tomekwojcik 13y agoenvelopes.conn.SMTP is a wrapper for smtplib.SMTP that supports Envelope objects and is reusable. Envelope.send() is just a shorthand you can use if you don't care about reusing connections. For requests it's simpler to support top-level functions, since in general HTTP request is self-contained. Envelope (or email.mime.MIMEMessage) object isn't enough to send an e-mail - you need to know the SMTP host, port, creds and set up the connection. While it's certainly possible to write envelopes.send() function that'd internally create an Envelope object and send it (all based on the args the function gets) I don't think it's that crucial.
- topherjaynes 13y agoNice wrapper, though it took me a while to get it to work. Tried with Google SMTP, but ended up throwing Sendgrid on a heroku app and hit that api. Wondering if a debug mode would be helpful for the initial set up. See what requests are being sent/received to see what the possible errors are.
- tomekwojcik 13y agoDebug mode is a nice catch. Thanks. As far as GMail SMTP goes, I've been using Envelopes over GMail SMTP for about a week with great success. The first example in the docs shows just that. Also, I have customized SMTP subclasses for GMail, SendGrid and local Mailcatcher in the pipeline. Using one of them, you'll only have to provide your creds to send e-mails.
- habitue 13y agoI feel I should mention Mailer https://pypi.python.org/pypi/mailer https://pypi.python.org/pypi/mailer I think everyone who has ever used the python standard library email modules has had the thought "Well, if I just made a small wrapper around this... it wouldn't be so bad" And just about everyone who thought that did it.