Ответ
FastAPI предоставляет широкие возможности для кастомизации различных аспектов приложения, что позволяет адаптировать его под специфические требования проекта и интегрировать с существующей инфраструктурой.
Основные примеры кастомизации:
-
Кастомные валидаторы Pydantic: Используются для обеспечения целостности данных и применения бизнес-правил, которые не могут быть выражены стандартными типами Pydantic. Это позволяет гибко контролировать входящие данные.
from pydantic import BaseModel, validator class User(BaseModel): name: str @validator('name') def name_must_contain_space(cls, v): if ' ' not in v: raise ValueError('Name must contain a space') return v.title() -
Кастомные Middleware: Позволяют перехватывать запросы и ответы на глобальном уровне, реализуя сквозную функциональность, такую как логирование, аутентификация, добавление заголовков или обработка CORS. Это централизует общую логику.
from fastapi import FastAPI, Request from starlette.responses import Response app = FastAPI() @app.middleware("http") async def add_process_time_header(request: Request, call_next): # Логика до обработки запроса response = await call_next(request) # Логика после обработки запроса response.headers["X-Custom-Header"] = "Custom Value" return response -
Кастомные обработчики ошибок: Используются для предоставления единообразных и информативных ответов при возникновении исключений, улучшая пользовательский опыт и упрощая отладку для клиентов API. Это обеспечивает предсказуемое поведение при ошибках.
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import JSONResponse app = FastAPI() @app.exception_handler(ValueError) async def value_error_handler(request: Request, exc: ValueError): return JSONResponse( status_code=400, content={"message": f"Некорректные данные: {exc}"} ) @app.get("/test-error/{value}") async def test_error(value: str): if value == "invalid": raise ValueError("Значение не может быть 'invalid'") return {"message": "OK"}
Помимо этого, FastAPI позволяет кастомизировать OpenAPI-документацию, систему внедрения зависимостей (Dependency Injection), маршрутизацию и многое другое, что делает его очень гибким и расширяемым фреймворком.
Ответ 18+ 🔞
Слушай, ну это ж просто пиздец какой-то, как же FastAPI-то всё можно по-своему настроить! Прямо как конструктор, блядь, для взрослых дядек, которые пишут API. Хочешь — валидацию свою прикрутишь, хочешь — запросы на лету перехватывай, а хочешь — ошибки так красиво заверни, что клиент аж прослезится, сука.
Вот на что, блядь, можно руки наложить, если совсем охуел от стандартных возможностей:
-
Свои валидаторы в Pydantic, ёпта. Ну стандартные типы — это, конечно, хорошо, но жизнь-то, блядь, сложнее! Вот, например, имя пользователя должно содержать пробел. Ну и как это стандартным
strпроверить, а? Правильно, нихуя. Пишем свой валидатор и наслаждаемся.from pydantic import BaseModel, validator class User(BaseModel): name: str @validator('name') def name_must_contain_space(cls, v): if ' ' not in v: raise ValueError('Name must contain a space') return v.title()Смотри, какая хитрая жопа: если пробела нет — выёбывается с ошибкой. А если есть — ещё и первую букву каждого слова в заглавную сделает. Красота, блядь!
-
Своё промежуточное ПО, оно же Middleware. Это такая, блядь, штука, которая встаёт между клиентом и твоим кодом, как охранник в клубе. Все запросы и ответы через неё проходят. Хочешь логировать? Пожалуйста. Хочешь ко всем ответам прилепить свою хитрожопую заголовуху? Да не вопрос!
from fastapi import FastAPI, Request from starlette.responses import Response app = FastAPI() @app.middleware("http") async def add_process_time_header(request: Request, call_next): # Тут можешь, блядь, что-то сделать ДО того, как запрос попадёт в твой ендпоинт response = await call_next(request) # А тут — ПОСЛЕ, когда ответ уже готов, но ещё не ушёл response.headers["X-Custom-Header"] = "Custom Value" return responseВот и весь секрет, сука. Всё, что глобально и для всех ручек — сюда.
-
Свои обработчики косяков. Ну а что, стандартные HTTPException — это, конечно, классика, но скучно, блядь! А если у тебя своя, ебаная бизнес-логика и свои исключения? Клиенту же прилетит какая-то хуйня непонятная, а он потом тебе в поддержку: «чё за ошибка, я ничего не делал!». А ты ему — красивый, внятный JSON, где всё по полочкам разложено.
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import JSONResponse app = FastAPI() @app.exception_handler(ValueError) async def value_error_handler(request: Request, exc: ValueError): return JSONResponse( status_code=400, content={"message": f"Некорректные данные: {exc}"} ) @app.get("/test-error/{value}") async def test_error(value: str): if value == "invalid": raise ValueError("Значение не может быть 'invalid'") return {"message": "OK"}Видишь? Поймали
ValueError— завернули в красивый ответ с кодом 400. Клиент доволен, ты спокоен. Идиллия, блядь.
А ещё, ёпта, можно документацию OpenAPI свою нарисовать, зависимости кастомные придумать, маршрутизацию извратить — да хуй его знает, что ещё! В общем, инструмент на все случаи жизни, главное — не перестараться, а то получится не фреймворк, а ёбаный Франкенштейн.