TGStat
TGStat
Qidiruv uchun matnni kiriting
Ilg‘or kanal qidiruvi
  • flag Uzbek
    Sayt tili
    flag Russian flag English flag Uzbek
  • Saytga kirish
  • Katalog
    Kanal va guruhlar katalogi Hududiy to‘plamlar Tematik to‘plamlar Платные каналы Kanallar qidiruvi
    Kanal/guruh qo‘shish
  • Reytinglar
    Kanallar reytingi Guruhlar reytingi Postlar reytingi
    Brendlar va shaxslar reytingi
  • Analitika
  • Postlarda qidiruv
  • Telegram'ni kuzatish
  • Targ‘ibot
    Yandex Business orqali reklama TGStat Agency orqali kanallarda reklama TGStat.ru saytida reklama
Коробка с питоном

15 Jun 2025, 17:44

Telegram'da ochish Ulashish Shikoyat qilish

🔩 Если вам понадобится в рантайме поменить тип принимаемого объекта в роуте FastAPI, вот вам небольшой рецепт.

😆 Для одного проекта я решил сделать плагин-систему, которая автоматически регистрирует python-файлы и добавляет эндпоинты в API написанном на FastAPI. Так как я использую OpenAPI, очень хочется, чтобы принимаемые и возвращаемые типы отображались в нём корректно.

➡️Допустим, есть у меня вот такой код, создающий эндпоинты в зависимости от переданного Action:
class Action[ReqT, RespT](Protocol):
name: str
request_schema: Type[ReqT] # тип который мы будем принимать
response_schema: Type[RespT] # тип который мы будем возвращать
interact: Callable[[ReqT], Coroutine[Any, Any, RespT]]

def create_action_handler(action: Action):
# какой-то код
async def action_endpoint(entity_id: int, data: dict[str, Any]) -> Any:
# какой-то код
return await action.interact(server, data)
return action_endpoint

➡️ А вот так я добавляю нашу ручку в роутер:
def add_action_route(router: APIRouter, action: Action):
handler = create_action_handler(action)
router.post(
f"/plugins/{action.name}",
response_model=action.response_schema, # установим схему для ответа
)(handler)

Схему для ответа мы установили при регистрации нашего эндпоинта в response_model. А что делать с data, тип которого должен быть не dict[str, Any] а action.request_schema ❓

ℹ️ Для начала, я подумал, что раз FastAPI строит доку из аннотаций, наверное я смогу поменять аннотации в `handler.annotations`и на этом дело сделано:
handler = create_action_handler(action)
handler.__annotations__["data"] = action.request_schema
Но это не помогло - аннотации поменялись, а вот схема - нет 🍺 !

😱 Оказывается, FastAPI не использует аннотации, а использует запеченные Signature, который собираются из Dependency. При чем, в понимании FastAPI, dependency не только источник каких-то функций, а еще и наших схем. А дальше он их них и строит OpenAPI.

Зная это нам остается только одно - изменить signature перед регистрацией роута 😱:

sig = inspect.signature(handler) # достаем сигнатуру
new = []
for p in sig.parameters.values():
if p.name == "data": # находим нашу data
p = p.replace(annotation=action.request_schema) # меняем
new.append(p)
handler.__signature__ = sig.replace(parameters=new) # записываем новую сигнтуру

Вуаля! Теперь в OpenAPI будет указанная в action.request_schema схема 👏

#fastapi #рецепт

299 0 8 6 7
Katalog
Kanal va guruhlar katalogi Kanallar to‘plamlari Kanallar qidiruvi Kanal/guruh qo‘shish
Reytinglar
Telegram-kanallar reytingi Telegram-guruhlar reytingi Postlar reytingi Brendlar va shaxslar reytingi
API
Statistika API'si Postlar qidiruvi API'si API Callback
Kanallarimiz
@TGStat @TGStat_Chat @telepulse @TGStatAPI
O‘qish
Академия TGStat Telegram tadqiqoti 2019 Telegram tadqiqoti 2021 Telegram tadqiqoti 2023
Kontaktlar
Справочный центр Qo‘llab-quvvatlash Email Vakansiyalar
Har xil narsalar
Foydalanuvchi shartnomasi Maxfiylik siyosati Ommaviy oferta
Botlarimiz
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot