Back to main menu

Email

Python tutorial: How ImgPage lets you upload 25 MB photos to S3 and Cloud files with just an email

This post is written by Paul Finn. Paul is a Portsmouth, NH-based Python developer, business owner (http://route3software.com/) and beer enthusiast (https://hoppypress.com/beer-art). Follow his blog at http://www.pfinn.net/, his tweets at @paulfinn and his code at https://github.com/pfinn

PUBLISHED ON

PUBLISHED ON

This post is written by Paul Finn. Paul is a Portsmouth, NH-based Python developer, business owner (http://route3software.com/) and beer enthusiast (https://hoppypress.com/beer-art). Follow his blog at http://www.pfinn.net/, his tweets at @paulfinn and his code at https://github.com/pfinn

My favorite web development projects always involve building a tool around a newly discovered API and I’ve been a big fan of Mailgun for a while now. Not only does their API tackle one of the most difficult-things-to-get-right, email parsing, it does it very well. It’s a great example of what a modern, developer-friendly API should be: it’s RESTful, solves a real problem, has solid documentation and it’s fast to get started with.

Building a easy-to-use image upload and hosting app

I turned to Mailgun a few weeks ago when I decided to build a quick image host that could receive images via email and not rely on a traditional client-side uploading process. Many of today’s smartphones don’t have native support for uploads in the browser so it can be a bit tricky to find a way to get photos off your phone and share them with just a link (and bypassing any social networks).

I created ImgPage (“Image Page”) to solve that problem: simply attach a photo (or a few) to an email and send it to inbox@imgpage.com. Wait a few seconds and you’ll get email response from ImgPage with a unique link to clean, clutter-free page featuring just your image(s) like below.

Below, I’ll show some simplified sample code on how ImgPage uses Mailgun to upload these images to the cloud.

Parsing incoming emails using the Mailgun Routes API

After creating a git repository for ImgPage, the next step was creating the inbox@imgpage.com route within Mailgun. A route is what Mailgun calls the logic that tells their system what to do with each incoming email it receives. For ImgPage, I configured Mailgun to parse each incoming email received at inbox@imgpage.com and POST the details to my server.

A cool trick about Mailgun: you aren’t limited by just matching on email recipients. You can match on email headers like subject line and also use regular expressions. You can create routes programmatically, as demonstrated above, or you can create routes using the Mailgun dashboard after logging in. Here are the full inbound email parsing API specs.

When it comes to the attachments, Mailgun does the heavy lifting for us and will POST the information we need about any and all attachments up to 25MB (actually the max size is 1 or 2 KB less than 25 MB since space needs to be reserved for email headers). In this simplified example, I’m checking out the request to verify that there is at least one attachment and the attachment has a common photo file extension that we are expecting (if not, return an HTTP 415 error).

@app.route(‘/mailgun-endpoint’, methods=[‘POST’]) def mailgun_endpoint(): if(len(request.files) > 0): for attachment in request.files.values(): file_name, file_extension = os.path.splitext(attachment.filename) if file_extension.lower() not in [‘.jpg’, ‘.gif’, ‘.png’, ‘.bmp’]: abort(415) #Unsupported Media Type

Uploading photos to Rackspace Cloud Files & Amazon S3

Now I had a few options for reliable cloud storage, the most popular being Amazon S3. I’m always up for trying a new service and learning a new API and I decided to give Rackspace Cloud Files a shot as well (Rackspace recently acquired Mailgun so over time they will probably build some native integrations). I had plenty of experience using S3 and I was pleasantly surprised at how easy it was to get started with Cloud Files. The basic concepts, things like containers and buckets, are quite similar between the two services.

In the case of ImgPage, it’s important that everything inside the images container is publicly reachable with a unique URL. After uploading, you can request the public URI from Cloud Files.

As you can see, Cloud Files is easy and simple to work with. If you want to stick with Amazon S3, here is how you could handle uploading the attachments using the boto Python library.

(When you’re done with handling the POST, Mailgun expects to see a 200 OK HTTP response. Otherwise this action will be logged as an error in your Mailgun logs.)

Conclusion

Routing incoming emails and parsing attachments is a breeze with Mailgun. I was able to pair Mailgun’s recipient matching and forwarding actions with both Cloud Files and Amazon S3 to create ImgPage. Without having Mailgun, I probably wouldn’t have tackled this project to begin with due to the difficulties of parsing incoming email. Mailgun gets two thumbs up from me for solving a tough problem and creating a stable and well-documented API to go with it.

Related readings

Mailgun for non-devs: Leveraging an email marketing platform

This guest post comes from Ongage, a front-end email marketing platform that integrates nicely with ESPs like Mailgun and empowers...

Read More

Email remains the most effective marketing platform

This article was written and contributed by Rod Ussing at Lookahead.io...

Read More

DigitalChalk leverages Mailgun for transactional email notifications

This post was written and contributed by Jon Wilkinson, Software Engineer at DigitalChalk...

Read More

Popular posts

Email inbox.

Email

5 min

Build Laravel 11 email authentication with Mailgun and Digital Ocean

Read More

Mailgun statistics.

Product

4 min

Sending email using the Mailgun PHP API

Read More

Statistics on deliverability.

Deliverability

5 min

Here’s everything you need to know about DNS blocklists

Read More

See what you can accomplish with the world's best email delivery platform. It's easy to get started.Let's get sending
CTA icon