Укр
Первый старт с FastAPI

Первый старт с FastAPI

  • 15 ноября, 2021
  • читать 10 мин
Валерий Дузь
Валерий Дузь Senior Software Engineer, Преподаватель Компьютерной школы Hillel.

В этой статье мы рассмотрим первые маленькие шаги в создании в Web API с использованием FastAPI и Postgres.

Данная статья будет полезная новичкам, которые уже знают, что такое Web API, как работать с Flask, но которые хотели бы смотреть на что-то более простое и современное.

Ранее мы уже рассматривали такие фреймворки как Django или Flask.

Рекомендуем публикацию по теме

Подготовка

Давайте создадим папку, в которую поместим наш проект.

Назовем директорию user_api и сразу в нее перейдем.

mkdir user_api
cd user_api

Далее нам потребуется создать виртуальное окружение и установить необходимые зависимости:

  • fastapi

  • fastapi-sqlalchemy

  • pydantic

  • alembic

  • psycopg2

  • uvicorn

Можно это сделать, воспользовавшись обычным virtualenv и pip.

virtualenv venv
source venv/bin/activate
pip install astapi fastapi-sqlalchemy pydantic alembic psycopg2-binary uvicorn

Но я бы советовал использовать менеджер зависимостей Poetry, о котором я упоминал в одной из своих статей:

Рекомендуем публикацию по теме

Первые шаги

После установки зависимостей можно начинать создавать первое приложение на FastAPI.

Создадим простой файл app.py, в который поместим данный кусок кода.

import uvicorn
from fastapi import FastAPI

app = FastAPI()


@app.post("/student/")
def students():
   return {"status": "success"}


if __name__ == "__main__":
   uvicorn.run(app, host="0.0.0.0", port=8000)

После чего можно попробовать запустить приложение:

uvicorn app:app --reload

--reload нужен для того, чтобы не перезапускать приложение после каждого изменения.

Docker

Давайте обернем наше приложение в Docker, нам будет проще взаимодействовать с ним и не нужно будет устанавливать базу данных конкретно на компьютер.

Dockerfile

FROM python:3.8

WORKDIR /code/

COPY . /code/

# Install dependencies
RUN pip install -r requirements.txt

EXPOSE 8000

docker-compose.yml

version: "3.9"

services:
 db:
   image: postgres:13.3
   ports:
     - "127.0.0.1:5432:5432"
   environment:
     - POSTGRES_PASSWORD=postgres

 api:
   build: .
   env_file: .env
   command: bash -c "alembic upgrade head && uvicorn app:app --reload"
   volumes:
     - .:/code
   ports:
     - "127.0.0.1:8000:8000"
   depends_on:
     - db

.env

DATABASE_URL = postgresql+psycopg2://postgres:postgres@db:5432

Модели

Для начала работы с базой данных и созданием таблиц нам нужно создать модели и схемы.

Schema

schema.py

from pydantic import BaseModel


class Student(BaseModel):
   first_name: str
   last_name: str = None
   age: int
   class Config:
       orm_mode = True

Model

model.py

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String


Base = declarative_base()


class Student(Base):
   __tablename__ = "students"
   id = Column(Integer, primary_key=True, index=True)
   first_name = Column(String,)
   last_name = Column(String)
   age = Column(Integer)

Давайте подключим модель и схему к нашему приложению.

import os
import uvicorn
from fastapi import FastAPI


from fastapi_sqlalchemy import DBSessionMiddleware
from fastapi_sqlalchemy import db

from models import Student as StudentModel
from schema import Student as StudentSchema


app = FastAPI()
app.add_middleware(DBSessionMiddleware, db_url=os.environ["DATABASE_URL"])

@app.post("/student/"), response_model=StudentSchema)
def students(student: StudentSchema):


   student_model = StudentModel(
       first_name=student.first_name,
       last_name=student.last_name,
       age=student.age
   )
   
   db.session.add(student_model)
   db.session.commit()

   return student_model


if __name__ == "__main__":
   uvicorn.run(app, host="0.0.0.0", port=8000)

Для того, чтобы посмотреть схему того, какие есть таблицы в базе и вообще данные, я советую использовать DBeaver (не реклама, это просто хороший инструмент с бесплатной версией).

Миграции

На данный момент база данных у нас пустая. Следует создать миграции и на основе их создать таблицу. Для этого будем использовать alembic.

Давайте создадим папку с миграциями.

alembic init migration

Теперь у нас есть папка migration, внутри которой в папке versions будут храниться версии наших миграций. Но для генерации миграций нам нужно настроить alembic.

Первое — идем в alembic.ini и меняем значение sqlalchemy.url на пустое значение, мы его будем менять в

sqlalchemy.url =

Далее в папке alembic в env.py заменяем содержимое на

import os, sys

from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import poolfrom alembic import context


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
config.set_main_option("sqlalchemy.url", os.environ["DATABASE_URL"])

# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)


import models
target_metadata = models.Base.metadata

После чего мы можем создать нашу первую миграцию с помощью команды:

alembic revision --autogenerate -m "Initial"

Запустим приложение:

docker-compose up -d

Проверим в /docs, что все работает и что возможно через сваггер посылать запросы, и наше приложение отвечает без ошибок. И также можно посмотреть, создались ли новые записи в базе данных через DBeaver.

Я надеюсь, статья поможет начинающим разработчикам попробовать новый фреймворк, который может стать хорошей заменой Flask.

Рекомендуем курс по теме