FastAPI — это мощный инструмент для создания веб-приложений, но его возможности не ограничиваются только быстрым созданием API. В этой статье мы обсудим две важные темы, которые значительно расширяют функциональность вашего приложения: middleware и фоновая обработка задач.
Создание и использование Middleware
Middleware (или промежуточное ПО) — это функции, которые выполняются до или после обработки запроса и ответа. Они полезны для таких задач, как логирование, аутентификация, изменение запроса или ответа, управление сессиями, обработка ошибок и многое другое.
В FastAPI создание middleware достаточно простое. Мы создаем функцию с декоратором @app.middleware(«http»), которая будет выполняться для каждого HTTP-запроса.
Пример: Логирование запросов
Давайте создадим простое middleware, которое будет логировать информацию о каждом запросе, включая его метод, URL и время обработки.
from fastapi import FastAPI, Request
import time
app = FastAPI()
# Определяем middleware для логирования времени запроса
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time.time() # Засекаем время начала запроса
response = await call_next(request) # Передаем запрос в обработчик
duration = time.time() - start_time # Вычисляем время выполнения запроса
# Логируем метод запроса, URL и длительность
print(f"Request: {request.method} {request.url} - {duration:.3f} sec")
return response # Возвращаем ответ
Пояснение к коду:
- request: Request — объект запроса, с помощью которого можно получить информацию о запросе (например, метод, URL, заголовки и т. д.).
- call_next(request) — передает управление следующему обработчику в цепочке.
- Мы засекли время выполнения запроса и вывели его на консоль.
Этот middleware можно использовать для анализа производительности или отслеживания запросов.
В дополнение к базовому логированию, часто бывает необходимо обработать запросы, например, проверив заголовки или параметры. Это можно делать в middleware до того, как запрос будет передан в обработчик.
Пример: Проверка заголовков
@app.middleware("http")
async def check_user_agent(request: Request, call_next):
user_agent = request.headers.get('User-Agent')
if "Mozilla" not in user_agent:
return PlainTextResponse("Browser is not supported", status_code=400)
response = await call_next(request)
return response
Здесь мы проверяем, что в заголовке User-Agent присутствует строка «Mozilla». Если это не так, возвращаем ошибку.
Фоновые задачи с BackgroundTasks
В FastAPI также поддерживаются фоновые задачи. Это позволяет выполнять операции, которые не должны блокировать основной поток выполнения приложения. Например, отправка электронных писем или обработка данных, которые занимают много времени, могут быть выполнены в фоновом режиме.
Пример: Отправка уведомлений в фоновом режиме
from fastapi import BackgroundTasks, FastAPI
from time import sleep
app = FastAPI()
# Функция для отправки уведомлений
def send_notification(email: str, message: str):
sleep(5) # Симуляция долгой операции
print(f"Sent email to {email}: {message}")
# Маршрут для отправки уведомлений
@app.post("/send-notification/")
async def send_email(background_tasks: BackgroundTasks, email: str, message: str):
background_tasks.add_task(send_notification, email, message)
return {"message": "Notification is being sent in the background"}
Пояснение:
- BackgroundTasks — объект, который позволяет добавлять задачи, которые будут выполняться в фоне.
- В методе send_email мы добавляем задачу отправки уведомления в фоновый процесс с помощью background_tasks.add_task().
Эта операция выполняется асинхронно, не блокируя основной поток, и мы сразу отправляем ответ клиенту.
Обработка CORS
CORS (Cross-Origin Resource Sharing) — это механизм, который позволяет управлять доступом к ресурсам вашего сервера с других доменов. В FastAPI обработка CORS включена с помощью встроенной библиотеки CORSMiddleware.
Пример: Включение CORS в FastAPI
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Разрешаем доступ с определенных доменов
app.add_middleware(
CORSMiddleware,
allow_origins=["http://example.com", "http://localhost:3000"], # Разрешенные источники
allow_credentials=True,
allow_methods=["GET", "POST"], # Разрешенные методы
allow_headers=["*"], # Разрешенные заголовки
)
@app.get("/")
def read_root():
return {"message": "Hello World"}
Пояснение:
- allow_origins — задает список доменов, с которых разрешено делать запросы.
- allow_methods — разрешает использование определенных HTTP методов (например, GET и POST).
- allow_headers — разрешает передавать определенные заголовки с запросами.
Этот подход помогает нам управлять доступом к API и защищать сервер от несанкционированных запросов с других доменов.
Практика: Реализация логирования запросов и фоновая отправка уведомлений
Давайте реализуем простой сервис, который будет:
- Логировать информацию о запросах.
- Отправлять уведомления в фоновом режиме.
from fastapi import BackgroundTasks, FastAPI, Request
from time import time
app = FastAPI()
def send_notification(email: str, message: str):
sleep(3) # Задержка для имитации отправки уведомления
print(f"Sent email to {email}: {message}")
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time()
response = await call_next(request)
duration = time() - start_time
print(f"Request: {request.method} {request.url} - {duration:.3f} sec")
return response
@app.post("/send-notification/")
async def send_email(background_tasks: BackgroundTasks, email: str, message: str):
background_tasks.add_task(send_notification, email, message)
return {"message": "Notification is being sent in the background"}
Что мы сделали:
- Логируем запросы: каждый запрос будет логироваться с временем его выполнения.
- Отправляем уведомления в фоне: уведомление отправляется в фоновом режиме, и основной поток не блокируется.
Заключение
Мы рассмотрели, как использовать middleware для логирования и обработки запросов в FastAPI, а также как внедрить фоновую обработку задач с помощью BackgroundTasks. Эти инструменты могут значительно улучшить производительность и гибкость вашего приложения. CORS помогает обеспечить безопасность и контроль над доступом к API с разных источников.
С помощью этих инструментов вы сможете создавать более сложные и масштабируемые приложения на FastAPI.