Section 3: Add a DynamoDB table for Todo application¶
In this step, we’ll replace the in-memory database with an Amazon DynamoDB table.
Initial Setup¶
The starting code for this step is in the chalice-workshop/code/todo-app/part1/03-add-dynamodb
file. If necessary, you can copy over those files as a starting point
for this step:
$ cp ../chalice-workshop/code/todo-app/part1/03-add-dynamodb/app.py app.py
$ cp ../chalice-workshop/code/todo-app/part1/03-add-dynamodb/createtable.py createtable.py
$ cp ../chalice-workshop/code/todo-app/part1/03-add-dynamodb/chalicelib/db.py chalicelib/db.py
$ cp ../chalice-workshop/code/todo-app/part1/03-add-dynamodb/.chalice/policy-dev.json .chalice/policy-dev.json
$ cp ../chalice-workshop/code/todo-app/part1/03-add-dynamodb/.chalice/config.json .chalice/config.json
Create a DynamoDB table¶
In this section, we’re going to create a DynamoDB table and configure chalice to pass in the table name to our application.
First, we’ll need to install boto3, the AWS SDK for Python. Run this command:
$ pip install boto3
Add boto3 to our requirements.txt file. Chalice uses this file when building the deployment package for your app:
$ pip freeze | grep boto3 >> requirements.txt
Now that boto3 is installed, we can create the DynamoDB table Run the
createtable.py
script with the--table-type app
option. This will take a few seconds to run.$ python createtable.py --table-type app
Verify that this script added the table name to the
.chalice/config.json
file. You should see a key namedAPP_TABLE_NAME
in this file:$ cat .chalice/config.json { "stages": { "dev": { "environment_variables": { "APP_TABLE_NAME": "todo-app-...." }, "api_gateway_stage": "api" } }, "version": "2.0", "app_name": "testapp" }
Next, we’ll add a test route to double check we’ve configured everything correctly. Open the
app.py
file and these import lines to the top of the file:import os import boto3
Add a new test route:
@app.route('/test-ddb') def test_ddb(): resource = boto3.resource('dynamodb') table = resource.Table(os.environ['APP_TABLE_NAME']) return table.name
Verification¶
Start up the local dev server:
chalice local
Make a request to this test route and verify you get a 200 response:
$ http localhost:8000/test-ddb HTTP/1.1 200 OK Content-Length: 45 Content-Type: application/json Server: BaseHTTP/0.3 Python/2.7.14 todo-app-0b116e7b-f0f8-4548-91d8-95c75898b8b6
Switching the InMemoryTodoDB
to a DynamoDBTodo
¶
Now that we’ve verified our DynamoDB table is plumbed into our
chalice app correctly, we can update to use a new DynamoDBTodo
backend instead of the InMemoryTodoDB
.
The chalicelib/db.py
file you copied from
code/todo-app/part1/03-add-dynamodb/chalicelib/db.py
has a new DynamoDBTodo
class. This has the same interface as InMemoryTodoDB
except that is uses
DynamoDB as the backend. We’re going to update our app.py
to use this new
class.
Remove the
@app.route('/test-ddb')
view function. We no longer need it now that we’ve verified that DynamoDB is correctly configured for our app.Go to the
get_app_db()
function in yourapp.py
file. Modify this function to use theDynamoDBTodo
backend:def get_app_db(): global _DB if _DB is None: _DB = db.DynamoDBTodo( boto3.resource('dynamodb').Table( os.environ['APP_TABLE_NAME']) ) return _DB
Go to the top of the
app.py
file. Modify the linefrom chalicelib.db import InMemoryTodoDB
to referencedb
instead:from chalicelib import db
Verification¶
Start up the local dev server
chalice local
Create a Todo item:
$ echo '{"description": "My first Todo", "metadata": {}}' | \ http POST localhost:8000/todos HTTP/1.1 200 OK Content-Length: 36 Content-Type: application/json Date: Thu, 19 Oct 2017 23:44:24 GMT Server: BaseHTTP/0.3 Python/2.7.10 de9a4981-f7fd-4639-97fb-2af247f20d79
Retrieve the Todo item you just created. Keep in mind that your UID will be different from what’s shown below:
$ http localhost:8000/todos/de9a4981-f7fd-4639-97fb-2af247f20d79 HTTP/1.1 200 OK Content-Length: 140 Content-Type: application/json Date: Fri, 20 Oct 2017 00:03:26 GMT Server: BaseHTTP/0.3 Python/2.7.10 { "description": "My first Todo", "metadata": {}, "state": "unstarted", "uid": "de9a4981-f7fd-4639-97fb-2af247f20d79", "username": "default" }
Deploy your app¶
Now that we’ve tested locally, we’re ready to deploy:
$ chalice deploy
Verification¶
First create a Todo item using the API Gateway endpoint:
$ chalice url https://your-chalice-url/ $ echo '{"description": "My second Todo", "metadata": {}}' | \ http POST https://your-chalice-url/todos HTTP/1.1 200 OK Content-Length: 36 Content-Type: application/json abcdefg-abcdefg
Verify you can retrieve this item:
$ http https://your-chalice-url/todos/abcdefg-abcdefg HTTP/1.1 200 OK Content-Length: 140 Content-Type: application/json { "description": "My second Todo", "metadata": {}, "state": "unstarted", "uid": "abcdefg-abcdefg", "username": "default" }