Developing a Restful API with FastAPI using PostgreSQL, Async SQLAlchemy, and AIOHTTP

Posted by


FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. In this tutorial, we will create a REST API using FastAPI with PostgreSQL as our database, Async SQLAlchemy for database operations, and AIOHTTP for asynchronous HTTP requests.

Step 1: Setting up the environment

First, create a new directory for your project and set up a virtual environment:

mkdir fastapi-tutorial
cd fastapi-tutorial
python3 -m venv env
source env/bin/activate

Next, install the necessary packages:

pip install fastapi[all]
pip install psycopg2-binary sqlalchemy databases aiohttp

Step 2: Set up the database

Create a PostgreSQL database and a table to store some data. You can do this using the psql command-line tool or a graphical client like pgAdmin.

psql postgres
CREATE DATABASE fastapi_tutorial;
connect fastapi_tutorial
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);

Step 3: Create a FastAPI app

Create a new Python file main.py and add the following code to set up a FastAPI app with Async SQLAlchemy and AIOHTTP:

from fastapi import FastAPI, HTTPException
from sqlalchemy import create_engine, Column, Integer, String, MetaData, Table
from databases import Database

app = FastAPI()

DATABASE_URL = "postgresql:///fastapi_tutorial"
database = Database(DATABASE_URL)

metadata = MetaData()

users = Table(
    "users",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("name", String(100)),
    Column("email", String(100)),
)

engine = create_engine(DATABASE_URL)
metadata.create_all(engine)

@app.on_event("startup")
async def startup():
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

Step 4: Create API endpoints

Now let’s create some API endpoints to perform CRUD operations on the users table. Add the following code to main.py:

from typing import List

@app.get("/users/", response_model=List[dict])
async def read_users():
    query = users.select()
    return await database.fetch_all(query)

@app.post("/users/", response_model=dict)
async def create_user(name: str, email: str):
    query = users.insert().values(name=name, email=email)
    return await database.execute(query)

@app.get("/users/{user_id}", response_model=dict)
async def read_user(user_id: int):
    query = users.select().where(users.c.id == user_id)
    result = await database.fetch_one(query)
    if result is None:
        raise HTTPException(status_code=404, detail="User not found")
    return result

@app.put("/users/{user_id}", response_model=dict)
async def update_user(user_id: int, name: str, email: str):
    query = users.update().where(users.c.id == user_id).values(name=name, email=email)
    return await database.execute(query)

@app.delete("/users/{user_id}")
async def delete_user(user_id: int):
    query = users.delete().where(users.c.id == user_id)
    return await database.execute(query)

Step 5: Run the FastAPI app

Now you can run the FastAPI app by executing the following command in your terminal:

uvicorn main:app --reload

You can now access your API endpoints at http://localhost:8000/users/ and perform CRUD operations on the users table in your PostgreSQL database.

Congratulations! You have successfully created a REST API using FastAPI with PostgreSQL, Async SQLAlchemy, and AIOHTTP. Feel free to extend this tutorial by adding more endpoints, implementing authentication, or adding more complex business logic. FastAPI’s high performance and automatic data validation make it a powerful tool for building web APIs with Python.

0 0 votes
Article Rating

Leave a Reply

22 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@romariolima6006
4 hours ago

muito bom , a inda nao tinha feito nenhuma api assincrona

@jeffersonalmeida4480
4 hours ago

Cara, muito obrigado pela aula, você é muito didático. Muito bom o seu conteúdo. Parabéns pela iniciativa de compartilhar o seu conhecimento.

@jeffersonalmeida4480
4 hours ago

Alguém mais teve esse erro –> asyncpg.exceptions.InvalidPasswordError: password authentication failed for user "admin" ????

@jammingkinght
4 hours ago

Não entendi pq não usou a api da binance

@alopsantos
4 hours ago

Fala Diogo, parabéns pelo conteúdo! Me tira uma dúvida, da para usar firebird no lugar do postgres ? Abs!

@viktorsantosdev
4 hours ago

Foi meu primeiro contato com Fast API!! Achei muito bom o vídeo aprendi bastante!! Espero continuar aprendendo cntg!

@XxP0WeReDxX
4 hours ago

E sobre paginação? Como fazer as paginações utilizando as boas práticas?

@mateusalves2100
4 hours ago

asyncpg.exceptions.InvalidPasswordError: password authentication failed for user "admin" || tá dando esse erro alguém sabe resolver?

@vitorkaviski7833
4 hours ago

Que Incrível a sua explicação! Estava a um tempo procurando uma solução para isso! Você teria alguma sugestão de site para fazer deploy gratuito de FastAPIs em Python, já que o Heroku vai se tornar pago? Tenho algumas APIs em Python lá já e to ficando meio desesperado kkk

@ramongiovane
4 hours ago

Ótimo vídeo! Obrigado!

@matheussoares8108
4 hours ago

Muito bom

@Calebbds
4 hours ago

Fala Diogo, ótimo conteúdo irmão! Quando eu vou iniciar as tabelas do banco de dados com o comando

run(create_engine())

dá uma exceção:

"RuntimeError: Event loop is closed"

As tabelas são criadas, mas aparece esse erro no terminal, e no seu não aparece. Pesquisei a respeito, mas não achei solução.
Você tem ideia do que seja?

Outra coisa, se eu precisar alterar as tabelas, precisa resetar tudo, ou tem algum comando que só faça a alteração? ( O comando "await connection.run_sync(Base.metadata.drop_all) zera o banco e apaga tudo)

@sgfaria
4 hours ago

Parabéns Diogo. Conhecimento, clareza e segurança no conteúdo. Obrigado.

@danielvianati
4 hours ago

Fala Diogo.
Como vão as coisas por ai? Você poderia passar um e-mail para trocar uma ideia ou até um freela para me ajudar a migrar um projeto pequeno feito em java?

@JeffersonAntuness
4 hours ago

Parabéns pela aula, contéudo esta muito bom!

@gustavo8433
4 hours ago

Olá. Parabéns pelo vídeo. Seria possível utilizar plotly/ dash para construir aplicações com dashboards dentro da FastApi ?

@fabiosousa9219
4 hours ago

Vídeo top mano, parabéns!

@paulomarvin7806
4 hours ago

Olá Diogo, estou aprendendo e esse tutorial esta me ajudando muito, só tenho uma dúvida sobre a pasta pgdata, quando dou um docker compose up –build pela primeira vez ele cria essa pasta normalmente, porém com proteção, ou seja, não pode ser delatada nem sobrescrita. Então se, por exemplo, eu quiser buildar de novo o postgresql ele sempre dá um erro pq não consegue sobrescrever essa pasta. Para continuar fico dando um sudo chown -R <meu_user> pgdata, mas creio que não seja o ideal fazer isso. Se vc tiver alguma ideia de como corrigir isso pelo docker para que ela fica desprotegida me ajudaria muito. Caso vc tenha explicado isso em algum momento do vídeo peço desculpas, pois não vi ele todo ainda, pois estou usando apenas algumas partes do seu vídeo.

@joaovictor-dl6ve
4 hours ago

Mano, me tira uma dúvida, fastAPI escala?

@eduardospek
4 hours ago

Ótimo conteúdo!

22
0
Would love your thoughts, please comment.x
()
x