How to allow direct file uploads from JavaScript to Amazon S3 signed by Python

On Close.io we originally implemented Filepicker.io to allow for file uploads while sending emails. While it was a quick way to get started with file uploading initially, after several minutes of downtime of their API and then an unannounced change in their JSON response format, I was reminded once again that you shouldn’t to rely on small startups for critical parts of your tech infrastructure.

There’s nothing wrong with filepicker.io if you want to use a lot of their features, but in our case we just needed to allow simple uploading of files to our own AWS S3 bucket. Here’s how:

Setup S3 Bucket with CORS Policy

Create an S3 bucket from the AWS Console (if you haven’t already). In its properties, click to Edit CORS Configuration:

This will allow cross-domain posting from the client.

Set up an IAM user
You can use your main AWS credentials, but I recommend generating keys with only the permissions that are necessary. In AWS, set up an IAM user with the following permissions policy.

Add the JavaScript
First grab the code and then implement it on your site:

Server endpoint for signing requests
To protect your AWS user credentials, we keep them on the server and then “sign” each upload right before sending it to S3. Here’s the endpoint in Python / Flask:

Here’s the gist with all the embedded code.

Thanks to CodeArtists for the original tutorial. I improved their code some and converted it to Python.