Bringing Tokusatsu to AWS using Python flask, Zappa and Contentful
I am a massive fan of Tokusatsu. The genre contains a wide variety of shows such as kaiju monster movies like Godzilla, superhero TV serials such as Kamen Rider — along with Giant Robot Shows like Super Sentai.
One of the aspects of Tokusatsu that most appeals to me are the transformation sequences. If you've seen an episode of Power Rangers, you've seen one of these transformations. For the past 20 years, Power Rangers has been reusing footage from the Super Sentai series for their action scenes.
When mentioning my passion for these transformations to my colleague and fellow developer evangelist Rouven Weßling, he suggested I channel my enthusiasm into building a small fan site. Never one to decline a challenge, I created a serverless Flask site in Python using Zappa — all powered by Contentful.
If you want to see my, website live then check out henshin.ruparel.co, or go straight to the code at GitHub.
In this blog post I’ll go through how to:
Build a simple python flask app
Use Contentful to manage, and create content
Deploy the web server on AWS lambda and returning a live URL through API Gateway
I’ll also highlight some of the costs and performance concerns when it comes to utilizing AWS lambda to manage your web server.
Why serverless is a good idea
Going serverless allows you to create and run applications and services without having to worry about servers - at least not servers that you have to maintain. You can leave provisioning, scaling, and managing servers to someone else. Best of all, when your code isn’t running, you’re not paying anything unlike traditional servers when your paying to maintain infrastructure.
Zappa is a fantastic Python library that makes it dead simple to deploy Python applications to AWS Lambda and Amazon API Gateway. With AWS Lambda, your application becomes completely serverless.
Combining Zappa, Flask, and Contentful enabled me to rapidly build a lightweight site that'll have negligible costs, require minimal time to update, and come with flexible scaling.
Getting started
To kick things off, we'll need to set up our Python environment together with our AWS configuration.
In the code snippet above we’re taking the following steps:
Installing virtualenv
Using virtualenv we’ll create a new virtual environment and activate that virtual environment.
In the activated virtual environment, we’ll use pip to install our dependencies for the project.
It’s essential that we use virtual environment since Zappa will utilize it to create a package that’ll be uploaded and run on AWS Lambda.
Lastly, install and configure the AWS CLI if you haven't used it before.
Setting up the Contentful part
First, we're going to create a content model to track all the different shows.
For our show we'll be adding the following field types:
Short text - Title of our show
Date & time - First air date
Date & time - Final air date
Short text - Type to track what the franchise the show is from
Media - To store the video transformation sequence. This is a single reference field. We'll be storing both the WebM and mp4 versions of this file to insure browser compatibility.
Media - For the second video file
Long text - A summary of the show
Short text - A URL to where we sourced the summary text from
Reference - To our separate character content model
Short Text - Our slug for building URLs
Which will look like so:
To finish our Contentful setup, we'll add our first content entry:
Building our Flask app
Now that we've taken care of the building our content model, creating our first show, and laying the groundwork with our virtualenv, we're ready to start writing our Python code.
We'll start by importing all our dependences, connecting to Contentful and creating a Flask instance. You can find your Space ID and Content Delivery API key at via app.contentful.com -> Space Settings -> API keys. If you’ve skipped setting up a content model you can use my SPACE ID (mt0pmhki5db7
) and Content Delivery API key (8c7dbd270cb98e83f9d8d57fb8a2ab7bac9d7501905fb013c69995ebf1b2a719
) which are pre-configured for this example.
Next, we'll build the routing for our home page.
In this function, we reach out to Contentful to get the array of all our shows sorted by when they first aired. We then pass the shows to the built-in flask render function along with the following index.html template:
With this flask can dynamically build a page containing all the shows. As we add entries into Contentful, our website will immediately update to include those entries as soon as we hit publish.
Now that we've got our flask app, let's get it deployed on AWS.
Deploying the Flask app to AWS with Zappa
Getting the python code onto the cloud is extremely simple. Since we've already installed Zappa in our virtual environment and configured AWS all we need to do to get rolling is to call 'zappa init'. This call will walk us through the creation of a configuration file.
Next call 'zappa deploy,' and Zappa will package your application using your active virtual environment. The command will download lambda compatible versions of your python dependencies if needed. Once that’s taken care of your code will get uploaded into s3, deployed onto lambda, configured with API gateway and then return a URL that you'll be immediately able to access.
If you head over to API Gateway, you'll see a new API containing your function.
When you want to update your code, all you need to do is call 'zappa update'.
Evaluating performance and cost with Datadog
I'm a big fan of using Datadog to keep an eye on my AWS account. Using their out of the box Lambda integration, I can quickly create and access dashboards to see the performance of my Lambda functions.
On average, it takes AWS Lambda and API Gateway about 30ms to render and return any of my pages — only 15ms of which are consumed by Contentful. Because of API Gateway a page view gets mapped directly to a function call.
Since AWS Lambda rounds up to the nearest 100ms and as I’m using the lowest available memory size, 128mb, for my function, I'll need to make 3,200,000 function calls a month before I exceed the Lambda free tier.
Even then, every additional function call that month will only cost a minuscule $0.000000208 or ~4,800,000 page views before I pay a cent. Additionally, API Gateway charges $3.50 per million API calls received — plus the cost of data transfer out, in gigabytes.
Something to note is that Zappa will schedule a regularly occurring CloudWatch event to keep the application warm and the responses in that 30ms range. By default, this is set to occur every 4 minutes. That means for every Zappa function you leave running you’ll be committing to about 10,000 function calls a month. Since I only leave my production instance running, that leaves me with plenty of additional calls before I have to move beyond the AWS Lambda free tier.
From this point, you can set up a custom domain and SSL certificate. Using these tools you'll be able to build a streamlined development and deployment process to quickly create and manage a serverless website. You can see some of the changes I've made to my fan site at henshin.ruparel.co and view the full source code at GitHub.
I want to hear from you
If this post helped you build something or you have questions I want to hear from you. Reach me at: Twitter: @ShyRuparel Email: Shy@Contentful.com GitHub: Shy
You can also head over to the Contentful Community and show off your creation in the Show & Tell section.