Introduction to FastAPI and Local DynamoDB
Take the first step to develop an application using Python FastAPI and AWS DynamoDB
Nowadays, SQL based database is not the only main option we have regarding databases. With such a flexible characteristic, NoSQL is now widely used when a common SQL based database is considered unsuitable.
There are several types of NoSQL databases:
- Key-value Pair Based
- Column-oriented Graph
- Graphs based
This time we’ll look at key-value pair based NoSQL database, specifically at AWS DynamoDB. But before jumping directly to the cloud version, let’s take a look at the local one.
Note: You can get the full code for this article here https://github.com/agusrichard/fastapi-workbook
Set Up Local DynamoDB
In this section, we’ll start at how to set up local DynamoDB. There are three ways to install DynamoDB locally, you can download it, using Docker or having DynamoDB as an Apache Maven repository. We’ll talk about the second one since this approach is considered the simplest way to get started.
First thing first, make sure that you have Docker installed on your local machine. If you haven't, you can take a look at how to do it here https://docs.docker.com/engine/install/.
To run DynamoDB locally, simply run this command:
docker run -p 8000:8000 -d amazon/dynamodb-local
By running the above command, you’ll have a detached container and it will run on port 8000.
Okay, so we have our database running. But how to interact with it non-programmatically? If we can connect to SQL based database using SQL clients software applications such as dbeaver or pgadmin, what about local DynamoDB? Let’s see how we can set up DynamoDB admin UI.
Set Up DynamoDB Admin
As I’ve mentioned in the previous section, we don’t have an interface to interact with the database yet (other than programmatically). If you have used MongoDB locally before, probably you are quite familiar with mongo-express. DynamoDB Admin is pretty much the same and we’ll look at how to set it up in this section.
Install DynamoDB Admin using npm:
npm install -g dynamodb-admin
By running this command, you’ll have DynamoDB Admin globally installed. We’ll see how to leverage Docker to containerize all services we have later on.
After it was installed, you can run these commands:
# For Windows:
# For Mac/Linux:
By now, you can open a new tab and go to http://localhost:8001 (default port). If you use a different port to run DynamoDB, you should change port 8000 to your chosen port in the above commands.
This is how the admin app looks like:
Pretty simple design right? Let’s create our first table.
In the above image, I want to create a table named
Movies. With partition key (hash attribute)
Title and sort key (range attribute)
ReleaseDate. These attributes compose what we usually call the primary key.
A bit explanation about these two attributes. Partition key is defined as an address in which partition a data point will be stored. It’s involving a hashing function that turns a raw value into a hashed value.
Note that partition keys can have a duplicate. It doesn’t necessarily unique if it’s combined with a sort key. If two or more data points have the same partition key, they all will be put in the same partition and sorted by the sort key.
You can play around with the admin app, like create an item, update, delete, scan and query.
Initialize FastAPI App
The first common thing to do when starting a python project is setting up a virtual environment. You can do that by running this command.
python3 -m venv venv
Install dependencies related to FastAPI and DynamoDB:
pip install fastapi uvicorn boto3
As a starter, let’s write a template code in
You can run the server by running:
There we have it, three essential building blocks of our application. But it’s pretty tedious to manage three separate entities, therefore let’s make it way simpler by using docker-compose.
Simplify Development Process Using Docker Compose
Inside your project’s root directory, create a Dockerfile named
It serves as the Dockerfile for our admin application. Now, create a Dockerfile for the FastAPI application.
To run all these services, run this command.
Write The Main Application Code
In this section, I’ll use Domain Driven Design (in simplified mode).
As a short explanation, basically we have layers of components. The business logic and domain specification are defined in the core. The outside components are attachable and changeable. Let’s say today you use PostgreSQL as your database, but later on, you think that DynamoDB is better for your current use cases. With this design pattern, you don’t have to change anything inside the core component. You can easily change or scale up your infrastructures without disturbing your already specified business logic.
Since this article is mainly focused on how to use DynamoDB. You can overlook the other components (domain and routers) other than the repository.
Let’s start with generating a table using a Python script and setting up a database resource using
boto3. Create a Python file named
Run this Python script using this command:
Create a folder named internal with a file named
Now, it’s the repository. Create a folder named
repository with a file named
Next, for the
Up to this point, we have a database and the main application. Let’s try it and test some of its features. Run all services and go to http://localhost:5000/docs. With the auto-generated OpenAPI docs, you can create, update, delete, get all and get single data. Pretty much implementing basic CRUD operations.
NoSQL databases such as DynamoDB can give us flexibility that a common SQL based database can’t. With its schemaless design, we don’t have to worry about foreseeing what kind of columns are needed later on.
In this article, we focused on developing an application using local DynamoDB. Even though this is an appropriate first step, for obvious reasons you should use a managed service like AWS DynamoDB cloud version. We’ll take a look at how to move our local database to the cloud version in the next article.
Moving our local database to the cloud version here:
Thank you for reading. Happy coding!