Build an API using FastApi

Let's build a backend API using FastAPI & Postgres, a battle-tested stack for building RestAPIs.

Requirements

Setup

Open the Terminal and create a python virtual environment

python3 -m venv ~/.venvs/apienv
source ~/.venvs/apienv/bin/activate

Install phidata

pip install phidata

Create your codebase

Create your codebase using the api-app template built with FastApi and Postgres.

phi ws create -t api-app -n api-app

This will create a folder named api-app with the following structure:

api-app
├── api               # directory for FastApi routes
├── db                # directory for database tables
├── Dockerfile        # Dockerfile for the application
├── pyproject.toml    # python project definition
├── requirements.txt  # python dependencies generated by pyproject.toml
├── scripts           # directory for helper scripts
├── tests             # directory for unit tests
├── utils             # directory for shared utilities
└── workspace
    ├── dev_resources.py  # Dev resources running locally
    ├── prd_resources.py  # Production resources running on AWS
    ├── secrets           # directory for storing secrets
    └── settings.py       # Phidata workspace settings

Run API locally

The API App comes with a FastApi server connected to a Postgres database. Run it using:

phi ws up dev:docker

Press Enter to confirm and give a few minutes for the image to download (only the first time). Verify container status and view logs on the docker dashboard.

View API Endpoints

  • Open localhost:9090/docs to view the API Endpoints.
  • Checkout the api/routes folder for the code.
  • Test the /v1/users/create endpoint to add a user.
  • Test the /v1/users/read endpoint and see if the user shows up.
  • FastApi resources are defined in the workspace/dev_resources.py file.
api-app-fastapi-local

View Database

  • Connect to the postgres database on port 9315, schema: dev, user: api, password: api.
  • Credentials are defined in the workspace/secrets/dev_db_secrets.yml file.
  • PosgresDb resources are defined in the workspace/dev_resources.py file.
api-app-database-local

Database Migrations

The API App is preconfigured with alembic for handling database migrations.

Setting the UPGRADE_DB env var for the FastApiServer in workspace/dev_resources.py will upgrade the database using alembic in the entrypoint.sh script. This creates the users table on startup.

Checkout the db/migrations/README.md file for more information.

workspace/dev_resources.py

# -*- FastApiServer running on port 9090
dev_fastapi = FastApiServer(
    ...
    env={
        ...
        # Create/Upgrade database on startup using alembic
        "UPGRADE_DB": True,
        ...
    },
    ...
)

Delete local resources

Stop the workspace using:

phi ws down dev:docker

Run API App on AWS

Now let's run the API App in production on AWS.

AWS Authentication

To run on AWS, you need one of the following:

  1. The ~/.aws/credentials file with your AWS credentials
  2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY environment variables

Add AWS Region and Subnets

Add 2 Subnets to the workspace/settings.py file, these are required to create ECS resources.

workspace/settings.py

ws_settings = WorkspaceSettings(
    ...
    # -*- AWS settings
    # Region for AWS resources
    aws_region="us-east-2",
    # Availability Zones for AWS resources
    aws_az1="us-east-2a",
    aws_az2="us-east-2b",
    # Subnet IDs in the aws_region
    subnet_ids=["subnet-0xxa", "subnet-0xxb"],
    ...

Run API on AWS

Create AWS resources for the API App using:

phi ws up prd:aws

This will create:

  1. ECS Cluster for running the application.
  2. ECS Task Definition for the application.
  3. ECS Service that run the tasks on the ECS cluster.
  4. LoadBalancer to route traffic to the application.
  5. Security Groups that control incoming and outgoing traffic.
  6. RDS Database for running Postgres.
  7. Secrets for managing application and database secrets.

Press Enter to confirm and give a few minutes for the resources to spin up.

  • These resources are defined in the workspace/prd_resources.py file.
  • Use the ECS console to view services and logs.
  • Use the RDS console to view the database instance.

View API Endpoints

  • Open the LoadBalancer DNS + the /docs endpoint to view the API Endpoints.
  • Test the /v1/users/create endpoint to add a user.
  • Test the /v1/users/read endpoint and see if the user shows up.
api-app-fastapi-prd

Database Migrations

Setting the UPGRADE_DB env var will upgrade the database using alembic in the entrypoint.sh script when the container starts. Checkout the db/migrations/README.md file for more information.

workspace/prd_resources.py

# -*- FastApiServer running on ECS
prd_fastapi = FastApiServer(
    ...
    env={
        ...
        # Create/Upgrade database on startup using alembic
        "UPGRADE_DB": True,
        ...
    },
    ...
)

Delete AWS resources

Play around and then delete production resources using phi ws down prd:aws

phi ws down prd:aws

Next

Congratulations on running your own API App. Next: