FastAPI – это самый популярный и самый простой фреймворк для создания API на Python. Все, что вам нужно сделать для разработки своего первого API – установить зависимости, подключить фреймворк и потратить 10 минут на создание эндпоинтов. О документации можете не беспокоиться – FastAPI все сделает за вас, причем – в двух экземплярах (по двум разным стандартам). Ниже мы покажем, как все это работает.
FastAPI – это фреймворк для быстрого создания API веб-приложений. По опросам 2023 года этот фреймворк был 3-м по популярности среди всех фреймворков Python и самым любимым. Основная фишка фреймворка – в том, что все технические детали реализации он прячет «под капот», и разработчику остается только реализовать непосредственно обработку конкретных запросов – для этого пишутся эндпоинты, то есть адреса, по которым клиент должен обратиться, чтобы получить ответ от API. FastAPI создан поверх двух других библиотек – Starlette и Pydantic: первая предоставляет инструменты для клиент-серверного взаимодействия, вторая работает со схемами данных; FastAPI объединяет их, прячет детали и добавляет высокоуровневые методы работы с API, поэтому вам с «подлежащими» библиотеками работать почти не придется.
Для того, чтобы создать приложение, вам нужно иметь под рукой любой редактор со встроенной командной строкой – VSCode или PyCharm вполне подойдут. Кроме того – вам нужен сервер, на котором ваше приложение будет запускаться. К счастью, все это можно установить одной командой:
pip install fastapi uvicorn
Естественно, у вас должен быть установлен пакетный менеджер Python – pip. Собственно, по серверной части – все, можно переходить к приложению. Создайте каталог для приложения, внутри создайте файл «main.py» - здесь вы будете писать приложение. В main.py должен быть следующий код:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI!"}
Что здесь происходит:
Собственно, API создано – если кто-то обратится к корневому адресу приложения, то получит сообщение «Hello, FastAPI!». Запустите приложение командой
uvicorn main:app --reload
(команду нужно исполнять из каталога, в котором лежит main.py), и по адресу http://127.0.0.1:8000 вы увидите результат.
FastAPI, к слову, уже создал документацию для вашего API в двух версиях:
Теперь сделаем наше приложение более реальным. Предположим, наше приложение – это магазинчик, продающий какие-либо товары. Для того, чтобы приложение стало функциональным, нам нужно: а) создать модель данных для товаров; б) реализовать CRUD – базовые методы HTTP для обмена данными (create, read, update, delete).
Для начала создадим модель данных:
from pydantic import BaseModel
class Item(BaseModel):
id: int
name: str
description: str = None
price: float
items = []
Для того, чтобы FastAPI мог распознавать данные, нам нужно реализовать их от родительского класса BaseModel, предоставляемого Pydantic. Наши товары (items) будут иметь минимальный набор данных – id, имя, описание, цену. В последней строке мы добавили пустой список – в нем мы будем хранить товары, которые будем добавлять через API.
Собственно, осталось только добавить эндпоинты, реализующие CRUD.
Create:
@app.post("/items/")
def create_item(item: Item):
items.append(item)
return item
Получаем объект Item, добавляем его в список товаров, возвращаем item – возврат присланного через API товара будет означать, что этот товар успешно добавлен.
Read:
@app.get("/items/")
def get_items():
return items
@app.get("/items/{item_id}")
def get_item(item_id: int):
for item in items:
if item.id == item_id:
return item
return {"error": "Item not found"}
Здесь у нас 2 метода. Первый – прочитать все, он возвращает список товаров. Второй метод – вернуть конкретный товар, ID которого пришло в запросе. Метод проходится по всему списку товаров, если нашел нужный – возвращает его, если ничего не нашел – возвращает ошибку.
Update:
@app.put("/items/{item_id}")
def update_item(item_id: int, new_item: Item):
for i, item in enumerate(items):
if item.id == item_id:
items[i] = new_item
return new_item
return {"error": "Item not found"}
Метод принимает ID товара, который нужно обновить, и Item – новые данные товара. Затем он проходится по всему списку товаров, и если находит нужный ID – обновляет и возвращает товар, если не находит ID – возвращает ошибку.
Delete:
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
global items
items = [item for item in items if item.id != item_id]
return {"message": "Item deleted"}
Метод принимает ID, после чего через генератор создает новый список товаров, в котором нет товара с указанным ID. Когда все сделано – метод возвращает сообщение об успехе.
Все, CRUD реализован – можете запустить приложение командой
uvicorn main:app –reload
и убедиться в этом самостоятельно.
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
id: int
name: str
description: str = None
price: float
items = []
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI!"}
@app.post("/items/")
def create_item(item: Item):
items.append(item)
return item
@app.get("/items/")
def get_items():
return items
@app.get("/items/{item_id}")
def get_item(item_id: int):
for item in items:
if item.id == item_id:
return item
return {"error": "Item not found"}
@app.put("/items/{item_id}")
def update_item(item_id: int, new_item: Item):
for i, item in enumerate(items):
if item.id == item_id:
items[i] = new_item
return new_item
return {"error": "Item not found"}
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
global items
items = [item for item in items if item.id != item_id]
return {"message": "Item deleted"}
Естественно, это приложение вряд ли покроет все запросы бизнеса. Первое, чем вы можете заняться – добавить новые запросы, любые на ваш вкус. При желании вы можете расширить класс Item, добавив новые данные – можете придумать, чем именно этот магазин будет заниматься. Следующие 2 шага, на которые вы можете обратить внимание – добавление авторизации и подключение базы данных: авторизация нужна для того, чтобы только пользователи с нужными правами могли добавлять/удалять/получать данные; база данных нужна для долгосрочного хранения данных магазина – поскольку сейчас все записи о товарах хранятся в списке, они будут уничтожены сразу, как только вы остановите приложение.