FastAPI — один из самых быстрорастущих фреймворков для создания API на Python. Его главные козыри: автоматическая валидация через Pydantic, асинхронность из коробки и встроенная поддержка фоновых задач. Но чтобы выжать максимум, важно правильно формулировать промты — запросы к AI-ассистентам вроде ChatGPT или Claude. Эта подборка поможет вам получать готовый, рабочий код без лишних правок. Опираемся на официальную документацию FastAPI, Pydantic и Starlette (источник фоновых задач).
1. Базовый эндпоинт с GET-запросом
Задача: Создать простой эндпоинт, возвращающий приветствие.
Промт: «Напиши FastAPI-приложение с одним GET-эндпоинтом /hello, который принимает опциональный параметр name (строка) и возвращает JSON {"message": "Привет, {name}!"}. Если name не указан, используй "Мир".»
Пример результата:
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/hello")
def read_hello(name: Optional[str] = "Мир"):
return {"message": f"Привет, {name}!"}
2. POST-эндпоинт с Pydantic-моделью
Задача: Валидация входных данных через Pydantic.
Промт: «Создай модель Pydantic Item с полями: name (str, min_length=1), price (float, ge=0), is_offer (bool, по умолчанию False). Напиши POST-эндпоинт /items/, который принимает Item и возвращает его же с полем total_price = price * 1.2 (налог 20%).»
Пример результата:
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(..., min_length=1)
price: float = Field(..., ge=0)
is_offer: bool = False
@app.post("/items/")
async def create_item(item: Item):
total_price = item.price * 1.2
return {**item.dict(), "total_price": total_price}
3. Асинхронный эндпоинт с await
Задача: Асинхронное выполнение с задержкой (имитация внешнего API).
Промт: «Создай асинхронную функцию fetch_data(delay: int), которая ждёт delay секунд через asyncio.sleep и возвращает строку "данные получены". Endpoint GET /async-data вызывает её с delay=2 и возвращает результат.»
Пример результата:
import asyncio
from fastapi import FastAPI
app = FastAPI()
async def fetch_data(delay: int):
await asyncio.sleep(delay)
return "данные получены"
@app.get("/async-data")
async def get_async_data():
result = await fetch_data(2)
return {"data": result}
4. Фоновая задача через BackgroundTasks
Задача: Выполнить действие после отправки ответа (логирование, отправка письма).
Промт: «Используй BackgroundTasks из FastAPI. Endpoint POST /send-notification принимает email (str) и запускает фоновую задачу write_log(email), которая пишет в файл logs.txt строку с email и временем. Ответ возвращается сразу.»
Пример результата:
from fastapi import FastAPI, BackgroundTasks
from datetime import datetime
app = FastAPI()
def write_log(email: str):
with open("logs.txt", "a") as f:
f.write(f"{datetime.now()}: {email}\n")
@app.post("/send-notification")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, email)
return {"message": "уведомление будет отправлено"}
5. Зависимости (Dependencies) для валидации
Задача: Общая проверка токена для нескольких эндпоинтов.
Промт: «Создай зависимость verify_token(x_token: str = Header(...)), которая проверяет, что токен равен "secret123". Если нет — вызывает HTTPException с кодом 401. Примени к двум GET-эндпоинтам: /protected и /admin.»
Пример результата:
from fastapi import FastAPI, Depends, HTTPException, Header
app = FastAPI()
def verify_token(x_token: str = Header(...)):
if x_token != "secret123":
raise HTTPException(status_code=401, detail="Неверный токен")
return x_token
@app.get("/protected")
async def protected_route(token: str = Depends(verify_token)):
return {"token": token, "message": "доступ разрешён"}
@app.get("/admin")
async def admin_route(token: str = Depends(verify_token)):
return {"admin": True}
6. Модель Pydantic с вложенными объектами
Задача: Валидация сложного JSON с вложенными данными.
Промт: «Создай модель User с полями id (int), name (str). Модель Order с order_id (int), user (User), items (list[str]). Endpoint POST /order принимает Order и возвращает количество items.»
Пример результата:
from pydantic import BaseModel
from typing import List
class User(BaseModel):
id: int
name: str
class Order(BaseModel):
order_id: int
user: User
items: List[str]
@app.post("/order")
async def create_order(order: Order):
return {"items_count": len(order.items)}
7. Кастомная валидация поля (validator)
Задача: Проверить, что строка соответствует регулярному выражению.
Промт: «Добавь к модели Pydantic поле phone (str) с валидатором, который проверяет, что номер начинается с "+7" и содержит ровно 12 цифр (с учётом +7). Если неверно — raise ValueError.»
Пример результата:
from pydantic import BaseModel, validator
import re
class Contact(BaseModel):
name: str
phone: str
@validator("phone")
def validate_phone(cls, v):
if not re.match(r'^\+7\d{10}$', v):
raise ValueError('Телефон должен быть в формате +7XXXXXXXXXX')
return v
8. Пагинация и фильтрация списка
Задача: Endpoint для получения списка пользователей с пагинацией и фильтром по имени.
Промт: «Создай GET /users с параметрами: skip (int=0), limit (int=10), name_filter (Optional[str]=None). Внутри имитируй список пользователей (например, список словарей). Верни отфильтрованный срез.»
Пример результата:
from typing import Optional
fake_users_db = [{"id": i, "name": f"User{i}"} for i in range(100)]
@app.get("/users")
async def get_users(skip: int = 0, limit: int = 10, name_filter: Optional[str] = None):
users = fake_users_db
if name_filter:
users = [u for u in users if name_filter.lower() in u["name"].lower()]
return users[skip:skip+limit]
9. Обработка ошибок с кастомным ответом
Задача: Единый формат ошибок для всех 404.
Промт: «Переопредели обработчик 404: верни JSON {"error": "Запись не найдена", "status": 404} вместо стандартного ответа. Проверь, создав эндпоинт /item/{item_id}, который для id > 100 выбрасывает HTTPException 404.»
Пример результата:
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(404)
async def custom_404_handler(request, exc):
return JSONResponse(
status_code=404,
content={"error": "Запись не найдена", "status": 404}
)
@app.get("/item/{item_id}")
async def read_item(item_id: int):
if item_id > 100:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}
10. Фоновая задача с возвратом ID задачи (наивный подход)
Задача: Запустить фоновую задачу и вернуть её идентификатор (через uuid).
Промт: «Создай эндпоинт POST /run-task, который генерирует UUID, сохраняет его в глобальный словарь задач со статусом "running", запускает фоновую задачу (симуляция 5 сек), после завершения меняет статус на "completed". Верни сразу task_id.»
Пример результата:
import uuid
import asyncio
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
tasks_status = {}
def long_task(task_id: str):
asyncio.sleep(5) # в реальном коде используйте синхронный time.sleep или асинхронный подход
tasks_status[task_id] = "completed"
@app.post("/run-task")
async def run_task(background_tasks: BackgroundTasks):
task_id = str(uuid.uuid4())
tasks_status[task_id] = "running"
background_tasks.add_task(long_task, task_id)
return {"task_id": task_id}
@app.get("/task/{task_id}")
async def get_task_status(task_id: str):
status = tasks_status.get(task_id, "not found")
return {"task_id": task_id, "status": status}
Эти 10 промтов покрывают базовые сценарии: от простых эндпоинтов до фоновых задач и кастомной валидации. Попробуйте скорректировать их под свой проект — FastAPI легко расширяется. Для углублённого изучения рекомендую официальную документацию и раздел о Background Tasks.
Комментарии