Python REST APIs with FastAPI, CRUD application

Introduction

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.

Why you should use FastApi for your next project?

  • Fast: Very high performance, on par with NodeJS and Go (thanks to Starlette and Pydantic). One of the fastest Python frameworks available.

  • Fast to code: Increase the speed to develop features by about 200% to 300%. *

  • Fewer bugs: Reduce about 40% of human (developer) induced errors. *

  • Intuitive: Great editor support. Completion everywhere. Less time debugging.
  • Easy: Designed to be easy to use and learn. Less time reading docs.
  • Short: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
  • Robust: Get production-ready code. With automatic interactive documentation.
  • Standards-based: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.

Project Setup

Start by creating a new folder to hold your project called "fastapi-blog":

mkdir fastapi-blog && cd fastapi-blog

Next, create and activate a virtual environment(we will use pipenv):

Learn how to use pipenv here

Install dependencies

pipenv install fastapi uvicorn
✔ Successfully created virtual environment!
Virtualenv location: /Users/rosie/.local/share/virtualenvs/fastapi-blog-FXGAPIoM
Creating a Pipfile for this project...
Installing fastapi...
Adding fastapi to Pipfile's [packages]...
✔ Installation Succeeded
Installing uvicorn...
Adding uvicorn to Pipfile's [packages]...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Updated Pipfile.lock (d74721)!
Installing dependencies from Pipfile.lock (d74721)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run

Run pipenv shell to activate your environment.

Create a new file and call it app.py we will put all codes in this file.

touch app.py

In this article we will use a Python list as a database, we will not use a real database.

Inside app.py file put this:

# app.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
  return {"home": "Home page"}

Open your terminal then run the server

$ uvicorn app:app

INFO:     Started server process [19004]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

The first app is the name of the file and the second one is the name of our application app = FirstAPI.

Head up at http://127.0.0.1:8000

Learn more about uvicorn here

Let's create our fake database to store posts.

# app.py
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional, Text
from datetime import datetime

app = FastAPI()

postdb = []

# post model
class Post(BaseModel):
    id: int
    title: str
    author: str
    content: Text
    created_at: datetime = datetime.now()
    published_at: datetime
    published: Optional[bool] = False

@app.get("/")
def read_root():
  return {"home": "Home page"}

Here we create a simple Python class with type annotations using Pydantic and Python types module.

For every blog post we store:

- the title
- the author
- the content
- the date we created it
- the date we published it
- and the status of the post

We use equal symbol(=) to add a default value.

Now, create a new route to view all posts.

# app.py
...
@app.get("/blog")
def get_posts():
    return postdb

Restart your server then open http://127.0.0.1:8000 you will see an empty list [].

Let's add our first post.

...
@app.post("/blog")
def add_post(post: Post):
    postdb.append(post.dict())
    return postdb[-1]

One of the things I really love about FastAPI is the auto-generated docs.

Head up at http://localhost:8000/docs.

Let's create our first post. Click on Try it out then put this:

{
  "id": 1,
  "title": "Getting started with Django",
  "author": "Ousseynou DIOP",
  "content": "Hello Django",
  "created_at": "2021-03-01T18:17:45.194020",
  "published_at": "2021-03-01T18:17:58.887Z",
  "published": true
}

Create more posts then go to http://localhost:8000/blog

Let's get a single post by its ID.

# app.py
...
@app.get("/blog/{post_id}")
def get_post(post_id: int):
    post = post_id - 1
    return postdb[post]

The last two pieces of the CRUD are Update and Delete.

Let's begin by updating a post.

# app.py
...
@app.post("/blog/{post_id}")
def update_post(post_id: int, post: Post):
    postdb[post_id] = post
    return {"message": "Post has been updated succesfully"}

Add now you can update a post easily.

To be able to delete a post, you need to add this.

# app.py
...
@app.delete("/blog/{post_id}")
def delete_post(post_id: int):
    postdb.pop(post_id-1)
    return {"message": "Post has been deleted succesfully"}

Wrap up

In this article, we've learned the basic building blocks of FastAPI by creating a simple CRUD application. Let me know if you want to learn how to integrate a database with FastAPI.

See you in the next tutorial.