models
Pydantic-модели для запросов и ответов Яндекс Диалогов.
Определяют структуры данных, используемые для валидации входящих запросов от Алисы и формирования ответов навыка.
1""" 2Pydantic-модели для запросов и ответов Яндекс Диалогов. 3 4Определяют структуры данных, используемые для валидации входящих 5запросов от Алисы и формирования ответов навыка. 6""" 7 8from typing import Any, Dict, List 9from pydantic import BaseModel 10 11 12class Meta(BaseModel): 13 """Мета-информация о запросе: локаль, часовой пояс, идентификатор клиента.""" 14 15 locale: str 16 timezone: str 17 client_id: str 18 interfaces: Dict[str, Any] 19 20 21class User(BaseModel): 22 """Информация о пользователе Яндекс Диалогов.""" 23 24 user_id: str 25 26 27class Application(BaseModel): 28 """Информация о приложении, с которого отправлен запрос.""" 29 30 application_id: str 31 32 33class Session(BaseModel): 34 """Данные сессии запроса: идентификаторы сообщения, сессии, навыка и пользователя.""" 35 36 message_id: int 37 session_id: str 38 skill_id: str 39 user: User 40 application: Application 41 user_id: str 42 new: bool 43 44 45class Entity(BaseModel): 46 """ 47 Сущность, распознанная NLU Алисы. 48 49 value и tokens намеренно типизированы как Any: это граница с внешним 50 сервисом, и Алиса присылает разные JSON-типы в зависимости от типа 51 сущности — 52 53 YANDEX.NUMBER -> int или str («шестьсот двадцать девять» -> 629) 54 YANDEX.DATE -> str ("2026-09-29") 55 YANDEX.DATETIME -> dict ({"year": 2026, "month": 9, "day": 29}) 56 прочие -> list / null 57 58 Любая узкая аннотация здесь превращается в HTTP 422 на живом трафике: 59 запрос отбрасывается на валидации до парсера, и Алиса отвечает 60 «не нашла задач», хотя NLU разобрал фразу корректно. Именно так сломался 61 список задач 2026-09-29 — типизация Union[str, int, float, bool, None] 62 отвергала value-объект YANDEX.DATETIME. 63 64 Нужное нам число (YANDEX.NUMBER) приводится к int в 65 command_parser._entity_number, который для любого другого типа 66 возвращает None. 67 """ 68 69 type: str 70 value: Any = None 71 tokens: Any = None 72 73 74class Nlu(BaseModel): 75 """NLU-составляющая запроса: токены, сущности и интенты.""" 76 77 tokens: List[str] 78 entities: List[Entity] = [] 79 intents: Dict[str, Any] = {} 80 81 82class Markup(BaseModel): 83 """Разметка запроса, указывающая на опасный контекст.""" 84 85 dangerous_context: bool 86 87 88class Request(BaseModel): 89 """Тело запроса от Яндекс Алисы: команда, оригинальная фраза, NLU и разметка.""" 90 91 command: str 92 original_utterance: str 93 nlu: Nlu 94 markup: Markup 95 type: str 96 97 98class AliceRequest(BaseModel): 99 """ 100 Полный входящий запрос от Яндекс Алисы. 101 102 Содержит мета-информацию, данные сессии, тело запроса и версию протокола. 103 """ 104 105 meta: Meta 106 session: Session 107 request: Request 108 version: str 109 110 111class AliceResponse(BaseModel): 112 """ 113 Модель ответа навыка Яндекс Алисы. 114 115 Включает текст ответа, данные сессии и версию протокола. 116 """ 117 118 response: Dict[str, Any] 119 session: Dict[str, Any] 120 version: str = "1.0"
13class Meta(BaseModel): 14 """Мета-информация о запросе: локаль, часовой пояс, идентификатор клиента.""" 15 16 locale: str 17 timezone: str 18 client_id: str 19 interfaces: Dict[str, Any]
Мета-информация о запросе: локаль, часовой пояс, идентификатор клиента.
Информация о пользователе Яндекс Диалогов.
28class Application(BaseModel): 29 """Информация о приложении, с которого отправлен запрос.""" 30 31 application_id: str
Информация о приложении, с которого отправлен запрос.
34class Session(BaseModel): 35 """Данные сессии запроса: идентификаторы сообщения, сессии, навыка и пользователя.""" 36 37 message_id: int 38 session_id: str 39 skill_id: str 40 user: User 41 application: Application 42 user_id: str 43 new: bool
Данные сессии запроса: идентификаторы сообщения, сессии, навыка и пользователя.
46class Entity(BaseModel): 47 """ 48 Сущность, распознанная NLU Алисы. 49 50 value и tokens намеренно типизированы как Any: это граница с внешним 51 сервисом, и Алиса присылает разные JSON-типы в зависимости от типа 52 сущности — 53 54 YANDEX.NUMBER -> int или str («шестьсот двадцать девять» -> 629) 55 YANDEX.DATE -> str ("2026-09-29") 56 YANDEX.DATETIME -> dict ({"year": 2026, "month": 9, "day": 29}) 57 прочие -> list / null 58 59 Любая узкая аннотация здесь превращается в HTTP 422 на живом трафике: 60 запрос отбрасывается на валидации до парсера, и Алиса отвечает 61 «не нашла задач», хотя NLU разобрал фразу корректно. Именно так сломался 62 список задач 2026-09-29 — типизация Union[str, int, float, bool, None] 63 отвергала value-объект YANDEX.DATETIME. 64 65 Нужное нам число (YANDEX.NUMBER) приводится к int в 66 command_parser._entity_number, который для любого другого типа 67 возвращает None. 68 """ 69 70 type: str 71 value: Any = None 72 tokens: Any = None
Сущность, распознанная NLU Алисы.
value и tokens намеренно типизированы как Any: это граница с внешним сервисом, и Алиса присылает разные JSON-типы в зависимости от типа сущности —
YANDEX.NUMBER -> int или str («шестьсот двадцать девять» -> 629)
YANDEX.DATE -> str ("2026-09-29")
YANDEX.DATETIME -> dict ({"year": 2026, "month": 9, "day": 29})
прочие -> list / null
Любая узкая аннотация здесь превращается в HTTP 422 на живом трафике: запрос отбрасывается на валидации до парсера, и Алиса отвечает «не нашла задач», хотя NLU разобрал фразу корректно. Именно так сломался список задач 2026-09-29 — типизация Union[str, int, float, bool, None] отвергала value-объект YANDEX.DATETIME.
Нужное нам число (YANDEX.NUMBER) приводится к int в command_parser._entity_number, который для любого другого типа возвращает None.
75class Nlu(BaseModel): 76 """NLU-составляющая запроса: токены, сущности и интенты.""" 77 78 tokens: List[str] 79 entities: List[Entity] = [] 80 intents: Dict[str, Any] = {}
NLU-составляющая запроса: токены, сущности и интенты.
83class Markup(BaseModel): 84 """Разметка запроса, указывающая на опасный контекст.""" 85 86 dangerous_context: bool
Разметка запроса, указывающая на опасный контекст.
89class Request(BaseModel): 90 """Тело запроса от Яндекс Алисы: команда, оригинальная фраза, NLU и разметка.""" 91 92 command: str 93 original_utterance: str 94 nlu: Nlu 95 markup: Markup 96 type: str
Тело запроса от Яндекс Алисы: команда, оригинальная фраза, NLU и разметка.
99class AliceRequest(BaseModel): 100 """ 101 Полный входящий запрос от Яндекс Алисы. 102 103 Содержит мета-информацию, данные сессии, тело запроса и версию протокола. 104 """ 105 106 meta: Meta 107 session: Session 108 request: Request 109 version: str
Полный входящий запрос от Яндекс Алисы.
Содержит мета-информацию, данные сессии, тело запроса и версию протокола.
112class AliceResponse(BaseModel): 113 """ 114 Модель ответа навыка Яндекс Алисы. 115 116 Включает текст ответа, данные сессии и версию протокола. 117 """ 118 119 response: Dict[str, Any] 120 session: Dict[str, Any] 121 version: str = "1.0"
Модель ответа навыка Яндекс Алисы.
Включает текст ответа, данные сессии и версию протокола.