From 920ffb578ed632204edb15a3940305a4adaf99ad Mon Sep 17 00:00:00 2001 From: 20081984 Date: Tue, 13 Feb 2024 17:44:45 +0300 Subject: [PATCH] fix models for python 3.8 --- .../example/app/sc/models/message.py | 8 +- nlpf_statemachine/models/context.py | 32 ++++---- nlpf_statemachine/models/debug_info.py | 10 +-- .../models/message/integration_message.py | 12 +-- .../models/message/protocol/app_info.py | 22 +++--- .../models/message/protocol/base_message.py | 10 ++- .../models/message/protocol/character.py | 10 ++- .../models/message/protocol/current_app.py | 8 +- .../models/message/protocol/device.py | 22 +++--- .../message/protocol/device_capability.py | 9 ++- .../message/protocol/device_features.py | 6 +- .../message/protocol/feature_launcher.py | 11 +-- .../models/message/protocol/item_selector.py | 22 +++--- .../models/message/protocol/message_object.py | 9 ++- .../models/message/protocol/meta.py | 52 ++++++------- .../models/message/protocol/payload.py | 76 ++++++++++--------- .../models/message/protocol/request_data.py | 7 +- .../models/message/protocol/selected_item.py | 8 +- .../models/message/protocol/server_action.py | 6 +- .../models/message/protocol/stratagies.py | 8 +- .../models/message/protocol/uuid.py | 12 +-- .../models/response/assistant_response.py | 30 ++++---- .../models/response/custom_responses.py | 4 +- nlpf_statemachine/models/static_storage.py | 13 ++-- .../override/test_user.py | 4 +- 25 files changed, 217 insertions(+), 194 deletions(-) diff --git a/nlpf_statemachine/example/app/sc/models/message.py b/nlpf_statemachine/example/app/sc/models/message.py index 65f41abb..96244aa2 100644 --- a/nlpf_statemachine/example/app/sc/models/message.py +++ b/nlpf_statemachine/example/app/sc/models/message.py @@ -20,10 +20,10 @@ class CustomState(BaseModel): # Описание стейта с фронта. """ - replace_message: bool | None = Field(default=None) + replace_message: Optional[bool] = Field(default=None) """Флаг подмены сообщения для примера с pre_process.""" - screen: str | None = Field(default=None) + screen: Optional[str] = Field(default=None) """Наименование текущего экрана.""" @@ -32,7 +32,7 @@ class CustomCurrentApp(CurrentApp): # Текущий current_app в запросе. """ - state: CustomState | None = Field(default=None) + state: Optional[CustomState] = Field(default=None) """Описание стейта.""" @@ -41,7 +41,7 @@ class CustomMeta(AssistantMeta): # Модель meta в запросе. """ - current_app: CustomCurrentApp | None = Field(default=None) + current_app: Optional[CustomCurrentApp] = Field(default=None) """Текущий current_app.""" diff --git a/nlpf_statemachine/models/context.py b/nlpf_statemachine/models/context.py index 2990bfd1..5353b750 100644 --- a/nlpf_statemachine/models/context.py +++ b/nlpf_statemachine/models/context.py @@ -44,7 +44,7 @@ def context_model(self) -> None: ``` """ - +from typing import Optional, Union, List from pydantic import BaseModel, Field from .debug_info import CallHistoryItem @@ -54,40 +54,40 @@ def context_model(self) -> None: class LocalContext(BaseModel): """Описание локального контекста (в рамках одной транзакции).""" - init_event: str | None = Field(default=None) + init_event: Optional[str] = Field(default=None) """Событие, с которого произошёл запуск ContextManager (может быть None, если был голосовой запуск).""" - base_event: str | None = Field(default=None) + base_event: Optional[str] = Field(default=None) """Базовое событие, с которого началась транзакция (событие, по которому был запущен первый экшен в транзакции).""" - base_message: BaseMessage | None = Field(default=None) + base_message: Optional[BaseMessage] = Field(default=None) """Сообщение, с которого началась транзакция.""" - last_transaction_step_timestamp: float | None = Field(default=None) + last_transaction_step_timestamp: Optional[float] = Field(default=None) """Timestamp последнего запроса в транзакции.""" - call_history: list[CallHistoryItem | None] = Field(default_factory=list) + call_history: Optional[List[Optional[CallHistoryItem]]] = Field(default_factory=list) """Список вызовов (полезное поле для отладки транзакции).""" - character_id: str | None = Field(default=None) + character_id: Optional[str] = Field(default=None) """Текущий выбранный ассистент.""" - run_isolated_scenario: bool | None = Field(default=False) + run_isolated_scenario: Optional[bool] = Field(default=False) """Флаг на запущенный изолированный сценарий.""" - isolated_scenario_id: str | None = Field(default=None) + isolated_scenario_id: Optional[str] = Field(default=None) """Идентификатор запущенного изолированного сценария (если запущен).""" class Context(BaseModel): """Описание контекста.""" - id: str | None = Field(default=None) + id: Optional[str] = Field(default=None) """Идентификатор текущего стейта.""" local: LocalContext = Field(default_factory=LocalContext) """Контекст, живущий в рамках одной транзакции (`LocalContext`).""" - screen: str | None = Field(default=None) + screen: Optional[str] = Field(default=None) """Страница, на которой находится пользователь в рамках текущего запроса (если определена).""" - event: str | None = Field(default=None) + event: Optional[str] = Field(default=None) """Событие, на которое реагируем в текущем запросе.""" - last_screen: str | None = Field(default=None) + last_screen: Optional[str] = Field(default=None) """Страница, которая была при предыдущем запросе (обновляется в конце транзакции).""" - last_event: str | None = Field(default=None) + last_event: Optional[str] = Field(default=None) """Предыдущее событие.""" - last_response_message_name: str | None = Field(default=None) + last_response_message_name: Optional[str] = Field(default=None) """Наименования предыдущего ответа.""" - last_intent: str | None = Field(default=None) + last_intent: Optional[str] = Field(default=None) """Последний пришедший интент от платформы.""" diff --git a/nlpf_statemachine/models/debug_info.py b/nlpf_statemachine/models/debug_info.py index 3e91434c..d5df2137 100644 --- a/nlpf_statemachine/models/debug_info.py +++ b/nlpf_statemachine/models/debug_info.py @@ -4,14 +4,14 @@ Данный объект можно использовать при написании тестов для проверки цепочки вызовов. Он возвращается в поле `nlpf_statemachine.models.response.Response.debug_info`. """ - +from typing import List, Optional from pydantic import BaseModel, Field class CallHistoryItem(BaseModel): """Элемент истории вызовов экшенов.""" - event: str | None = Field(default=None) + event: Optional[str] = Field(default=None) """Событие, которое отработало.""" action: str """Экшен, который был вызван.""" @@ -22,11 +22,11 @@ class CallHistoryItem(BaseModel): class DebugInfo(BaseModel): """Коллекция отладочной информации по работе ContextManager в транзакции в конкретном сценарии.""" - base_event: str | None = Field(default=None) + base_event: Optional[str] = Field(default=None) """Базовое событие текущей транзакции.""" - call_history: list[CallHistoryItem | None] = Field(default_factory=list) + call_history: Optional[List[Optional[CallHistoryItem]]] = Field(default_factory=list) """Список вызовов.""" transaction_finished: bool = Field(default=True) """Флаг на окончание транзакции.""" - static_code: str | None = Field(default=None) + static_code: Optional[str] = Field(default=None) """Код ответа из статики.""" diff --git a/nlpf_statemachine/models/message/integration_message.py b/nlpf_statemachine/models/message/integration_message.py index ac75d526..0e2a3548 100644 --- a/nlpf_statemachine/models/message/integration_message.py +++ b/nlpf_statemachine/models/message/integration_message.py @@ -2,6 +2,8 @@ # Базовые модели для интеграций. """ +from typing import Optional, Dict + from pydantic import BaseModel, Field from nlpf_statemachine.models.enums import Event @@ -13,15 +15,15 @@ class IntegrationPayload(BaseModel): # Описание модели IntegrationPayload. """ - status: str | None = Field(default=None) + status: Optional[str] = Field(default=None) """Статус интеграции.""" - errorTitle: str | None = Field(default=None) + errorTitle: Optional[str] = Field(default=None) """Заголовок ошибки (если есть).""" - errorMessage: str | None = Field(default=None) + errorMessage: Optional[str] = Field(default=None) """Сообщение об ошибке (если есть).""" - error: str | None = Field(default=None) + error: Optional[str] = Field(default=None) """Информация об ошибке (если есть).""" - data: dict | None = Field(default=None) + data: Optional[Dict] = Field(default=None) """Данные, полученные в ответ от интеграции.""" diff --git a/nlpf_statemachine/models/message/protocol/app_info.py b/nlpf_statemachine/models/message/protocol/app_info.py index 43bb6706..7c5cfcc7 100644 --- a/nlpf_statemachine/models/message/protocol/app_info.py +++ b/nlpf_statemachine/models/message/protocol/app_info.py @@ -2,6 +2,8 @@ Информация о смартапе. """ +from typing import Optional, Dict + from pydantic import BaseModel, Field @@ -10,23 +12,23 @@ class AppInfo(BaseModel): # Описание модели AppInfo. """ - projectId: str | None = Field(default=None) + projectId: Optional[str] = Field(default=None) """Идентификатор проекта в SmartMarket Studio.""" - frontendType: str | None = Field(default=None) + frontendType: Optional[str] = Field(default=None) """Тип смартапа.""" - applicationId: str | None = Field(default=None) + applicationId: Optional[str] = Field(default=None) """Идентификатор смартапа.""" - appversionId: str | None = Field(default=None) + appversionId: Optional[str] = Field(default=None) """Идентификатор опубликованной версии смартапа.""" - frontendEndpoint: str | None = Field(default=None) + frontendEndpoint: Optional[str] = Field(default=None) """Ссылка на веб-приложение. Поле актуально для Canvas Apps.""" - systemName: str | None = Field(default=None) + systemName: Optional[str] = Field(default=None) """Более читаемый аналог поля projectId.Не актуален для внешних приложений.""" - frontendStateId: str | None = Field(default=None) + frontendStateId: Optional[str] = Field(default=None) """Объединённое значение полей projectId, applicationId и appversionId.""" - apkInfo: dict | None = Field(default=None) + apkInfo: Optional[Dict] = Field(default=None) """Информация о приложении""" - ageLimit: int | None = Field(default=None) + ageLimit: Optional[int] = Field(default=None) """Информация о возрастном ограничении""" - affiliationType: str | None = Field(default=None) + affiliationType: Optional[str] = Field(default=None) """Тип перехода""" diff --git a/nlpf_statemachine/models/message/protocol/base_message.py b/nlpf_statemachine/models/message/protocol/base_message.py index 0d76d9f8..1234341f 100644 --- a/nlpf_statemachine/models/message/protocol/base_message.py +++ b/nlpf_statemachine/models/message/protocol/base_message.py @@ -2,6 +2,8 @@ # Базовая модель любого запроса в сервис. """ +from typing import Optional, Dict + from pydantic import BaseModel, Field from .uuid import UUID @@ -14,17 +16,17 @@ class BaseMessage(BaseModel): messageName: str """Тип сообщения. Определяет логику обработки события.""" - messageId: int | None = Field(default=None) + messageId: Optional[int] = Field(default=None) """ Идентификатор запроса, который отправил ассистент. Ответ на запрос должен содержать такой же идентификатор в поле messageId. """ - sessionId: str | None = Field(default=None) + sessionId: Optional[str] = Field(default=None) """ Идентификатор соединения платформы (не диалоговой сессии). 128 bit hex GUID converted to string. """ - uuid: UUID | None = Field(default=None) + uuid: Optional[UUID] = Field(default=None) "Составной идентификатор пользователя." - payload: dict | None = Field(default={}) + payload: Optional[Dict] = Field(default={}) """Коллекция, в которой в зависимости от потребителя и messageName передается дополнительная информация.""" diff --git a/nlpf_statemachine/models/message/protocol/character.py b/nlpf_statemachine/models/message/protocol/character.py index e636196c..f0aef5c7 100644 --- a/nlpf_statemachine/models/message/protocol/character.py +++ b/nlpf_statemachine/models/message/protocol/character.py @@ -2,6 +2,8 @@ # Описание модели ассистента. """ +from typing import Optional + from pydantic import BaseModel, Field from nlpf_statemachine.models.enums import AssistantAppeal, AssistantGender, AssistantId, AssistantName @@ -12,7 +14,7 @@ class Character(BaseModel): # Модель ассистента. """ - id: AssistantId | None = Field(default=None) - name: AssistantName | None = Field(default=None) - gender: AssistantGender | None = Field(default=None) - appeal: AssistantAppeal | None = Field(default=None) + id: Optional[AssistantId] = Field(default=None) + name: Optional[AssistantName] = Field(default=None) + gender: Optional[AssistantGender] = Field(default=None) + appeal: Optional[AssistantAppeal] = Field(default=None) diff --git a/nlpf_statemachine/models/message/protocol/current_app.py b/nlpf_statemachine/models/message/protocol/current_app.py index bf3cb4c3..aff59f17 100644 --- a/nlpf_statemachine/models/message/protocol/current_app.py +++ b/nlpf_statemachine/models/message/protocol/current_app.py @@ -18,8 +18,8 @@ class AssistantState(BaseModel): *Данный класс необходимо переопределять в конкретных приложениях.* """ - screen: str | None = Field(default=None) - item_selector: ItemSelector | None = Field(default=None) + screen: Optional[str] = Field(default=None) + item_selector: Optional[ItemSelector] = Field(default=None) class CurrentApp(BaseModel): @@ -27,5 +27,5 @@ class CurrentApp(BaseModel): # Описание модели CurrentApp. """ - app_info: AppInfo | None = Field(default=None) - state: AssistantState | None = Field(default=None) + app_info: Optional[AppInfo] = Field(default=None) + state: Optional[AssistantState] = Field(default=None) diff --git a/nlpf_statemachine/models/message/protocol/device.py b/nlpf_statemachine/models/message/protocol/device.py index 4b312c8c..ef4f416b 100644 --- a/nlpf_statemachine/models/message/protocol/device.py +++ b/nlpf_statemachine/models/message/protocol/device.py @@ -1,7 +1,7 @@ """ # Описание модели Device. """ -from typing import Any +from typing import Any, Optional from pydantic import BaseModel, Field @@ -14,7 +14,7 @@ class Device(BaseModel): # Описание модели Device. """ - platformType: str | None = Field(default=None) + platformType: Optional[str] = Field(default=None) """ Операционная система устройства. @@ -23,9 +23,9 @@ class Device(BaseModel): * ANDROID; * IOS. """ - platformVersion: str | None = Field(default=None) + platformVersion: Optional[str] = Field(default=None) """Версия операционной системы.""" - surface: str | None = Field(default=None) + surface: Optional[str] = Field(default=None) """ Устройство или мобильное приложение, от которого приходит вызов ассистента. @@ -35,17 +35,17 @@ class Device(BaseModel): * COMPANION — запрос от приложения Салют; * STARGATE — запрос от устройства SberPortal. """ - surfaceVersion: str | None = Field(default=None) + surfaceVersion: Optional[str] = Field(default=None) """Версия поверхности.""" - deviceId: str | None = Field(default=None) + deviceId: Optional[str] = Field(default=None) """Идентификатор устройства.""" - features: DeviceFeatures | None = Field(default=None) + features: Optional[DeviceFeatures] = Field(default=None) """Описание функциональности устройства.""" - capabilities: DeviceCapabilities | None = Field(default=None) + capabilities: Optional[DeviceCapabilities] = Field(default=None) """Описание возможностей устройства пользователя.""" - additionalInfo: Any | None = Field(default=None) + additionalInfo: Optional[Any] = Field(default=None) """Дополнительная информация об объекте или устройстве. В настоящий момент не используется.""" - deviceManufacturer: str | None = Field(default=None) + deviceManufacturer: Optional[str] = Field(default=None) """Производитель устройства""" - deviceModel: str | None = Field(default=None) + deviceModel: Optional[str] = Field(default=None) """Модель устройства""" diff --git a/nlpf_statemachine/models/message/protocol/device_capability.py b/nlpf_statemachine/models/message/protocol/device_capability.py index 684b9855..1dda21d8 100644 --- a/nlpf_statemachine/models/message/protocol/device_capability.py +++ b/nlpf_statemachine/models/message/protocol/device_capability.py @@ -1,6 +1,7 @@ """ # Описание возможностей устройства пользователя. """ +from typing import Optional from pydantic import BaseModel, Field @@ -10,7 +11,7 @@ class DeviceCapability(BaseModel): # Описание модели DeviceCapability. """ - available: bool | None = Field(default=None) + available: Optional[bool] = Field(default=None) """Флаг наличия возможностию""" @@ -19,9 +20,9 @@ class DeviceCapabilities(BaseModel): # Описание модели DeviceCapabilities. """ - screen: DeviceCapability | None = Field(default=None) + screen: Optional[DeviceCapability] = Field(default=None) """Описание экрана устройства.""" - mic: DeviceCapability | None = Field(default=None) + mic: Optional[DeviceCapability] = Field(default=None) """Описание микрофона устройства.""" - speak: DeviceCapability | None = Field(default=None) + speak: Optional[DeviceCapability] = Field(default=None) """Описание динамиков устройства.""" diff --git a/nlpf_statemachine/models/message/protocol/device_features.py b/nlpf_statemachine/models/message/protocol/device_features.py index 3972bf32..ff65d5d9 100644 --- a/nlpf_statemachine/models/message/protocol/device_features.py +++ b/nlpf_statemachine/models/message/protocol/device_features.py @@ -1,7 +1,7 @@ """ Описание функциональности устройства. """ - +from typing import Optional, List, Union, Dict from pydantic import BaseModel, Field from nlpf_statemachine.models.enums import DeviceFeaturesAppTypes @@ -12,7 +12,7 @@ class DeviceFeatures(BaseModel): # Описание модели DeviceFeatures. """ - appTypes: list[DeviceFeaturesAppTypes | str] | None = Field(default=None) + appTypes: Optional[List[Union[DeviceFeaturesAppTypes, str]]] = Field(default=None) """ Типы смартапов, которые поддерживает устройство. @@ -25,5 +25,5 @@ class DeviceFeatures(BaseModel): * EMBEDDED_APP * ... """ - clientFlags: dict | None = Field(default={}) + clientFlags: Optional[Dict] = Field(default={}) """Описание клиентских флагов""" diff --git a/nlpf_statemachine/models/message/protocol/feature_launcher.py b/nlpf_statemachine/models/message/protocol/feature_launcher.py index fde87884..abd0aded 100644 --- a/nlpf_statemachine/models/message/protocol/feature_launcher.py +++ b/nlpf_statemachine/models/message/protocol/feature_launcher.py @@ -1,6 +1,7 @@ """ # Модели для описания фиче-лаунчера. """ +from typing import List, Optional, Dict from pydantic import BaseModel, Field @@ -10,9 +11,9 @@ class PublicFL(BaseModel): # Общая коллекция флагов, которые предназначены для всех сервисов/навыков. """ - greenfield_segment_list: list[str] | None = Field(default=None) + greenfield_segment_list: Optional[List[str]] = Field(default=None) """Список сегментов GF к которым принадлежит пользователь""" - greenfield_percentage: int | None = Field(default=None) + greenfield_percentage: Optional[int] = Field(default=None) """ Процент раскатки который рассчитан для пользователя по формуле: user_id = uid.encode('utf-8') @@ -26,9 +27,9 @@ class FeatureLauncher(BaseModel): # Модель фиче лончера. """ - assigned_testing_groups: list[str] | None = Field(default=None) + assigned_testing_groups: Optional[List[str]] = Field(default=None) """Список групп тестирования в которые попал пользователь""" - public: PublicFL | None = Field(default=None) + public: Optional[PublicFL] = Field(default=None) """Общая коллекция флагов, которые предназначены для всех сервисов/навыков""" - nlp_platform: dict | None = Field(default=None) + nlp_platform: Optional[Dict] = Field(default=None) """Общая секция""" diff --git a/nlpf_statemachine/models/message/protocol/item_selector.py b/nlpf_statemachine/models/message/protocol/item_selector.py index 58bbe7c1..a6adfe15 100644 --- a/nlpf_statemachine/models/message/protocol/item_selector.py +++ b/nlpf_statemachine/models/message/protocol/item_selector.py @@ -1,7 +1,7 @@ """ # Описание ItemSelector. """ -from typing import Any +from typing import Any, Optional, List, Dict from pydantic import BaseModel, Field @@ -13,9 +13,9 @@ class AssistantViewAction(BaseModel): Описания события, которое ожидается к возвращению в веб-приложение. """ - type: str | None = Field(default=None) + type: Optional[str] = Field(default=None) """Уникальный тип/id действия для обработки в веб-приложении.""" - payload: Any | None = Field(default=None) + payload: Optional[Any] = Field(default=None) """Данные от бэкенда без изменений.""" @@ -26,19 +26,19 @@ class AssistantVoiceAction(BaseModel): Основные события, которые можно вызвать голосом (= UI-элементы). """ - number: int | None = Field(default=None) + number: Optional[int] = Field(default=None) """Порядковый номер элемента.""" - id: str | None = Field(default=None) + id: Optional[str] = Field(default=None) """Уникальный id элемента.""" - title: str | None = Field(default=None) + title: Optional[str] = Field(default=None) """Ключевая фраза, которая должна приводить к данному действию.""" - type: str | None = Field(default=None) + type: Optional[str] = Field(default=None) """Тип элемента.""" - paraphrases: list[str] | None = Field(default=None) + paraphrases: Optional[List[str]] = Field(default=None) """Фразы-синонимы, которые должны быть расценены как данное действие.""" - payload: dict | None = Field(default=None) + payload: Optional[Dict] = Field(default=None) """Дополнительные данные для бэкенда.""" - action: AssistantViewAction | None = Field(default=None) + action: Optional[AssistantViewAction] = Field(default=None) """Объект, который ожидается к возвращению в веб-приложение.""" @@ -49,5 +49,5 @@ class ItemSelector(BaseModel): Множество объектов, которые можно вызвать голосом. """ - items: list[AssistantVoiceAction] | None = Field(default=None) + items: Optional[List[AssistantVoiceAction]] = Field(default=None) """Список элементов.""" diff --git a/nlpf_statemachine/models/message/protocol/message_object.py b/nlpf_statemachine/models/message/protocol/message_object.py index 188b99f9..8377fa88 100644 --- a/nlpf_statemachine/models/message/protocol/message_object.py +++ b/nlpf_statemachine/models/message/protocol/message_object.py @@ -1,6 +1,7 @@ """ # Результат предобработки. """ +from typing import List, Dict, Optional from pydantic import BaseModel, Field @@ -18,26 +19,26 @@ class Message(BaseModel): Пример: *"хочу заказать пиццу на девять вечера за пятьсот рублей".* """ - normalized_text: str | None = Field(default=None) + normalized_text: Optional[str] = Field(default=None) """ Нормализованный текст, который ввел пользователь. Можно использовать для снижения многообразия запросов, например, для аналитики. Пример: *хотеть заказать пицца на TIME_TIME_TOKEN за MONEY_TOKEN .* """ - entities: dict | None = Field(default=None) + entities: Optional[Dict] = Field(default=None) """ Извлеченные из запроса сущности. [Подробнее тут.](https://developers.sber.ru/docs/ru/salute/brain/entities/ner) """ - asr_normalized_message: str | None = Field(default=None) + asr_normalized_message: Optional[str] = Field(default=None) """ Отображаемый на экране текст запроса / нормализованный на этапе ASR запрос. Пример: *"Хочу заказать пиццу на 9 вечера за 500 ₽".* """ - tokenized_elements_list: list[dict] | None = Field(default=None) + tokenized_elements_list: Optional[List[Dict]] = Field(default=None) """ Список токенов в запросе пользователя. Содержит грамматический и синтаксический разбор, diff --git a/nlpf_statemachine/models/message/protocol/meta.py b/nlpf_statemachine/models/message/protocol/meta.py index 5407aef0..4a1c3ad1 100644 --- a/nlpf_statemachine/models/message/protocol/meta.py +++ b/nlpf_statemachine/models/message/protocol/meta.py @@ -1,7 +1,7 @@ """ # Данные о содержимом экрана пользователя. """ -from typing import Any, Dict, Optional +from typing import Dict, Optional from pydantic import BaseModel, Field @@ -15,11 +15,11 @@ class MetaTime(BaseModel): Данные о текущем времени на устройстве пользователя """ - timestamp: int | None = Field(default=None) + timestamp: Optional[int] = Field(default=None) """Unix-время в миллисекундах.""" - timezone_id: str | None = Field(default=None) + timezone_id: Optional[str] = Field(default=None) """Наименование часового пояса. Пример Europe/Moscow""" - timezone_offset_sec: int | None = Field(default=None) + timezone_offset_sec: Optional[int] = Field(default=None) """Наименование часового пояса. Пример Europe/Moscow.""" @@ -30,7 +30,7 @@ class MetaFeature(BaseModel): Признака фичи. """ - enabled: bool | None = Field(default=None) + enabled: Optional[bool] = Field(default=None) """Флаг доступности фичи.""" @@ -41,9 +41,9 @@ class MetaFeatures(BaseModel): Данные о текущем времени на устройстве пользователя """ - screen: MetaFeature | None = Field(default=None) + screen: Optional[MetaFeature] = Field(default=None) """признак включенного экрана на устройстве.""" - int_login: MetaFeature | None = Field(default=None) + int_login: Optional[MetaFeature] = Field(default=None) """авторизован ли пользователь на устройстве.""" @@ -52,15 +52,15 @@ class MetaLocation(BaseModel): # Описание модели location в meta в запросе. """ - accuracy: float | None = Field(default=None) + accuracy: Optional[float] = Field(default=None) """Точность""" - lat: float | None = Field(default=None) + lat: Optional[float] = Field(default=None) """Широта""" - lon: float | None = Field(default=None) + lon: Optional[float] = Field(default=None) """Долгота""" - source: str | None = Field(default=None) + source: Optional[str] = Field(default=None) """Источник""" - timestamp: int | None = Field(default=None) + timestamp: Optional[int] = Field(default=None) """Время""" @@ -71,7 +71,7 @@ class AssistantMeta(BaseModel): Данные о содержимом экрана пользователя. """ - time: MetaTime | None = Field(default=None) + time: Optional[MetaTime] = Field(default=None) """ Данные о текущем времени на устройстве пользователя. @@ -81,33 +81,33 @@ class AssistantMeta(BaseModel): timezone_id — строка. Наименование часового пояса. Пример Europe/Moscow. timezone_offset_sec — число. """ - features: MetaFeatures | None = Field(default=None) + features: Optional[MetaFeatures] = Field(default=None) """Данные о режиме работы устройства.""" - current_app: CurrentApp | None = Field(default=None) + current_app: Optional[CurrentApp] = Field(default=None) """Информация о текущем аппе.""" - host_meta: dict | None = Field(default=None) + host_meta: Optional[Dict] = Field(default=None) """ Произвольный JSON-объект, который заполняет хост приложение, в которое встроено Assistant SDK. Например 2gis, будет заполнять координаты, текущий экран, регион и другие данные, которые доступны в приложении 2gis """ - mobile_sdk_data: str | None = Field(default=None) + mobile_sdk_data: Optional[str] = Field(default=None) """Данные для анти-фрода, закодировааные в base64-строку""" - network: dict | None = Field(default=None) + network: Optional[Dict] = Field(default=None) """Информация о сети""" - user_settings: dict | None = Field(default=None) + user_settings: Optional[Dict] = Field(default=None) """Пользовательские настройки""" - location: MetaLocation | None = Field(default=None) + location: Optional[MetaLocation] = Field(default=None) """Данные о расположении устройства""" - experimental_flags: dict | None = Field(default=None) + experimental_flags: Optional[Dict] = Field(default=None) """Параметры сети""" - volume: dict | None = Field(default=None) + volume: Optional[Dict] = Field(default=None) """Информация о громкости""" - start_audio_recording_source: str | None = Field(default=None) + start_audio_recording_source: Optional[str] = Field(default=None) """Откуда был инициирован голосовой запрос, например в приложении 2gis есть две точки входа, для разных точек входа тут будет разные значения""" - background_apps: dict | None = Field(default=None) + background_apps: Optional[Dict] = Field(default=None) """Фоновые приложения""" - installed_apps: dict | None = Field(default=None) + installed_apps: Optional[Dict] = Field(default=None) """Установленные приложения""" - capabilities_state: dict | None = Field(default=None) + capabilities_state: Optional[Dict] = Field(default=None) """Стейт внешних устройств""" diff --git a/nlpf_statemachine/models/message/protocol/payload.py b/nlpf_statemachine/models/message/protocol/payload.py index cfb9e599..8a9f771e 100644 --- a/nlpf_statemachine/models/message/protocol/payload.py +++ b/nlpf_statemachine/models/message/protocol/payload.py @@ -2,6 +2,8 @@ # Описание Payload для основных запросов. """ +from typing import Optional, List, Dict + from pydantic import BaseModel, Field from .annotations import Annotations @@ -21,19 +23,19 @@ class AssistantPayload(BaseModel): # Описание модели AssistantPayload. """ - app_info: AppInfo | None = Field(default=None) + app_info: Optional[AppInfo] = Field(default=None) """Информация о смартапе.""" - intent: str | None = Field(default=None) + intent: Optional[str] = Field(default=None) """Интент, полученный из предыдущего ответа смартапа""" - original_intent: str | None = Field(default=None) + original_intent: Optional[str] = Field(default=None) """Исходный интент. Значение поля отличается от значения intent только при монопольном захвате контекста""" meta: AssistantMeta = Field(default_factory=AssistantMeta) """Данные о содержимом экрана пользователя.""" - projectName: str | None = Field(default=None) + projectName: Optional[str] = Field(default=None) """Имя смартапа, которое задается при создании проекта и отображается в каталоге приложений.""" - device: Device | None = Field(default=None) + device: Optional[Device] = Field(default=None) """Информация об устройстве пользователя.""" - new_session: bool | None = Field(default=None) + new_session: Optional[bool] = Field(default=None) """ Указывает на характер запуска смартапа. @@ -47,65 +49,65 @@ class AssistantPayload(BaseModel): По умолчанию: `false`. """ - character: Character | None = Field(default=None) + character: Optional[Character] = Field(default=None) """Информация о текущем персонаже ассистента, который установлен у пользователя.""" - strategies: Strategies | None = Field(default=None) + strategies: Optional[Strategies] = Field(default=None) """Возможные стратегии смартапа.""" - smartBio: dict | None = Field(default=None) + smartBio: Optional[Dict] = Field(default=None) """Данные от биометрии""" - contentProvider: dict | None = Field(default=None) + contentProvider: Optional[Dict] = Field(default=None) """Проброс payload для звонков вк""" - epkId: str | None = Field(default=None) + epkId: Optional[str] = Field(default=None) """ЕПК ID""" - ufs_info: dict | None = Field(default=None) + ufs_info: Optional[Dict] = Field(default=None) """Блок с куками для ЕФС""" - applicationId: str | None = Field(default=None) + applicationId: Optional[str] = Field(default=None) """Id апликейшена проекта из апп дир""" - appversionId: str | None = Field(default=None) + appversionId: Optional[str] = Field(default=None) """Id версии проекта из апп дир""" - token: str | None = Field(default=None) + token: Optional[str] = Field(default=None) """Токен поверхности""" - tokenType: str | None = Field(default=None) + tokenType: Optional[str] = Field(default=None) """Тип токена""" - client_profile: dict | None = Field(default=None) + client_profile: Optional[Dict] = Field(default=None) """ Передается во внутренние аппы и в Axon, если DP удалось получить профиль. Профиль обновляется не каждый запрос а N раз в день. Профиль - ЕПК. """ - feature_launcher: FeatureLauncher | None = Field(default=None) + feature_launcher: Optional[FeatureLauncher] = Field(default=None) """Коллекция флагов для проведения экспериментов для сервисов и навыков Виртуального Ассистента""" - reverseGeocoding: dict | None = Field(default=None) + reverseGeocoding: Optional[Dict] = Field(default=None) """Данные от сервиса геокодинга""" - legacyEribInfo: dict | None = Field(default=None) + legacyEribInfo: Optional[Dict] = Field(default=None) """Поддержка токена ЕРИБ""" - dynamic_stuff: dict | None = Field(default=None) + dynamic_stuff: Optional[Dict] = Field(default=None) """Динамические данные""" - backInfo: list | None = Field(default=None) + backInfo: Optional[List] = Field(default=None) """Данные для доступа к брокерским счетам""" - permitted_actions: list | None = Field(default=None) + permitted_actions: Optional[List] = Field(default=None) """Список согласий этого пользователя которые он дал этому навыку""" - additional_info: dict | None = Field(default=None) + additional_info: Optional[Dict] = Field(default=None) """Дополнительные данные для запуска приложения""" - domain_search: dict | None = Field(default=None) + domain_search: Optional[Dict] = Field(default=None) """Результат поиска сущностей по домену""" - linkedSmartapp: dict | None = Field(default=None) + linkedSmartapp: Optional[Dict] = Field(default=None) """Информация о навыке, который запускает прилинкованный навык в случае если исходный навык недоступен""" - last_messages_new: dict | None = Field(default=None) + last_messages_new: Optional[Dict] = Field(default=None) """N последних сообщениq от пользователя + интент + ответы ассистента для аксон""" - last_messages: dict | None = Field(default=None) + last_messages: Optional[Dict] = Field(default=None) """N последних сообщениq от пользователя + интент + ответы ассистента""" - dp_first_session: bool | None = Field(default=None) + dp_first_session: Optional[bool] = Field(default=None) """ Флаг, говорящий, является ли это самой первой сессией общения с пользователем Передается только в навыки "приветствий" """ - is_first_session: bool | None = Field(default=None) + is_first_session: Optional[bool] = Field(default=None) """Флаг первой сессии из VPS. Передается только в навыки "приветствий" """ - employeeId: str | None = Field(default=None) + employeeId: Optional[str] = Field(default=None) """Идентификатор сотрудника. Передается только для внутренних навыков""" - employee_profile: dict | None = Field(default=None) + employee_profile: Optional[Dict] = Field(default=None) """Профиль сотрудника. Передается только для внутренних навыков и только в канале B2E""" - debug_info: dict | None = Field(default=None) + debug_info: Optional[Dict] = Field(default=None) """Дебаг информация по сервисам""" @@ -125,14 +127,14 @@ class MessageToSkillPayload(AssistantPayload): message: Message """Результат предобработки сообщения.""" - intent_meta: dict | None = Field(default=None) + intent_meta: Optional[Dict] = Field(default=None) """ Мета данные, полученные от сервиса распознавания интентов. Поле будет использовано в будущем. В текущей реализации содержит пустой объект. """ - selected_item: SelectedItem | None = Field(default=None) + selected_item: Optional[SelectedItem] = Field(default=None) """Описание элемента экрана, который пользователь назвал при запросе.""" - annotations: Annotations | None = Field(default=None) + annotations: Optional[Annotations] = Field(default=None) """Общие характеристики сообщения пользователя.""" - asr: str | None = Field(default=None) + asr: Optional[str] = Field(default=None) """Блок с гипотезами от ASR.""" diff --git a/nlpf_statemachine/models/message/protocol/request_data.py b/nlpf_statemachine/models/message/protocol/request_data.py index becb2adb..b57a4003 100644 --- a/nlpf_statemachine/models/message/protocol/request_data.py +++ b/nlpf_statemachine/models/message/protocol/request_data.py @@ -1,6 +1,7 @@ """ # Описание модели конфигурации данных для запроса в интеграцию. """ +from typing import Optional from pydantic import BaseModel, Field @@ -10,9 +11,9 @@ class RequestData(BaseModel): # Данные для запроса в кафку. """ - topic_key: str | None = Field(default=None) + topic_key: Optional[str] = Field(default=None) """Ключ кафки для запроса""" - kafka_replyTopic: str | None = Field(default=None) + kafka_replyTopic: Optional[str] = Field(default=None) """Ключ кафки для ответа""" - app_callback_id: str | None = Field(default=None) + app_callback_id: Optional[str] = Field(default=None) """ID бихейвора""" diff --git a/nlpf_statemachine/models/message/protocol/selected_item.py b/nlpf_statemachine/models/message/protocol/selected_item.py index a57c4bc8..a28affd4 100644 --- a/nlpf_statemachine/models/message/protocol/selected_item.py +++ b/nlpf_statemachine/models/message/protocol/selected_item.py @@ -8,6 +8,8 @@ Объект передается всегда и может быть либо пустым, либо содержать все указанные поля. """ +from typing import Optional + from pydantic import BaseModel, Field @@ -16,11 +18,11 @@ class SelectedItem(BaseModel): # Описание модели SelectedItem. """ - index: int | None = Field(default=None) + index: Optional[int] = Field(default=None) """Номер элемента из списка, начиная с 0.""" - title: str | None = Field(default=None) + title: Optional[str] = Field(default=None) """Название элемента.""" - is_query_by_number: bool | None = Field(default=None) + is_query_by_number: Optional[bool] = Field(default=None) """Указывает выбор элемента по номеру.""" def __bool__(self) -> bool: diff --git a/nlpf_statemachine/models/message/protocol/server_action.py b/nlpf_statemachine/models/message/protocol/server_action.py index a33155bd..b9985130 100644 --- a/nlpf_statemachine/models/message/protocol/server_action.py +++ b/nlpf_statemachine/models/message/protocol/server_action.py @@ -3,7 +3,7 @@ (может так же использоваться при запуске) """ - +from typing import Optional, Dict from pydantic import BaseModel, Field from .app_info import AppInfo @@ -19,9 +19,9 @@ class ServerAction(BaseModel): Действие, которое обрабатывает бэкенд смартапа. Значение по умолчанию для запуска: *run_app*. """ - app_info: AppInfo | None = Field(default=None) + app_info: Optional[AppInfo] = Field(default=None) """Информация о смартапе.""" - parameters: dict | None = Field(default=None) + parameters: Optional[Dict] = Field(default=None) """ Любые параметры, которые требуются для запуска смартапа. Параметры должны быть представлены в виде валидного JSON-объекта. diff --git a/nlpf_statemachine/models/message/protocol/stratagies.py b/nlpf_statemachine/models/message/protocol/stratagies.py index 37fd4c8e..c356afca 100644 --- a/nlpf_statemachine/models/message/protocol/stratagies.py +++ b/nlpf_statemachine/models/message/protocol/stratagies.py @@ -2,6 +2,8 @@ # Возможные стратегии смартапа. """ +from typing import Optional + from pydantic import BaseModel, Field @@ -10,11 +12,11 @@ class Strategies(BaseModel): # Описание модели Strategies. """ - happy_birthday: bool | None = Field(default=None) + happy_birthday: Optional[bool] = Field(default=None) """Сообщает, что у пользователя сегодня день рождения.""" - last_call: bool | None = Field(default=None) + last_call: Optional[bool] = Field(default=None) """Время, которое прошло с момента последнего обращения к смартапу.""" - is_alice: bool | None = Field(default=None) + is_alice: Optional[bool] = Field(default=None) """ Передается только в том случае, когда биометрия определила голос Яндекс Алисы. В остальных случаях поле отсутствует. diff --git a/nlpf_statemachine/models/message/protocol/uuid.py b/nlpf_statemachine/models/message/protocol/uuid.py index a6f25af0..90ac2bc9 100644 --- a/nlpf_statemachine/models/message/protocol/uuid.py +++ b/nlpf_statemachine/models/message/protocol/uuid.py @@ -2,6 +2,8 @@ # Составной идентификатор пользователя. """ +from typing import Optional + from pydantic import BaseModel, Field @@ -12,16 +14,16 @@ class UUID(BaseModel): Составной идентификатор пользователя, от которого пришёл запрос. """ - sub: str | None = Field(default=None) + sub: Optional[str] = Field(default=None) """ Постоянный идентификатор пользователя, созданный на основе SberID. Может отсутствовать, если пользователь не аутентифицирован """ - userId: str | None = Field(default=None) + userId: Optional[str] = Field(default=None) """Id пользователя.""" - userChannel: str | None = Field(default=None) + userChannel: Optional[str] = Field(default=None) """Идентификатор канала коммуникации""" - sid: str | None = Field(default=None) + sid: Optional[str] = Field(default=None) """Сквозной идентификатор пользователя""" - uuid_sberid: str | None = Field(default=None) + uuid_sberid: Optional[str] = Field(default=None) """Единый идентификатор пользователя от СберИд""" diff --git a/nlpf_statemachine/models/response/assistant_response.py b/nlpf_statemachine/models/response/assistant_response.py index 779b861e..2bbb4c50 100644 --- a/nlpf_statemachine/models/response/assistant_response.py +++ b/nlpf_statemachine/models/response/assistant_response.py @@ -1,5 +1,7 @@ """Модель ответа от ассистента.""" +from typing import List, Optional, Union + from pydantic import BaseModel, Field from nlpf_statemachine.models.enums import ResponseMessageName, TextBubbleExpandPolicy @@ -149,26 +151,26 @@ class ASRHints(BaseModel): # Описание модели ASRHints. """ - words: list[str] = Field(default_factory=list) + words: List[str] = Field(default_factory=list) """ Позволяет использовать список слов или фраз, распознавание которых мы хотим усилить. Здесь можно перечислить слова, которые с высокой вероятностью будет произносить пользователь, отвечая ассистенту в приложении. """ - enable_letters: bool | None = Field(default=None) + enable_letters: Optional[bool] = Field(default=None) """Позволяет включить модель коротких фраз, тем самым улучшить распознавание отдельных букв и коротких слов""" - nospeechtimeout: int | None = Field(default=None) + nospeechtimeout: Optional[int] = Field(default=None) """ Меняет интервал ожидания речи пользователя. Возможные значения от 2 до 20 секунд. По умолчанию стоит 7 секунд """ - eou_timeout: int | None = Field(default=None) + eou_timeout: Optional[int] = Field(default=None) """ Меняет настройку системы распознавания конца фразы (End of Utterance --- eou). Система закончит распознавать речь, как только от конца фразы, определенного ею, пройдет столько секунд, сколько установлено в этом параметре. Возможные значения от 0.5 до 5 секунд. По умолчанию распознавание конца фразы срабатывает после 1 секунды. """ - eou_phrase_match: ASRHintsEOUPhraseMatch | None = Field(default=None) + eou_phrase_match: Optional[ASRHintsEOUPhraseMatch] = Field(default=None) """ Использует регулярные выражения при распознавании конца фразы. Данный хинт позволяет не прерывать речь пользователя, пока он говорит ожидаемую от него фразу, @@ -192,7 +194,7 @@ class AssistantResponsePayload(BaseModel): Модель для описания payload ответа от ассистента. """ - pronounceText: str | None = Field(default=None) + pronounceText: Optional[str] = Field(default=None) """ Текст, который ассистент озвучит пользователю. @@ -200,7 +202,7 @@ class AssistantResponsePayload(BaseModel): Используйте разметку синтеза речи (тег `audio`), чтобы добавлять звуки в смартап. """ - pronounceTextType: str | None = Field(default=None) + pronounceTextType: Optional[str] = Field(default=None) """ Указывает, что в тексте, который необходимо озвучить (поле pronounceText). есть разметка `application/text` или `application/ssml`. @@ -210,15 +212,15 @@ class AssistantResponsePayload(BaseModel): * `application/text`; * `application/ssml`. """ - emotion: Emotion | None = Field(default=None) + emotion: Optional[Emotion] = Field(default=None) """Эмоция ассистента, которую он показывает с помощью лавашара""" auto_listening: bool = Field(default=False) """Указывает, что ассистент должен слушать пользователя после выполнения действия, по умолчанию false""" - items: list[CanvasAppItem | Bubble] = Field(default_factory=list) + items: Optional[List[Union[CanvasAppItem, Bubble]]] = Field(default_factory=list) """Список команд и элементов интерфейса смартапа""" - intent: str | None = Field(default=None) + intent: Optional[str] = Field(default=None) """Интент, который смартап получит в следующем ответе ассистента""" - finished: bool | None = Field(default=None) + finished: Optional[bool] = Field(default=None) """ Сообщает ассистенту о завершении работы смартапа. @@ -232,16 +234,16 @@ class AssistantResponsePayload(BaseModel): Для этого требуется передать ассистенту команду close_app с помощью метода `assistant.close()` или `window.AssistantHost.close()`, если вы не используете Assistant Client. """ - asr_hints: ASRHints | None = Field(default=None) + asr_hints: Optional[ASRHints] = Field(default=None) """Подсказки для сервиса синтеза и распознавания речи.""" - suggestions: list[Button] = Field(default_factory=list) + suggestions: Optional[List[Button]] = Field(default_factory=list) """ Предложения, которые смартап может сделать пользователю в зависимости от контекста диалога. Предложения могут быть представлены в виде кнопок и карточек. Важно! Предложения носят **информационный характер.** Оформляйте их в виде подсказок, а не кнопок. """ - activate_app_info: bool | None = Field(default=None) + activate_app_info: Optional[bool] = Field(default=None) """Флаг, по которому фронт открывает навык или считает что навык открывать не нужно, по умолчанию считается true""" diff --git a/nlpf_statemachine/models/response/custom_responses.py b/nlpf_statemachine/models/response/custom_responses.py index a415cab5..68c48804 100644 --- a/nlpf_statemachine/models/response/custom_responses.py +++ b/nlpf_statemachine/models/response/custom_responses.py @@ -1,7 +1,7 @@ """ # Кастомные модели ответов. """ - +from typing import Optional from pydantic import Field from nlpf_statemachine.models.enums import IntegrationRequestType, ResponseMessageName @@ -29,7 +29,7 @@ class IntegrationResponse(Response): request_type: str = IntegrationRequestType.KAFKA """Способ интеграции.""" - request_data: RequestData | None = Field(default_factory=RequestData) + request_data: Optional[RequestData] = Field(default_factory=RequestData) """Конфигурация интеграции.""" diff --git a/nlpf_statemachine/models/static_storage.py b/nlpf_statemachine/models/static_storage.py index bd58e6b3..52cb77b7 100644 --- a/nlpf_statemachine/models/static_storage.py +++ b/nlpf_statemachine/models/static_storage.py @@ -1,6 +1,7 @@ """ # Описание моделей для StaticStorage. """ +from typing import Optional, List, Dict from pydantic import BaseModel, Field @@ -12,7 +13,7 @@ class AssistantAnswer(AssistantResponsePayload): # Описание модели AssistantAnswer. """ - answers: list[AssistantResponsePayload] + answers: Optional[List[AssistantResponsePayload]] """Список ответов.""" @@ -21,13 +22,13 @@ class StaticStorageItem(AssistantResponsePayload): # Описание модели StaticStorageItem. """ - joy: AssistantAnswer | None = Field(default=None) + joy: Optional[AssistantAnswer] = Field(default=None) """Ответы Джой.""" - sber: AssistantAnswer | None = Field(default=None) + sber: Optional[AssistantAnswer] = Field(default=None) """Ответы Сбера.""" - athena: AssistantAnswer | None = Field(default=None) + athena: Optional[AssistantAnswer] = Field(default=None) """Ответы Афины.""" - any: AssistantAnswer | None = Field(default=None) + any: Optional[AssistantAnswer] = Field(default=None) """Дефолтные ответы.""" @@ -36,5 +37,5 @@ class StaticStorage(BaseModel): # Описание модели StaticStorage. """ - data: dict[str, StaticStorageItem] = Field(default_factory=dict) + data: Dict[str, StaticStorageItem] = Field(default_factory=dict) """Словарь ответов ассистентов.""" diff --git a/tests/nlpf_statemachine_tests/override/test_user.py b/tests/nlpf_statemachine_tests/override/test_user.py index eb0d9ff1..b5de1c8a 100644 --- a/tests/nlpf_statemachine_tests/override/test_user.py +++ b/tests/nlpf_statemachine_tests/override/test_user.py @@ -3,7 +3,7 @@ """ import json from random import randint -from typing import Type +from typing import Type, Optional from pydantic import BaseModel, Field @@ -105,7 +105,7 @@ class CustomContext(Context): # Пример переопределение Context с обязательным вложенным полем. """ - field: SomeField | None = Field(default=None) + field: Optional[SomeField] = Field(default=None) class CustomUser(SMUser): """