Topic 2 of 6

Course materials are currently available in Russian only.

Пути и параметры

FastAPI — современный фреймворк для API. Он быстрый, сам проверяет данные по аннотациям типов и сам пишет документацию. На нём делают серверную часть для сайтов, мобильных приложений и ботов.

В курсе вы соберёте API для списка задач: получить, добавить, изменить, удалить, найти — с проверкой данных и доступом по ключу.

Минимальное приложение

from fastapi import FastAPI

app = FastAPI(title="Список задач")


@app.get("/")
def root():
    return {"message": "Привет!"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app)

FastAPI само по себе не сервер — запускает его uvicorn. Откройте http://127.0.0.1:8000/ — увидите JSON. А на http://127.0.0.1:8000/docs — автоматическую документацию, где каждый маршрут можно вызвать кнопкой «Try it out».

Функция возвращает словарь, список, строку или число — FastAPI сам превратит это в JSON. Метод запроса задаёт декоратор: @app.get, @app.post, @app.put, @app.delete.

Параметры пути

@app.get("/todos/{todo_id}")
def get_todo(todo_id: int):
    return {"id": todo_id}

Аннотация int — не украшение: FastAPI превратит "5" из адреса в число 5, а на /todos/abc сам ответит ошибкой 422 с объяснением, что не так. Типы бывают int, float, str, bool и другие.

Параметры запроса

Всё, что объявлено в функции, но не встречается в пути, — параметры запроса (после ?):

from fastapi import Query


@app.get("/todos")
def list_todos(skip: int = 0, limit: int = Query(10, ge=1, le=50), q: str | None = None):
    ...
  • со значением по умолчанию параметр необязателен, без него — обязателен;
  • str | None = None — необязательный параметр, который можно отличить от пустой строки;
  • Query(по_умолчанию, ge=…, le=…, gt=…, lt=…) — ограничения для чисел, min_length, max_length — для строк;
  • bool понимает true/false, 1/0, yes/no, on/off.

Ошибки

from fastapi import HTTPException

if todo_id not in TODOS:
    raise HTTPException(status_code=404, detail="Задача не найдена")

raise HTTPException сразу прерывает функцию; клиент получит {"detail": "Задача не найдена"} с кодом 404.

TestClient

from fastapi.testclient import TestClient

client = TestClient(app)
r = client.get("/todos/5")
print(r.status_code, r.json())

Так проверяются задачи курса — без сервера. «Запустить у себя» поднимает настоящий uvicorn; откройте /docs и попробуйте свои маршруты.

Итог

  • FastAPI(), @app.get/post/put/delete, запуск через uvicorn.run(app);
  • параметры пути {x} и запроса; типы проверяются сами, ошибка — 422;
  • Query(ge=, le=), X | None = None;
  • HTTPException(status_code, detail); /docs; TestClient.