chalice-http-toolkit¶
chalice-http-toolkit enables a Flask like website building experience using Chalice, AWS Lambda, API Gateway & CloudFront. It does this by bolting on Jinja2 templates, and CloudFront cache management layer.
Installation¶
Base installation via pip:
pip install chalice-http-toolkit
The above command only installs the base dependancies, there is also an additional extra_requires directive shown below that installs packages which would normally push your Lambda package over the 250MB limit.
For local testing the rest of the dependancies can be installed via:
pip install chalice-http-toolkit[layered]
For deployments to AWS Lambda the following layers should be used:
arn:aws:lambda:us-east-2:770693421928:layer:Klayers-python38-jinja2:2
arn:aws:lambda:us-east-2:770693421928:layer:Klayers-python38-Pillow:10
OR run
$ chalice-http-toolkit layers -r us-east-1 # Returns the latest compatible layer versions
arn:aws:lambda:us-east-1:770693421928:layer:Klayers-python38-jinja2:6
arn:aws:lambda:us-east-1:770693421928:layer:Klayers-python38-Pillow:15
Quick setup¶
challice-http-toolkit now comes with a CLI utility to quicky create a project, usage is as follows:
chalice-http-toolkit setup -n myapp -p . -e magic -r us-east-1
The above script does the following:
Creates your app.py, with handlers for index, static content, 404 and a event to keep the Lambda function warm.
Creates directory structure for templates, static content, chalice libraries.
Sets up Chalice layers (Pillow and Jinja2) which are required chalice-http-toolkit.
If
-e magic
is provided, then magic binaries are included inchalicelib/libs
directory. This is required because Lambda instances dont include these binaries so magic wont work without it.
The latest layers can be fetched using the following command:
chalice-http-toolkit layers -r us-east-1
Currently only Python 3.8 is supported for chalice-http-toolkit, this is because we would need to extract binaries for magic from different AWS Linux versions with varying Python versions and also build Pillow and Jinja2 layers for different Python versions.
Chalice config.json¶
A basic Chalice config.json
is defined below which has two stages, dev
is meant for local testing and prod
is the stage which gets deployed to AWS Lambda. The STAGE
environment variable must be defined for local testing to work around some differences between AWS API Gateway behaviour vs the way locally served API works.
{
"version": "2.0",
"app_name": "example",
"stages": {
"dev": {
"api_gateway_stage": "dev",
"lambda_timeout": 60,
"lambda_memory_size": 64,
"environment_variables": {
"STAGE": "dev"
},
},
"prod": {
"api_gateway_stage": "prod",
"layers": ["arn:aws:lambda:us-east-2:770693421928:layer:Klayers-python38-jinja2:2",
"arn:aws:lambda:us-east-2:770693421928:layer:Klayers-python38-Pillow:10"],
"lambda_timeout": 60,
"lambda_memory_size": 64,
"environment_variables": {
"STAGE": "prod"
}
}
}
}
Project Structure¶
Templates and static content needs to be placed in the chalicelib
directory because that is where additional content is packaged into the deployment by Chalice.
Architecture¶
Placing CloudFront in front of a chalice-http-toolkit website is not required, but if your website is popular it probably starts to make sense given that every invocation ends up costing more then it would for CloudFront to server the website.
ContentManager¶
This class is designed to support:
serving static content (such as Javascript/CSS). Although these might be better served by S3 depending on scale.
rendering Jinja2 templates
support generating 304 redirects
support returning JSON Responses
serving assets
converting images based on the accepts header in a request
cleaner handling of binary content
Every chalice-http-toolkit app requires a ContentManager be created, usually right after the Chalice app is created.
CloudFront¶
This class is designed to support:
caching static content by modifed dates
caching Jinja2 templates by hashing dependancies (ie arguments and child templates) without rendering.
caching assets
Using this module is optional, but it is best practice.
Gotchas¶
There are a few differences between locally testing & a deployed instance of a Chalice website. They are detailed below.
Binary Content¶
Due to the way API Gateway handles binary content, the binary content is Base64 encoded in the absence of an Accepts header in the request. This restriction does not apply for local testing.
Request & Reponse Limits¶
API Gateway has a request & response filesize limit of 10MB. This restriction does not apply for local testing.
Cold Starts¶
Chalice based websites are vulnerable to the Lambda Coldstart problem. A cold start happens when you execute an inactive function. The delay comes from AWS provisioning your selected runtime container and then running your function. Functions stay ‘warm’ for approximately 5 minutes, which means they respond to requests much quicker. After this period of time, the contianer is dropped by AWS and a cold start needs to happen.