From ae091aba041d00ceeeb939c607938ead23f2e112 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 22 Jan 2024 04:46:56 +0100 Subject: [PATCH 001/140] new telegram message proposal --- dff/messengers/telegram.py | 132 ++++++++++++++ dff/messengers/telegram/__init__.py | 14 -- dff/messengers/telegram/interface.py | 222 ------------------------ dff/messengers/telegram/message.py | 105 ------------ dff/messengers/telegram/messenger.py | 247 --------------------------- dff/messengers/telegram/utils.py | 54 ------ dff/script/core/message.py | 81 +++++++-- pyproject.toml | 4 +- 8 files changed, 197 insertions(+), 662 deletions(-) create mode 100644 dff/messengers/telegram.py delete mode 100644 dff/messengers/telegram/__init__.py delete mode 100644 dff/messengers/telegram/interface.py delete mode 100644 dff/messengers/telegram/message.py delete mode 100644 dff/messengers/telegram/messenger.py delete mode 100644 dff/messengers/telegram/utils.py diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py new file mode 100644 index 000000000..ee4f6da9d --- /dev/null +++ b/dff/messengers/telegram.py @@ -0,0 +1,132 @@ +""" +Interface +------------ +This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` +that can be used to interact with the Telegram API. +""" +from pydantic import HttpUrl + +from telegram import InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Sticker as TelegramSticker, Message as TelegramMessage +from telegram.ext import Application, MessageHandler, ContextTypes +from telegram.ext.filters import ALL + +from dff.messengers.common import MessengerInterface +from dff.pipeline.types import PipelineRunnerFunction +from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Location, Message, Poll, PollOption, Sticker, Story, Venue, Video + + +# TODO: do we need Game, VideoNote, Dice classes? +def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover + message = Message() + message.attachments = list() + + if update.text is not None: + message.text = update.text + if update.location is not None: + message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] + if update.venue is not None: + message.attachments += [Venue(latitude=update.venue.location.latitude, longitude=update.venue.location.longitude, title=update.venue.title)] + if update.contact is not None: + message.attachments += [Contact(phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name)] + if update.invoice is not None: + message.attachments += [Invoice(title=update.invoice.title, description=update.invoice.description, currency=update.invoice.currency, amount=update.invoice.total_amount)] + if update.poll is not None: + message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] + if update.audio is not None: + message.attachments += [Audio(source=HttpUrl(update.audio.file_id))] + if update.video is not None: + message.attachments += [Video(source=HttpUrl(update.video.file_id))] + if update.animation is not None: + message.attachments += [Animation(source=HttpUrl(update.animation.file_id))] + if len(update.photo) > 0: + message.attachments += [Image(source=HttpUrl(photo.file_id)) for photo in update.photo] + if update.story is not None: + message.attachments += [Story()] + if update.sticker is not None: + message.attachments += [Sticker(source=HttpUrl(update.sticker.file_id))] + if update.document is not None: + message.attachments += [Document(source=HttpUrl(update.document.file_id))] + + message.original_message = update + return message + + +async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Message) -> None: # pragma: no cover + if message.attachments is not None: + files = list() + for attachment in message.attachments: + if isinstance(attachment, Location): + await update.reply_location(attachment.latitude, attachment.longitude) + if isinstance(attachment, Venue): + await update.reply_venue(attachment.latitude, attachment.longitude, attachment.title) + if isinstance(attachment, Contact): + await update.reply_contact(attachment.phone_number, attachment.first_name, attachment.last_name) + if isinstance(attachment, Poll): + await update.reply_poll(attachment.question, [option.text for option in attachment.options]) + if isinstance(attachment, Audio): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaAudio(attachment_bytes)] + if isinstance(attachment, Video): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaVideo(attachment_bytes)] + if isinstance(attachment, Animation): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaAnimation(attachment_bytes)] + if isinstance(attachment, Image): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaPhoto(attachment_bytes)] + if isinstance(attachment, Story): + pass + if isinstance(attachment, Sticker): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + await update.reply_sticker(attachment_bytes) + if isinstance(attachment, Document): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaDocument(attachment_bytes)] + await update.reply_media_group(files, caption=message.text) + elif message.text is not None: + await update.reply_text(message.text) + + +class AbstractTelegramInterface(MessengerInterface): # pragma: no cover + def __init__(self, token: str) -> None: + self.application = Application.builder().token(token).build() + self.application.add_handler(MessageHandler(ALL, self.on_message)) + + async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + if update.effective_user is not None and update.message is not None: + message = extract_message_from_telegram(update.message) + resp = self.callback(message, update.effective_user.id) + if resp.last_response is not None: + await cast_message_to_telegram_and_send(update.message, resp.last_response) + + async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): + self.callback = callback + + +class PollingTelegramInterface(AbstractTelegramInterface): # pragma: no cover + def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: + super().__init__(token) + self.interval = interval + self.timeout = timeout + + async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): + await super().connect(callback, *args, **kwargs) + self.application.run_polling(poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES) + + +class CallbackTelegramInterface(AbstractTelegramInterface): # pragma: no cover + def __init__(self, token: str, host: str = "localhost", port: int = 844): + super().__init__(token) + self.listen = host + self.port = port + + async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): + await super().connect(callback, *args, **kwargs) + self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) diff --git a/dff/messengers/telegram/__init__.py b/dff/messengers/telegram/__init__.py deleted file mode 100644 index cb7e38305..000000000 --- a/dff/messengers/telegram/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- - -try: - import telebot -except ImportError: - raise ImportError("telebot is not installed. Run `pip install dff[telegram]`") - -from .messenger import TelegramMessenger -from .interface import PollingTelegramInterface, CallbackTelegramInterface -from .message import TelegramUI, TelegramMessage, RemoveKeyboard, ParseMode -from .messenger import ( - UpdateType, - telegram_condition, -) diff --git a/dff/messengers/telegram/interface.py b/dff/messengers/telegram/interface.py deleted file mode 100644 index ba482f01b..000000000 --- a/dff/messengers/telegram/interface.py +++ /dev/null @@ -1,222 +0,0 @@ -""" -Interface ------------- -This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` -that can be used to interact with the Telegram API. -""" -import asyncio -from typing import Any, Optional, List, Tuple, Callable - -from telebot import types, apihelper - -from dff.messengers.common import MessengerInterface, CallbackMessengerInterface -from dff.pipeline.types import PipelineRunnerFunction -from .messenger import TelegramMessenger -from .message import TelegramMessage - -try: - from flask import Flask, request, abort - - flask_imported = True -except ImportError: - flask_imported = False - Flask = Any - request, abort = None, None - - -apihelper.ENABLE_MIDDLEWARE = True - - -def extract_telegram_request_and_id( - update: types.Update, messenger: Optional[TelegramMessenger] = None -) -> Tuple[TelegramMessage, int]: # pragma: no cover - """ - Utility function that extracts parameters from a telegram update. - Changes the messenger state, setting the last update id. - - Returned message has the following fields: - - - | `update_id` -- this field stores `update.update_id`, - - | `update` -- this field stores the first non-empty field of `update`, - - | `update_type` -- this field stores the name of the first non-empty field of `update`, - - | `text` -- this field stores `update.message.text`, - - | `callback_query` -- this field stores `update.callback_query.data`. - - Also return context id which is `chat`, `from_user` or `user` of the update. - - :param update: Update to process. - :param messenger: - Messenger instance. If passed updates `last_update_id`. - Defaults to None. - """ - if messenger is not None: - if update.update_id > messenger.last_update_id: - messenger.last_update_id = update.update_id - - message = TelegramMessage(update_id=update.update_id) - ctx_id = None - - for update_field, update_value in vars(update).items(): - if update_field != "update_id" and update_value is not None: - if message.update is not None: - raise RuntimeError(f"Two update fields. First: {message.update_type}; second: {update_field}") - message.update_type = update_field - message.update = update_value - if isinstance(update_value, types.Message): - message.text = update_value.text - - if isinstance(update_value, types.CallbackQuery): - data = update_value.data - if data is not None: - message.callback_query = data - - dict_update = vars(update_value) - # if 'chat' is not available, fall back to 'from_user', then to 'user' - user = dict_update.get("chat", dict_update.get("from_user", dict_update.get("user"))) - ctx_id = getattr(user, "id", None) - if message.update is None: - raise RuntimeError(f"No update fields found: {update}") - - return message, ctx_id - - -class PollingTelegramInterface(MessengerInterface): # pragma: no cover - """ - Telegram interface that retrieves updates by polling. - Multi-threaded polling is currently not supported. - - :param token: Bot token - :param messenger: - :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` instance. - If not `None` will be used instead of creating messenger from token. - Token value does not matter in that case. - Defaults to None. - :param interval: - Polling interval. See `link `__. - Defaults to 2. - :param allowed_updates: - Processed updates. See `link `__. - Defaults to None. - :param timeout: - General timeout. See `link `__. - Defaults to 20. - :param long_polling_timeout: - Polling timeout. See `link `__. - Defaults to 20. - """ - - def __init__( - self, - token: str, - interval: int = 2, - allowed_updates: Optional[List[str]] = None, - timeout: int = 20, - long_polling_timeout: int = 20, - messenger: Optional[TelegramMessenger] = None, - ): - self.messenger = ( - messenger if messenger is not None else TelegramMessenger(token, suppress_middleware_excepions=True) - ) - self.allowed_updates = allowed_updates - self.interval = interval - self.timeout = timeout - self.long_polling_timeout = long_polling_timeout - - async def connect(self, callback: PipelineRunnerFunction, loop: Optional[Callable] = None, *args, **kwargs): - def dff_middleware(bot_instance, update): - message, ctx_id = extract_telegram_request_and_id(update, self.messenger) - - ctx = asyncio.run(callback(message, ctx_id)) - - bot_instance.send_response(ctx_id, ctx.last_response) - - self.messenger.middleware_handler()(dff_middleware) - - self.messenger.infinity_polling( - timeout=self.timeout, long_polling_timeout=self.long_polling_timeout, interval=self.interval - ) - - -class CallbackTelegramInterface(CallbackMessengerInterface): # pragma: no cover - """ - Asynchronous Telegram interface that retrieves updates via webhook. - Any Flask server can be passed to set up a webhook on a separate endpoint. - - :param token: Bot token - :param messenger: - :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` instance. - If not `None` will be used instead of creating messenger from token. - Token value does not matter in that case. - Defaults to None. - :param app: - Flask instance. - Defaults to `Flask(__name__)`. - :param endpoint: - Webhook endpoint. Should be prefixed with "/". - Defaults to "/telegram-webhook". - :param host: - Host IP. - Defaults to "localhost". - :param port: - Port of the app. - Defaults to 8443. - :param debug: - Run the Flask app in debug mode. - :param load_dotenv: - Whether or not the .env file in the project folder - should be used to set environment variables. - :param full_uri: - Full public IP of your webhook that is accessible by https. - Defaults to `"https://{host}:{port}{endpoint}"`. - :param wsgi_options: - Keyword arguments to forward to `Flask.run` method. - Use these to set `ssl_context` and other WSGI options. - """ - - def __init__( - self, - token: str, - app: Optional[Flask] = None, - host: str = "localhost", - port: int = 8443, - debug: Optional[bool] = None, - load_dotenv: bool = True, - endpoint: str = "/telegram-webhook", - full_uri: Optional[str] = None, - messenger: Optional[TelegramMessenger] = None, - **wsgi_options, - ): - if not flask_imported: - raise ModuleNotFoundError("Flask is not installed. Install it with `pip install flask`.") - - self.messenger = messenger if messenger is not None else TelegramMessenger(token) - self.app = app if app else Flask(__name__) - self.host = host - self.port = port - self.debug = debug - self.load_dotenv = load_dotenv - self.wsgi_options = wsgi_options - self.endpoint = endpoint - self.full_uri = full_uri if full_uri is not None else "".join([f"https://{host}:{port}", endpoint]) - - async def endpoint(): - if not request.headers.get("content-type") == "application/json": - abort(403) - - json_string = request.get_data().decode("utf-8") - update = types.Update.de_json(json_string) - resp = await self.on_request_async(*extract_telegram_request_and_id(update, self.messenger)) - self.messenger.send_response(resp.id, resp.last_response) - return "" - - self.app.route(self.endpoint, methods=["POST"])(endpoint) - - async def connect(self, callback: PipelineRunnerFunction): - await super().connect(callback) - - self.messenger.remove_webhook() - self.messenger.set_webhook(self.full_uri) - - self.app.run( - host=self.host, port=self.port, load_dotenv=self.load_dotenv, debug=self.debug, **self.wsgi_options - ) diff --git a/dff/messengers/telegram/message.py b/dff/messengers/telegram/message.py deleted file mode 100644 index bc47c4f21..000000000 --- a/dff/messengers/telegram/message.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -Telegram Message ----------------- -This module implements inherited classes :py:mod:`dff.script.core.message` modified for usage with Telegram. -""" -from typing import Optional, Union -from enum import Enum - -from telebot.types import ( - ReplyKeyboardRemove, - ReplyKeyboardMarkup, - InlineKeyboardMarkup, - Message as tlMessage, - InlineQuery, - ChosenInlineResult, - CallbackQuery as tlCallbackQuery, - ShippingQuery, - PreCheckoutQuery, - Poll, - PollAnswer, - ChatMemberUpdated, - ChatJoinRequest, -) - -from dff.script.core.message import Message, Location, Keyboard, DataModel -from pydantic import model_validator - - -class TelegramUI(Keyboard): - is_inline: bool = True - """ - Whether to use `inline keyboard `__ or - a `keyboard `__. - """ - row_width: int = 3 - """Limits the maximum number of buttons in a row.""" - - @model_validator(mode="after") - def validate_buttons(self, _): - if not self.is_inline: - for button in self.buttons: - if button.payload is not None or button.source is not None: - raise AssertionError(f"`payload` and `source` are only used for inline keyboards: {button}") - return self - - -class _ClickButton(DataModel): - """This class is only used in telegram tests (to click buttons as a client).""" - - button_index: int - - -class RemoveKeyboard(DataModel): - """Pass an instance of this class to :py:attr:`~.TelegramMessage.ui` to remove current keyboard.""" - - ... - - -class ParseMode(Enum): - """ - Parse mode of the message. - More info: https://core.telegram.org/bots/api#formatting-options. - """ - - HTML = "HTML" - MARKDOWN = "MarkdownV2" - - -class TelegramMessage(Message): - ui: Optional[ - Union[TelegramUI, RemoveKeyboard, ReplyKeyboardRemove, ReplyKeyboardMarkup, InlineKeyboardMarkup] - ] = None - location: Optional[Location] = None - callback_query: Optional[Union[str, _ClickButton]] = None - update: Optional[ - Union[ - tlMessage, - InlineQuery, - ChosenInlineResult, - tlCallbackQuery, - ShippingQuery, - PreCheckoutQuery, - Poll, - PollAnswer, - ChatMemberUpdated, - ChatJoinRequest, - ] - ] = None - """This field stores an update representing this message.""" - update_id: Optional[int] = None - update_type: Optional[str] = None - """Name of the field that stores an update representing this message.""" - parse_mode: Optional[ParseMode] = None - """Parse mode of the message.""" - - def __eq__(self, other): - if isinstance(other, Message): - for field in self.model_fields: - if field not in ("parse_mode", "update_id", "update", "update_type"): - if field not in other.model_fields: - return False - if self.__getattribute__(field) != other.__getattribute__(field): - return False - return True - return NotImplemented diff --git a/dff/messengers/telegram/messenger.py b/dff/messengers/telegram/messenger.py deleted file mode 100644 index 07919c3d0..000000000 --- a/dff/messengers/telegram/messenger.py +++ /dev/null @@ -1,247 +0,0 @@ -""" -Messenger ------------------ -The Messenger module provides the :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` class. -The former inherits from the :py:class:`~TeleBot` class from the `pytelegrambotapi` library. -Using it, you can put Telegram update handlers inside your script and condition your transitions accordingly. - -""" -from pathlib import Path -from typing import Union, List, Optional, Callable -from enum import Enum - -from telebot import types, TeleBot - -from dff.script import Context -from dff.pipeline import Pipeline - -from .utils import batch_open_io -from .message import TelegramMessage, TelegramUI, RemoveKeyboard - -from dff.script import Message -from dff.script.core.message import Audio, Video, Image, Document - - -class TelegramMessenger(TeleBot): # pragma: no cover - """ - This class inherits from `Telebot` and implements framework-specific functionality - like sending generic responses. - - :param token: A Telegram API bot token. - :param kwargs: Arbitrary parameters that match the signature of the `Telebot` class. - For reference see: `link `_ . - - """ - - def __init__( - self, - token: str, - **kwargs, - ): - super().__init__(token, threaded=False, **kwargs) - - def send_response(self, chat_id: Union[str, int], response: Union[str, dict, Message]) -> None: - """ - Cast `response` to :py:class:`~dff.messengers.telegram.types.TelegramMessage` and send it. - Message fields are sent in separate messages in the following order: - - 1. Attachments - 2. Location - 3. Text with keyboard - - :param chat_id: Telegram chat ID. - :param response: Response data. String, dictionary or :py:class:`~dff.script.responses.generics.Response`. - will be cast to :py:class:`~dff.messengers.telegram.types.TelegramMessage`. - """ - if isinstance(response, TelegramMessage): - ready_response = response - elif isinstance(response, str): - ready_response = TelegramMessage(text=response) - elif isinstance(response, Message): - ready_response = TelegramMessage.model_validate(response.model_dump()) - elif isinstance(response, dict): - ready_response = TelegramMessage.model_validate(response) - else: - raise TypeError( - "Type of the response argument should be one of the following:" - " `str`, `dict`, `Message`, or `TelegramMessage`." - ) - parse_mode = ready_response.parse_mode.value if ready_response.parse_mode is not None else None - if ready_response.attachments is not None: - if len(ready_response.attachments.files) == 1: - attachment = ready_response.attachments.files[0] - if isinstance(attachment, Audio): - method = self.send_audio - elif isinstance(attachment, Document): - method = self.send_document - elif isinstance(attachment, Video): - method = self.send_video - elif isinstance(attachment, Image): - method = self.send_photo - else: - raise TypeError(type(attachment)) - params = {"caption": attachment.title, "parse_mode": parse_mode} - if isinstance(attachment.source, Path): - with open(attachment.source, "rb") as file: - method(chat_id, file, **params) - else: - method(chat_id, str(attachment.source or attachment.id), **params) - else: - - def cast(file): - if isinstance(file, Image): - cast_to_media_type = types.InputMediaPhoto - elif isinstance(file, Audio): - cast_to_media_type = types.InputMediaAudio - elif isinstance(file, Document): - cast_to_media_type = types.InputMediaDocument - elif isinstance(file, Video): - cast_to_media_type = types.InputMediaVideo - else: - raise TypeError(type(file)) - return cast_to_media_type(media=str(file.source or file.id), caption=file.title) - - files = map(cast, ready_response.attachments.files) - with batch_open_io(files) as media: - self.send_media_group(chat_id=chat_id, media=media) - - if ready_response.location: - self.send_location( - chat_id=chat_id, - latitude=ready_response.location.latitude, - longitude=ready_response.location.longitude, - ) - - if ready_response.ui is not None: - if isinstance(ready_response.ui, RemoveKeyboard): - keyboard = types.ReplyKeyboardRemove() - elif isinstance(ready_response.ui, TelegramUI): - if ready_response.ui.is_inline: - keyboard = types.InlineKeyboardMarkup(row_width=ready_response.ui.row_width) - buttons = [ - types.InlineKeyboardButton( - text=item.text, - url=item.source, - callback_data=item.payload, - ) - for item in ready_response.ui.buttons - ] - else: - keyboard = types.ReplyKeyboardMarkup(row_width=ready_response.ui.row_width) - buttons = [ - types.KeyboardButton( - text=item.text, - ) - for item in ready_response.ui.buttons - ] - keyboard.add(*buttons, row_width=ready_response.ui.row_width) - else: - keyboard = ready_response.ui - else: - keyboard = None - - if ready_response.text is not None: - self.send_message( - chat_id=chat_id, - text=ready_response.text, - reply_markup=keyboard, - parse_mode=parse_mode, - ) - elif keyboard is not None: - self.send_message( - chat_id=chat_id, - text="", - reply_markup=keyboard, - parse_mode=parse_mode, - ) - - -_default_messenger = TeleBot("") - - -class UpdateType(Enum): - """ - Represents a type of the telegram update - (which field contains an update in :py:class:`telebot.types.Update`). - See `link `__. - """ - - ALL = "ALL" - MESSAGE = "message" - EDITED_MESSAGE = "edited_message" - CHANNEL_POST = "channel_post" - EDITED_CHANNEL_POST = "edited_channel_post" - INLINE_QUERY = "inline_query" - CHOSEN_INLINE_RESULT = "chosen_inline_result" - CALLBACK_QUERY = "callback_query" - SHIPPING_QUERY = "shipping_query" - PRE_CHECKOUT_QUERY = "pre_checkout_query" - POLL = "poll" - POLL_ANSWER = "poll_answer" - MY_CHAT_MEMBER = "my_chat_member" - CHAT_MEMBER = "chat_member" - CHAT_JOIN_REQUEST = "chat_join_request" - - -def telegram_condition( - messenger: TeleBot = _default_messenger, - update_type: UpdateType = UpdateType.MESSAGE, - commands: Optional[List[str]] = None, - regexp: Optional[str] = None, - func: Optional[Callable] = None, - content_types: Optional[List[str]] = None, - chat_types: Optional[List[str]] = None, - **kwargs, -): - """ - A condition triggered by updates that match the given parameters. - - :param messenger: - Messenger to test filters on. Used only for :py:attr:`Telebot.custom_filters`. - Defaults to :py:data:`._default_messenger`. - :param update_type: - If set to any `UpdateType` other than `UpdateType.ALL` - it will check that an update is of the same type. - Defaults to `UpdateType.Message`. - :param commands: - Telegram command trigger. - See `link `__. - :param regexp: - Regex trigger. - See `link `__. - :param func: - Callable trigger. - See `link `__. - :param content_types: - Content type trigger. - See `link `__. - :param chat_types: - Chat type trigger. - See `link `__. - """ - - update_handler = messenger._build_handler_dict( - None, - False, - commands=commands, - regexp=regexp, - func=func, - content_types=content_types, - chat_types=chat_types, - **kwargs, - ) - - def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover - last_request = ctx.last_request - if last_request is None: - return False - update = getattr(last_request, "update", None) - request_update_type = getattr(last_request, "update_type", None) - if update is None: - return False - if update_type != UpdateType.ALL and request_update_type != update_type.value: - return False - test_result = messenger._test_message_handler(update_handler, update) - return test_result - - return condition diff --git a/dff/messengers/telegram/utils.py b/dff/messengers/telegram/utils.py deleted file mode 100644 index f21dc0016..000000000 --- a/dff/messengers/telegram/utils.py +++ /dev/null @@ -1,54 +0,0 @@ -""" -Utils ------- -This module contains utilities for connecting to Telegram. -""" -from typing import Union, Iterable -from contextlib import contextmanager -from pathlib import Path -from io import IOBase - -from telebot import types - - -def open_io(item: types.InputMedia): - """ - Returns `InputMedia` with an opened file descriptor instead of path. - - :param item: InputMedia object. - """ - if isinstance(item.media, Path): - item.media = item.media.open(mode="rb") - return item - - -def close_io(item: types.InputMedia): - """ - Closes an IO in an `InputMedia` object to perform the cleanup. - - :param item: InputMedia object. - """ - if isinstance(item.media, IOBase): - item.media.close() - - -@contextmanager -def batch_open_io(item: Union[types.InputMedia, Iterable[types.InputMedia]]): - """ - Context manager that controls the state of file descriptors inside `InputMedia`. - Can be used both for single objects and collections. - - :param item: InputMedia objects that contain file descriptors. - """ - if isinstance(item, Iterable): - resources = list(map(open_io, item)) - else: - resources = open_io(item) - try: - yield resources - finally: - if isinstance(resources, Iterable): - for resource in resources: - close_io(resource) - else: - close_io(resources) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 05f9974f9..25cd2465e 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -26,7 +26,7 @@ class DataModel(BaseModel, extra="allow", arbitrary_types_allowed=True): This class is a Pydantic BaseModel that serves as a base class for all DFF models. """ - ... + pass class Command(DataModel): @@ -35,10 +35,15 @@ class Command(DataModel): a command that can be executed in response to a user input. """ - ... + pass -class Location(DataModel): +class Attachment(DataModel): + + pass + + +class Location(Attachment): """ This class is a data model that represents a geographical location on the Earth's surface. @@ -56,7 +61,39 @@ def __eq__(self, other): return NotImplemented -class Attachment(DataModel): +class Venue(Location): + + title: str + + +class Contact(Attachment): + + phone_number: str + first_name: str + last_name: Optional[str] + + +class Invoice(Attachment): + + title: str + description: str + currency: str + amount: int + + +class PollOption(DataModel): + + text: str + votes: int + + +class Poll(Attachment): + + question: str + options: List[PollOption] + + +class DataAttachment(Attachment): """ This class represents an attachment that can be either a file or a URL, along with an optional ID and title. @@ -77,7 +114,7 @@ def get_bytes(self) -> Optional[bytes]: return file.read() def __eq__(self, other): - if isinstance(other, Attachment): + if isinstance(other, DataAttachment): if self.title != other.title: return False if self.id != other.id: @@ -102,39 +139,46 @@ def validate_source(cls, value): return value -class Audio(Attachment): +class Audio(DataAttachment): """Represents an audio file attachment.""" pass -class Video(Attachment): +class Video(DataAttachment): """Represents a video file attachment.""" pass -class Image(Attachment): +class Animation(DataAttachment): + """Represents an animation file attachment.""" + + pass + + +class Image(DataAttachment): """Represents an image file attachment.""" pass -class Document(Attachment): - """Represents a document file attachment.""" +class Story(DataAttachment): + """Represents an story attachment.""" pass -class Attachments(DataModel): - """This class is a data model that represents a list of attachments.""" +class Sticker(DataAttachment): + """Represents an sticker attachment.""" - files: List[Attachment] = Field(default_factory=list) + pass - def __eq__(self, other): - if isinstance(other, Attachments): - return self.files == other.files - return NotImplemented + +class Document(DataAttachment): + """Represents a document file attachment.""" + + pass class Link(DataModel): @@ -192,9 +236,10 @@ class level variables to store message information. text: Optional[str] = None commands: Optional[List[Command]] = None - attachments: Optional[Attachments] = None + attachments: Optional[List[Attachment]] = None annotations: Optional[dict] = None misc: Optional[dict] = None + original_message: Optional[Any] = None # commands and state options are required for integration with services # that use an intermediate backend server, like Yandex's Alice # state: Optional[Session] = Session.ACTIVE diff --git a/pyproject.toml b/pyproject.toml index e071ae56e..29b2e3834 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ aiosqlite = { version = "*", optional = true } omegaconf = { version = "*", optional = true } cryptography = { version = "*", optional = true } requests = { version = "*", optional = true } -pytelegrambotapi = { version = "*", optional = true } +python-telegram-bot = { version = "*", optional = true } opentelemetry-instrumentation = { version = "*", optional = true } sqlalchemy = { version = "*", extras = ["asyncio"], optional = true } opentelemetry-exporter-otlp = { version = ">=1.20.0", optional = true } # log body serialization is required @@ -87,7 +87,7 @@ mongodb = ["motor"] mysql = ["sqlalchemy", "asyncmy", "cryptography"] postgresql = ["sqlalchemy", "asyncpg"] ydb = ["ydb", "six"] -telegram = ["pytelegrambotapi"] +telegram = ["python-telegram-bot"] stats = ["opentelemetry-exporter-otlp", "opentelemetry-instrumentation", "requests", "tqdm", "omegaconf"] benchmark = ["pympler", "humanize", "pandas", "altair", "tqdm"] From b1c4da9967c6dd91b1c605cd7981985914f6dade Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 23 Jan 2024 00:54:20 +0100 Subject: [PATCH 002/140] only required attachments remain --- dff/messengers/telegram.py | 19 ++----------------- dff/script/core/message.py | 17 ----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index ee4f6da9d..3b9582943 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -6,16 +6,15 @@ """ from pydantic import HttpUrl -from telegram import InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Sticker as TelegramSticker, Message as TelegramMessage +from telegram import InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage from telegram.ext import Application, MessageHandler, ContextTypes from telegram.ext.filters import ALL from dff.messengers.common import MessengerInterface from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Location, Message, Poll, PollOption, Sticker, Story, Venue, Video +from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Location, Message, Poll, PollOption, Video -# TODO: do we need Game, VideoNote, Dice classes? def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover message = Message() message.attachments = list() @@ -24,8 +23,6 @@ def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma message.text = update.text if update.location is not None: message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] - if update.venue is not None: - message.attachments += [Venue(latitude=update.venue.location.latitude, longitude=update.venue.location.longitude, title=update.venue.title)] if update.contact is not None: message.attachments += [Contact(phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name)] if update.invoice is not None: @@ -40,10 +37,6 @@ def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma message.attachments += [Animation(source=HttpUrl(update.animation.file_id))] if len(update.photo) > 0: message.attachments += [Image(source=HttpUrl(photo.file_id)) for photo in update.photo] - if update.story is not None: - message.attachments += [Story()] - if update.sticker is not None: - message.attachments += [Sticker(source=HttpUrl(update.sticker.file_id))] if update.document is not None: message.attachments += [Document(source=HttpUrl(update.document.file_id))] @@ -57,8 +50,6 @@ async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Me for attachment in message.attachments: if isinstance(attachment, Location): await update.reply_location(attachment.latitude, attachment.longitude) - if isinstance(attachment, Venue): - await update.reply_venue(attachment.latitude, attachment.longitude, attachment.title) if isinstance(attachment, Contact): await update.reply_contact(attachment.phone_number, attachment.first_name, attachment.last_name) if isinstance(attachment, Poll): @@ -79,12 +70,6 @@ async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Me attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: files += [InputMediaPhoto(attachment_bytes)] - if isinstance(attachment, Story): - pass - if isinstance(attachment, Sticker): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - await update.reply_sticker(attachment_bytes) if isinstance(attachment, Document): attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 25cd2465e..876b9186b 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -61,11 +61,6 @@ def __eq__(self, other): return NotImplemented -class Venue(Location): - - title: str - - class Contact(Attachment): phone_number: str @@ -163,18 +158,6 @@ class Image(DataAttachment): pass -class Story(DataAttachment): - """Represents an story attachment.""" - - pass - - -class Sticker(DataAttachment): - """Represents an sticker attachment.""" - - pass - - class Document(DataAttachment): """Represents a document file attachment.""" From 86c15c2548178bb384198785dd30444b0d482ddb Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 23 Jan 2024 01:17:47 +0100 Subject: [PATCH 003/140] keyboard implemented --- dff/messengers/telegram.py | 29 ++++++++++++++++++++++------- dff/script/core/message.py | 35 +---------------------------------- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 3b9582943..cc02e4d6f 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -4,15 +4,16 @@ This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` that can be used to interact with the Telegram API. """ +from typing import Optional, Sequence from pydantic import HttpUrl -from telegram import InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage +from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage from telegram.ext import Application, MessageHandler, ContextTypes from telegram.ext.filters import ALL from dff.messengers.common import MessengerInterface from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Location, Message, Poll, PollOption, Video +from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover @@ -44,16 +45,27 @@ def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma return message +def _create_keyboard(buttons: Sequence[Sequence[str]]) -> Optional[InlineKeyboardMarkup]: + button_list = None + if len(buttons) > 0: + button_list = [[InlineKeyboardButton(button) for button in row] for row in buttons] + if button_list is None: + return None + else: + return InlineKeyboardMarkup(button_list) + + async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Message) -> None: # pragma: no cover + buttons = list() if message.attachments is not None: files = list() for attachment in message.attachments: if isinstance(attachment, Location): - await update.reply_location(attachment.latitude, attachment.longitude) + await update.reply_location(attachment.latitude, attachment.longitude, reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Contact): - await update.reply_contact(attachment.phone_number, attachment.first_name, attachment.last_name) + await update.reply_contact(attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Poll): - await update.reply_poll(attachment.question, [option.text for option in attachment.options]) + await update.reply_poll(attachment.question, [option.text for option in attachment.options], reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Audio): attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: @@ -74,9 +86,12 @@ async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Me attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: files += [InputMediaDocument(attachment_bytes)] - await update.reply_media_group(files, caption=message.text) + if isinstance(attachment, Keyboard): + buttons = attachment.buttons + if len(files > 0): + await update.reply_media_group(files, caption=message.text) elif message.text is not None: - await update.reply_text(message.text) + await update.reply_text(message.text, reply_markup=_create_keyboard(buttons)) class AbstractTelegramInterface(MessengerInterface): # pragma: no cover diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 876b9186b..5a47d80ba 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -164,46 +164,13 @@ class Document(DataAttachment): pass -class Link(DataModel): - """This class is a DataModel representing a hyperlink.""" - - source: HttpUrl - title: Optional[str] = None - - @property - def html(self): - return f'{self.title if self.title else self.source}' - - -class Button(DataModel): - """ - This class allows for the creation of a button object - with a source URL, a text description, and a payload. - """ - - source: Optional[HttpUrl] = None - text: str - payload: Optional[Any] = None - - def __eq__(self, other): - if isinstance(other, Button): - if self.source != other.source: - return False - if self.text != other.text: - return False - first_payload = bytes(self.payload, encoding="utf-8") if isinstance(self.payload, str) else self.payload - second_payload = bytes(other.payload, encoding="utf-8") if isinstance(other.payload, str) else other.payload - return first_payload == second_payload - return NotImplemented - - class Keyboard(DataModel): """ This class is a DataModel that represents a keyboard object that can be used for a chatbot or messaging application. """ - buttons: List[Button] = Field(default_factory=list, min_length=1) + buttons: List[List[str]] = Field(default_factory=list, min_length=1) def __eq__(self, other): if isinstance(other, Keyboard): From a0a859c04522ad235097e05ee4095a7dd9714992 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 29 Jan 2024 15:43:31 +0100 Subject: [PATCH 004/140] tests reworked --- dff/messengers/telegram.py | 59 +++++--- dff/script/core/message.py | 24 +++- tutorials/messengers/telegram/2_buttons.py | 130 ++++++++---------- .../telegram/3_buttons_with_callback.py | 108 ++++++++------- tutorials/messengers/telegram/4_conditions.py | 61 ++++---- .../telegram/5_conditions_with_media.py | 117 +++++++++------- .../telegram/6_conditions_extras.py | 29 ++-- .../messengers/telegram/7_polling_setup.py | 5 +- .../messengers/telegram/8_webhook_setup.py | 4 +- 9 files changed, 294 insertions(+), 243 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index cc02e4d6f..550649987 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -4,16 +4,18 @@ This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` that can be used to interact with the Telegram API. """ -from typing import Optional, Sequence +from typing import Callable, Optional, Sequence, cast from pydantic import HttpUrl from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage -from telegram.ext import Application, MessageHandler, ContextTypes +from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes from telegram.ext.filters import ALL from dff.messengers.common import MessengerInterface +from dff.pipeline import Pipeline from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.message import Animation, Audio, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video +from dff.script.core.context import Context +from dff.script.core.message import Animation, Audio, Button, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover @@ -41,31 +43,30 @@ def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma if update.document is not None: message.attachments += [Document(source=HttpUrl(update.document.file_id))] - message.original_message = update return message -def _create_keyboard(buttons: Sequence[Sequence[str]]) -> Optional[InlineKeyboardMarkup]: +def _create_keyboard(buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: button_list = None if len(buttons) > 0: - button_list = [[InlineKeyboardButton(button) for button in row] for row in buttons] + button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data) for button in row] for row in buttons] if button_list is None: return None else: return InlineKeyboardMarkup(button_list) -async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Message) -> None: # pragma: no cover +async def cast_message_to_telegram_and_send(bot: ExtBot, chat_id: int, message: Message) -> None: # pragma: no cover buttons = list() if message.attachments is not None: files = list() for attachment in message.attachments: if isinstance(attachment, Location): - await update.reply_location(attachment.latitude, attachment.longitude, reply_markup=_create_keyboard(buttons)) + await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Contact): - await update.reply_contact(attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=_create_keyboard(buttons)) + await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Poll): - await update.reply_poll(attachment.question, [option.text for option in attachment.options], reply_markup=_create_keyboard(buttons)) + await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=_create_keyboard(buttons)) if isinstance(attachment, Audio): attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: @@ -89,28 +90,38 @@ async def cast_message_to_telegram_and_send(update: TelegramMessage, message: Me if isinstance(attachment, Keyboard): buttons = attachment.buttons if len(files > 0): - await update.reply_media_group(files, caption=message.text) + await bot.send_media_group(chat_id, files, caption=message.text) elif message.text is not None: - await update.reply_text(message.text, reply_markup=_create_keyboard(buttons)) + await bot.send_message(chat_id, message.text, reply_markup=_create_keyboard(buttons)) -class AbstractTelegramInterface(MessengerInterface): # pragma: no cover +class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover def __init__(self, token: str) -> None: self.application = Application.builder().token(token).build() self.application.add_handler(MessageHandler(ALL, self.on_message)) + self.application.add_handler(CallbackQueryHandler(self.on_callback)) async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - if update.effective_user is not None and update.message is not None: + if update.effective_chat is not None and update.message is not None: message = extract_message_from_telegram(update.message) - resp = self.callback(message, update.effective_user.id) + message.original_message = update + resp = self.callback(message, update.effective_chat.id) if resp.last_response is not None: - await cast_message_to_telegram_and_send(update.message, resp.last_response) + await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + + async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + if update.effective_chat is not None and update.callback_query is not None: + message = Message(text=update.callback_query.data) + message.original_message = update + resp = self.callback(message, update.effective_chat.id) + if resp.last_response is not None: + await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): self.callback = callback -class PollingTelegramInterface(AbstractTelegramInterface): # pragma: no cover +class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: super().__init__(token) self.interval = interval @@ -121,7 +132,7 @@ async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): self.application.run_polling(poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES) -class CallbackTelegramInterface(AbstractTelegramInterface): # pragma: no cover +class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover def __init__(self, token: str, host: str = "localhost", port: int = 844): super().__init__(token) self.listen = host @@ -130,3 +141,15 @@ def __init__(self, token: str, host: str = "localhost", port: int = 844): async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): await super().connect(callback, *args, **kwargs) self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) + + +def telegram_condition(func: Callable[[Update], bool]): + + def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover + last_request = ctx.last_request + if last_request is None: + return False + original_message = cast(Update, last_request.original_message) + return func(original_message) + + return condition diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 5a47d80ba..034d60689 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -164,13 +164,31 @@ class Document(DataAttachment): pass -class Keyboard(DataModel): +class Button(DataModel): + """Represents a button of an inline keyboard.""" + + text: str + data: Optional[str] = None + + @field_validator("data") + @classmethod + def data_length_should_be_constrained(cls, value: Optional[str]) -> Optional[str]: + if value is None: + return value + value_size = len(value.encode("utf-8")) + if 1 >= value_size >= 64 and value: + return value + else: + raise ValueError(f"Unexpected data length: {value_size} bytes") + + +class Keyboard(Attachment): """ - This class is a DataModel that represents a keyboard object + This class is an Attachment that represents a keyboard object that can be used for a chatbot or messaging application. """ - buttons: List[List[str]] = Field(default_factory=list, min_length=1) + buttons: List[List[Button]] = Field(default_factory=list, min_length=1) def __eq__(self, other): if isinstance(other, Keyboard): diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index 6e5817fe0..a92851bc0 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -23,14 +23,9 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE -from dff.script.core.message import Button +from dff.script.core.message import Button, Keyboard, Message from dff.pipeline import Pipeline -from dff.messengers.telegram import ( - PollingTelegramInterface, - TelegramUI, - TelegramMessage, - RemoveKeyboard, -) +from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode @@ -57,7 +52,7 @@ class is used to represent telegram message, }, }, "fallback": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Finishing test, send /restart command to restart" ), TRANSITIONS: { @@ -70,40 +65,30 @@ class is used to represent telegram message, }, "general": { "native_keyboard": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Question: What's 2 + 2?", - # In this case, we use telegram-specific classes. - # They derive from the generic ones and include more options, - # e.g. simple keyboard or inline keyboard. - ui=TelegramUI( - buttons=[ - Button(text="5"), - Button(text="4"), - ], - is_inline=False, - row_width=4, - ), + attachments=[ + Keyboard( + buttons=[ + [ + Button(text="5"), + Button(text="4"), + ], + ], + ), + ] ), TRANSITIONS: { - ("general", "success"): cnd.exact_match( - TelegramMessage(text="4") - ), + ("general", "success"): cnd.exact_match(Message(text="4")), ("general", "fail"): cnd.true(), }, }, "success": { - RESPONSE: TelegramMessage( - **{"text": "Success!", "ui": RemoveKeyboard()} - ), + RESPONSE: Message(text="Success!"), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, "fail": { - RESPONSE: TelegramMessage( - **{ - "text": "Incorrect answer, type anything to try again", - "ui": RemoveKeyboard(), - } - ), + RESPONSE: Message(text="Incorrect answer, type anything to try again"), TRANSITIONS: {("general", "native_keyboard"): cnd.true()}, }, }, @@ -114,62 +99,65 @@ class is used to represent telegram message, # this variable is only for testing happy_path = ( ( - TelegramMessage(text="/start"), - TelegramMessage( + Message(text="/start"), + Message( text="Question: What's 2 + 2?", - ui=TelegramUI( - buttons=[ - Button(text="5"), - Button(text="4"), - ], - is_inline=False, - row_width=4, - ), + attachments= [ + Keyboard( + buttons=[ + [ + Button(text="5"), + Button(text="4"), + ], + ], + ), + ], ), ), ( - TelegramMessage(text="5"), - TelegramMessage( - text="Incorrect answer, type anything to try again", - ui=RemoveKeyboard(), - ), + Message(text="5"), + Message(text="Incorrect answer, type anything to try again"), ), ( - TelegramMessage(text="ok"), - TelegramMessage( + Message(text="ok"), + Message( text="Question: What's 2 + 2?", - ui=TelegramUI( - buttons=[ - Button(text="5"), - Button(text="4"), - ], - is_inline=False, - row_width=4, - ), + attachments= [ + Keyboard( + buttons=[ + [ + Button(text="5"), + Button(text="4"), + ], + ], + ), + ], ), ), ( - TelegramMessage(text="4"), - TelegramMessage(text="Success!", ui=RemoveKeyboard()), + Message(text="4"), + Message(text="Success!"), ), ( - TelegramMessage(text="Yay!"), - TelegramMessage( + Message(text="Yay!"), + Message( text="Finishing test, send /restart command to restart" ), ), ( - TelegramMessage(text="/start"), - TelegramMessage( + Message(text="/start"), + Message( text="Question: What's 2 + 2?", - ui=TelegramUI( - buttons=[ - Button(text="5"), - Button(text="4"), - ], - is_inline=False, - row_width=4, - ), + attachments= [ + Keyboard( + buttons=[ + [ + Button(text="5"), + Button(text="4"), + ], + ], + ), + ], ), ), ) diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index 10d54927f..0fdae39b3 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -25,13 +25,8 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE from dff.pipeline import Pipeline -from dff.script.core.message import Button -from dff.messengers.telegram import ( - PollingTelegramInterface, - TelegramUI, - TelegramMessage, -) -from dff.messengers.telegram.message import _ClickButton +from dff.script.core.message import Button, Keyboard, Message +from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode @@ -59,7 +54,7 @@ class is used to represent telegram message, }, }, "fallback": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Finishing test, send /restart command to restart" ), TRANSITIONS: { @@ -72,33 +67,34 @@ class is used to represent telegram message, }, "general": { "keyboard": { - RESPONSE: TelegramMessage( - **{ - "text": "Starting test! What's 9 + 10?", - "ui": TelegramUI( + RESPONSE: Message( + text="Starting test! What's 9 + 10?", + attachments=[ + Keyboard( buttons=[ - Button(text="19", payload="correct"), - Button(text="21", payload="wrong"), + [ + Button(text="19", data="correct"), + Button(text="21", data="wrong"), + ], ], - is_inline=True, ), - } + ], ), TRANSITIONS: { ("general", "success"): cnd.exact_match( - TelegramMessage(callback_query="correct") + Message(text="correct") ), ("general", "fail"): cnd.exact_match( - TelegramMessage(callback_query="wrong") + Message(text="wrong") ), }, }, "success": { - RESPONSE: TelegramMessage(text="Success!"), + RESPONSE: Message(text="Success!"), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, "fail": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Incorrect answer, type anything to try again" ), TRANSITIONS: {("general", "keyboard"): cnd.true()}, @@ -109,53 +105,65 @@ class is used to represent telegram message, # this variable is only for testing happy_path = ( ( - TelegramMessage(text="/start"), - TelegramMessage( + Message(text="/start"), + Message( text="Starting test! What's 9 + 10?", - ui=TelegramUI( - buttons=[ - Button(text="19", payload="correct"), - Button(text="21", payload="wrong"), - ], - ), + attachments=[ + Keyboard( + buttons=[ + [ + Button(text="19", data="correct"), + Button(text="21", data="wrong"), + ], + ], + ), + ], ), ), ( - TelegramMessage(callback_query=_ClickButton(button_index=1)), - TelegramMessage(text="Incorrect answer, type anything to try again"), + Message(text="wrong"), + Message(text="Incorrect answer, type anything to try again"), ), ( - TelegramMessage(text="try again"), - TelegramMessage( + Message(text="try again"), + Message( text="Starting test! What's 9 + 10?", - ui=TelegramUI( - buttons=[ - Button(text="19", payload="correct"), - Button(text="21", payload="wrong"), - ], - ), + attachments=[ + Keyboard( + buttons=[ + [ + Button(text="19", data="correct"), + Button(text="21", data="wrong"), + ], + ], + ), + ], ), ), ( - TelegramMessage(callback_query=_ClickButton(button_index=0)), - TelegramMessage(text="Success!"), + Message(text="correct"), + Message(text="Success!"), ), ( - TelegramMessage(text="Yay!"), - TelegramMessage( + Message(text="Yay!"), + Message( text="Finishing test, send /restart command to restart" ), ), ( - TelegramMessage(text="/restart"), - TelegramMessage( + Message(text="/restart"), + Message( text="Starting test! What's 9 + 10?", - ui=TelegramUI( - buttons=[ - Button(text="19", payload="correct"), - Button(text="21", payload="wrong"), - ], - ), + attachments=[ + Keyboard( + buttons=[ + [ + Button(text="19", data="correct"), + Button(text="21", data="wrong"), + ], + ], + ), + ], ), ), ) diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index d856e3056..347597202 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -17,13 +17,10 @@ from dff.script import TRANSITIONS, RESPONSE -from dff.messengers.telegram import ( - PollingTelegramInterface, - telegram_condition, - UpdateType, -) +import dff.script.conditions as cnd +from dff.messengers.telegram import PollingTelegramInterface, telegram_condition from dff.pipeline import Pipeline -from dff.messengers.telegram import TelegramMessage +from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -63,47 +60,59 @@ "greeting_flow": { "start_node": { TRANSITIONS: { - "node1": telegram_condition(commands=["start", "restart"]) + "node1": cnd.any( + [ + cnd.exact_match(Message(text="start")), + cnd.exact_match(Message(text="restart")), + ] + ) }, }, "node1": { - RESPONSE: TelegramMessage(text="Hi, how are you?"), + RESPONSE: Message(text="Hi, how are you?"), TRANSITIONS: { - "node2": telegram_condition( - update_type=UpdateType.MESSAGE, regexp="fine" - ) + "node2": cnd.regexp("fine") }, # this is the same as # TRANSITIONS: {"node2": telegram_condition(regexp="fine")}, }, "node2": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Good. What do you want to talk about?" ), TRANSITIONS: { "node3": telegram_condition( - func=lambda msg: "music" in msg.text + func=lambda upd: ( + upd.message is not None + and upd.message.text is not None + and "music" in upd.message.text + ) ) }, }, "node3": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Sorry, I can not talk about music now." ), TRANSITIONS: { - "node4": telegram_condition(update_type=UpdateType.ALL) + "node4": telegram_condition(func=lambda _: True) }, # This condition is true for any type of update }, "node4": { - RESPONSE: TelegramMessage(text="bye"), - TRANSITIONS: {"node1": telegram_condition()}, + RESPONSE: Message(text="bye"), + TRANSITIONS: {"node1": telegram_condition(func=lambda _: True)}, # This condition is true if the last update is of type `message` }, "fallback_node": { - RESPONSE: TelegramMessage(text="Ooops"), + RESPONSE: Message(text="Ooops"), TRANSITIONS: { - "node1": telegram_condition(commands=["start", "restart"]) + "node1": cnd.any( + [ + cnd.exact_match(Message(text="start")), + cnd.exact_match(Message(text="restart")), + ] + ) }, }, } @@ -111,17 +120,17 @@ # this variable is only for testing happy_path = ( - (TelegramMessage(text="/start"), TelegramMessage(text="Hi, how are you?")), + (Message(text="/start"), Message(text="Hi, how are you?")), ( - TelegramMessage(text="I'm fine"), - TelegramMessage(text="Good. What do you want to talk about?"), + Message(text="I'm fine"), + Message(text="Good. What do you want to talk about?"), ), ( - TelegramMessage(text="About music"), - TelegramMessage(text="Sorry, I can not talk about music now."), + Message(text="About music"), + Message(text="Sorry, I can not talk about music now."), ), - (TelegramMessage(text="ok"), TelegramMessage(text="bye")), - (TelegramMessage(text="bye"), TelegramMessage(text="Hi, how are you?")), + (Message(text="ok"), Message(text="bye")), + (Message(text="bye"), Message(text="Hi, how are you?")), ) diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 144ef9c32..6e39b34dc 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -17,24 +17,22 @@ # %% import os +from typing import cast -from telebot.types import Message +from pydantic import HttpUrl +from telegram import Update, Message as TelegramMessage import dff.script.conditions as cnd from dff.script import Context, TRANSITIONS, RESPONSE -from dff.script.core.message import Image, Attachments -from dff.messengers.telegram import ( - PollingTelegramInterface, - TelegramMessage, - telegram_condition, -) +from dff.script.core.message import Message, Image +from dff.messengers.telegram import PollingTelegramInterface, telegram_condition from dff.pipeline import Pipeline from dff.utils.testing.common import is_interactive_mode # %% -picture_url = "https://avatars.githubusercontent.com/u/29918795?s=200&v=4" +picture_url = HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4") # %% [markdown] @@ -53,25 +51,31 @@ "root": { "start": { TRANSITIONS: { - ("pics", "ask_picture"): telegram_condition( - commands=["start", "restart"] + ("pics", "ask_picture"): cnd.any( + [ + cnd.exact_match(Message(text="start")), + cnd.exact_match(Message(text="restart")), + ] ) }, }, "fallback": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Finishing test, send /restart command to restart" ), TRANSITIONS: { - ("pics", "ask_picture"): telegram_condition( - commands=["start", "restart"] + ("pics", "ask_picture"): cnd.any( + [ + cnd.exact_match(Message(text="start")), + cnd.exact_match(Message(text="restart")), + ] ) }, }, }, "pics": { "ask_picture": { - RESPONSE: TelegramMessage(text="Send me a picture"), + RESPONSE: Message(text="Send me a picture"), TRANSITIONS: { ("pics", "send_one"): cnd.any( [ @@ -79,36 +83,41 @@ # both in 'photo' and 'document' fields. # We should consider both cases # when we check the message for media. - telegram_condition(content_types=["photo"]), telegram_condition( - func=lambda message: ( + func=lambda update: ( + update.message is not None + and len(update.message.photo) > 0 + ) + ), + telegram_condition( + func=lambda update: ( # check attachments in message properties - message.document - and message.document.mime_type == "image/jpeg" - ), - content_types=["document"], + update.message is not None + and update.message.document is not None + and update.message.document.mime_type == "image/jpeg" + ) ), ] ), ("pics", "send_many"): telegram_condition( - content_types=["text"] + func=lambda upd: upd.message is not None and upd.message.text is not None ), ("pics", "ask_picture"): cnd.true(), }, }, "send_one": { # An HTTP path or a path to a local file can be used here. - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Here's my picture!", - attachments=Attachments(files=[Image(source=picture_url)]), + attachments=[Image(source=picture_url)], ), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, "send_many": { - RESPONSE: TelegramMessage( + RESPONSE: Message( text="Look at my pictures!", # An HTTP path or a path to a local file can be used here. - attachments=Attachments(files=[Image(source=picture_url)] * 2), + attachments=list(tuple([Image(source=picture_url)] * 2)), ), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, @@ -119,69 +128,71 @@ # testing happy_path = ( ( - TelegramMessage(text="/start"), - TelegramMessage(text="Send me a picture"), + Message(text="/start"), + Message(text="Send me a picture"), ), ( - TelegramMessage( - attachments=Attachments(files=[Image(source=picture_url)]) + Message( + attachments=[Image(source=picture_url)] ), - TelegramMessage( + Message( text="Here's my picture!", - attachments=Attachments(files=[Image(source=picture_url)]), + attachments=[Image(source=picture_url)], ), ), ( - TelegramMessage(text="ok"), - TelegramMessage( + Message(text="ok"), + Message( text="Finishing test, send /restart command to restart" ), ), ( - TelegramMessage(text="/restart"), - TelegramMessage(text="Send me a picture"), + Message(text="/restart"), + Message(text="Send me a picture"), ), ( - TelegramMessage(text="No"), - TelegramMessage( + Message(text="No"), + Message( text="Look at my pictures!", - attachments=Attachments(files=[Image(source=picture_url)] * 2), + attachments=list(tuple([Image(source=picture_url)] * 2)), ), ), ( - TelegramMessage(text="ok"), - TelegramMessage( + Message(text="ok"), + Message( text="Finishing test, send /restart command to restart" ), ), ( - TelegramMessage(text="/restart"), - TelegramMessage(text="Send me a picture"), + Message(text="/restart"), + Message(text="Send me a picture"), ), ) # %% -def extract_data(ctx: Context, _: Pipeline): # A function to extract data with +async def extract_data(ctx: Context, _: Pipeline): # A function to extract data with message = ctx.last_request if message is None: return - update = getattr(message, "update", None) - if update is None: + original_update = cast(Update, message.original_message) + if original_update is None: + return + if not isinstance(original_update, Update): + return + original_message = original_update.message + if not isinstance(original_message, TelegramMessage): return - if not isinstance(update, Message): + if original_message is None: return if ( # check attachments in update properties - not update.photo - and not (update.document and update.document.mime_type == "image/jpeg") + len(original_message.photo) > 0 + and not (original_message.document is not None and original_message.document.mime_type == "image/jpeg") ): return - photo = update.document or update.photo[-1] - file = interface.messenger.get_file(photo.file_id) - result = interface.messenger.download_file(file.file_path) - with open("photo.jpg", "wb+") as new_file: - new_file.write(result) + photo = original_message.document or original_message.photo[-1] + await (await photo.get_file()).download_to_drive("photo.jpg") return diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index c154a2ed7..cf4d22e65 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -19,13 +19,9 @@ from dff.script import TRANSITIONS, RESPONSE, GLOBAL import dff.script.conditions as cnd -from dff.messengers.telegram import ( - PollingTelegramInterface, - TelegramMessage, - telegram_condition, - UpdateType, -) +from dff.messengers.telegram import PollingTelegramInterface, telegram_condition from dff.pipeline import Pipeline +from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -67,38 +63,41 @@ [ # say hi when invited to a chat telegram_condition( - update_type=UpdateType.CHAT_JOIN_REQUEST, - func=lambda x: True, + func=lambda x: x.chat_join_request is not None, ), # say hi when someone enters the chat telegram_condition( - update_type=UpdateType.MY_CHAT_MEMBER, - func=lambda x: True, + func=lambda x: x.my_chat_member is not None, ), ] ), # send a message when inline query is received ("greeting_flow", "node2"): telegram_condition( - update_type=UpdateType.INLINE_QUERY, + func=lambda x: x.inline_query is not None, ), }, }, "greeting_flow": { "start_node": { TRANSITIONS: { - "node1": telegram_condition(commands=["start", "restart"]) + "node1": cnd.any( + [ + cnd.exact_match(Message(text="start")), + cnd.exact_match(Message(text="restart")), + ] + ) }, }, "node1": { - RESPONSE: TelegramMessage(text="Hi"), + RESPONSE: Message(text="Hi"), TRANSITIONS: {"start_node": cnd.true()}, }, "node2": { - RESPONSE: TelegramMessage(text="Inline query received."), + RESPONSE: Message(text="Inline query received."), TRANSITIONS: {"start_node": cnd.true()}, }, "fallback_node": { - RESPONSE: TelegramMessage(text="Ooops"), + RESPONSE: Message(text="Ooops"), }, }, } diff --git a/tutorials/messengers/telegram/7_polling_setup.py b/tutorials/messengers/telegram/7_polling_setup.py index d070e4728..48ceb5ede 100644 --- a/tutorials/messengers/telegram/7_polling_setup.py +++ b/tutorials/messengers/telegram/7_polling_setup.py @@ -13,12 +13,11 @@ # %% import os -from dff.messengers.telegram.interface import PollingTelegramInterface +from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline from dff.utils.testing.common import is_interactive_mode from dff.utils.testing.toy_script import TOY_SCRIPT_ARGS, HAPPY_PATH -from telebot.util import update_types # %% [markdown] @@ -37,9 +36,7 @@ interface = PollingTelegramInterface( token=os.environ["TG_BOT_TOKEN"], interval=2, - allowed_updates=update_types, timeout=30, - long_polling_timeout=30, ) diff --git a/tutorials/messengers/telegram/8_webhook_setup.py b/tutorials/messengers/telegram/8_webhook_setup.py index a7f4fd68f..f29e24620 100644 --- a/tutorials/messengers/telegram/8_webhook_setup.py +++ b/tutorials/messengers/telegram/8_webhook_setup.py @@ -14,9 +14,7 @@ # %% import os -from dff.messengers.telegram import ( - CallbackTelegramInterface, -) +from dff.messengers.telegram import CallbackTelegramInterface from dff.pipeline import Pipeline from dff.utils.testing.toy_script import TOY_SCRIPT_ARGS, HAPPY_PATH from dff.utils.testing.common import is_interactive_mode From 89fa2c781cc5629f9f9eb25015cb6e30588e77ec Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 31 Jan 2024 12:36:10 +0100 Subject: [PATCH 005/140] telegram examples debugged --- dff/messengers/telegram.py | 46 ++++--- dff/pipeline/types.py | 2 +- dff/script/core/message.py | 2 +- dff/utils/testing/telegram.py | 17 +-- tests/messengers/telegram/test_types.py | 130 ++++++++---------- tutorials/messengers/telegram/4_conditions.py | 8 +- .../telegram/5_conditions_with_media.py | 35 +---- .../telegram/6_conditions_extras.py | 18 +-- 8 files changed, 106 insertions(+), 152 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 550649987..d869139b0 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -4,12 +4,15 @@ This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` that can be used to interact with the Telegram API. """ +from pathlib import Path +from tempfile import gettempdir from typing import Callable, Optional, Sequence, cast -from pydantic import HttpUrl +from pydantic import FilePath from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes from telegram.ext.filters import ALL +from telegram._files._basemedium import _BaseMedium from dff.messengers.common import MessengerInterface from dff.pipeline import Pipeline @@ -18,7 +21,14 @@ from dff.script.core.message import Animation, Audio, Button, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video -def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover +async def _download_telegram_file(file: _BaseMedium) -> FilePath: # pragma: no cover + file_name = Path(gettempdir()) / file.file_unique_id + if not file_name.exists(): + await (await file.get_file()).download_to_drive(file_name) + return FilePath(file_name) + + +async def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover message = Message() message.attachments = list() @@ -33,23 +43,23 @@ def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma if update.poll is not None: message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] if update.audio is not None: - message.attachments += [Audio(source=HttpUrl(update.audio.file_id))] + message.attachments += [Audio(source=await _download_telegram_file(update.audio))] if update.video is not None: - message.attachments += [Video(source=HttpUrl(update.video.file_id))] + message.attachments += [Video(source=await _download_telegram_file(update.video))] if update.animation is not None: - message.attachments += [Animation(source=HttpUrl(update.animation.file_id))] + message.attachments += [Animation(source=await _download_telegram_file(update.animation))] if len(update.photo) > 0: - message.attachments += [Image(source=HttpUrl(photo.file_id)) for photo in update.photo] + message.attachments += [Image(source=await _download_telegram_file(photo)) for photo in update.photo] if update.document is not None: - message.attachments += [Document(source=HttpUrl(update.document.file_id))] + message.attachments += [Document(source=await _download_telegram_file(update.document))] return message -def _create_keyboard(buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: +def _create_keyboard(buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: # pragma: no cover button_list = None if len(buttons) > 0: - button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data) for button in row] for row in buttons] + button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data if button.data is not None else button.text) for button in row] for row in buttons] if button_list is None: return None else: @@ -63,10 +73,13 @@ async def cast_message_to_telegram_and_send(bot: ExtBot, chat_id: int, message: for attachment in message.attachments: if isinstance(attachment, Location): await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=_create_keyboard(buttons)) + return if isinstance(attachment, Contact): await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=_create_keyboard(buttons)) + return if isinstance(attachment, Poll): await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=_create_keyboard(buttons)) + return if isinstance(attachment, Audio): attachment_bytes = attachment.get_bytes() if attachment_bytes is not None: @@ -89,9 +102,10 @@ async def cast_message_to_telegram_and_send(bot: ExtBot, chat_id: int, message: files += [InputMediaDocument(attachment_bytes)] if isinstance(attachment, Keyboard): buttons = attachment.buttons - if len(files > 0): + if len(files) > 0: await bot.send_media_group(chat_id, files, caption=message.text) - elif message.text is not None: + return + if message.text is not None: await bot.send_message(chat_id, message.text, reply_markup=_create_keyboard(buttons)) @@ -103,9 +117,9 @@ def __init__(self, token: str) -> None: async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: if update.effective_chat is not None and update.message is not None: - message = extract_message_from_telegram(update.message) + message = await extract_message_from_telegram(update.message) message.original_message = update - resp = self.callback(message, update.effective_chat.id) + resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) @@ -113,7 +127,7 @@ async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> Non if update.effective_chat is not None and update.callback_query is not None: message = Message(text=update.callback_query.data) message.original_message = update - resp = self.callback(message, update.effective_chat.id) + resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) @@ -143,11 +157,11 @@ async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) -def telegram_condition(func: Callable[[Update], bool]): +def telegram_condition(func: Callable[[Update], bool]): # pragma: no cover def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover last_request = ctx.last_request - if last_request is None: + if last_request is None or last_request.original_message is None: return False original_message = cast(Update, last_request.original_message) return func(original_message) diff --git a/dff/pipeline/types.py b/dff/pipeline/types.py index ef7bef9ae..80ee9d116 100644 --- a/dff/pipeline/types.py +++ b/dff/pipeline/types.py @@ -32,7 +32,7 @@ class PipelineRunnerFunction(Protocol): def __call__( self, message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None - ) -> Context: + ) -> Awaitable[Context]: """ :param message: User request for pipeline to process. :param ctx_id: diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 034d60689..640e50eb9 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -176,7 +176,7 @@ def data_length_should_be_constrained(cls, value: Optional[str]) -> Optional[str if value is None: return value value_size = len(value.encode("utf-8")) - if 1 >= value_size >= 64 and value: + if 1 <= value_size <= 64 and value: return value else: raise ValueError(f"Unexpected data length: {value_size} bytes") diff --git a/dff/utils/testing/telegram.py b/dff/utils/testing/telegram.py index d06ba3bb6..85c6b6a7e 100644 --- a/dff/utils/testing/telegram.py +++ b/dff/utils/testing/telegram.py @@ -11,16 +11,9 @@ from pathlib import Path from copy import deepcopy -from telethon.tl.types import ReplyKeyboardHide -from telethon import TelegramClient -from telethon.types import User -from telethon.custom import Message as TlMessage -from telebot import types - from dff.pipeline.pipeline.pipeline import Pipeline -from dff.script.core.message import Message, Attachments, Attachment, Button, Location -from dff.messengers.telegram.interface import PollingTelegramInterface -from dff.messengers.telegram.message import TelegramMessage, TelegramUI, RemoveKeyboard, _ClickButton +from dff.script.core.message import Message, Attachment, Location +from dff.messengers.telegram import PollingTelegramInterface def replace_click_button(happy_path): @@ -34,12 +27,12 @@ def replace_click_button(happy_path): result = deepcopy(happy_path) for index in range(len(happy_path)): user_request = happy_path[index][0] - if not isinstance(user_request, TelegramMessage): + if not isinstance(user_request, Message): continue if isinstance(user_request.callback_query, _ClickButton): callback_query = None for _, bot_response in reversed(happy_path[:index]): - if isinstance(bot_response, TelegramMessage) and bot_response.ui is not None and callback_query is None: + if isinstance(bot_response, Message) and bot_response.ui is not None and callback_query is None: callback_query = bot_response.ui.buttons[user_request.callback_query.button_index].payload if callback_query is None: raise RuntimeError("Bot response with buttons not found.") @@ -98,7 +91,7 @@ def __init__( self.bot = bot """Bot user (to know whom to send messages to from client).""" - async def send_message(self, message: TelegramMessage, last_bot_messages: List[TlMessage]): + async def send_message(self, message: Message, last_bot_messages: List[TlMessage]): """ Send a message from client to bot. If the message contains `callback_query`, only press the button, ignore other fields. diff --git a/tests/messengers/telegram/test_types.py b/tests/messengers/telegram/test_types.py index cc50ae558..01f1b0063 100644 --- a/tests/messengers/telegram/test_types.py +++ b/tests/messengers/telegram/test_types.py @@ -5,39 +5,28 @@ import pytest try: - import telebot # noqa: F401 - import telethon # noqa: F401 + import telegram # noqa: F401 except ImportError: pytest.skip(reason="`telegram` is not available", allow_module_level=True) -from pydantic import ValidationError -from telebot import types +from pydantic import FilePath, HttpUrl, ValidationError -from dff.messengers.telegram.message import ( - TelegramMessage, - TelegramUI, - RemoveKeyboard, - ParseMode, -) from dff.script import Message -from dff.script.core.message import Attachments, Keyboard, Button, Image, Location, Audio, Video, Attachment, Document -from dff.messengers.telegram.utils import open_io, close_io, batch_open_io +from dff.script.core.message import Button, DataAttachment, Keyboard, Image, Location, Audio, Video, Attachment, Document from dff.utils.testing.telegram import TelegramTesting -image = Image( - source="https://gist.githubusercontent.com/scotthaleen/32f76a413e0dfd4b4d79c2a534d49c0b/raw" - "/6c1036b1eca90b341caf06d4056d36f64fc11e88/tiny.jpg" -) -audio = Audio(source="https://github.com/mathiasbynens/small/raw/master/mp3.mp3") -video = Video(source="https://github.com/mathiasbynens/small/raw/master/Mpeg4.mp4") -document = Document(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf") +_image_link = "https://gist.githubusercontent.com/scotthaleen/32f76a413e0dfd4b4d79c2a534d49c0b/raw/6c1036b1eca90b341caf06d4056d36f64fc11e88/tiny.jpg" +image = Image(source=HttpUrl(_image_link)) +audio = Audio(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/mp3.mp3")) +video = Video(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/Mpeg4.mp4")) +document = Document(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/pdf.pdf")) @pytest.mark.asyncio @pytest.mark.telegram async def test_text(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage(text="test") + telegram_response = Message(text="test") test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -46,48 +35,37 @@ async def test_text(pipeline_instance, api_credentials, bot_user, session_file): @pytest.mark.asyncio @pytest.mark.parametrize( - ["ui", "markup_type", "button_type"], + ["keyboard"], [ - ( - Keyboard( - buttons=[ - Button(text="button 1", payload=json.dumps({"text": "1", "other_prop": "4"})), - Button(text="button 2", payload=json.dumps({"text": "2", "other_prop": "3"})), - Button(text="button 3", payload=json.dumps({"text": "3", "other_prop": "2"})), - Button(text="button 4", payload=json.dumps({"text": "4", "other_prop": "1"})), + Keyboard( + buttons=[ + [ + Button(text="button 1", data=json.dumps({"text": "1", "other_prop": "4"})), + Button(text="button 2", data=json.dumps({"text": "2", "other_prop": "3"})), + ], + [ + Button(text="button 3", data=json.dumps({"text": "3", "other_prop": "2"})), + Button(text="button 4", data=json.dumps({"text": "4", "other_prop": "1"})), ] - ), - types.InlineKeyboardMarkup, - types.InlineKeyboardButton, + ] ), - ( - TelegramUI( - is_inline=False, - buttons=[ + Keyboard( + buttons=[ + [ Button(text="button 1"), Button(text="button 2"), + ], + [ Button(text="button 3"), Button(text="button 4"), - ], - ), - types.ReplyKeyboardMarkup, - types.KeyboardButton, + ] + ], ), ], ) @pytest.mark.telegram -async def test_buttons(ui, button_type, markup_type, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage(text="test", ui=ui) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.telegram -async def test_keyboard_remove(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage(text="test", ui=RemoveKeyboard()) +async def test_buttons(keyboard: Keyboard, pipeline_instance, api_credentials, bot_user, session_file): + telegram_response = Message(text="test", attachments=[keyboard]) test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -101,27 +79,32 @@ async def test_keyboard_remove(pipeline_instance, api_credentials, bot_user, ses ( Message( text="test", - attachments=Attachments(files=[image]), + attachments=[image], + ), + ), + ( + Message( + text="test", + attachments=[audio], ), ), ( Message( text="test", - attachments=Attachments(files=[audio]), + attachments=[video], ), ), ( Message( text="test", - attachments=Attachments(files=[video]), + attachments=[document], ), ), - (Message(text="test", attachments=Attachments(files=[document])),), ], ) @pytest.mark.telegram async def test_telegram_attachment(generic_response, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage.model_validate(generic_response) + telegram_response = Message.model_validate(generic_response) test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -135,27 +118,32 @@ async def test_telegram_attachment(generic_response, pipeline_instance, api_cred ( Message( text="test", - attachments=Attachments(files=2 * [image]), + attachments=list(tuple(2 * [image])), + ), + ), + ( + Message( + text="test", + attachments=list(tuple(2 * [audio])), ), ), ( Message( text="test", - attachments=Attachments(files=2 * [audio]), + attachments=list(tuple(2 * [video])), ), ), ( Message( text="test", - attachments=Attachments(files=2 * [video]), + attachments=list(tuple(2 * [document])), ), ), - (Message(text="test", attachments=Attachments(files=2 * [document])),), ], ) @pytest.mark.telegram async def test_attachments(attachments, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage.model_validate(attachments) + telegram_response = Message.model_validate(attachments) test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -165,7 +153,7 @@ async def test_attachments(attachments, pipeline_instance, api_credentials, bot_ @pytest.mark.asyncio @pytest.mark.telegram async def test_location(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage(text="location", location=Location(longitude=39.0, latitude=43.0)) + telegram_response = Message(text="location", attachments=[Location(longitude=39.0, latitude=43.0)]) test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -175,7 +163,7 @@ async def test_location(pipeline_instance, api_credentials, bot_user, session_fi @pytest.mark.asyncio @pytest.mark.telegram async def test_parsed_text(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = TelegramMessage(text="[inline URL](http://www.example.com/)", parse_mode=ParseMode.MARKDOWN) + telegram_response = Message(text="[inline URL](http://www.example.com/)", parse_mode=ParseMode.MARKDOWN) test_helper = TelegramTesting( pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user ) @@ -184,29 +172,23 @@ async def test_parsed_text(pipeline_instance, api_credentials, bot_user, session def test_missing_error(): with pytest.raises(ValidationError) as e: - _ = Attachment(source="http://google.com", id="123") + _ = DataAttachment(source=HttpUrl("http://google.com"), id="123") assert e with pytest.raises(ValidationError) as e: - _ = Attachment(source="/etc/missing_file") - assert e - - -def test_attachment_error(): - with pytest.raises(ValidationError) as e: - _ = Attachments(files=["a", "b"]) + _ = DataAttachment(source=FilePath("/etc/missing_file")) assert e def test_empty_keyboard(): with pytest.raises(ValidationError) as e: - _ = TelegramUI(buttons=[]) + _ = Keyboard(buttons=[]) assert e -def test_non_inline_keyboard_with_payload(): +def test_long_button_data(): with pytest.raises(ValidationError) as error: - TelegramUI(buttons=[Button(text="", payload="")], is_inline=False) + Button(text="", data="test" * 64) assert error diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index 347597202..f32f791dd 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -62,8 +62,8 @@ TRANSITIONS: { "node1": cnd.any( [ - cnd.exact_match(Message(text="start")), - cnd.exact_match(Message(text="restart")), + cnd.exact_match(Message(text="/start")), + cnd.exact_match(Message(text="/restart")), ] ) }, @@ -109,8 +109,8 @@ TRANSITIONS: { "node1": cnd.any( [ - cnd.exact_match(Message(text="start")), - cnd.exact_match(Message(text="restart")), + cnd.exact_match(Message(text="/start")), + cnd.exact_match(Message(text="/restart")), ] ) }, diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 6e39b34dc..b39dbd84a 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -53,8 +53,8 @@ TRANSITIONS: { ("pics", "ask_picture"): cnd.any( [ - cnd.exact_match(Message(text="start")), - cnd.exact_match(Message(text="restart")), + cnd.exact_match(Message(text="/start")), + cnd.exact_match(Message(text="/restart")), ] ) }, @@ -66,8 +66,8 @@ TRANSITIONS: { ("pics", "ask_picture"): cnd.any( [ - cnd.exact_match(Message(text="start")), - cnd.exact_match(Message(text="restart")), + cnd.exact_match(Message(text="/start")), + cnd.exact_match(Message(text="/restart")), ] ) }, @@ -170,39 +170,12 @@ ) -# %% -async def extract_data(ctx: Context, _: Pipeline): # A function to extract data with - message = ctx.last_request - if message is None: - return - original_update = cast(Update, message.original_message) - if original_update is None: - return - if not isinstance(original_update, Update): - return - original_message = original_update.message - if not isinstance(original_message, TelegramMessage): - return - if original_message is None: - return - if ( - # check attachments in update properties - len(original_message.photo) > 0 - and not (original_message.document is not None and original_message.document.mime_type == "image/jpeg") - ): - return - photo = original_message.document or original_message.photo[-1] - await (await photo.get_file()).download_to_drive("photo.jpg") - return - - # %% pipeline = Pipeline.from_script( script=script, start_label=("root", "start"), fallback_label=("root", "fallback"), messenger_interface=interface, - pre_services=[extract_data], ) diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index cf4d22e65..ea2b8da15 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -59,17 +59,9 @@ script = { GLOBAL: { TRANSITIONS: { - ("greeting_flow", "node1"): cnd.any( - [ - # say hi when invited to a chat - telegram_condition( - func=lambda x: x.chat_join_request is not None, - ), - # say hi when someone enters the chat - telegram_condition( - func=lambda x: x.my_chat_member is not None, - ), - ] + # say hi when someone enters the chat + ("greeting_flow", "node1"): telegram_condition( + func=lambda x: x.message is not None and x.message.new_chat_members is not None, ), # send a message when inline query is received ("greeting_flow", "node2"): telegram_condition( @@ -82,8 +74,8 @@ TRANSITIONS: { "node1": cnd.any( [ - cnd.exact_match(Message(text="start")), - cnd.exact_match(Message(text="restart")), + cnd.exact_match(Message(text="/start")), + cnd.exact_match(Message(text="/restart")), ] ) }, From 3745cff8208ccae2afaf0d18b57c6459f0afeceb Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 31 Jan 2024 16:02:21 +0100 Subject: [PATCH 006/140] optional attachment processing added --- dff/messengers/telegram.py | 202 +++++++++--------- .../telegram/5_conditions_with_media.py | 2 +- 2 files changed, 105 insertions(+), 99 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index d869139b0..f8d48e68c 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -6,7 +6,7 @@ """ from pathlib import Path from tempfile import gettempdir -from typing import Callable, Optional, Sequence, cast +from typing import Callable, Optional, Sequence, Type, cast from pydantic import FilePath from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage @@ -18,110 +18,116 @@ from dff.pipeline import Pipeline from dff.pipeline.types import PipelineRunnerFunction from dff.script.core.context import Context -from dff.script.core.message import Animation, Audio, Button, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video - - -async def _download_telegram_file(file: _BaseMedium) -> FilePath: # pragma: no cover - file_name = Path(gettempdir()) / file.file_unique_id - if not file_name.exists(): - await (await file.get_file()).download_to_drive(file_name) - return FilePath(file_name) - - -async def extract_message_from_telegram(update: TelegramMessage) -> Message: # pragma: no cover - message = Message() - message.attachments = list() - - if update.text is not None: - message.text = update.text - if update.location is not None: - message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] - if update.contact is not None: - message.attachments += [Contact(phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name)] - if update.invoice is not None: - message.attachments += [Invoice(title=update.invoice.title, description=update.invoice.description, currency=update.invoice.currency, amount=update.invoice.total_amount)] - if update.poll is not None: - message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] - if update.audio is not None: - message.attachments += [Audio(source=await _download_telegram_file(update.audio))] - if update.video is not None: - message.attachments += [Video(source=await _download_telegram_file(update.video))] - if update.animation is not None: - message.attachments += [Animation(source=await _download_telegram_file(update.animation))] - if len(update.photo) > 0: - message.attachments += [Image(source=await _download_telegram_file(photo)) for photo in update.photo] - if update.document is not None: - message.attachments += [Document(source=await _download_telegram_file(update.document))] - - return message - - -def _create_keyboard(buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: # pragma: no cover - button_list = None - if len(buttons) > 0: - button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data if button.data is not None else button.text) for button in row] for row in buttons] - if button_list is None: - return None - else: - return InlineKeyboardMarkup(button_list) - - -async def cast_message_to_telegram_and_send(bot: ExtBot, chat_id: int, message: Message) -> None: # pragma: no cover - buttons = list() - if message.attachments is not None: - files = list() - for attachment in message.attachments: - if isinstance(attachment, Location): - await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=_create_keyboard(buttons)) - return - if isinstance(attachment, Contact): - await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=_create_keyboard(buttons)) - return - if isinstance(attachment, Poll): - await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=_create_keyboard(buttons)) - return - if isinstance(attachment, Audio): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - files += [InputMediaAudio(attachment_bytes)] - if isinstance(attachment, Video): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - files += [InputMediaVideo(attachment_bytes)] - if isinstance(attachment, Animation): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - files += [InputMediaAnimation(attachment_bytes)] - if isinstance(attachment, Image): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - files += [InputMediaPhoto(attachment_bytes)] - if isinstance(attachment, Document): - attachment_bytes = attachment.get_bytes() - if attachment_bytes is not None: - files += [InputMediaDocument(attachment_bytes)] - if isinstance(attachment, Keyboard): - buttons = attachment.buttons - if len(files) > 0: - await bot.send_media_group(chat_id, files, caption=message.text) - return - if message.text is not None: - await bot.send_message(chat_id, message.text, reply_markup=_create_keyboard(buttons)) +from dff.script.core.message import Animation, Audio, Button, Contact, DataAttachment, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - def __init__(self, token: str) -> None: + def __init__(self, token: str, download_all_attachments: bool) -> None: self.application = Application.builder().token(token).build() self.application.add_handler(MessageHandler(ALL, self.on_message)) self.application.add_handler(CallbackQueryHandler(self.on_callback)) + self.download_all = download_all_attachments + + async def download_telegram_file(self, file: DataAttachment) -> Optional[FilePath]: # pragma: no cover + if file.title is not None and file.id is not None: + file_name = Path(gettempdir()) / str(file.title) + if not file_name.exists(): + await (await self.application.bot.get_file(file.id)).download_to_drive(file_name) + return FilePath(file_name) + else: + return None + + async def _process_attachment(self, attachment: _BaseMedium, download: bool, cls: Type[DataAttachment]) -> DataAttachment: # pragma: no cover + data_attachment = cls(id=attachment.file_id, title=attachment.file_unique_id) + if download: + data_attachment.source = await self.download_telegram_file(data_attachment) + return data_attachment + + async def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover + message = Message() + message.attachments = list() + + if update.text is not None: + message.text = update.text + if update.location is not None: + message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] + if update.contact is not None: + message.attachments += [Contact(phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name)] + if update.invoice is not None: + message.attachments += [Invoice(title=update.invoice.title, description=update.invoice.description, currency=update.invoice.currency, amount=update.invoice.total_amount)] + if update.poll is not None: + message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] + if update.audio is not None: + message.attachments += [await self._process_attachment(update.audio, self.download_all, Audio)] + if update.video is not None: + message.attachments += [await self._process_attachment(update.video, self.download_all, Video)] + if update.animation is not None: + message.attachments += [await self._process_attachment(update.animation, self.download_all, Animation)] + if len(update.photo) > 0: + message.attachments += [await self._process_attachment(picture, self.download_all, Image) for picture in update.photo] + if update.document is not None: + message.attachments += [await self._process_attachment(update.document, self.download_all, Document)] + + return message + + def _create_keyboard(self, buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: # pragma: no cover + button_list = None + if len(buttons) > 0: + button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data if button.data is not None else button.text) for button in row] for row in buttons] + if button_list is None: + return None + else: + return InlineKeyboardMarkup(button_list) + + async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, message: Message) -> None: # pragma: no cover + buttons = list() + if message.attachments is not None: + files = list() + for attachment in message.attachments: + if isinstance(attachment, Location): + await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons)) + return + if isinstance(attachment, Contact): + await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=self._create_keyboard(buttons)) + return + if isinstance(attachment, Poll): + await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=self._create_keyboard(buttons)) + return + if isinstance(attachment, Audio): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaAudio(attachment_bytes)] + if isinstance(attachment, Video): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaVideo(attachment_bytes)] + if isinstance(attachment, Animation): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaAnimation(attachment_bytes)] + if isinstance(attachment, Image): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaPhoto(attachment_bytes)] + if isinstance(attachment, Document): + attachment_bytes = attachment.get_bytes() + if attachment_bytes is not None: + files += [InputMediaDocument(attachment_bytes)] + if isinstance(attachment, Keyboard): + buttons = attachment.buttons + if len(files) > 0: + await bot.send_media_group(chat_id, files, caption=message.text) + return + if message.text is not None: + await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: if update.effective_chat is not None and update.message is not None: - message = await extract_message_from_telegram(update.message) + message = await self.extract_message_from_telegram(update.message) message.original_message = update resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: - await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + await self.cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: if update.effective_chat is not None and update.callback_query is not None: @@ -129,15 +135,15 @@ async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> Non message.original_message = update resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: - await cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + await self.cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): self.callback = callback class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: - super().__init__(token) + def __init__(self, token: str, download_all_attachments: bool = False, interval: int = 2, timeout: int = 20) -> None: + super().__init__(token, download_all_attachments) self.interval = interval self.timeout = timeout @@ -147,8 +153,8 @@ async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, host: str = "localhost", port: int = 844): - super().__init__(token) + def __init__(self, token: str, download_all_attachments: bool = False, host: str = "localhost", port: int = 844): + super().__init__(token, download_all_attachments) self.listen = host self.port = port diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index b39dbd84a..08357dddc 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -43,7 +43,7 @@ # %% -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) +interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"], download_all_attachments=True) # %% From 18ddd2c6089ec342fe93efc10df053ac7fe40861 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 Date: Thu, 1 Feb 2024 11:29:28 +0300 Subject: [PATCH 007/140] Started implementing VK interface --- dff/messengers/vk.py | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 dff/messengers/vk.py diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py new file mode 100644 index 000000000..dd878dd06 --- /dev/null +++ b/dff/messengers/vk.py @@ -0,0 +1,79 @@ +""" +Interface +------------ +This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` +that can be used to interact with the Telegram API. +""" +from typing import Callable, Optional, Sequence, cast +from pydantic import HttpUrl + +from pyvkbot import Bot +import requests + +from dff.messengers.common import MessengerInterface +from dff.pipeline import Pipeline +from dff.pipeline.types import PipelineRunnerFunction +from dff.script.core.context import Context +from dff.script.core.message import Animation, Audio, Button, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video + + +def extract_message_from_vk(message_vk: dict[str, str]) -> Message: + message = Message() + message.attachments = list() + + if message_vk["text"] is not None: + message.text = message_vk["text"] + + if message_vk["attachments"] is not []: + for element in message_vk["attachments"]: + match element["type"]: + case "photo": + message.attachments += [Image(source=HttpUrl(element[element["type"]]['sizes'][-1]['url']))] + case "video": + pass + case "audio": + pass + case "doc": + pass + case "link": + pass + case _: + pass + + return message + +def _create_keyboard(buttons: Sequence[Sequence[Button]]): + pass + + +async def cast_message_to_vk_and_send(bot: Bot, chat_id: int, message: Message) -> None: + pass + + +class _AbstractVKInterface(MessengerInterface): + def __init__(self, token: str, group_id: str) -> None: + self.bot = Bot(token=token, group_id=group_id) + self.bot.on('message', self.on_message) + + async def on_message(self, bot: Bot, message: dict[str, str]) -> None: + pass + + +class PollingVKInterface(_AbstractVKInterface): + pass + + +if __name__=="__main__": + KEY = "" + GROUP_ID = "" + + bot = Bot(token=KEY, group_id=GROUP_ID) + + def echo(bot: Bot, message: dict[str, str]): + for element in message["attachments"]: + print(element[element["type"]]) + bot.send_message(peer_id=message["peer_id"], text="thx") + + bot.on('message', echo) + + bot.start_polling(lambda: print("Bot started")) \ No newline at end of file From 26dc2d63d4ff7a31a80a37f6172bc53618d2acca Mon Sep 17 00:00:00 2001 From: pseusys Date: Sun, 4 Feb 2024 20:42:19 +0100 Subject: [PATCH 008/140] download all removed, special downloading method created --- dff/messengers/common/interface.py | 5 ++ dff/messengers/telegram.py | 49 ++++++++----------- dff/script/core/message.py | 15 +++--- .../telegram/5_conditions_with_media.py | 2 +- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 13747b06c..67d11cb1c 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -13,6 +13,7 @@ from dff.script import Context, Message from dff.messengers.common.types import PollingInterfaceLoopFunction +from dff.script.core.message import DataAttachment if TYPE_CHECKING: from dff.pipeline.types import PipelineRunnerFunction @@ -37,6 +38,10 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction): """ raise NotImplementedError + @abc.abstractmethod + async def populate_attachment(self, attachment: DataAttachment) -> None: + raise NotImplementedError + class PollingMessengerInterface(MessengerInterface): """ diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index f8d48e68c..5970eeef1 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -22,26 +22,19 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - def __init__(self, token: str, download_all_attachments: bool) -> None: + def __init__(self, token: str) -> None: self.application = Application.builder().token(token).build() self.application.add_handler(MessageHandler(ALL, self.on_message)) self.application.add_handler(CallbackQueryHandler(self.on_callback)) - self.download_all = download_all_attachments - async def download_telegram_file(self, file: DataAttachment) -> Optional[FilePath]: # pragma: no cover - if file.title is not None and file.id is not None: - file_name = Path(gettempdir()) / str(file.title) + async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover + if attachment.title is not None and attachment.id is not None: + file_name = Path(gettempdir()) / str(attachment.title) if not file_name.exists(): - await (await self.application.bot.get_file(file.id)).download_to_drive(file_name) - return FilePath(file_name) + await (await self.application.bot.get_file(attachment.id)).download_to_drive(file_name) + attachment.source = FilePath(file_name) else: - return None - - async def _process_attachment(self, attachment: _BaseMedium, download: bool, cls: Type[DataAttachment]) -> DataAttachment: # pragma: no cover - data_attachment = cls(id=attachment.file_id, title=attachment.file_unique_id) - if download: - data_attachment.source = await self.download_telegram_file(data_attachment) - return data_attachment + raise ValueError(f"For attachment {attachment} title or id is not defined!") async def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover message = Message() @@ -58,15 +51,15 @@ async def extract_message_from_telegram(self, update: TelegramMessage) -> Messag if update.poll is not None: message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] if update.audio is not None: - message.attachments += [await self._process_attachment(update.audio, self.download_all, Audio)] + message.attachments += [Audio(id=update.audio.file_id, title=update.audio.file_unique_id)] if update.video is not None: - message.attachments += [await self._process_attachment(update.video, self.download_all, Video)] + message.attachments += [Video(id=update.video.file_id, title=update.video.file_unique_id)] if update.animation is not None: - message.attachments += [await self._process_attachment(update.animation, self.download_all, Animation)] + message.attachments += [Animation(id=update.animation.file_id, title=update.animation.file_unique_id)] if len(update.photo) > 0: - message.attachments += [await self._process_attachment(picture, self.download_all, Image) for picture in update.photo] + message.attachments += [Image(id=picture.file_id, title=picture.file_unique_id) for picture in update.photo] if update.document is not None: - message.attachments += [await self._process_attachment(update.document, self.download_all, Document)] + message.attachments += [Document(id=update.document.file_id, title=update.document.file_unique_id)] return message @@ -94,23 +87,23 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=self._create_keyboard(buttons)) return if isinstance(attachment, Audio): - attachment_bytes = attachment.get_bytes() + attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaAudio(attachment_bytes)] if isinstance(attachment, Video): - attachment_bytes = attachment.get_bytes() + attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaVideo(attachment_bytes)] if isinstance(attachment, Animation): - attachment_bytes = attachment.get_bytes() + attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaAnimation(attachment_bytes)] if isinstance(attachment, Image): - attachment_bytes = attachment.get_bytes() + attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaPhoto(attachment_bytes)] if isinstance(attachment, Document): - attachment_bytes = attachment.get_bytes() + attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaDocument(attachment_bytes)] if isinstance(attachment, Keyboard): @@ -142,8 +135,8 @@ async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, download_all_attachments: bool = False, interval: int = 2, timeout: int = 20) -> None: - super().__init__(token, download_all_attachments) + def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: + super().__init__(token) self.interval = interval self.timeout = timeout @@ -153,8 +146,8 @@ async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, download_all_attachments: bool = False, host: str = "localhost", port: int = 844): - super().__init__(token, download_all_attachments) + def __init__(self, token: str, host: str = "localhost", port: int = 844): + super().__init__(token) self.listen = host self.port = port diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 640e50eb9..2181c3cb7 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -11,6 +11,8 @@ from pydantic import field_validator, Field, FilePath, HttpUrl, BaseModel, model_validator +from dff.messengers.common.interface import MessengerInterface + class Session(Enum): """ @@ -98,23 +100,24 @@ class DataAttachment(Attachment): id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None - def get_bytes(self) -> Optional[bytes]: + async def get_bytes(self, interface: MessengerInterface) -> Optional[bytes]: if self.source is None: - return None + await interface.populate_attachment(self) if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() - else: + elif isinstance(self.source, HttpUrl): with urlopen(self.source.unicode_string()) as file: return file.read() + else: + return None def __eq__(self, other): if isinstance(other, DataAttachment): - if self.title != other.title: - return False if self.id != other.id: return False - return self.get_bytes() == other.get_bytes() + if self.title != other.title: + return False return NotImplemented @model_validator(mode="before") diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 08357dddc..b39dbd84a 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -43,7 +43,7 @@ # %% -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"], download_all_attachments=True) +interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) # %% From 57f418ef46f167bad181dd2964d659f1259cd74d Mon Sep 17 00:00:00 2001 From: NotBioWaste905 Date: Mon, 5 Feb 2024 14:19:40 +0300 Subject: [PATCH 009/140] Attempts to implement asyncronous vk API usage --- bot_test.py | 29 +++++++++++ dff/messengers/vk.py | 112 ++++++++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 55 deletions(-) create mode 100644 bot_test.py diff --git a/bot_test.py b/bot_test.py new file mode 100644 index 000000000..6b0fa3613 --- /dev/null +++ b/bot_test.py @@ -0,0 +1,29 @@ +import asyncio +from dff.messengers import vk +from dff.pipeline import Pipeline + +from dff.utils.testing import ( + check_happy_path, + is_interactive_mode, + HAPPY_PATH, + TOY_SCRIPT, + TOY_SCRIPT_ARGS, +) + +KEY = "vk1.a.BwQyndaC87dkYdmZQt9TCGuRx5VRh1_ZyvGy5Twxl35-u8euOrjHPU4YNh7Re7C-S8Am8zRyuexBatnFLksrfzCPG3kYXNmQ0Gm2Wld1Cx3b8VPAnW0M0agaDDboDBm5iYZdMJutpTqAqCyWlAaZPdEcKLdgSyqRSLO2cLac7MwTtOzN4jTtd8WJUoHOd3Ts0Af_KyefrG-NEzP9BbMHYA" +GROUP_ID = "224377718" + +interface = vk.PollingVKInterface(KEY, GROUP_ID) + +pipeline = Pipeline.from_script( + *TOY_SCRIPT_ARGS, + messenger_interface=interface, + # The interface can be passed as a pipeline argument. +) + +async def main(): + await interface.connect(pipeline) + +if __name__ == "__main__": + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) \ No newline at end of file diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index dd878dd06..fadfbbfce 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -6,74 +6,76 @@ """ from typing import Callable, Optional, Sequence, cast from pydantic import HttpUrl +import asyncio -from pyvkbot import Bot +# from vkbottle import API +from vkwave.bots import SimpleLongPollBot, SimpleBotEvent import requests from dff.messengers.common import MessengerInterface from dff.pipeline import Pipeline -from dff.pipeline.types import PipelineRunnerFunction +# from dff.pipeline.types import PipelineRunnerFunction from dff.script.core.context import Context -from dff.script.core.message import Animation, Audio, Button, Contact, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video +from dff.script.core.message import Audio, Button, Document, Image, Keyboard, Location, Message, Video -def extract_message_from_vk(message_vk: dict[str, str]) -> Message: - message = Message() - message.attachments = list() - - if message_vk["text"] is not None: - message.text = message_vk["text"] - - if message_vk["attachments"] is not []: - for element in message_vk["attachments"]: - match element["type"]: - case "photo": - message.attachments += [Image(source=HttpUrl(element[element["type"]]['sizes'][-1]['url']))] - case "video": - pass - case "audio": - pass - case "doc": - pass - case "link": - pass - case _: - pass - - return message - def _create_keyboard(buttons: Sequence[Sequence[Button]]): pass - -async def cast_message_to_vk_and_send(bot: Bot, chat_id: int, message: Message) -> None: - pass - - class _AbstractVKInterface(MessengerInterface): def __init__(self, token: str, group_id: str) -> None: - self.bot = Bot(token=token, group_id=group_id) - self.bot.on('message', self.on_message) - - async def on_message(self, bot: Bot, message: dict[str, str]) -> None: - pass - + self.bot = SimpleLongPollBot(tokens=token, group_id=group_id) + self.bot.message_handler()(self.on_message) + + + def extract_message_from_vk(self, message_vk) -> Message: + message = Message() + message.attachments = list() + + if message_vk.object.object.message.text is not None: + message.text = message_vk.object.object.message.text + + if message_vk.attachments is not []: + for element in message_vk["attachments"]: + match element["type"]: + case "photo": + message.attachments += [Image(source=HttpUrl(element[element["type"]]['sizes'][-1]['url']))] + case "video": + pass + case "audio": + pass + case "doc": + pass + case "link": + pass + case _: + pass + + return message + + + async def cast_message_to_vk_and_send(self, bot: SimpleLongPollBot, orig_message, message: Message) -> None: + if message.attachments is not None: + pass + if message.text is not None: + await orig_message.answer(message=message.text) + + + async def on_message(self, event: SimpleBotEvent) -> None: + message = await self.extract_message_from_vk(event) + message.original_message = event + resp = await self.callback(message, event.object.object.message.peer_id) + if resp.last_response is not None: + await self.cast_message_to_vk_and_send(self.bot, event, resp.last_response) + + + async def connect(self, callback, *args, **kwargs): + self.callback = callback class PollingVKInterface(_AbstractVKInterface): - pass - - -if __name__=="__main__": - KEY = "" - GROUP_ID = "" - - bot = Bot(token=KEY, group_id=GROUP_ID) - - def echo(bot: Bot, message: dict[str, str]): - for element in message["attachments"]: - print(element[element["type"]]) - bot.send_message(peer_id=message["peer_id"], text="thx") - - bot.on('message', echo) + def __init__(self, token: str) -> None: + super().__init__(token) - bot.start_polling(lambda: print("Bot started")) \ No newline at end of file + async def connect(self, callback, *args, **kwargs): + await super().connect(callback, *args, **kwargs) + self.bot.run_forever() From bf1a81a1cb45ec957101e0acefebfce1cef09041 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 Date: Tue, 6 Feb 2024 00:53:09 +0300 Subject: [PATCH 010/140] Added attachment management, started implementing keyboard --- dff/messengers/vk.py | 56 +++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index fadfbbfce..e6ade1158 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -6,10 +6,9 @@ """ from typing import Callable, Optional, Sequence, cast from pydantic import HttpUrl -import asyncio +# import asyncio -# from vkbottle import API -from vkwave.bots import SimpleLongPollBot, SimpleBotEvent +from pyvkbot import Bot import requests from dff.messengers.common import MessengerInterface @@ -19,23 +18,25 @@ from dff.script.core.message import Audio, Button, Document, Image, Keyboard, Location, Message, Video -def _create_keyboard(buttons: Sequence[Sequence[Button]]): - pass + class _AbstractVKInterface(MessengerInterface): def __init__(self, token: str, group_id: str) -> None: - self.bot = SimpleLongPollBot(tokens=token, group_id=group_id) - self.bot.message_handler()(self.on_message) + self.bot = Bot(token=token, group_id=group_id) + self.bot.on('message', self.on_message) + def _create_keyboard(self, buttons: Sequence[Sequence[Button]]): + keyboard = Keyboard(inline=False) + keyboard.add_button(label="123") - def extract_message_from_vk(self, message_vk) -> Message: + def extract_message_from_vk(self, message_vk: dict[str, str]) -> Message: message = Message() message.attachments = list() - if message_vk.object.object.message.text is not None: - message.text = message_vk.object.object.message.text - - if message_vk.attachments is not []: + if message_vk["text"] is not None: + message.text = message_vk["text"] + + if message_vk["attachments"] is not []: for element in message_vk["attachments"]: match element["type"]: case "photo": @@ -43,39 +44,40 @@ def extract_message_from_vk(self, message_vk) -> Message: case "video": pass case "audio": - pass + message.attachments += [Audio(source=HttpUrl(element[element["type"]]['url']))] case "doc": - pass + message.attachments += [Document(source=HttpUrl(element[element["type"]]['url']))] case "link": - pass + message.text = element[element["type"]]['url'] case _: pass return message - async def cast_message_to_vk_and_send(self, bot: SimpleLongPollBot, orig_message, message: Message) -> None: + def cast_message_to_vk_and_send(self, bot, orig_message, message: Message) -> None: if message.attachments is not None: pass if message.text is not None: - await orig_message.answer(message=message.text) + bot.send_message(peer_id=orig_message["peer_id"], text=message.text) - async def on_message(self, event: SimpleBotEvent) -> None: - message = await self.extract_message_from_vk(event) + def on_message(self, _, event) -> None: + message = self.extract_message_from_vk(event) message.original_message = event - resp = await self.callback(message, event.object.object.message.peer_id) + resp = self.callback(message, event["peer_id"]) if resp.last_response is not None: - await self.cast_message_to_vk_and_send(self.bot, event, resp.last_response) + self.cast_message_to_vk_and_send(self.bot, event, resp.last_response) - async def connect(self, callback, *args, **kwargs): + def connect(self, callback, *args, **kwargs): self.callback = callback + class PollingVKInterface(_AbstractVKInterface): - def __init__(self, token: str) -> None: - super().__init__(token) + def __init__(self, token: str, group_id: str) -> None: + super().__init__(token, group_id) - async def connect(self, callback, *args, **kwargs): - await super().connect(callback, *args, **kwargs) - self.bot.run_forever() + def connect(self, callback, *args, **kwargs): + super().connect(callback, *args, **kwargs) + self.bot.start_polling(lambda: print("Bot started")) From 7e65068070e20bf0203e8f02c785ca2de1467135 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 7 Feb 2024 21:41:13 +0100 Subject: [PATCH 011/140] callback query added as an attachment --- dff/messengers/telegram.py | 33 ++++++++++++------- dff/script/core/message.py | 5 +++ tutorials/messengers/telegram/2_buttons.py | 6 ++-- .../telegram/3_buttons_with_callback.py | 12 +++---- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 5970eeef1..e09163cf2 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -6,19 +6,18 @@ """ from pathlib import Path from tempfile import gettempdir -from typing import Callable, Optional, Sequence, Type, cast +from typing import Callable, Optional, Sequence, cast from pydantic import FilePath from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes from telegram.ext.filters import ALL -from telegram._files._basemedium import _BaseMedium from dff.messengers.common import MessengerInterface from dff.pipeline import Pipeline from dff.pipeline.types import PipelineRunnerFunction from dff.script.core.context import Context -from dff.script.core.message import Animation, Audio, Button, Contact, DataAttachment, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video +from dff.script.core.message import Animation, Audio, Button, CallbackQuery, Contact, DataAttachment, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover @@ -114,21 +113,19 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if message.text is not None: await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) - async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + async def _on_event(self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message]) -> None: if update.effective_chat is not None and update.message is not None: - message = await self.extract_message_from_telegram(update.message) + message = create_message(update) message.original_message = update resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: await self.cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + await self._on_event(update, _, lambda u: await self.extract_message_from_telegram(u.message)) + async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - if update.effective_chat is not None and update.callback_query is not None: - message = Message(text=update.callback_query.data) - message.original_message = update - resp = await self.callback(message, update.effective_chat.id) - if resp.last_response is not None: - await self.cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + await self._on_event(update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)])) async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): self.callback = callback @@ -166,3 +163,17 @@ def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover return func(original_message) return condition + + +def query_callback_condition_exact_match(expected: CallbackQuery): + + def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover + last_request = ctx.last_request + if last_request is None or last_request.attachments is None or len(last_request.attachments) == 0: + return False + callback_query = next((attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None) + if callback_query is None: + return False + return callback_query == expected + + return condition diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 2181c3cb7..780b1daf5 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -45,6 +45,11 @@ class Attachment(DataModel): pass +class CallbackQuery(Attachment): + + query_string: Optional[str] + + class Location(Attachment): """ This class is a data model that represents a geographical diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index a92851bc0..7951bbe11 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -23,9 +23,9 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE -from dff.script.core.message import Button, Keyboard, Message +from dff.script.core.message import Button, Keyboard, Message, CallbackQuery from dff.pipeline import Pipeline -from dff.messengers.telegram import PollingTelegramInterface +from dff.messengers.telegram import PollingTelegramInterface, query_callback_condition_exact_match from dff.utils.testing.common import is_interactive_mode @@ -79,7 +79,7 @@ class is used to represent telegram message, ] ), TRANSITIONS: { - ("general", "success"): cnd.exact_match(Message(text="4")), + ("general", "success"): query_callback_condition_exact_match(CallbackQuery(query_string="4")), ("general", "fail"): cnd.true(), }, }, diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index 0fdae39b3..a05f02581 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -25,8 +25,8 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE from dff.pipeline import Pipeline -from dff.script.core.message import Button, Keyboard, Message -from dff.messengers.telegram import PollingTelegramInterface +from dff.script.core.message import Button, Keyboard, Message, CallbackQuery +from dff.messengers.telegram import PollingTelegramInterface, query_callback_condition_exact_match from dff.utils.testing.common import is_interactive_mode @@ -81,11 +81,11 @@ class is used to represent telegram message, ], ), TRANSITIONS: { - ("general", "success"): cnd.exact_match( - Message(text="correct") + ("general", "success"): query_callback_condition_exact_match( + CallbackQuery(query_string="correct") ), - ("general", "fail"): cnd.exact_match( - Message(text="wrong") + ("general", "fail"): query_callback_condition_exact_match( + CallbackQuery(query_string="wrong") ), }, }, From efece761dd92de6b37b3b8d6ec819cef7bf2d3be Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 7 Feb 2024 21:56:23 +0100 Subject: [PATCH 012/140] callback query conditions added --- dff/messengers/telegram.py | 4 ++-- tutorials/messengers/telegram/2_buttons.py | 4 ++-- .../messengers/telegram/3_buttons_with_callback.py | 10 +++------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index e09163cf2..60e68339d 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -165,7 +165,7 @@ def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover return condition -def query_callback_condition_exact_match(expected: CallbackQuery): +def has_callback_query(expected: str): def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover last_request = ctx.last_request @@ -174,6 +174,6 @@ def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cove callback_query = next((attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None) if callback_query is None: return False - return callback_query == expected + return callback_query.query_string == expected return condition diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index 7951bbe11..431877ba4 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -25,7 +25,7 @@ class is used to represent telegram message, from dff.script import TRANSITIONS, RESPONSE from dff.script.core.message import Button, Keyboard, Message, CallbackQuery from dff.pipeline import Pipeline -from dff.messengers.telegram import PollingTelegramInterface, query_callback_condition_exact_match +from dff.messengers.telegram import PollingTelegramInterface, has_callback_query from dff.utils.testing.common import is_interactive_mode @@ -79,7 +79,7 @@ class is used to represent telegram message, ] ), TRANSITIONS: { - ("general", "success"): query_callback_condition_exact_match(CallbackQuery(query_string="4")), + ("general", "success"): has_callback_query("4"), ("general", "fail"): cnd.true(), }, }, diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index a05f02581..0abe31d15 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -26,7 +26,7 @@ class is used to represent telegram message, from dff.script import TRANSITIONS, RESPONSE from dff.pipeline import Pipeline from dff.script.core.message import Button, Keyboard, Message, CallbackQuery -from dff.messengers.telegram import PollingTelegramInterface, query_callback_condition_exact_match +from dff.messengers.telegram import PollingTelegramInterface, has_callback_query from dff.utils.testing.common import is_interactive_mode @@ -81,12 +81,8 @@ class is used to represent telegram message, ], ), TRANSITIONS: { - ("general", "success"): query_callback_condition_exact_match( - CallbackQuery(query_string="correct") - ), - ("general", "fail"): query_callback_condition_exact_match( - CallbackQuery(query_string="wrong") - ), + ("general", "success"): has_callback_query("correct"), + ("general", "fail"): has_callback_query("wrong"), }, }, "success": { From c947b4ea1779deaca114959a380989bbfb376259 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Thu, 22 Feb 2024 15:20:19 +0300 Subject: [PATCH 013/140] remove tg tests; move message tests to core tests TG tutorials are tested (without tg API) during tutorial tests. --- dff/utils/testing/telegram.py | 271 -------------------- tests/messengers/__init__.py | 0 tests/messengers/telegram/__init__.py | 0 tests/messengers/telegram/conftest.py | 78 ------ tests/messengers/telegram/test_tutorials.py | 58 ----- tests/messengers/telegram/test_types.py | 204 --------------- tests/script/core/test_message.py | 45 +++- 7 files changed, 34 insertions(+), 622 deletions(-) delete mode 100644 dff/utils/testing/telegram.py delete mode 100644 tests/messengers/__init__.py delete mode 100644 tests/messengers/telegram/__init__.py delete mode 100644 tests/messengers/telegram/conftest.py delete mode 100644 tests/messengers/telegram/test_tutorials.py delete mode 100644 tests/messengers/telegram/test_types.py diff --git a/dff/utils/testing/telegram.py b/dff/utils/testing/telegram.py deleted file mode 100644 index 85c6b6a7e..000000000 --- a/dff/utils/testing/telegram.py +++ /dev/null @@ -1,271 +0,0 @@ -""" -Telegram testing utils ----------------------- -This module defines functions used to test Telegram interface. -""" -from typing import List, Optional, cast, Tuple -from contextlib import asynccontextmanager, nullcontext -import logging -import asyncio -from tempfile import TemporaryDirectory -from pathlib import Path -from copy import deepcopy - -from dff.pipeline.pipeline.pipeline import Pipeline -from dff.script.core.message import Message, Attachment, Location -from dff.messengers.telegram import PollingTelegramInterface - - -def replace_click_button(happy_path): - """ - Replace all _ClickButton instances in `happy_path`. - This allows using :py:func:`~dff.utils.testing.common.check_happy_path` instead of - :py:meth:~dff.utils.testing.telegram.TelegramTesting.check_happy_path`. - - :return: A `happy_path` with all `_ClickButton` replaced with payload values of the buttons. - """ - result = deepcopy(happy_path) - for index in range(len(happy_path)): - user_request = happy_path[index][0] - if not isinstance(user_request, Message): - continue - if isinstance(user_request.callback_query, _ClickButton): - callback_query = None - for _, bot_response in reversed(happy_path[:index]): - if isinstance(bot_response, Message) and bot_response.ui is not None and callback_query is None: - callback_query = bot_response.ui.buttons[user_request.callback_query.button_index].payload - if callback_query is None: - raise RuntimeError("Bot response with buttons not found.") - result[index][0].callback_query = callback_query - return result - - -async def get_bot_user(client: TelegramClient, username: str): - async with client: - return await client.get_entity(username) - - -class TelegramTesting: # pragma: no cover - """ - Defines functions for testing. - - :param pipeline: - Pipeline with the telegram messenger interface. - Required for :py:meth:`~dff.utils.testing.telegram.TelegramTesting.send_and_check` and - :py:meth:`~dff.utils.testing.telegram.TelegramTesting.check_happy_path` with `run_bot=True` - :param api_credentials: - Telegram API id and hash. - Obtainable via https://core.telegram.org/api/obtaining_api_id. - :param session_file: - A `telethon` session file. - Obtainable by connecting to :py:class:`telethon.TelegramClient` and entering phone number and code. - :param client: - An alternative to passing `api_credentials` and `session_file`. - :param bot_username: - Either a link to the bot user or its handle. Used to determine whom to talk with as a client. - :param bot: - An alternative to passing `bot_username`. - Result of calling :py:func:`~dff.utils.testing.telegram.get_bot_user` with `bot_username` as parameter. - """ - - def __init__( - self, - pipeline: Pipeline, - api_credentials: Optional[Tuple[int, str]] = None, - session_file: Optional[str] = None, - client: Optional[TelegramClient] = None, - bot_username: Optional[str] = None, - bot: Optional[User] = None, - ): - if client is None: - if api_credentials is None or session_file is None: - raise RuntimeError("Pass either `client` or `api_credentials` and `session_file`.") - client = TelegramClient(session_file, *api_credentials) - self.client = client - """Telegram client (not bot). Needed to verify bot replies.""" - self.pipeline = pipeline - if bot is None: - if bot_username is None: - raise RuntimeError("Pass either `bot_username` or `bot`.") - bot = asyncio.run(get_bot_user(self.client, bot_username)) - self.bot = bot - """Bot user (to know whom to send messages to from client).""" - - async def send_message(self, message: Message, last_bot_messages: List[TlMessage]): - """ - Send a message from client to bot. - If the message contains `callback_query`, only press the button, ignore other fields. - - :param message: Message to send. - :param last_bot_messages: - The last bot response. Accepts a list because messages with multiple fields are split in telegram. - Can only contain one keyboard in the list. - Used to determine which button to press when message contains - :py:class:`~dff.messengers.telegram.message._ClickButton`. - """ - if message.callback_query is not None: - query = message.callback_query - if not isinstance(query, _ClickButton): - raise RuntimeError(f"Use `_ClickButton` during tests: {query}") - for bot_message in last_bot_messages: - if bot_message.buttons is not None: - await bot_message.click(i=query.button_index) - return None - if message.attachments is None or len(message.attachments.files) == 0: - return await self.client.send_message(self.bot, message.text) - else: - if len(message.attachments.files) == 1: - attachment = message.attachments.files[0] - files = attachment.source - else: - files = [file.source for file in message.attachments.files] - return await self.client.send_file(self.bot, files, caption=message.text) - - @staticmethod - async def parse_responses(responses: List[TlMessage], file_download_destination) -> Message: - """ - Convert a list of bot responses into a single message. - This function accepts a list because messages with multiple attachments are split. - - :param responses: A list of bot responses that are considered to be a single message. - :param file_download_destination: A directory to download sent media to. - """ - msg = TelegramMessage() - for response in responses: - if response.text and response.file is None: - if msg.text: - raise RuntimeError(f"Several messages with text:\n{msg.text}\n{response.text}") - msg.text = response.text or msg.text - if response.file is not None: - file = Path(file_download_destination) / (str(response.file.media.id) + response.file.ext) - await response.download_media(file=file) - if msg.attachments is None: - msg.attachments = Attachments() - msg.attachments.files.append( - Attachment(source=file, id=None, title=response.file.title or response.text or None) - ) - if response.buttons is not None: - buttons = [] - for row in response.buttons: - for button in row: - buttons.append( - Button( - source=button.url, - text=button.text, - payload=button.data, - ) - ) - if msg.ui is not None: - raise RuntimeError(f"Several messages with ui:\n{msg.ui}\n{TelegramUI(buttons=buttons)}") - msg.ui = TelegramUI(buttons=buttons) - if isinstance(response.reply_markup, ReplyKeyboardHide): - if msg.ui is not None: - raise RuntimeError(f"Several messages with ui:\n{msg.ui}\n{types.ReplyKeyboardRemove()}") - msg.ui = RemoveKeyboard() - if response.geo is not None: - location = Location(latitude=response.geo.lat, longitude=response.geo.long) - if msg.location is not None: - raise RuntimeError(f"Several messages with location:\n{msg.location}\n{location}") - msg.location = location - return msg - - @asynccontextmanager - async def run_bot_loop(self): - """A context manager that returns a function to run one polling loop of a messenger interface.""" - self.pipeline.messenger_interface.timeout = 2 - self.pipeline.messenger_interface.long_polling_timeout = 2 - await self.forget_previous_updates() - - yield lambda: self.pipeline.messenger_interface._polling_loop(self.pipeline._run_pipeline) - - self.pipeline.messenger_interface.forget_processed_updates() - - async def send_and_check(self, message: Message, file_download_destination=None): - """ - Send a message from a bot, receive it as client, verify it. - - :param message: Message to send and check. - :param file_download_destination: - Temporary directory (used to download sent files). - Defaults to :py:class:`tempfile.TemporaryDirectory`. - """ - await self.forget_previous_updates() - - async with self.client: - messenger_interface = cast(PollingTelegramInterface, self.pipeline.messenger_interface) - - messages = await self.client.get_messages(self.bot, limit=1) - if len(messages) == 0: - last_message_id = 0 - else: - last_message_id = messages[0].id - - messenger_interface.messenger.send_response((await self.client.get_me(input_peer=True)).user_id, message) - - await asyncio.sleep(3) - bot_messages = [ - x async for x in self.client.iter_messages(self.bot, min_id=last_message_id, from_user=self.bot) - ] # iter_messages is used instead of get_messages because get_messages requires bot min_id and max_id - - if file_download_destination is None: - fd_context = TemporaryDirectory() - else: - fd_context = nullcontext(file_download_destination) - - with fd_context as file_download_destination: - result = await self.parse_responses(bot_messages, file_download_destination) - - assert result == message - - async def forget_previous_updates(self): - messenger_interface = cast(PollingTelegramInterface, self.pipeline.messenger_interface) - messenger = messenger_interface.messenger - updates = messenger.get_updates(offset=messenger.last_update_id + 1, timeout=1, long_polling_timeout=1) - max_update_id = max([*map(lambda x: x.update_id, updates), -1]) - messenger.get_updates(offset=max_update_id + 1, timeout=1, long_polling_timeout=1) - - async def check_happy_path(self, happy_path, file_download_destination=None, run_bot: bool = True): - """ - Play out a dialogue with the bot. Check that the dialogue is correct. - - :param happy_path: Expected dialogue - :param file_download_destination: Temporary directory (used to download sent files) - :param run_bot: Whether a bot inside pipeline should be running (disable this to test non-async bots) - :return: - """ - if run_bot: - bot = self.run_bot_loop() - else: - - async def null(): - ... - - bot = nullcontext(null) - - if file_download_destination is None: - fd_context = TemporaryDirectory() - else: - fd_context = nullcontext(file_download_destination) - - async with self.client, bot as boot_loop: - with fd_context as file_download_destination: - bot_messages = [] - last_message = None - for request, response in happy_path: - logging.info(f"Sending request {request}") - user_message = await self.send_message(TelegramMessage.model_validate(request), bot_messages) - if user_message is not None: - last_message = user_message - logging.info("Request sent") - await boot_loop() - await asyncio.sleep(2) - logging.info("Extracting responses") - bot_messages = [ - x async for x in self.client.iter_messages(self.bot, min_id=last_message.id, from_user=self.bot) - ] - # iter_messages is used instead of get_messages because get_messages requires bot min_id and max_id - if len(bot_messages) > 0: - last_message = bot_messages[0] - logging.info("Got responses") - result = await self.parse_responses(bot_messages, file_download_destination) - assert result == TelegramMessage.model_validate(response) diff --git a/tests/messengers/__init__.py b/tests/messengers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/messengers/telegram/__init__.py b/tests/messengers/telegram/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/messengers/telegram/conftest.py b/tests/messengers/telegram/conftest.py deleted file mode 100644 index d3436410a..000000000 --- a/tests/messengers/telegram/conftest.py +++ /dev/null @@ -1,78 +0,0 @@ -import os -import asyncio -import importlib -from pathlib import Path - -import pytest - -from tests.test_utils import get_path_from_tests_to_current_dir - -try: - from dff.utils.testing.telegram import get_bot_user, TelegramClient - - telegram_available = True -except ImportError: - telegram_available = False - -dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") - - -@pytest.fixture(scope="session") -def pipeline_tutorial(): - if not telegram_available: - pytest.skip("`telegram` not available.") - yield importlib.import_module(f"tutorials.{dot_path_to_addon}.{'7_polling_setup'}") - - -@pytest.fixture(scope="session") -def session_file(): - dff_root_dir = Path(__file__).parent.parent.parent.parent - file = dff_root_dir / "anon.session" - - if not file.exists(): - pytest.skip(f"Session file does not exist at {str(file)}") - - return str(file) - - -@pytest.fixture(scope="session") -def env_vars(): - env_variables = {"TG_BOT_TOKEN": None, "TG_API_ID": None, "TG_API_HASH": None, "TG_BOT_USERNAME": None} - - for arg in env_variables: - env_variables[arg] = os.getenv(arg) - - if env_variables[arg] is None: - pytest.skip(f"`{arg}` is not set", allow_module_level=True) - - yield env_variables - - -@pytest.fixture(scope="session") -def pipeline_instance(env_vars, pipeline_tutorial): - yield pipeline_tutorial.pipeline - - -@pytest.fixture(scope="session") -def document(tmpdir_factory): - filename: Path = tmpdir_factory.mktemp("data").join("file.txt") - with filename.open("w") as f: - f.write("test") - yield filename - - -@pytest.fixture(scope="session") -def api_credentials(env_vars): - yield (int(env_vars["TG_API_ID"]), env_vars["TG_API_HASH"]) - - -@pytest.fixture(scope="session") -def bot_user(api_credentials, env_vars, session_file): - if not telegram_available: - pytest.skip("`telegram` not available.") - client = TelegramClient(session_file, *api_credentials) - yield asyncio.run(get_bot_user(client, env_vars["TG_BOT_USERNAME"])) - - -def pytest_sessionfinish(session, exitstatus): - asyncio.get_event_loop().close() diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py deleted file mode 100644 index c92e0e048..000000000 --- a/tests/messengers/telegram/test_tutorials.py +++ /dev/null @@ -1,58 +0,0 @@ -""" -These tests check that pipelines defined in tutorials follow `happy_path` defined in the same tutorials. -""" -import importlib -import logging - -import pytest - -try: - import telebot # noqa: F401 - import telethon # noqa: F401 -except ImportError: - pytest.skip(reason="`telegram` is not available", allow_module_level=True) - -from tests.test_utils import get_path_from_tests_to_current_dir -from dff.utils.testing.common import check_happy_path -from dff.utils.testing.telegram import TelegramTesting, replace_click_button - -dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") - - -@pytest.mark.parametrize( - "tutorial_module_name", - [ - "1_basic", - "2_buttons", - "3_buttons_with_callback", - ], -) -def test_client_tutorials_without_telegram(tutorial_module_name, env_vars): - tutorial_module = importlib.import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") - pipeline = tutorial_module.pipeline - happy_path = tutorial_module.happy_path - check_happy_path(pipeline, replace_click_button(happy_path)) - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - "tutorial_module_name", - [ - "1_basic", - "2_buttons", - "3_buttons_with_callback", - "4_conditions", - "5_conditions_with_media", - "7_polling_setup", - ], -) -@pytest.mark.telegram -async def test_client_tutorials(tutorial_module_name, api_credentials, bot_user, session_file): - tutorial_module = importlib.import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") - pipeline = tutorial_module.pipeline - happy_path = tutorial_module.happy_path - test_helper = TelegramTesting( - pipeline=pipeline, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - logging.info("Test start") - await test_helper.check_happy_path(happy_path) diff --git a/tests/messengers/telegram/test_types.py b/tests/messengers/telegram/test_types.py deleted file mode 100644 index 01f1b0063..000000000 --- a/tests/messengers/telegram/test_types.py +++ /dev/null @@ -1,204 +0,0 @@ -import json -from io import IOBase -from pathlib import Path - -import pytest - -try: - import telegram # noqa: F401 -except ImportError: - pytest.skip(reason="`telegram` is not available", allow_module_level=True) - -from pydantic import FilePath, HttpUrl, ValidationError - -from dff.script import Message -from dff.script.core.message import Button, DataAttachment, Keyboard, Image, Location, Audio, Video, Attachment, Document - -from dff.utils.testing.telegram import TelegramTesting - -_image_link = "https://gist.githubusercontent.com/scotthaleen/32f76a413e0dfd4b4d79c2a534d49c0b/raw/6c1036b1eca90b341caf06d4056d36f64fc11e88/tiny.jpg" -image = Image(source=HttpUrl(_image_link)) -audio = Audio(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/mp3.mp3")) -video = Video(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/Mpeg4.mp4")) -document = Document(source=HttpUrl("https://github.com/mathiasbynens/small/raw/master/pdf.pdf")) - - -@pytest.mark.asyncio -@pytest.mark.telegram -async def test_text(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message(text="test") - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - ["keyboard"], - [ - Keyboard( - buttons=[ - [ - Button(text="button 1", data=json.dumps({"text": "1", "other_prop": "4"})), - Button(text="button 2", data=json.dumps({"text": "2", "other_prop": "3"})), - ], - [ - Button(text="button 3", data=json.dumps({"text": "3", "other_prop": "2"})), - Button(text="button 4", data=json.dumps({"text": "4", "other_prop": "1"})), - ] - ] - ), - Keyboard( - buttons=[ - [ - Button(text="button 1"), - Button(text="button 2"), - ], - [ - Button(text="button 3"), - Button(text="button 4"), - ] - ], - ), - ], -) -@pytest.mark.telegram -async def test_buttons(keyboard: Keyboard, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message(text="test", attachments=[keyboard]) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - ["generic_response"], - [ - ( - Message( - text="test", - attachments=[image], - ), - ), - ( - Message( - text="test", - attachments=[audio], - ), - ), - ( - Message( - text="test", - attachments=[video], - ), - ), - ( - Message( - text="test", - attachments=[document], - ), - ), - ], -) -@pytest.mark.telegram -async def test_telegram_attachment(generic_response, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message.model_validate(generic_response) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - ["attachments"], - [ - ( - Message( - text="test", - attachments=list(tuple(2 * [image])), - ), - ), - ( - Message( - text="test", - attachments=list(tuple(2 * [audio])), - ), - ), - ( - Message( - text="test", - attachments=list(tuple(2 * [video])), - ), - ), - ( - Message( - text="test", - attachments=list(tuple(2 * [document])), - ), - ), - ], -) -@pytest.mark.telegram -async def test_attachments(attachments, pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message.model_validate(attachments) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.telegram -async def test_location(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message(text="location", attachments=[Location(longitude=39.0, latitude=43.0)]) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -@pytest.mark.asyncio -@pytest.mark.telegram -async def test_parsed_text(pipeline_instance, api_credentials, bot_user, session_file): - telegram_response = Message(text="[inline URL](http://www.example.com/)", parse_mode=ParseMode.MARKDOWN) - test_helper = TelegramTesting( - pipeline=pipeline_instance, api_credentials=api_credentials, session_file=session_file, bot=bot_user - ) - await test_helper.send_and_check(telegram_response) - - -def test_missing_error(): - with pytest.raises(ValidationError) as e: - _ = DataAttachment(source=HttpUrl("http://google.com"), id="123") - assert e - - with pytest.raises(ValidationError) as e: - _ = DataAttachment(source=FilePath("/etc/missing_file")) - assert e - - -def test_empty_keyboard(): - with pytest.raises(ValidationError) as e: - _ = Keyboard(buttons=[]) - assert e - - -def test_long_button_data(): - with pytest.raises(ValidationError) as error: - Button(text="", data="test" * 64) - assert error - - -def test_io(document): - tele_doc = types.InputMediaDocument(media=Path(document)) - opened_doc = open_io(tele_doc) - print(type(opened_doc.media)) - assert isinstance(opened_doc.media, IOBase) - close_io(opened_doc) - assert opened_doc.media.closed - with batch_open_io(tele_doc) as med: - assert isinstance(med.media, IOBase) - assert tele_doc.media.closed diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index b846c38dd..96134e6fb 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -1,6 +1,7 @@ import pytest +from pydantic import ValidationError, HttpUrl, FilePath -from dff.script.core.message import Location, Attachment +from dff.script.core.message import Location, DataAttachment, Keyboard, Button def test_location(): @@ -19,31 +20,53 @@ def test_location(): "attachment1,attachment2,equal", [ ( - Attachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), - Attachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File"), + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), + DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File"), True, ), ( - Attachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), - Attachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2"), + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), + DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2"), False, ), ( - Attachment(source=__file__, title="File"), - Attachment(source=__file__, title="File"), + DataAttachment(source=__file__, title="File"), + DataAttachment(source=__file__, title="File"), True, ), ( - Attachment(source=__file__, title="1"), - Attachment(source=__file__, title="2"), + DataAttachment(source=__file__, title="1"), + DataAttachment(source=__file__, title="2"), False, ), ( - Attachment(id="1", title="File"), - Attachment(id="2", title="File"), + DataAttachment(id="1", title="File"), + DataAttachment(id="2", title="File"), False, ), ], ) def test_attachment(attachment1, attachment2, equal): assert (attachment1 == attachment2) == equal + + +def test_missing_error(): + with pytest.raises(ValidationError) as e: + _ = DataAttachment(source=HttpUrl("http://google.com"), id="123") + assert e + + with pytest.raises(ValidationError) as e: + _ = DataAttachment(source=FilePath("/etc/missing_file")) + assert e + + +def test_empty_keyboard(): + with pytest.raises(ValidationError) as e: + _ = Keyboard(buttons=[]) + assert e + + +def test_long_button_data(): + with pytest.raises(ValidationError) as error: + Button(text="", data="test" * 64) + assert error From 25b8ac9a97b50ef4e62a514783f2a319fbef88c2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 28 Feb 2024 01:03:43 +0100 Subject: [PATCH 014/140] buttons pulled out of attachments list --- dff/messengers/telegram.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 60e68339d..24d0ea671 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -75,6 +75,9 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes buttons = list() if message.attachments is not None: files = list() + for attachment in message.attachments: + if isinstance(attachment, Keyboard): + buttons = attachment.buttons for attachment in message.attachments: if isinstance(attachment, Location): await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons)) @@ -105,8 +108,6 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: files += [InputMediaDocument(attachment_bytes)] - if isinstance(attachment, Keyboard): - buttons = attachment.buttons if len(files) > 0: await bot.send_media_group(chat_id, files, caption=message.text) return From bdda83e6875e6557e73015ca808801fa2d3a2953 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:50:00 +0300 Subject: [PATCH 015/140] Added multiple attachments --- dff/messengers/vk.py | 236 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 207 insertions(+), 29 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index e6ade1158..65feb31aa 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -1,35 +1,62 @@ """ Interface ------------ -This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` -that can be used to interact with the Telegram API. """ from typing import Callable, Optional, Sequence, cast from pydantic import HttpUrl -# import asyncio +import asyncio +import aiofiles +import aiohttp -from pyvkbot import Bot import requests +import io -from dff.messengers.common import MessengerInterface +from dff.messengers.common import MessengerInterface, PollingMessengerInterface from dff.pipeline import Pipeline + # from dff.pipeline.types import PipelineRunnerFunction from dff.script.core.context import Context -from dff.script.core.message import Audio, Button, Document, Image, Keyboard, Location, Message, Video +from dff.script.core.message import ( + Audio, + Button, + Document, + Image, + Keyboard, + Location, + Message, + Video, +) + + +async def vk_api_call(method, payload={}, headers={}): + async with aiohttp.ClientSession() as session: + async with session.post(method) as response: + # print(response.json()) + return response.json() +def extract_vk_update(update): + text, id = update + message = Message(text=text) + return message, int(id) + class _AbstractVKInterface(MessengerInterface): - def __init__(self, token: str, group_id: str) -> None: - self.bot = Bot(token=token, group_id=group_id) - self.bot.on('message', self.on_message) - - def _create_keyboard(self, buttons: Sequence[Sequence[Button]]): + async def __init__(self, token: str, group_id: str) -> None: + self.token = token + self.group_id = group_id + await vk_api_call( + f"https://api.vk.com/method/status.get?user_id={self.group_id}&v=5.131&access_token={self.token}" + ) + + async def _create_keyboard(self, buttons: Sequence[Sequence[Button]]): keyboard = Keyboard(inline=False) keyboard.add_button(label="123") + - def extract_message_from_vk(self, message_vk: dict[str, str]) -> Message: + + async def extract_message_from_vk(self, message_vk: dict[str, str]) -> Message: message = Message() message.attachments = list() @@ -40,44 +67,195 @@ def extract_message_from_vk(self, message_vk: dict[str, str]) -> Message: for element in message_vk["attachments"]: match element["type"]: case "photo": - message.attachments += [Image(source=HttpUrl(element[element["type"]]['sizes'][-1]['url']))] + message.attachments += [ + Image( + source=HttpUrl( + element[element["type"]]["sizes"][-1]["url"] + ) + ) + ] case "video": pass case "audio": - message.attachments += [Audio(source=HttpUrl(element[element["type"]]['url']))] + message.attachments += [ + Audio(source=HttpUrl(element[element["type"]]["url"])) + ] case "doc": - message.attachments += [Document(source=HttpUrl(element[element["type"]]['url']))] + message.attachments += [ + Document(source=HttpUrl(element[element["type"]]["url"])) + ] case "link": - message.text = element[element["type"]]['url'] + message.text = element[element["type"]]["url"] case _: pass return message - - def cast_message_to_vk_and_send(self, bot, orig_message, message: Message) -> None: + async def cast_message_to_vk_and_send( + self, bot, orig_message, message: Message + ) -> None: if message.attachments is not None: - pass + for attachment in message.attachments: + if isinstance(attachment, Image): + bot.send_api_method( + "send", + { + "peer_id": orig_message["peer_id"], + "photo_id": self._upload_attachment( + orig_message["peer_id"], + ), + }, + ) if message.text is not None: bot.send_message(peer_id=orig_message["peer_id"], text=message.text) - - def on_message(self, _, event) -> None: + async def on_message(self, _, event) -> None: message = self.extract_message_from_vk(event) message.original_message = event resp = self.callback(message, event["peer_id"]) if resp.last_response is not None: self.cast_message_to_vk_and_send(self.bot, event, resp.last_response) - - def connect(self, callback, *args, **kwargs): + async def connect(self, callback, *args, **kwargs): self.callback = callback -class PollingVKInterface(_AbstractVKInterface): - def __init__(self, token: str, group_id: str) -> None: - super().__init__(token, group_id) +class FilesOpener(object): + def __init__(self, paths, key_format='file{}'): + if not isinstance(paths, list): + paths = [paths] + + self.paths = paths + self.key_format = key_format + self.opened_files = [] + + def __enter__(self): + return self.open_files() + + def __exit__(self, type, value, traceback): + self.close_files() + + def open_files(self): + self.close_files() + + files = [] + + for x, file in enumerate(self.paths): + if hasattr(file, 'read'): + f = file + + filename = file.name if hasattr(file, 'name') else '.jpg' + else: + filename = file + if "http" in filename: + f = io.BytesIO(requests.get(filename).content) + else: + f = open(filename, 'rb') + self.opened_files.append(f) + + ext = filename.split('.')[-1] + files.append((self.key_format.format(x), (f'file{x}.{ext}', f))) + + return files + + def close_files(self): + for f in self.opened_files: + f.close() + + self.opened_files = [] + + +class PollingVKInterface(PollingMessengerInterface): + def __init__(self, token: str, group_id: str, interval: str) -> None: + super().__init__() + self.token = token + self.group_id = group_id + server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json()['response'] + self.server = server_request['server'] + self.ts_base = int(server_request['ts']) + self.ts_current = self.ts_base + self.server_key = server_request['key'] + self.last_update_id = None + self._last_processed_update = None + + + def upload_attachment( + self, peer_id, attachment, attachment_type: str + ) -> str: + match attachment_type: + case "photo": + upload_url = requests.post( + f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json()["response"]["upload_url"] + attachment_path = str(attachment.source) + + with FilesOpener(attachment_path) as photo_files: + uploaded_photo_data = requests.post(upload_url, files=photo_files).json() + + saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() + # returns json object with `owner_id` and `photo_id` needed to send it + + return saved_photo_data["response"] + + case "doc": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json()["response"]["upload_url"] + attachment_path = str(attachment.source) + + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + return saved_doc_data["response"] + + + def send_message(self, response, id): + if response.attachments is not None: + for _ in response.attachments: + attachment_list = [] + for attachment in _[1]: + match attachment: + case Image(): + data_to_send = self.upload_attachment(id, attachment, "photo") + attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() + case Document(): + data_to_send = self.upload_attachment(id, attachment, "doc") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + + attachment_string = ','.join(attachment_list).strip(',') + + requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&v=5.81&access_token={self.token}").json() + else: + requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}").json() + + + def _request(self): + updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() + self.ts_current = updates['ts'] + update_list = [] + for i in updates["updates"]: + update_list.append( + extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) + ) + return update_list + + + def _respond(self, response): + + for resp in response: + self.send_message(resp.last_response, resp.id) + # update_id = getattr(resp.last_request, "update_id", None) + # if update_id is not None: + # if update_id != self._last_processed_update: + # self._last_processed_update = update_idnest_asyncio + + print("Responded") + - def connect(self, callback, *args, **kwargs): - super().connect(callback, *args, **kwargs) - self.bot.start_polling(lambda: print("Bot started")) + async def connect(self, callback, loop: Optional[Callable] = None, *args, **kwargs): + await super().connect( + callback, loop=lambda: True, timeout=1 + ) From b67b497d48943fb120432aaea73f315bbdee25a2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 12 Mar 2024 19:45:39 +0100 Subject: [PATCH 016/140] some errors fixed --- dff/messengers/common/conditions.py | 16 ++++++++++++ dff/messengers/telegram.py | 26 +++++-------------- tutorials/messengers/telegram/2_buttons.py | 5 ++-- .../telegram/3_buttons_with_callback.py | 5 ++-- 4 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 dff/messengers/common/conditions.py diff --git a/dff/messengers/common/conditions.py b/dff/messengers/common/conditions.py new file mode 100644 index 000000000..f5534f993 --- /dev/null +++ b/dff/messengers/common/conditions.py @@ -0,0 +1,16 @@ +from dff.pipeline import Pipeline +from dff.script import Context + + +def has_callback_query(expected: str): + + def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover + last_request = ctx.last_request + if last_request is None or last_request.attachments is None or len(last_request.attachments) == 0: + return False + callback_query = next((attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None) + if callback_query is None: + return False + return callback_query.query_string == expected + + return condition diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 60e68339d..b8f76a318 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -127,8 +127,8 @@ async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: await self._on_event(update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)])) - async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): - self.callback = callback + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + self.callback = pipeline_runner class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover @@ -137,8 +137,8 @@ def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: self.interval = interval self.timeout = timeout - async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): - await super().connect(callback, *args, **kwargs) + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + await super().connect(pipeline_runner, *args, **kwargs) self.application.run_polling(poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES) @@ -148,8 +148,8 @@ def __init__(self, token: str, host: str = "localhost", port: int = 844): self.listen = host self.port = port - async def connect(self, callback: PipelineRunnerFunction, *args, **kwargs): - await super().connect(callback, *args, **kwargs) + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + await super().connect(pipeline_runner, *args, **kwargs) self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) @@ -163,17 +163,3 @@ def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover return func(original_message) return condition - - -def has_callback_query(expected: str): - - def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover - last_request = ctx.last_request - if last_request is None or last_request.attachments is None or len(last_request.attachments) == 0: - return False - callback_query = next((attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None) - if callback_query is None: - return False - return callback_query.query_string == expected - - return condition diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index 431877ba4..2c1ae78ed 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -23,9 +23,10 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE -from dff.script.core.message import Button, Keyboard, Message, CallbackQuery +from dff.script.core.message import Button, Keyboard, Message from dff.pipeline import Pipeline -from dff.messengers.telegram import PollingTelegramInterface, has_callback_query +from dff.messengers.common.conditions import has_callback_query +from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index 0abe31d15..cd84c016f 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -25,8 +25,9 @@ class is used to represent telegram message, import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE from dff.pipeline import Pipeline -from dff.script.core.message import Button, Keyboard, Message, CallbackQuery -from dff.messengers.telegram import PollingTelegramInterface, has_callback_query +from dff.script.core.message import Button, Keyboard, Message +from dff.messengers.common.conditions import has_callback_query +from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode From 5ad47151ef7140d2524c1e7d3df24e554f1ae936 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Wed, 13 Mar 2024 13:47:51 +0300 Subject: [PATCH 017/140] Added basic attachments --- dff/messengers/vk.py | 64 +++++++++++++++++++++++++++++--------- dff/script/core/message.py | 2 +- dff/script/extra_types.py | 15 +++++++++ 3 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 dff/script/extra_types.py diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 65feb31aa..2b6583daf 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -25,8 +25,11 @@ Location, Message, Video, + Link ) +from dff.script.extra_types import Poll + async def vk_api_call(method, payload={}, headers={}): async with aiohttp.ClientSession() as session: @@ -182,6 +185,7 @@ def __init__(self, token: str, group_id: str, interval: str) -> None: def upload_attachment( self, peer_id, attachment, attachment_type: str ) -> str: + #returns json object with `owner_id` and `photo_id` needed to send it match attachment_type: case "photo": upload_url = requests.post( @@ -193,7 +197,6 @@ def upload_attachment( uploaded_photo_data = requests.post(upload_url, files=photo_files).json() saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() - # returns json object with `owner_id` and `photo_id` needed to send it return saved_photo_data["response"] @@ -209,25 +212,58 @@ def upload_attachment( saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() return saved_doc_data["response"] + + case "audio": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" + ).json()["response"]["upload_url"] + attachment_path = str(attachment.source) + + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + return saved_doc_data["response"] + + case "video": + vid = requests.post(f"https://api.vk.com/method/video.save?link={attachment.source}&group_id={self.group_id}&v=5.81&access_token={self.token}").json()["response"] + return vid def send_message(self, response, id): if response.attachments is not None: - for _ in response.attachments: - attachment_list = [] - for attachment in _[1]: - match attachment: - case Image(): - data_to_send = self.upload_attachment(id, attachment, "photo") - attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() - case Document(): - data_to_send = self.upload_attachment(id, attachment, "doc") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + attachment_list = [] + for attachment in response.attachments: + match attachment: + case Image(): + data_to_send = self.upload_attachment(id, attachment, "photo") + attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() + case Document(): + data_to_send = self.upload_attachment(id, attachment, "doc") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + case Video(): + data_to_send = self.upload_attachment(id, attachment, "video") + attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") + case Audio(): + data_to_send = self.upload_attachment(id, attachment, "audio") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + case Link(): + link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} + # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachments=[{link_vk}]&v=5.81&access_token={self.token}").json() + attachment_list.append(link_vk) + # attachment_list.append(str(link_vk)) + case Poll(): + poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json()["response"] + attachment_list.append({ + "type": "poll", + "poll": poll_obj + }) attachment_string = ','.join(attachment_list).strip(',') - - requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&v=5.81&access_token={self.token}").json() + + requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() else: requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}").json() diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 05f9974f9..55be8e9df 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -192,7 +192,7 @@ class level variables to store message information. text: Optional[str] = None commands: Optional[List[Command]] = None - attachments: Optional[Attachments] = None + attachments: Optional[List[DataModel]] = None annotations: Optional[dict] = None misc: Optional[dict] = None # commands and state options are required for integration with services diff --git a/dff/script/extra_types.py b/dff/script/extra_types.py new file mode 100644 index 000000000..d983759a9 --- /dev/null +++ b/dff/script/extra_types.py @@ -0,0 +1,15 @@ +from typing_extensions import Unpack +from pydantic import ConfigDict +from dff.script.core.message import Attachment + + +class Poll(Attachment): + question: str = None + is_anonymous: bool = 0 + is_multiple: bool = 0 + end_date: int = None + owner_id: int = None + add_answers: list = [] + photo_id: int = None + background_id: int = None + disable_unvote: bool = False From e4e6951496355347f0f10cc1df172e1d47083fbb Mon Sep 17 00:00:00 2001 From: askatasuna Date: Wed, 13 Mar 2024 13:59:24 +0300 Subject: [PATCH 018/140] Fixed link --- dff/messengers/vk.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 2b6583daf..00911e15a 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -250,9 +250,10 @@ def send_message(self, response, id): data_to_send = self.upload_attachment(id, attachment, "audio") attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") case Link(): - link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} + # link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} + response.text += f"[{attachment.source}|{attachment.title}]" # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachments=[{link_vk}]&v=5.81&access_token={self.token}").json() - attachment_list.append(link_vk) + # attachment_list.append(link_vk) # attachment_list.append(str(link_vk)) case Poll(): poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json()["response"] From 29b11f017d259644d63100ec2d7b03c65a4ad766 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:17:27 +0300 Subject: [PATCH 019/140] Add/First version of tutorial --- tutorials/messengers/vk/1_basic.py | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tutorials/messengers/vk/1_basic.py diff --git a/tutorials/messengers/vk/1_basic.py b/tutorials/messengers/vk/1_basic.py new file mode 100644 index 000000000..a70fa22ee --- /dev/null +++ b/tutorials/messengers/vk/1_basic.py @@ -0,0 +1,88 @@ +# %% [markdown] +""" +# VK: 1. Basic + +The following tutorial shows how to run a regular DFF script as a VK Bot. + +Before we start, we will need to setup our bot in VK, what can be done through these steps: +1. Create a community in VK. +![photo_1](https://imgur.com/NaCfts6.png) + +2. Follow this [guide](https://dev.vk.com/en/api/bots/getting-started) to obtain an access token. +NOTE: Current version of DFF VK Interface only works with [Bots Long Poll API](https://dev.vk.com/en/api/bots-long-poll/getting-started) + +3. Grant access to required scopes for your bot. +![photo_2](https://imgur.com/or5NUxy.png) + +4. Make sure to enable Long Poll API and set up events your bot will listen to. +![photo_3](https://imgur.com/or5NUxy.png) +![photo_4](https://imgur.com/kJtXTnV.png) + +""" + +# %% +from dff.messengers.vk import PollingVKInterface +from dff.script import conditions as cnd +from dff.script import labels as lbl +from dff.script import RESPONSE, TRANSITIONS, Message +from dff.pipeline import Pipeline + +from dff.script.core.message import Image, Message + + +# %% [markdown] +""" +Then you can specify your script as usual. +More extensive guide on working with attachments with examples and best practices. (link) +""" + + +# %% +script = { + "greeting_flow": { + "start_node": { + TRANSITIONS: { + "greeting_node": cnd.exact_match(Message(text="Hello")) + }, + }, + "greeting_node": { + RESPONSE: Message(text="Hi", attachments=[Image(source="/home/askatasuna/Documents/DeepPavlov/DFF/dialog_flow_framework/1.png")]), + TRANSITIONS: {lbl.repeat(): cnd.true()}, + }, + "fallback_node": { + RESPONSE: Message(text="Please, repeat the request"), + TRANSITIONS: { + "greeting_node": cnd.exact_match(Message(text="/start")) + }, + }, + } +} + +# %% [markdown] +""" +Here you put your `access_key` and `group_id` of the group your bot connected to. +You can check id of your group via many web services, for example https://regvk.com/id/. +""" + +# %% +KEY = "" +GROUP_ID = "" + +interface = PollingVKInterface(token=KEY, group_id=GROUP_ID, interval='2') + +# %% + +pipeline = Pipeline.from_script( + script=script, + start_label=("greeting_flow", "start_node"), + fallback_label=("greeting_flow", "fallback_node"), + messenger_interface=interface, + # The interface can be passed as a pipeline argument. +) + +def main(): + pipeline.run() + + +if __name__ == "__main__": + main() From 95926d63c3def0102ed28b29d6d8b945ef19c1ad Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:58:49 +0300 Subject: [PATCH 020/140] Fix/deleted sending image --- tutorials/messengers/vk/1_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/messengers/vk/1_basic.py b/tutorials/messengers/vk/1_basic.py index a70fa22ee..3f2feebee 100644 --- a/tutorials/messengers/vk/1_basic.py +++ b/tutorials/messengers/vk/1_basic.py @@ -46,7 +46,7 @@ }, }, "greeting_node": { - RESPONSE: Message(text="Hi", attachments=[Image(source="/home/askatasuna/Documents/DeepPavlov/DFF/dialog_flow_framework/1.png")]), + RESPONSE: Message(text="Hi"), TRANSITIONS: {lbl.repeat(): cnd.true()}, }, "fallback_node": { From ede04a97d445e64706301a3cc6efffe69ef90b5e Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:15:05 +0300 Subject: [PATCH 021/140] Delete bot_test.py --- bot_test.py | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 bot_test.py diff --git a/bot_test.py b/bot_test.py deleted file mode 100644 index 6b0fa3613..000000000 --- a/bot_test.py +++ /dev/null @@ -1,29 +0,0 @@ -import asyncio -from dff.messengers import vk -from dff.pipeline import Pipeline - -from dff.utils.testing import ( - check_happy_path, - is_interactive_mode, - HAPPY_PATH, - TOY_SCRIPT, - TOY_SCRIPT_ARGS, -) - -KEY = "vk1.a.BwQyndaC87dkYdmZQt9TCGuRx5VRh1_ZyvGy5Twxl35-u8euOrjHPU4YNh7Re7C-S8Am8zRyuexBatnFLksrfzCPG3kYXNmQ0Gm2Wld1Cx3b8VPAnW0M0agaDDboDBm5iYZdMJutpTqAqCyWlAaZPdEcKLdgSyqRSLO2cLac7MwTtOzN4jTtd8WJUoHOd3Ts0Af_KyefrG-NEzP9BbMHYA" -GROUP_ID = "224377718" - -interface = vk.PollingVKInterface(KEY, GROUP_ID) - -pipeline = Pipeline.from_script( - *TOY_SCRIPT_ARGS, - messenger_interface=interface, - # The interface can be passed as a pipeline argument. -) - -async def main(): - await interface.connect(pipeline) - -if __name__ == "__main__": - loop = asyncio.get_event_loop() - loop.run_until_complete(main()) \ No newline at end of file From 68b4a3725f93e467e133176edcddc75cf877f1b4 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 18 Mar 2024 10:28:48 +0100 Subject: [PATCH 022/140] review issues fixed --- dff/messengers/common/interface.py | 3 ++ dff/messengers/telegram.py | 28 ++++---------- dff/script/core/message.py | 5 ++- tutorials/messengers/telegram/4_conditions.py | 26 ++++--------- .../telegram/5_conditions_with_media.py | 37 +++++++------------ .../telegram/6_conditions_extras.py | 15 ++++---- 6 files changed, 43 insertions(+), 71 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 67d11cb1c..01ffedf67 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -27,6 +27,9 @@ class MessengerInterface(abc.ABC): It is responsible for connection between user and pipeline, as well as for request-response transactions. """ + accepts_attachments = tuple() + produces_attachments = tuple() + @abc.abstractmethod async def connect(self, pipeline_runner: PipelineRunnerFunction): """ diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index b8f76a318..edc783666 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -21,6 +21,9 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover + accepts_attachments = (Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document) + produces_attachments = (Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard) + def __init__(self, token: str) -> None: self.application = Application.builder().token(token).build() self.application.add_handler(MessageHandler(ALL, self.on_message)) @@ -50,15 +53,15 @@ async def extract_message_from_telegram(self, update: TelegramMessage) -> Messag if update.poll is not None: message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] if update.audio is not None: - message.attachments += [Audio(id=update.audio.file_id, title=update.audio.file_unique_id)] + message.attachments += [Audio(id=update.audio.file_id, title=update.audio.file_unique_id, from_messenger_interface=self)] if update.video is not None: - message.attachments += [Video(id=update.video.file_id, title=update.video.file_unique_id)] + message.attachments += [Video(id=update.video.file_id, title=update.video.file_unique_id, from_messenger_interface=self)] if update.animation is not None: - message.attachments += [Animation(id=update.animation.file_id, title=update.animation.file_unique_id)] + message.attachments += [Animation(id=update.animation.file_id, title=update.animation.file_unique_id, from_messenger_interface=self)] if len(update.photo) > 0: - message.attachments += [Image(id=picture.file_id, title=picture.file_unique_id) for picture in update.photo] + message.attachments += [Image(id=picture.file_id, title=picture.file_unique_id, from_messenger_interface=self) for picture in update.photo] if update.document is not None: - message.attachments += [Document(id=update.document.file_id, title=update.document.file_unique_id)] + message.attachments += [Document(id=update.document.file_id, title=update.document.file_unique_id, from_messenger_interface=self)] return message @@ -78,13 +81,10 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes for attachment in message.attachments: if isinstance(attachment, Location): await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons)) - return if isinstance(attachment, Contact): await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=self._create_keyboard(buttons)) - return if isinstance(attachment, Poll): await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=self._create_keyboard(buttons)) - return if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: @@ -151,15 +151,3 @@ def __init__(self, token: str, host: str = "localhost", port: int = 844): async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): await super().connect(pipeline_runner, *args, **kwargs) self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) - - -def telegram_condition(func: Callable[[Update], bool]): # pragma: no cover - - def condition(ctx: Context, _: Pipeline, *__, **___): # pragma: no cover - last_request = ctx.last_request - if last_request is None or last_request.original_message is None: - return False - original_message = cast(Update, last_request.original_message) - return func(original_message) - - return condition diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 780b1daf5..95c4dccb9 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -104,10 +104,11 @@ class DataAttachment(Attachment): source: Optional[Union[HttpUrl, FilePath]] = None id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None + from_messenger_interface: MessengerInterface = Field(exclude=True) - async def get_bytes(self, interface: MessengerInterface) -> Optional[bytes]: + async def get_bytes(self) -> Optional[bytes]: if self.source is None: - await interface.populate_attachment(self) + await self.from_messenger_interface.populate_attachment(self) if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index f32f791dd..69641a27c 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -5,7 +5,7 @@ This tutorial shows how to process Telegram updates in your script and reuse handler triggers from the `pytelegrambotapi` library. -Here, %mddoclink(api,messengers.telegram.messenger,telegram_condition) +Here, %mddoclink(api,messengers.telegram.messenger) function is used for graph navigation according to Telegram events. """ @@ -18,7 +18,7 @@ from dff.script import TRANSITIONS, RESPONSE import dff.script.conditions as cnd -from dff.messengers.telegram import PollingTelegramInterface, telegram_condition +from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -29,15 +29,10 @@ In our Telegram module, we adopted the system of filters available in the `pytelegrambotapi` library. -You can use `telegram_condition` to filter -text messages from telegram in various ways. - - Setting the `update_type` will allow filtering by update type: if you want the condition to trigger only on updates of the type `edited_message`, set it to `UpdateType.EDITED_MESSAGE`. The field defaults to `message`. -- Setting the `command` argument will cause - the telegram_condition to only react to listed commands. - `func` argument on the other hand allows you to define arbitrary conditions. - `regexp` creates a regular expression filter, etc. @@ -73,21 +68,16 @@ TRANSITIONS: { "node2": cnd.regexp("fine") }, - # this is the same as - # TRANSITIONS: {"node2": telegram_condition(regexp="fine")}, }, "node2": { RESPONSE: Message( text="Good. What do you want to talk about?" ), TRANSITIONS: { - "node3": telegram_condition( - func=lambda upd: ( - upd.message is not None - and upd.message.text is not None - and "music" in upd.message.text - ) - ) + "node3": lambda ctx, _, __, ___: + ctx.last_request.original_message.message is not None + and ctx.last_request.original_message.message.text is not None + and "music" in ctx.last_request.original_message.message.text }, }, "node3": { @@ -95,13 +85,13 @@ text="Sorry, I can not talk about music now." ), TRANSITIONS: { - "node4": telegram_condition(func=lambda _: True) + "node4": lambda _, __, ___, ____: True }, # This condition is true for any type of update }, "node4": { RESPONSE: Message(text="bye"), - TRANSITIONS: {"node1": telegram_condition(func=lambda _: True)}, + TRANSITIONS: {"node1": lambda _, __, ___, ____: True}, # This condition is true if the last update is of type `message` }, "fallback_node": { diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index b39dbd84a..67ecaaebb 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -4,7 +4,7 @@ This tutorial shows how to use media-related logic in your script. -Here, %mddoclink(api,messengers.telegram.messenger,telegram_condition) +Here, %mddoclink(api,messengers.telegram.messenger) function is used for graph navigation according to Telegram events. Different %mddoclink(api,script.core.message,message) @@ -17,15 +17,13 @@ # %% import os -from typing import cast from pydantic import HttpUrl -from telegram import Update, Message as TelegramMessage import dff.script.conditions as cnd -from dff.script import Context, TRANSITIONS, RESPONSE +from dff.script import TRANSITIONS, RESPONSE from dff.script.core.message import Message, Image -from dff.messengers.telegram import PollingTelegramInterface, telegram_condition +from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline from dff.utils.testing.common import is_interactive_mode @@ -38,7 +36,7 @@ # %% [markdown] """ To filter user messages depending on whether or not media files were sent, -you can use the `content_types` parameter of the `telegram_condition`. +you can use the `content_types` parameter of the `ctx.last_request.original_message.message.document`. """ @@ -83,25 +81,18 @@ # both in 'photo' and 'document' fields. # We should consider both cases # when we check the message for media. - telegram_condition( - func=lambda update: ( - update.message is not None - and len(update.message.photo) > 0 - ) - ), - telegram_condition( - func=lambda update: ( - # check attachments in message properties - update.message is not None - and update.message.document is not None - and update.message.document.mime_type == "image/jpeg" - ) - ), + lambda ctx, _, __, ___: + ctx.last_request.original_message.message is not None + and len(ctx.last_request.original_message.message.photo) > 0, + lambda ctx, _, __, ___: + ctx.last_request.original_message.message is not None + and ctx.last_request.original_message.message.document is not None + and ctx.last_request.original_message.message.document.mime_type == "image/jpeg", ] ), - ("pics", "send_many"): telegram_condition( - func=lambda upd: upd.message is not None and upd.message.text is not None - ), + ("pics", "send_many"): lambda ctx, _, __, ___: + ctx.last_request.original_message.message is not None + and ctx.last_request.original_message.message.text is not None, ("pics", "ask_picture"): cnd.true(), }, }, diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index ea2b8da15..7ed535e0a 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -5,7 +5,7 @@ This tutorial shows how to use additional update filters inherited from the `pytelegrambotapi` library. -%mddoclink(api,messengers.telegram.messenger,telegram_condition) +%mddoclink(api,messengers.telegram.messenger) function and different types of %mddoclink(api,messengers.telegram.messenger,UpdateType) are used for telegram message type checking. @@ -19,7 +19,7 @@ from dff.script import TRANSITIONS, RESPONSE, GLOBAL import dff.script.conditions as cnd -from dff.messengers.telegram import PollingTelegramInterface, telegram_condition +from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -60,13 +60,12 @@ GLOBAL: { TRANSITIONS: { # say hi when someone enters the chat - ("greeting_flow", "node1"): telegram_condition( - func=lambda x: x.message is not None and x.message.new_chat_members is not None, - ), + ("greeting_flow", "node1"): lambda ctx, _, __, ___: + ctx.last_request.original_message.message is not None + and ctx.last_request.original_message.message.new_chat_members is not None, # send a message when inline query is received - ("greeting_flow", "node2"): telegram_condition( - func=lambda x: x.inline_query is not None, - ), + ("greeting_flow", "node2"): lambda ctx, _, __, ___: + ctx.last_request.original_message.inline_query is not None, }, }, "greeting_flow": { From 6f8de0b5a9dab17439760375c8669af8a34cd912 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 00:24:33 +0100 Subject: [PATCH 023/140] lock file updated --- poetry.lock | 1399 ++++++++++++++++++++++++--------------------------- 1 file changed, 662 insertions(+), 737 deletions(-) diff --git a/poetry.lock b/poetry.lock index 343d984ba..75fe27bb9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -570,34 +570,6 @@ files = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -optional = false -python-versions = ">=3.6" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "beautifulsoup4" version = "4.12.3" @@ -621,33 +593,33 @@ lxml = ["lxml"] [[package]] name = "black" -version = "24.2.0" +version = "24.3.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, - {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, - {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, - {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, - {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, - {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, - {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, - {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, - {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, - {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, - {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, - {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, - {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, - {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, - {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, - {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, - {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, - {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, - {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, - {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, - {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, - {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, + {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, + {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, + {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, + {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, + {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, + {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, + {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, + {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, + {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, + {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, + {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, + {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, + {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, + {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, + {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, + {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, + {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, + {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, + {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, + {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, + {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, + {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, ] [package.dependencies] @@ -788,18 +760,18 @@ files = [ [[package]] name = "build" -version = "1.0.3" +version = "1.1.1" description = "A simple, correct Python build frontend" optional = false python-versions = ">= 3.7" files = [ - {file = "build-1.0.3-py3-none-any.whl", hash = "sha256:589bf99a67df7c9cf07ec0ac0e5e2ea5d4b37ac63301c4986d1acb126aa83f8f"}, - {file = "build-1.0.3.tar.gz", hash = "sha256:538aab1b64f9828977f84bc63ae570b060a8ed1be419e7870b8b4fc5e6ea553b"}, + {file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"}, + {file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"}, ] [package.dependencies] colorama = {version = "*", markers = "os_name == \"nt\""} -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""} packaging = ">=19.0" pyproject_hooks = "*" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -1058,13 +1030,13 @@ files = [ [[package]] name = "comm" -version = "0.2.1" +version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false python-versions = ">=3.8" files = [ - {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, - {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, ] [package.dependencies] @@ -1101,63 +1073,63 @@ files = [ [[package]] name = "coverage" -version = "7.4.3" +version = "7.4.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, - {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, - {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, - {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, - {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, - {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, - {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, - {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, - {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, - {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, - {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, - {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, - {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, - {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c"}, + {file = "coverage-7.4.4-cp310-cp310-win32.whl", hash = "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d"}, + {file = "coverage-7.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b"}, + {file = "coverage-7.4.4-cp311-cp311-win32.whl", hash = "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286"}, + {file = "coverage-7.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9"}, + {file = "coverage-7.4.4-cp312-cp312-win32.whl", hash = "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0"}, + {file = "coverage-7.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c"}, + {file = "coverage-7.4.4-cp38-cp38-win32.whl", hash = "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e"}, + {file = "coverage-7.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade"}, + {file = "coverage-7.4.4-cp39-cp39-win32.whl", hash = "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57"}, + {file = "coverage-7.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c"}, + {file = "coverage-7.4.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677"}, + {file = "coverage-7.4.4.tar.gz", hash = "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49"}, ] [package.dependencies] @@ -1755,119 +1727,119 @@ test = ["cffi (>=1.12.2)", "coverage (>=5.0)", "dnspython (>=1.16.0,<2.0)", "idn [[package]] name = "geventhttpclient" -version = "2.0.11" +version = "2.0.12" description = "http client library for gevent" optional = false python-versions = "*" files = [ - {file = "geventhttpclient-2.0.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f509176bc7754b1181375a25ec6909425a5997e58c98ea29a36fe8b6a376852f"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cda51b46d8ab3993763a394ed6601137c32f70cff78dfe703edecb3dfa143009"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:072f24198c0f179fcd8567e9270d5cb78ceea1d562a55b052cd083cf4c67feef"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b97c84e9be76bdd726757437327be5446710eafb64f7097d8d86db9c0f7d280"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abb32554c1ad103ed1114cee3d75fa6a3c5d8a0898e4e64db68f3fc0f11fb0de"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78a7e493e09d0aa4ba9651147d02fc555159371fecab0e4e96196c72f191322e"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e521089a3a95c98e1742f1a1ea41568b029bc2528cc6fc7ab91bb5d416f1f2c"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8329c60d94e688d75ec1c6f67a77ab96f726f8ea562a8d48afa1ed6470334a6f"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:572364fc4acd7ff2e77641e6bd1e64cf315d899a7fc48953eac1dd3b6865fd99"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:81e73ee32f4217072935825a0bad7264dc803b0d24cc4e2f4bfcac3fff49a899"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d79ee0d7ab5d775b056400155cab1e3547a7fa6511f6098e25613ed8705ae8b8"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-win32.whl", hash = "sha256:2911d3657e2426b6a2d59af0b52285c1a7c4a78d0e4d03ee4ec1d5195a25a09f"}, - {file = "geventhttpclient-2.0.11-cp310-cp310-win_amd64.whl", hash = "sha256:a489573a0a0559f8960b38795dc53d1e222bc0978b211763d1303b2f94e4c3e0"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1e27a9521e0ad0d97d0ff81578fd4dd6ae9eee8095d46edb820dfda33c0bd233"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d54b886ce042186a4f731dcbcb4ffa8d674b0542907fc72de20d0b5088adc252"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f2337e10e2ad20970436f216d7b3b8d1503f8e4645d439173a98b4b418fe5768"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f41bcdcec859264a1b6cc7c57bdb9411da8047f17b982cb62756bcc74a1b045b"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f5d73be013a7a2a357eb27d18e5990c773365f63f50a43eaf357d6efb1fd46a6"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4d86f042501a783e94188ef8b099f32bc4680f2423bbbb56f40158d4556a56b"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaa2bc31a38dbb387c7539cfa03d3bafaa32151972d34b42f2f648b66778e128"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3e24ff4c398f9e49c5c0740585f12fcf7033dc27a20ec884f3b2c729e2f47f14"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b70f80528ae74518a16214261abba2a276739e6e35ce518fdbd8be2a3f42f93a"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:efa467997f87d39f774ed1916a9e184c9a936f8fa90ab1a8ebf97aba2ee7ed63"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4597ea18ddc9838dc0e6cb9d5efb812191f2ca65ab38c115a56894045c73ea40"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-win32.whl", hash = "sha256:a4361c5a522d2a79d8a9047926b8f8926e0f797777da9f450d359bed9f33ac33"}, - {file = "geventhttpclient-2.0.11-cp311-cp311-win_amd64.whl", hash = "sha256:f430257a7b0a75e7f4c0d6f4f3f8960d45b5aae56b8eca7988963487501a52a0"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a84f48f2eff42171cc446690baffa914122e88cea5b1de44cf6dd1c82b07623b"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a21dba9cf5e7511e76845f62dcf5072f4df7415bb8f20e47e0dfde675943a39"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99feb5581111c7ec44e1ce507b4420947b4c49b363b2fbc3edd543e2ac67a1e0"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bc799d50db685e093b5819459889f356dd7478a82af66f880832a95fcfa37c3"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94a8be54ac74ff6cf4703d049766e6ed07787fa9b6a2dd538c46f81de72ffdde"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71a9e152bb3cb86552f61659f3c7bdc272d9baf21726b3caceb5ab5d0e703fe6"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05a7699b49c9bc478b7ae165809ff97b21811a624791abe3927da5066128a10c"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:598951751b2162b0697cd5b6a9edcc65ec30f34388b6e09caaa0c453fb08fb6e"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4f0c773ceeeedfab56b24b97a0c8f04c58a716dfc7403e51ea898ad01599f1a6"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ee03ea884e6aa318078c0c7132d246fe92b51d587410532e63b864e6e61ea192"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:98a25e30ddccd49f80e037d48f136050b8f3c24ed9c6a69df7a643989f29c4e8"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-win32.whl", hash = "sha256:968587b59372e825411935e188b9a05dcdec6db6769be3eb3bba949cb414ae98"}, - {file = "geventhttpclient-2.0.11-cp312-cp312-win_amd64.whl", hash = "sha256:465e62fb055e2ca5907606d32d421970f93506309b11a33b367eef33d95a6b7a"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ba597da51b59df28cf484326d7d59e33a57d3b32d7a4e1646c580f175354d6ce"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c125a225188bcacd51f05878d6e62554116a5be6b3a203cd0ba2460857bc8cd3"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f016093e8d26b724efdeda776968368fb591a57afbded2d86c408db8723e38ce"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a25a7fc768791cf9fe590f1b4f231727441e8f7e9279e8ae2bee83e0f3b010f8"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae71a7740526be78c6e899b03b63ab47a1a434332f7ca725dcdc916d938d46c6"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:06914f401541681d8cb834652f53e65a8179ea17dd0e496fd52712fd3f548fbb"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6ccdebfd20ab07ace7aa4dcd020f094d1cae237b4eacfca08ac523cac64e02d3"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:b2bea1386dbfd262571157da319e2285e20844fdbaabb22f95e784ca8b47d90c"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f468f88df7649bfcc6f74878182d0b7bcb3c23445a76be2b8b59e46224e2c244"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-win32.whl", hash = "sha256:d75c706f2a2401f703585cddf51cb0e43c28b7f12b1998c4a41fd6d14feec89b"}, - {file = "geventhttpclient-2.0.11-cp36-cp36m-win_amd64.whl", hash = "sha256:27f9e22a31451087854204f7f341bd4adc32050180580f74b5de75b61a3b405f"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:105af48455d4eecb4e0f2b2b7f766131811aa1a9a1e768fb020b9ae0ba840ee4"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb9e9c6f3fb902dd622964097df77e0ed9b249b8904b44fc3461734cc791b0aa"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1b73c37fbecb26475fa6e2d018dab4b5a03c7ba08c8907598605c874a70ee79"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09167de901f5b5273ddc14fd53512cc696495be07f02e3cb8a0335e1ecbff57e"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52ac561df8d363fe2e00ba4cccea470745129a48bb86f665a1447d0d68abec54"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ceb038cbf92105d124433066685c73e6a4a762c15885f00be2e25663468e4f29"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:0b70eedf64c162067765ddfb30c8f52daeb875c717a3d25f81d5e411e5ac4367"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:e87fb8bd748bf32e9902e9cbea3f20ff5456705d3f53f0a8ea0c4983594457a8"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0ae01d50529ac739573bc9cbc192b71bf9a13c3fcdbf2054952947a25e9f75a3"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-win32.whl", hash = "sha256:beb3a99e7a0a5130fbed2453348d81a78f2ef7d6aa326b5799c7f3dde88cabea"}, - {file = "geventhttpclient-2.0.11-cp37-cp37m-win_amd64.whl", hash = "sha256:63fc49d73e70cab8316a4d0106c037a2a5d0f6650683af05d0d05d354b694d49"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:106e2ba0ce34a3501651995dd46ed38b87e7b5ada0fb977142d952661853f36a"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0edacd51cd9a6f0b88e25cb6c8744488ba6c7c22044b09de585b2a1224f2a7b9"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2214352e01fef4218bbbc61bd84af6f101bb5a33244088f6db28ff6d1141797f"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38384af2da776563a19951958df65e31ecc7b8d20788d43aff35ec909e4a115f"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33c4af3aa0312c27668171ea061d461f678848a09a32953b4d895f72a1bde0c9"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d461cdac133d4a4d173e2c1cc213f3a9924e6e092aeebd49bf8924719a073e0b"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ad49019e2828508526d35e7026b95a1fd9ef49ed0cdd2526a5cb3eb39583640"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a59b164a68bbb1a6f7bee859d7e75ef148b1e9bd72c4810c712cd49603dc37cd"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6cc44c57c02db1ded6f5a6bd4ccc385c4d13c7ae3528b831e70b5cc87e5b0ad1"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2d7318b3493c2e21df79429be3dbfefbc254c41a5b5c02c148a4521d59169ad6"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:40df90cd9b5f5f7355526cc538e626466cb60c2e737e9cb8958569377d568e9f"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-win32.whl", hash = "sha256:6f89edc316a8ff967a50c6f98277619786ed6abf2dd36ea905baf840a02b1b1b"}, - {file = "geventhttpclient-2.0.11-cp38-cp38-win_amd64.whl", hash = "sha256:b179a13c113a90c5501f1b1121bdc4c1f816d942280a9c3d2d46aff2bc97269a"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:63826170b520894578bd269b54139bb2f0cc2d96ae1f4a49b3928fe01ffa22ff"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a6fcc3968ea1adf764bc11b0e7d01b94ffe27bdd21c5b1d9e55be56de6a53c3"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c61c02c2d32e1b5b1f73d2b201c1e088e956b73e431ed6b5589010faed88380"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aec646409fa6eee277e33a1f4f1860d4c25e0448eedea149df92918d4502f38c"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b91290138518b201fba98bc82b062ef32e5e3da28843998902852298c354dcf"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b523860ee558f752847b29ad6678d1b8a40154d06bc7a8973132991aff727fdd"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5594bc889a686511039d1efd17473eecc4a91fa01d66a59bfa0a8cf04fb34551"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e573b86999cfeae38c4dd881f05818b9a60245a6763bc77efb48fa136cefdfcc"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a30bd715480ddbab0217764b516a65e36ecee2e81c9a04d074769eec6e0c1681"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:49ff1c00e64e0820a02fadc6a72b49ae8cc69028caa40170873a3012de98d475"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea232981e29869524e85b5e6c79ad64abf40dd7b6dc01be6765b5e6bd191fd73"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-win32.whl", hash = "sha256:a0b30fef1eb118927b5d8cab106198883f1bde021e9036277ea2f9e0020e0ad2"}, - {file = "geventhttpclient-2.0.11-cp39-cp39-win_amd64.whl", hash = "sha256:844b30e3694a4d9518fe6f0b167fa3ffc3ea3444563d9fdd7a18a961f6a77d9c"}, - {file = "geventhttpclient-2.0.11-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:94579ec289d46fca939b78cfe91732e82491f3dab03604f974a2e711654e7210"}, - {file = "geventhttpclient-2.0.11-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955b04deac7ea09a3d5183ba92a3d2a81121ad71d10f1489cb56fd31d0cb4ac4"}, - {file = "geventhttpclient-2.0.11-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7947aae2d7123a970669ebd763a09ef0c85104cda414689dd77b5e5a5c1f2a40"}, - {file = "geventhttpclient-2.0.11-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c483daa1deda0c52a77ed7af2906a38657c15120cb3240bf589dfb139255921"}, - {file = "geventhttpclient-2.0.11-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bc9634e025f17dc25987ebd5b0461659178ca57052ec70ad65052d0495111a74"}, - {file = "geventhttpclient-2.0.11-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9dca243f58f245872458647b0b6da4be9ce8d707639d76a50d2e8d3f4abb1659"}, - {file = "geventhttpclient-2.0.11-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64d36604974bc2b2ed0166bc666cead87f3c0f2d9487ef73d4e11df9ba6ebcc8"}, - {file = "geventhttpclient-2.0.11-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46677a56fa9f2f650be74024601b3a1968cfc58a434f5819fc2fc227bb292836"}, - {file = "geventhttpclient-2.0.11-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:989a1ed8dbdaf683dd5701087b736b93e6bacb3c29f4090014e64033cc8620e2"}, - {file = "geventhttpclient-2.0.11-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9b406ef64382a9c42b88331cdd6639a2b998e8034dbb1b702264d27c01f3ad5d"}, - {file = "geventhttpclient-2.0.11-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:713530c8f67a08ce0d5a4af80045112213c63eacefa1c08b76beebf780c755b0"}, - {file = "geventhttpclient-2.0.11-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd894ec63974fe4e916a1bf6efd35307b86ef53bd88e8fbe61020a289fee2f7c"}, - {file = "geventhttpclient-2.0.11-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e18e622171d09f068b26304b7d3c484d55952813e09eec5b3db1012dc53795de"}, - {file = "geventhttpclient-2.0.11-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce8421aa0a2307edf04a7086236e7e9f9188ab349154c409d723744032746eb"}, - {file = "geventhttpclient-2.0.11-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:237eba77682553253040588f136a2980dfcd71307202422a17b716e9d8be5614"}, - {file = "geventhttpclient-2.0.11-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:60641b8ff7077a57bb68f1189c8ae8ffc6f14ae238ba6a81748659c30894d580"}, - {file = "geventhttpclient-2.0.11-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5939bca6ab38a482352be8a7141570464d4d18281d8a3a2e2f7a82a0d8c38c4"}, - {file = "geventhttpclient-2.0.11-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:025026620e5a369844b576981ddab25d60e7e3bb0e0657c1fe9360a52769eb9d"}, - {file = "geventhttpclient-2.0.11-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b48b10e2a812b9297ad5c43e7a1a088220940060bbfb84fb721b17ab3012e0d"}, - {file = "geventhttpclient-2.0.11-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e572e63e51fde06c30beabf8021e7d3f93e198a9c241ef2f3ed16d7828966768"}, - {file = "geventhttpclient-2.0.11.tar.gz", hash = "sha256:549d0f3af08420b9ad2beeda211153c7605b5ba409b228db7f1b81c8bfbec6b4"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6d0fafc15bbd93b1f271b4c14b327d15c6930c8d78d8ee0d8a55c9cd3e34c18f"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3f429ece7b6612ef333e9bbeb205513cec33a178f545b3612530a9c5c36a0310"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20ffc5a2b9cb5557d529d9296ffdaa5057a23e6bb439a905160a787079ec78a2"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80a96670c5ab668f52dcaf705640b442faeafb2bfd2e54d5f08ac29ac80aab12"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766aff690198119c998474d9c20c1b3ffaff337d0d62a6d8b19cc871c3a276d"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6d15f459737178e2b9a1d37b32161955a7d72062a3fc473d88c9e9f146cff22"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a75007314fc15947fd94f154e139a6f78a4d40ed70d52dbb1724e7ea2d732ca7"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:16e440152ea4f943dfc476462c1c3f29d47d583e679b58bccac9bfaa33eedcfd"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e1d9c9b533b6c0b5a7eac23f68b25c8d3db1d38b8e504756c53366d2622a24a5"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:758dd4a3172f740255f755fd393f0888e879a7102a537bba98a35a417be30d3e"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:933426c92e85d8f6717c4d61f2c6c99fbb7d84c91373400eaf381052a35ea414"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-win32.whl", hash = "sha256:e70247c900c4e4413af155e49f342055af9eb20c141735cce36d8a9dc10dc314"}, + {file = "geventhttpclient-2.0.12-cp310-cp310-win_amd64.whl", hash = "sha256:8dac40240fe446b94dd8645e2691d077b98b1e109ed945d2c91923c300c6f66d"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3e3b3b2857ed48dd8af15c8e09539c8e0bf3721f515c0a8f3cfcbe0090196cc4"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:114cfa7f4db7dcb5603ade4744bc6f5d6d168c94b05aca052e2fc84c906d2009"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:904aaab04a8c4ebf52217930242693509cfbbd90f2b2afc454e14da82710367f"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56935ebec38a7c9ccc3dcadaebf2624601567504cd3a44794dc9262aca147040"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bff88eededd1f915cd86de5e8a891e1988b6d42093cc07be5fe3133f8baf170c"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:212014f4133938ba6453dbfa6d3a643c915dd4873d1de1d6172e4c6c178e4a6c"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d471e79a55d37ad021a4832b0895bccb638f70664040a29230e156a0b92b23d"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:599c4d37d928323b5f0353434f73de9e88f305f59a5472ffc7f5c131a2485512"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fddf2b3c4d5d99b826561173be04adbc92cab52081ba142c2158e0ba3b08b762"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5075c7f15e0a39b7ceae6afcb0b3a66c0ab9364a9eb589b7f51b567835fae5d7"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:58a6f9d93ef2b1a09479564c951bc7b058350bd757628a32945f274cd314fb98"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-win32.whl", hash = "sha256:a0bb5a35b199356b0c9b5ec3c3152ebfe4ecbd79e00d486d461920a9d96d1fd2"}, + {file = "geventhttpclient-2.0.12-cp311-cp311-win_amd64.whl", hash = "sha256:972a92f4a453a3ef4737e79e7e64f3089a06f385e13493fa19381486e893bd98"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0bee74f32eed6278f3837e07983b5a6b186920c7eb3b35bc6e97360697632655"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fb85d8ed42cc389e5cdac06221f16cb6bca9dbbf5219c44d0731f742a6bffc09"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c302a16328406003cf4d7d71f59cafc2d42f13d5dc9ea4c8bd248390de985a86"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3266ef4da21a47d0181d4e3cb5209494e3ce6e4d4cc71414ea74b3a1f7e0e921"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acb7a257e8f4f0c0335a259f2e9eae527fa042db9ea2e4580a381e9c01fc49f4"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4741d66098b2b289f584effa7de3ae7bf1efb06e2d83abdbbc468a0a4dec6b3a"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef2b523043ab9c6057ed19993f629e3fa47f8f92a319f5682de05e604ed8cc9"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:235058a6e420b2aae196a4ba7e23f81ebc2dc3acf6baa9d85dc99963b3e0f0cf"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c918d731e0fe676b4c06f53081526f4d3f4836b7a72be7b46c90603a280260fa"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:9e7696a61b384f8d2a075cca9633fdcc897c43eabbcf70fca492206241fa1a3b"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105a1aa161223079dbd669b4334cd765964b5917ca4f3da8c5b59c4ef36a0adf"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-win32.whl", hash = "sha256:09e13c05633d1eeb2cba68835618f4ee25c5a7b466c47cfdb01174f61e51a23d"}, + {file = "geventhttpclient-2.0.12-cp312-cp312-win_amd64.whl", hash = "sha256:f853438a1850d45fb434e42ffbb06be81af558e5dd9243d530c2cdc5f804627f"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62ad2ac321967ff92768e93ea18cb59f8920fbae5b42340b93e7cf11ee4f35d3"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de8b6618a354bded39224def8b6e8b939c468f0edeb2570fdacd9003fd14c57c"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:902ba66284d40dd97a693e952e4bb2f59528806ee40ecd586471fd5bca7fb295"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ef6c9acff6ce379c8a851554954eee6481c35531d82888a46ccada0ea17a791"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e8abf4ccd59d58f7aa91f4c68760d82534bac5c5c9b7d2ccb4c0a5fc69585ff"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:bdeed563faa09fd51ee4606b92f69ecd42b67277ed590f2921816941ed031177"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5a7d9b7e2dbc962f143938cdef8a657af1ccf423b2443a194b86ba0e85735c23"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:a9a7ea4665418abe093e48576769181ae3c75a97cafe107c0463a169af755b2c"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:19488a212c858792fd4fa83be568d4cdbbd4c1267b03b10b6a8a654fd862d2f9"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-win32.whl", hash = "sha256:445b80548062ef6c1b30e5e1b4ec471937fda64b783da953462972f48c2038de"}, + {file = "geventhttpclient-2.0.12-cp36-cp36m-win_amd64.whl", hash = "sha256:bf283bdbb4b935bfef114e1af19535a602e717ae9a7e8408ab61775d06a463b4"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:370086ced942449f9b60590d215eec7f81fe54d7e3ee3add6b2f014ccac4f38d"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e405735db8261ca99d9b80fda3f46d457f04b98a7ce0e49bb35ca32c2a5bbb2d"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f4680b0ed5e588437797026f25829eb9681954ac64470dc8014436910b2fb09"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad053e7b4ac2f9fcdb02a5d9b99fd72acf28265ba8be7392a25235bb631d2511"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64232158542f2adfde24f41c1e3ed731cca67e469e653ac7634815af168551b4"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9be5c3f68e4f41aceccae38508029a70b1fb3f9fc840b7c55971f5fbe099d7e4"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:06b4276075f4f3eeb30a3c1476f40d53030159450def58c1d8c3b724411d8ed9"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b311beb0657394b5df09af05ec5d84058f3531f3176ab1a0f7f4eae7b56bc315"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b6a9d00b58527328d9f7a0a20b715d4e780a990b0fb75b556085417c22d73dd0"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-win32.whl", hash = "sha256:987ef3bd0d7e3b01cafc8e135ab6e8f977b60eeda096ead2cb5504124896b1a2"}, + {file = "geventhttpclient-2.0.12-cp37-cp37m-win_amd64.whl", hash = "sha256:dca64867b2d79433eb8557db00e74e17a2f0d444a9a90fb6f49cadaeddf703a5"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:707467d6e8ad19749e7130b7c7bcb3a446c8e4f66454e1d47f4dfffa974683da"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c2e436a2c41c71db17fd46df4925eb5e4d3856eb1b5fda0ce6b1137a6c6c87fa"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f88d2f3a20afa999548622b31dbc3db5aa355c3032f3ae96a4195c5f938fee92"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a6581b8de9fa4b44916dcfabdc608409cfcf02fac39a62d40f6bcf6af726ad"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c91e0ee50f8a1ea3a268f06c5bd44efe86b7f57961d7c923602038fcc010c3c"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e3031817b8f2411086765de4bb1080c755b009ee8dc4a6111ad74f6ff4a363f"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ff9a95e2d2035c1f5ac726166a598ea4071412c304a74a8cd5d2d8dfbf40b5e"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:04f41d8f14e241e8d0c828ff59634674e98f96f39f6d12f43009a7332c4e2c82"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bea7376205629e8964f624b08d6836892e8d17ed8b8a57d5d2edbd7983440652"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd9baf30e2bdd3110394365998037a45b43f86804b8f3c77f194f64eddc7dc54"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:23c27b04ad25258959c088c0d87832befc7be2b09c5c35fdd76e417f5b546da0"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-win32.whl", hash = "sha256:792e154009f6f63e3fbbe4b3109780ada275c4ed29659430c06dc8e1b2ed03ef"}, + {file = "geventhttpclient-2.0.12-cp38-cp38-win_amd64.whl", hash = "sha256:7b41a0510297a8ebbeffbef082e0896ecf37d5302999a3b58d208193c3c3e362"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5006e34586bba4ebd5a7a5482f9e7743e1b3b9ff50c994105fb45e43044c38c9"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d812074192822f57603973d6bcced0f02c6cc371cf63e729793f193c874f30ce"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a64bd8bce446be4fe869b64af310cd218d2329aa4e9d85b6a060da93c62296b"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7fc536f2972c75da85f9360d0a3e5433baf6d777442a013052f9a501311ddcd"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a60dec2ac44f494af9e42889dd7f7d653545b4c4892da4acbe383c0ffc305a1"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa2ef1b92662ee9866bda52123f6f266ff4479437e7b5037a6427cf09e071e25"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b8215e9a018a3634bdef4891634ceb9b10f47292b0091a1d96c363d8d5d7fdd"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:90d5c0974518d35514a8896529d113e778e9d42d10699ac6051cd3e8f1ff81f6"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:83c28617b02b6ab53653324b2a9ff2d4a4b1f1582fbc4e70f47d2ef9fe6ab1f7"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d8c7dfa2bcd15988a350e90b32c6b5426924f2ffd0ce75f52ca2d5ef540b3fbc"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ded99bdbe7953f0734720d9908ed6f808fd12e97de05508822695a87b69f10f2"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-win32.whl", hash = "sha256:ebcd7311901e52929d2bd3af9442970fdd12b200285d9a55d52994e033e73050"}, + {file = "geventhttpclient-2.0.12-cp39-cp39-win_amd64.whl", hash = "sha256:204c3976b2a4fcefe8f157fe303da45b85fc31147bdfce7b53b1098f05f1cad2"}, + {file = "geventhttpclient-2.0.12-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c651d22fae3084502afc876e8c73d521496f512e16828939333f17cad64ea47f"}, + {file = "geventhttpclient-2.0.12-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c111addb5b27431805a8ad544dec292a7153cc44b68df28e782821431970d8"}, + {file = "geventhttpclient-2.0.12-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14cb7f4854d77c63506e31677fb548d137b20cbe34a11b5442f065b1e46c2246"}, + {file = "geventhttpclient-2.0.12-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8ac257aa714999b523282c0da6faf4d333d44131cea3b15fe802e00d35dd5c2"}, + {file = "geventhttpclient-2.0.12-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d97a41f959cd331eb8a633ed8edf6cc002a2a41a21e94876db833729b803924f"}, + {file = "geventhttpclient-2.0.12-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6ecb9a600a2da862b079ef3ebdffc9acec089c914bebc0c54614049584bfbb94"}, + {file = "geventhttpclient-2.0.12-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:662bb04e99466c25a1bf8b47351f79b339b6627721bb357bf3bc0d263c394176"}, + {file = "geventhttpclient-2.0.12-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a6b4c9e1ade3ae090b7b679d5b691d0c87460612983d4ab951043f859adffb"}, + {file = "geventhttpclient-2.0.12-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a359605dab2b92df4ef1bab7f1bec26e82acdc4253828a508f55375af50b48"}, + {file = "geventhttpclient-2.0.12-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:fc17f57be8254329715702d00536a443c29b52f2ef750bc0650554fb3b7e33e7"}, + {file = "geventhttpclient-2.0.12-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b58096bcaaa259e8d107749539b1d3804fc6ec395e91dec8040d448d298861c8"}, + {file = "geventhttpclient-2.0.12-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb66bff9ed4d4f0bced3498746d86c949bf99e2440ceb968e6e7c542b3982b0"}, + {file = "geventhttpclient-2.0.12-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0158f45fd611b585c54380d981181c303313f3e059395310112805f53998d061"}, + {file = "geventhttpclient-2.0.12-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13129723ba3568f0a373cbd612130e2d78b3f284cf6a62385e26a92d7627a570"}, + {file = "geventhttpclient-2.0.12-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:571be0c875503ef5088cb417e84b707c922e3e2bd5e302e609d25e008cf037eb"}, + {file = "geventhttpclient-2.0.12-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:46e1706e3a44bb3423fc8d10b44e71c8a52c6535e22d483519dde008723c4f25"}, + {file = "geventhttpclient-2.0.12-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9de259de7ccc19b47537e21b47a74442ad64d1a1a262b971713d6af8cc8f16f9"}, + {file = "geventhttpclient-2.0.12-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d777dced8a8e04fd8e0811c3b764d9a476b6a4c865f10079cc4f27b95b37196"}, + {file = "geventhttpclient-2.0.12-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcd4f45055a2e2f66e67016599d3fac33bc67b3bd67b672c1503a5de7543c1b6"}, + {file = "geventhttpclient-2.0.12-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61b078cfc4b34a0d50224adf80c7eeae8e23fe6d8cb35926ccd3f3a6b86f921f"}, + {file = "geventhttpclient-2.0.12.tar.gz", hash = "sha256:ebea08e79c1aa7d03b43936b347c0f87356e6fb1c6845735a11f23c949c655f7"}, ] [package.dependencies] @@ -1909,13 +1881,13 @@ test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre [[package]] name = "googleapis-common-protos" -version = "1.62.0" +version = "1.63.0" description = "Common protobufs used in Google APIs" optional = true python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.62.0.tar.gz", hash = "sha256:83f0ece9f94e5672cced82f592d2a5edf527a96ed1794f0bab36d5735c996277"}, - {file = "googleapis_common_protos-1.62.0-py2.py3-none-any.whl", hash = "sha256:4750113612205514f9f6aa4cb00d523a94f3e8c06c5ad2fee466387dc4875f07"}, + {file = "googleapis-common-protos-1.63.0.tar.gz", hash = "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e"}, + {file = "googleapis_common_protos-1.63.0-py2.py3-none-any.whl", hash = "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632"}, ] [package.dependencies] @@ -1997,69 +1969,69 @@ test = ["objgraph", "psutil"] [[package]] name = "grpcio" -version = "1.62.0" +version = "1.62.1" description = "HTTP/2-based RPC framework" optional = true python-versions = ">=3.7" files = [ - {file = "grpcio-1.62.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:136ffd79791b1eddda8d827b607a6285474ff8a1a5735c4947b58c481e5e4271"}, - {file = "grpcio-1.62.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d6a56ba703be6b6267bf19423d888600c3f574ac7c2cc5e6220af90662a4d6b0"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:4cd356211579043fce9f52acc861e519316fff93980a212c8109cca8f47366b6"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e803e9b58d8f9b4ff0ea991611a8d51b31c68d2e24572cd1fe85e99e8cc1b4f8"}, - {file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4c04fe33039b35b97c02d2901a164bbbb2f21fb9c4e2a45a959f0b044c3512c"}, - {file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:95370c71b8c9062f9ea033a0867c4c73d6f0ff35113ebd2618171ec1f1e903e0"}, - {file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c912688acc05e4ff012c8891803659d6a8a8b5106f0f66e0aed3fb7e77898fa6"}, - {file = "grpcio-1.62.0-cp310-cp310-win32.whl", hash = "sha256:821a44bd63d0f04e33cf4ddf33c14cae176346486b0df08b41a6132b976de5fc"}, - {file = "grpcio-1.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:81531632f93fece32b2762247c4c169021177e58e725494f9a746ca62c83acaa"}, - {file = "grpcio-1.62.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:3fa15850a6aba230eed06b236287c50d65a98f05054a0f01ccedf8e1cc89d57f"}, - {file = "grpcio-1.62.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:36df33080cd7897623feff57831eb83c98b84640b016ce443305977fac7566fb"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7a195531828b46ea9c4623c47e1dc45650fc7206f8a71825898dd4c9004b0928"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab140a3542bbcea37162bdfc12ce0d47a3cda3f2d91b752a124cc9fe6776a9e2"}, - {file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9d6c3223914abb51ac564dc9c3782d23ca445d2864321b9059d62d47144021"}, - {file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fbe0c20ce9a1cff75cfb828b21f08d0a1ca527b67f2443174af6626798a754a4"}, - {file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38f69de9c28c1e7a8fd24e4af4264726637b72f27c2099eaea6e513e7142b47e"}, - {file = "grpcio-1.62.0-cp311-cp311-win32.whl", hash = "sha256:ce1aafdf8d3f58cb67664f42a617af0e34555fe955450d42c19e4a6ad41c84bd"}, - {file = "grpcio-1.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:eef1d16ac26c5325e7d39f5452ea98d6988c700c427c52cbc7ce3201e6d93334"}, - {file = "grpcio-1.62.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8aab8f90b2a41208c0a071ec39a6e5dbba16fd827455aaa070fec241624ccef8"}, - {file = "grpcio-1.62.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:62aa1659d8b6aad7329ede5d5b077e3d71bf488d85795db517118c390358d5f6"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0d7ae7fc7dbbf2d78d6323641ded767d9ec6d121aaf931ec4a5c50797b886532"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f359d635ee9428f0294bea062bb60c478a8ddc44b0b6f8e1f42997e5dc12e2ee"}, - {file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d48e5b1f8f4204889f1acf30bb57c30378e17c8d20df5acbe8029e985f735c"}, - {file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:662d3df5314ecde3184cf87ddd2c3a66095b3acbb2d57a8cada571747af03873"}, - {file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92cdb616be44c8ac23a57cce0243af0137a10aa82234f23cd46e69e115071388"}, - {file = "grpcio-1.62.0-cp312-cp312-win32.whl", hash = "sha256:0b9179478b09ee22f4a36b40ca87ad43376acdccc816ce7c2193a9061bf35701"}, - {file = "grpcio-1.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:614c3ed234208e76991992342bab725f379cc81c7dd5035ee1de2f7e3f7a9842"}, - {file = "grpcio-1.62.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:7e1f51e2a460b7394670fdb615e26d31d3260015154ea4f1501a45047abe06c9"}, - {file = "grpcio-1.62.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:bcff647e7fe25495e7719f779cc219bbb90b9e79fbd1ce5bda6aae2567f469f2"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:56ca7ba0b51ed0de1646f1735154143dcbdf9ec2dbe8cc6645def299bb527ca1"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e84bfb2a734e4a234b116be208d6f0214e68dcf7804306f97962f93c22a1839"}, - {file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c1488b31a521fbba50ae86423f5306668d6f3a46d124f7819c603979fc538c4"}, - {file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:98d8f4eb91f1ce0735bf0b67c3b2a4fea68b52b2fd13dc4318583181f9219b4b"}, - {file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b3d3d755cfa331d6090e13aac276d4a3fb828bf935449dc16c3d554bf366136b"}, - {file = "grpcio-1.62.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a33f2bfd8a58a02aab93f94f6c61279be0f48f99fcca20ebaee67576cd57307b"}, - {file = "grpcio-1.62.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:5e709f7c8028ce0443bddc290fb9c967c1e0e9159ef7a030e8c21cac1feabd35"}, - {file = "grpcio-1.62.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:2f3d9a4d0abb57e5f49ed5039d3ed375826c2635751ab89dcc25932ff683bbb6"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:62ccb92f594d3d9fcd00064b149a0187c246b11e46ff1b7935191f169227f04c"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:921148f57c2e4b076af59a815467d399b7447f6e0ee10ef6d2601eb1e9c7f402"}, - {file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f897b16190b46bc4d4aaf0a32a4b819d559a37a756d7c6b571e9562c360eed72"}, - {file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1bc8449084fe395575ed24809752e1dc4592bb70900a03ca42bf236ed5bf008f"}, - {file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81d444e5e182be4c7856cd33a610154fe9ea1726bd071d07e7ba13fafd202e38"}, - {file = "grpcio-1.62.0-cp38-cp38-win32.whl", hash = "sha256:88f41f33da3840b4a9bbec68079096d4caf629e2c6ed3a72112159d570d98ebe"}, - {file = "grpcio-1.62.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc2836cb829895ee190813446dce63df67e6ed7b9bf76060262c55fcd097d270"}, - {file = "grpcio-1.62.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:fcc98cff4084467839d0a20d16abc2a76005f3d1b38062464d088c07f500d170"}, - {file = "grpcio-1.62.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:0d3dee701e48ee76b7d6fbbba18ba8bc142e5b231ef7d3d97065204702224e0e"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:b7a6be562dd18e5d5bec146ae9537f20ae1253beb971c0164f1e8a2f5a27e829"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29cb592c4ce64a023712875368bcae13938c7f03e99f080407e20ffe0a9aa33b"}, - {file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eda79574aec8ec4d00768dcb07daba60ed08ef32583b62b90bbf274b3c279f7"}, - {file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7eea57444a354ee217fda23f4b479a4cdfea35fb918ca0d8a0e73c271e52c09c"}, - {file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0e97f37a3b7c89f9125b92d22e9c8323f4e76e7993ba7049b9f4ccbe8bae958a"}, - {file = "grpcio-1.62.0-cp39-cp39-win32.whl", hash = "sha256:39cd45bd82a2e510e591ca2ddbe22352e8413378852ae814549c162cf3992a93"}, - {file = "grpcio-1.62.0-cp39-cp39-win_amd64.whl", hash = "sha256:b71c65427bf0ec6a8b48c68c17356cb9fbfc96b1130d20a07cb462f4e4dcdcd5"}, - {file = "grpcio-1.62.0.tar.gz", hash = "sha256:748496af9238ac78dcd98cce65421f1adce28c3979393e3609683fcd7f3880d7"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.62.0)"] + {file = "grpcio-1.62.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:179bee6f5ed7b5f618844f760b6acf7e910988de77a4f75b95bbfaa8106f3c1e"}, + {file = "grpcio-1.62.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:48611e4fa010e823ba2de8fd3f77c1322dd60cb0d180dc6630a7e157b205f7ea"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b2a0e71b0a2158aa4bce48be9f8f9eb45cbd17c78c7443616d00abbe2a509f6d"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbe80577c7880911d3ad65e5ecc997416c98f354efeba2f8d0f9112a67ed65a5"}, + {file = "grpcio-1.62.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f6c693d446964e3292425e1d16e21a97a48ba9172f2d0df9d7b640acb99243"}, + {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:77c339403db5a20ef4fed02e4d1a9a3d9866bf9c0afc77a42234677313ea22f3"}, + {file = "grpcio-1.62.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b5a4ea906db7dec694098435d84bf2854fe158eb3cd51e1107e571246d4d1d70"}, + {file = "grpcio-1.62.1-cp310-cp310-win32.whl", hash = "sha256:4187201a53f8561c015bc745b81a1b2d278967b8de35f3399b84b0695e281d5f"}, + {file = "grpcio-1.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:844d1f3fb11bd1ed362d3fdc495d0770cfab75761836193af166fee113421d66"}, + {file = "grpcio-1.62.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:833379943d1728a005e44103f17ecd73d058d37d95783eb8f0b28ddc1f54d7b2"}, + {file = "grpcio-1.62.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:c7fcc6a32e7b7b58f5a7d27530669337a5d587d4066060bcb9dee7a8c833dfb7"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:fa7d28eb4d50b7cbe75bb8b45ed0da9a1dc5b219a0af59449676a29c2eed9698"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48f7135c3de2f298b833be8b4ae20cafe37091634e91f61f5a7eb3d61ec6f660"}, + {file = "grpcio-1.62.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71f11fd63365ade276c9d4a7b7df5c136f9030e3457107e1791b3737a9b9ed6a"}, + {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b49fd8fe9f9ac23b78437da94c54aa7e9996fbb220bac024a67469ce5d0825f"}, + {file = "grpcio-1.62.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:482ae2ae78679ba9ed5752099b32e5fe580443b4f798e1b71df412abf43375db"}, + {file = "grpcio-1.62.1-cp311-cp311-win32.whl", hash = "sha256:1faa02530b6c7426404372515fe5ddf66e199c2ee613f88f025c6f3bd816450c"}, + {file = "grpcio-1.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bd90b8c395f39bc82a5fb32a0173e220e3f401ff697840f4003e15b96d1befc"}, + {file = "grpcio-1.62.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:b134d5d71b4e0837fff574c00e49176051a1c532d26c052a1e43231f252d813b"}, + {file = "grpcio-1.62.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d1f6c96573dc09d50dbcbd91dbf71d5cf97640c9427c32584010fbbd4c0e0037"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:359f821d4578f80f41909b9ee9b76fb249a21035a061a327f91c953493782c31"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a485f0c2010c696be269184bdb5ae72781344cb4e60db976c59d84dd6354fac9"}, + {file = "grpcio-1.62.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b50b09b4dc01767163d67e1532f948264167cd27f49e9377e3556c3cba1268e1"}, + {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3227c667dccbe38f2c4d943238b887bac588d97c104815aecc62d2fd976e014b"}, + {file = "grpcio-1.62.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3952b581eb121324853ce2b191dae08badb75cd493cb4e0243368aa9e61cfd41"}, + {file = "grpcio-1.62.1-cp312-cp312-win32.whl", hash = "sha256:83a17b303425104d6329c10eb34bba186ffa67161e63fa6cdae7776ff76df73f"}, + {file = "grpcio-1.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:6696ffe440333a19d8d128e88d440f91fb92c75a80ce4b44d55800e656a3ef1d"}, + {file = "grpcio-1.62.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:e3393b0823f938253370ebef033c9fd23d27f3eae8eb9a8f6264900c7ea3fb5a"}, + {file = "grpcio-1.62.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:83e7ccb85a74beaeae2634f10eb858a0ed1a63081172649ff4261f929bacfd22"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:882020c87999d54667a284c7ddf065b359bd00251fcd70279ac486776dbf84ec"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a10383035e864f386fe096fed5c47d27a2bf7173c56a6e26cffaaa5a361addb1"}, + {file = "grpcio-1.62.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:960edebedc6b9ada1ef58e1c71156f28689978188cd8cff3b646b57288a927d9"}, + {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:23e2e04b83f347d0aadde0c9b616f4726c3d76db04b438fd3904b289a725267f"}, + {file = "grpcio-1.62.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978121758711916d34fe57c1f75b79cdfc73952f1481bb9583399331682d36f7"}, + {file = "grpcio-1.62.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9084086190cc6d628f282e5615f987288b95457292e969b9205e45b442276407"}, + {file = "grpcio-1.62.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:22bccdd7b23c420a27fd28540fb5dcbc97dc6be105f7698cb0e7d7a420d0e362"}, + {file = "grpcio-1.62.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:8999bf1b57172dbc7c3e4bb3c732658e918f5c333b2942243f10d0d653953ba9"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d9e52558b8b8c2f4ac05ac86344a7417ccdd2b460a59616de49eb6933b07a0bd"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1714e7bc935780bc3de1b3fcbc7674209adf5208ff825799d579ffd6cd0bd505"}, + {file = "grpcio-1.62.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8842ccbd8c0e253c1f189088228f9b433f7a93b7196b9e5b6f87dba393f5d5d"}, + {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f1e7b36bdff50103af95a80923bf1853f6823dd62f2d2a2524b66ed74103e49"}, + {file = "grpcio-1.62.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bba97b8e8883a8038606480d6b6772289f4c907f6ba780fa1f7b7da7dfd76f06"}, + {file = "grpcio-1.62.1-cp38-cp38-win32.whl", hash = "sha256:a7f615270fe534548112a74e790cd9d4f5509d744dd718cd442bf016626c22e4"}, + {file = "grpcio-1.62.1-cp38-cp38-win_amd64.whl", hash = "sha256:e6c8c8693df718c5ecbc7babb12c69a4e3677fd11de8886f05ab22d4e6b1c43b"}, + {file = "grpcio-1.62.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:73db2dc1b201d20ab7083e7041946910bb991e7e9761a0394bbc3c2632326483"}, + {file = "grpcio-1.62.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:407b26b7f7bbd4f4751dbc9767a1f0716f9fe72d3d7e96bb3ccfc4aace07c8de"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f8de7c8cef9261a2d0a62edf2ccea3d741a523c6b8a6477a340a1f2e417658de"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd5c8a1af40ec305d001c60236308a67e25419003e9bb3ebfab5695a8d0b369"}, + {file = "grpcio-1.62.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0477cb31da67846a33b1a75c611f88bfbcd427fe17701b6317aefceee1b96f"}, + {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:60dcd824df166ba266ee0cfaf35a31406cd16ef602b49f5d4dfb21f014b0dedd"}, + {file = "grpcio-1.62.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:973c49086cabab773525f6077f95e5a993bfc03ba8fc32e32f2c279497780585"}, + {file = "grpcio-1.62.1-cp39-cp39-win32.whl", hash = "sha256:12859468e8918d3bd243d213cd6fd6ab07208195dc140763c00dfe901ce1e1b4"}, + {file = "grpcio-1.62.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7209117bbeebdfa5d898205cc55153a51285757902dd73c47de498ad4d11332"}, + {file = "grpcio-1.62.1.tar.gz", hash = "sha256:6c455e008fa86d9e9a9d85bb76da4277c0d7d9668a3bfa70dbe86e9f3c759947"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.62.1)"] [[package]] name = "h11" @@ -2174,13 +2146,13 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs [[package]] name = "importlib-resources" -version = "6.1.2" +version = "6.3.1" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.1.2-py3-none-any.whl", hash = "sha256:9a0a862501dc38b68adebc82970140c9e4209fc99601782925178f8386339938"}, - {file = "importlib_resources-6.1.2.tar.gz", hash = "sha256:308abf8474e2dba5f867d279237cd4076482c3de7104a40b41426370e891549b"}, + {file = "importlib_resources-6.3.1-py3-none-any.whl", hash = "sha256:4811639ca7fa830abdb8e9ca0a104dc6ad13de691d9fe0d3173a71304f068159"}, + {file = "importlib_resources-6.3.1.tar.gz", hash = "sha256:29a3d16556e330c3c8fb8202118c5ff41241cc34cbfb25989bbad226d99b7995"}, ] [package.dependencies] @@ -2188,7 +2160,7 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +testing = ["jaraco.collections", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -2415,18 +2387,15 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "json5" -version = "0.9.17" +version = "0.9.24" description = "A Python implementation of the JSON5 data format." optional = false python-versions = ">=3.8" files = [ - {file = "json5-0.9.17-py2.py3-none-any.whl", hash = "sha256:f8ec1ecf985951d70f780f6f877c4baca6a47b6e61e02c4cd190138d10a7805a"}, - {file = "json5-0.9.17.tar.gz", hash = "sha256:717d99d657fa71b7094877b1d921b1cce40ab444389f6d770302563bb7dfd9ae"}, + {file = "json5-0.9.24-py3-none-any.whl", hash = "sha256:4ca101fd5c7cb47960c055ef8f4d0e31e15a7c6c48c3b6f1473fc83b6c462a13"}, + {file = "json5-0.9.24.tar.gz", hash = "sha256:0c638399421da959a20952782800e5c1a78c14e08e1dc9738fa10d8ec14d58c8"}, ] -[package.extras] -dev = ["hypothesis"] - [[package]] name = "jsonpointer" version = "2.4" @@ -2506,13 +2475,13 @@ qtconsole = "*" [[package]] name = "jupyter-client" -version = "8.6.0" +version = "8.6.1" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, - {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, + {file = "jupyter_client-8.6.1-py3-none-any.whl", hash = "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f"}, + {file = "jupyter_client-8.6.1.tar.gz", hash = "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f"}, ] [package.dependencies] @@ -2553,13 +2522,13 @@ test = ["flaky", "pexpect", "pytest"] [[package]] name = "jupyter-core" -version = "5.7.1" +version = "5.7.2" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, - {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, ] [package.dependencies] @@ -2569,17 +2538,17 @@ traitlets = ">=5.3" [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyter-events" -version = "0.9.0" +version = "0.10.0" description = "Jupyter Event System library" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_events-0.9.0-py3-none-any.whl", hash = "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf"}, - {file = "jupyter_events-0.9.0.tar.gz", hash = "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399"}, + {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, + {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, ] [package.dependencies] @@ -2598,13 +2567,13 @@ test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "p [[package]] name = "jupyter-lsp" -version = "2.2.3" +version = "2.2.4" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter-lsp-2.2.3.tar.gz", hash = "sha256:33dbcbc5df24237ff5c8b696b04ff4689fcd316cb8d4957d620fe5504d7d2c3f"}, - {file = "jupyter_lsp-2.2.3-py3-none-any.whl", hash = "sha256:57dd90d0a2e2530831793550846168c81c952b49e187aa339e455027a5f0fd2e"}, + {file = "jupyter-lsp-2.2.4.tar.gz", hash = "sha256:5e50033149344065348e688608f3c6d654ef06d9856b67655bd7b6bac9ee2d59"}, + {file = "jupyter_lsp-2.2.4-py3-none-any.whl", hash = "sha256:da61cb63a16b6dff5eac55c2699cc36eac975645adee02c41bdfc03bf4802e77"}, ] [package.dependencies] @@ -2613,13 +2582,13 @@ jupyter-server = ">=1.1.2" [[package]] name = "jupyter-server" -version = "2.12.5" +version = "2.13.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server-2.12.5-py3-none-any.whl", hash = "sha256:184a0f82809a8522777cfb6b760ab6f4b1bb398664c5860a27cec696cb884923"}, - {file = "jupyter_server-2.12.5.tar.gz", hash = "sha256:0edb626c94baa22809be1323f9770cf1c00a952b17097592e40d03e6a3951689"}, + {file = "jupyter_server-2.13.0-py3-none-any.whl", hash = "sha256:77b2b49c3831fbbfbdb5048cef4350d12946191f833a24e5f83e5f8f4803e97b"}, + {file = "jupyter_server-2.13.0.tar.gz", hash = "sha256:c80bfb049ea20053c3d9641c2add4848b38073bf79f1729cea1faed32fc1c78e"}, ] [package.dependencies] @@ -2645,17 +2614,17 @@ websocket-client = "*" [package.extras] docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] [[package]] name = "jupyter-server-terminals" -version = "0.5.2" +version = "0.5.3" description = "A Jupyter Server Extension Providing Terminals." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server_terminals-0.5.2-py3-none-any.whl", hash = "sha256:1b80c12765da979513c42c90215481bbc39bd8ae7c0350b4f85bc3eb58d0fa80"}, - {file = "jupyter_server_terminals-0.5.2.tar.gz", hash = "sha256:396b5ccc0881e550bf0ee7012c6ef1b53edbde69e67cab1d56e89711b46052e8"}, + {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, + {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, ] [package.dependencies] @@ -2668,13 +2637,13 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.1.2" +version = "4.1.5" description = "JupyterLab computational environment" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.1.2-py3-none-any.whl", hash = "sha256:aa88193f03cf4d3555f6712f04d74112b5eb85edd7d222c588c7603a26d33c5b"}, - {file = "jupyterlab-4.1.2.tar.gz", hash = "sha256:5d6348b3ed4085181499f621b7dfb6eb0b1f57f3586857aadfc8e3bf4c4885f9"}, + {file = "jupyterlab-4.1.5-py3-none-any.whl", hash = "sha256:3bc843382a25e1ab7bc31d9e39295a9f0463626692b7995597709c0ab236ab2c"}, + {file = "jupyterlab-4.1.5.tar.gz", hash = "sha256:c9ad75290cb10bfaff3624bf3fbb852319b4cce4c456613f8ebbaa98d03524db"}, ] [package.dependencies] @@ -2713,13 +2682,13 @@ files = [ [[package]] name = "jupyterlab-server" -version = "2.25.3" +version = "2.25.4" description = "A set of server components for JupyterLab and JupyterLab like applications." optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab_server-2.25.3-py3-none-any.whl", hash = "sha256:c48862519fded9b418c71645d85a49b2f0ec50d032ba8316738e9276046088c1"}, - {file = "jupyterlab_server-2.25.3.tar.gz", hash = "sha256:846f125a8a19656611df5b03e5912c8393cea6900859baa64fa515eb64a8dc40"}, + {file = "jupyterlab_server-2.25.4-py3-none-any.whl", hash = "sha256:eb645ecc8f9b24bac5decc7803b6d5363250e16ec5af814e516bc2c54dd88081"}, + {file = "jupyterlab_server-2.25.4.tar.gz", hash = "sha256:2098198e1e82e0db982440f9b5136175d73bea2cd42a6480aa6fd502cb23c4f9"}, ] [package.dependencies] @@ -2735,7 +2704,7 @@ requests = ">=2.31" [package.extras] docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] [[package]] name = "jupyterlab-widgets" @@ -2803,13 +2772,13 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-ena [[package]] name = "locust" -version = "2.23.1" +version = "2.24.0" description = "Developer friendly load testing framework" optional = false python-versions = ">=3.8" files = [ - {file = "locust-2.23.1-py3-none-any.whl", hash = "sha256:96013a460a4b4d6d4fd46c70e6ff1fd2b6e03b48ddb1b48d1513d3134ba2cecf"}, - {file = "locust-2.23.1.tar.gz", hash = "sha256:6cc729729e5ebf5852fc9d845302cfcf0ab0132f198e68b3eb0c88b438b6a863"}, + {file = "locust-2.24.0-py3-none-any.whl", hash = "sha256:1b6b878b4fd0108fec956120815e69775d2616c8f4d1e9f365c222a7a5c17d9a"}, + {file = "locust-2.24.0.tar.gz", hash = "sha256:6cffa378d995244a7472af6be1d6139331f19aee44e907deee73e0281252804d"}, ] [package.dependencies] @@ -2825,6 +2794,7 @@ pywin32 = {version = "*", markers = "platform_system == \"Windows\""} pyzmq = ">=25.0.0" requests = ">=2.26.0" roundrobin = ">=0.0.2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} Werkzeug = ">=2.0.0" [[package]] @@ -3039,67 +3009,67 @@ zstd = ["pymongo[zstd] (>=4.5,<5)"] [[package]] name = "msgpack" -version = "1.0.7" +version = "1.0.8" description = "MessagePack serializer" optional = false python-versions = ">=3.8" files = [ - {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"}, - {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"}, - {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"}, - {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"}, - {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"}, - {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"}, - {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"}, - {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"}, - {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"}, - {file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"}, - {file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"}, - {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"}, - {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"}, - {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] @@ -3203,38 +3173,38 @@ files = [ [[package]] name = "mypy" -version = "1.8.0" +version = "1.9.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, + {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, + {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, + {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, + {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, + {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, + {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, + {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, + {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, + {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, + {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, + {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, + {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, + {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, + {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, + {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, + {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, + {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] @@ -3261,13 +3231,13 @@ files = [ [[package]] name = "nbclient" -version = "0.9.0" +version = "0.10.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." optional = false python-versions = ">=3.8.0" files = [ - {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, - {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, ] [package.dependencies] @@ -3279,17 +3249,17 @@ traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.16.1" +version = "7.16.2" description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." optional = false python-versions = ">=3.8" files = [ - {file = "nbconvert-7.16.1-py3-none-any.whl", hash = "sha256:3188727dffadfdc9c6a1c7250729063d7bc78b355ad7aa023138afa030d1cd07"}, - {file = "nbconvert-7.16.1.tar.gz", hash = "sha256:e79e6a074f49ba3ed29428ed86487bf51509d9aab613bd8522ac08f6d28fd7fd"}, + {file = "nbconvert-7.16.2-py3-none-any.whl", hash = "sha256:0c01c23981a8de0220255706822c40b751438e32467d6a686e26be08ba784382"}, + {file = "nbconvert-7.16.2.tar.gz", hash = "sha256:8310edd41e1c43947e4ecf16614c61469ebc024898eb808cce0999860fc9fb16"}, ] [package.dependencies] @@ -3321,13 +3291,13 @@ webpdf = ["playwright"] [[package]] name = "nbformat" -version = "5.9.2" +version = "5.10.3" description = "The Jupyter Notebook format" optional = false python-versions = ">=3.8" files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, + {file = "nbformat-5.10.3-py3-none-any.whl", hash = "sha256:d9476ca28676799af85385f409b49d95e199951477a159a576ef2a675151e5e8"}, + {file = "nbformat-5.10.3.tar.gz", hash = "sha256:60ed5e910ef7c6264b87d644f276b1b49e24011930deef54605188ddeb211685"}, ] [package.dependencies] @@ -3372,13 +3342,13 @@ files = [ [[package]] name = "notebook" -version = "7.1.1" +version = "7.1.2" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" optional = false python-versions = ">=3.8" files = [ - {file = "notebook-7.1.1-py3-none-any.whl", hash = "sha256:197d8e0595acabf4005851c8716e952a81b405f7aefb648067a761fbde267ce7"}, - {file = "notebook-7.1.1.tar.gz", hash = "sha256:818e7420fa21f402e726afb9f02df7f3c10f294c02e383ed19852866c316108b"}, + {file = "notebook-7.1.2-py3-none-any.whl", hash = "sha256:fc6c24b9aef18d0cd57157c9c47e95833b9b0bdc599652639acf0bdb61dc7d5f"}, + {file = "notebook-7.1.2.tar.gz", hash = "sha256:efc2c80043909e0faa17fce9e9b37c059c03af0ec99a4d4db84cb21d9d2e936a"}, ] [package.dependencies] @@ -3902,17 +3872,17 @@ xmp = ["defusedxml"] [[package]] name = "pkginfo" -version = "1.9.6" +version = "1.10.0" description = "Query metadata from sdists / bdists / installed packages." optional = false python-versions = ">=3.6" files = [ - {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, - {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, + {file = "pkginfo-1.10.0-py3-none-any.whl", hash = "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097"}, + {file = "pkginfo-1.10.0.tar.gz", hash = "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297"}, ] [package.extras] -testing = ["pytest", "pytest-cov"] +testing = ["pytest", "pytest-cov", "wheel"] [[package]] name = "pkgutil-resolve-name" @@ -3976,13 +3946,13 @@ poetry-plugin = ["poetry (>=1.0,<2.0)"] [[package]] name = "poetry" -version = "1.8.1" +version = "1.8.2" description = "Python dependency management and packaging made easy." optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "poetry-1.8.1-py3-none-any.whl", hash = "sha256:cf133946661025822672422769567980f8e489ed5b6fc170d1025a4d6c9aac29"}, - {file = "poetry-1.8.1.tar.gz", hash = "sha256:23519cc45eb3cf48e899145bc762425a141e3afd52ecc53ec443ca635122327f"}, + {file = "poetry-1.8.2-py3-none-any.whl", hash = "sha256:b42b400d9a803af6e788a30a6f3e9998020b77860e28df20647eb10b6f414910"}, + {file = "poetry-1.8.2.tar.gz", hash = "sha256:49cceb3838104647c3e1021f3a4f13c6053704cc18d33f849a90fe687a29cb73"}, ] [package.dependencies] @@ -4024,17 +3994,17 @@ files = [ [[package]] name = "poetry-plugin-export" -version = "1.6.0" +version = "1.7.0" description = "Poetry plugin to export the dependencies to various formats" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "poetry_plugin_export-1.6.0-py3-none-any.whl", hash = "sha256:2dce6204c9318f1f6509a11a03921fb3f461b201840b59f1c237b6ab454dabcf"}, - {file = "poetry_plugin_export-1.6.0.tar.gz", hash = "sha256:091939434984267a91abf2f916a26b00cff4eee8da63ec2a24ba4b17cf969a59"}, + {file = "poetry_plugin_export-1.7.0-py3-none-any.whl", hash = "sha256:2283b28e0209f9f9598c6fe44f30586ec91329ea1558f908708261e0516bf427"}, + {file = "poetry_plugin_export-1.7.0.tar.gz", hash = "sha256:e73f207fc0e08c2f59ead82cbe39ef259b351a318d5c0bddcec13990bcd324a7"}, ] [package.dependencies] -poetry = ">=1.6.0,<2.0.0" +poetry = ">=1.8.0,<2.0.0" poetry-core = ">=1.7.0,<2.0.0" [[package]] @@ -4150,47 +4120,47 @@ files = [ [[package]] name = "pyarrow" -version = "15.0.0" +version = "15.0.2" description = "Python library for Apache Arrow" optional = false python-versions = ">=3.8" files = [ - {file = "pyarrow-15.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0a524532fd6dd482edaa563b686d754c70417c2f72742a8c990b322d4c03a15d"}, - {file = "pyarrow-15.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a6bdb314affa9c2e0d5dddf3d9cbb9ef4a8dddaa68669975287d47ece67642"}, - {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66958fd1771a4d4b754cd385835e66a3ef6b12611e001d4e5edfcef5f30391e2"}, - {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f500956a49aadd907eaa21d4fff75f73954605eaa41f61cb94fb008cf2e00c6"}, - {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6f87d9c4f09e049c2cade559643424da84c43a35068f2a1c4653dc5b1408a929"}, - {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85239b9f93278e130d86c0e6bb455dcb66fc3fd891398b9d45ace8799a871a1e"}, - {file = "pyarrow-15.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b8d43e31ca16aa6e12402fcb1e14352d0d809de70edd185c7650fe80e0769e3"}, - {file = "pyarrow-15.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:fa7cd198280dbd0c988df525e50e35b5d16873e2cdae2aaaa6363cdb64e3eec5"}, - {file = "pyarrow-15.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8780b1a29d3c8b21ba6b191305a2a607de2e30dab399776ff0aa09131e266340"}, - {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0ec198ccc680f6c92723fadcb97b74f07c45ff3fdec9dd765deb04955ccf19"}, - {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036a7209c235588c2f07477fe75c07e6caced9b7b61bb897c8d4e52c4b5f9555"}, - {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2bd8a0e5296797faf9a3294e9fa2dc67aa7f10ae2207920dbebb785c77e9dbe5"}, - {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e8ebed6053dbe76883a822d4e8da36860f479d55a762bd9e70d8494aed87113e"}, - {file = "pyarrow-15.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:17d53a9d1b2b5bd7d5e4cd84d018e2a45bc9baaa68f7e6e3ebed45649900ba99"}, - {file = "pyarrow-15.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9950a9c9df24090d3d558b43b97753b8f5867fb8e521f29876aa021c52fda351"}, - {file = "pyarrow-15.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:003d680b5e422d0204e7287bb3fa775b332b3fce2996aa69e9adea23f5c8f970"}, - {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f75fce89dad10c95f4bf590b765e3ae98bcc5ba9f6ce75adb828a334e26a3d40"}, - {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca9cb0039923bec49b4fe23803807e4ef39576a2bec59c32b11296464623dc2"}, - {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ed5a78ed29d171d0acc26a305a4b7f83c122d54ff5270810ac23c75813585e4"}, - {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6eda9e117f0402dfcd3cd6ec9bfee89ac5071c48fc83a84f3075b60efa96747f"}, - {file = "pyarrow-15.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a3a6180c0e8f2727e6f1b1c87c72d3254cac909e609f35f22532e4115461177"}, - {file = "pyarrow-15.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:19a8918045993349b207de72d4576af0191beef03ea655d8bdb13762f0cd6eac"}, - {file = "pyarrow-15.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0ec076b32bacb6666e8813a22e6e5a7ef1314c8069d4ff345efa6246bc38593"}, - {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5db1769e5d0a77eb92344c7382d6543bea1164cca3704f84aa44e26c67e320fb"}, - {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2617e3bf9df2a00020dd1c1c6dce5cc343d979efe10bc401c0632b0eef6ef5b"}, - {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:d31c1d45060180131caf10f0f698e3a782db333a422038bf7fe01dace18b3a31"}, - {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:c8c287d1d479de8269398b34282e206844abb3208224dbdd7166d580804674b7"}, - {file = "pyarrow-15.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:07eb7f07dc9ecbb8dace0f58f009d3a29ee58682fcdc91337dfeb51ea618a75b"}, - {file = "pyarrow-15.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:47af7036f64fce990bb8a5948c04722e4e3ea3e13b1007ef52dfe0aa8f23cf7f"}, - {file = "pyarrow-15.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93768ccfff85cf044c418bfeeafce9a8bb0cee091bd8fd19011aff91e58de540"}, - {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6ee87fd6892700960d90abb7b17a72a5abb3b64ee0fe8db6c782bcc2d0dc0b4"}, - {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:001fca027738c5f6be0b7a3159cc7ba16a5c52486db18160909a0831b063c4e4"}, - {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:d1c48648f64aec09accf44140dccb92f4f94394b8d79976c426a5b79b11d4fa7"}, - {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:972a0141be402bb18e3201448c8ae62958c9c7923dfaa3b3d4530c835ac81aed"}, - {file = "pyarrow-15.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:f01fc5cf49081426429127aa2d427d9d98e1cb94a32cb961d583a70b7c4504e6"}, - {file = "pyarrow-15.0.0.tar.gz", hash = "sha256:876858f549d540898f927eba4ef77cd549ad8d24baa3207cf1b72e5788b50e83"}, + {file = "pyarrow-15.0.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:88b340f0a1d05b5ccc3d2d986279045655b1fe8e41aba6ca44ea28da0d1455d8"}, + {file = "pyarrow-15.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eaa8f96cecf32da508e6c7f69bb8401f03745c050c1dd42ec2596f2e98deecac"}, + {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23c6753ed4f6adb8461e7c383e418391b8d8453c5d67e17f416c3a5d5709afbd"}, + {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f639c059035011db8c0497e541a8a45d98a58dbe34dc8fadd0ef128f2cee46e5"}, + {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:290e36a59a0993e9a5224ed2fb3e53375770f07379a0ea03ee2fce2e6d30b423"}, + {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:06c2bb2a98bc792f040bef31ad3e9be6a63d0cb39189227c08a7d955db96816e"}, + {file = "pyarrow-15.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:f7a197f3670606a960ddc12adbe8075cea5f707ad7bf0dffa09637fdbb89f76c"}, + {file = "pyarrow-15.0.2-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5f8bc839ea36b1f99984c78e06e7a06054693dc2af8920f6fb416b5bca9944e4"}, + {file = "pyarrow-15.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5e81dfb4e519baa6b4c80410421528c214427e77ca0ea9461eb4097c328fa33"}, + {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a4f240852b302a7af4646c8bfe9950c4691a419847001178662a98915fd7ee7"}, + {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e7d9cfb5a1e648e172428c7a42b744610956f3b70f524aa3a6c02a448ba853e"}, + {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2d4f905209de70c0eb5b2de6763104d5a9a37430f137678edfb9a675bac9cd98"}, + {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90adb99e8ce5f36fbecbbc422e7dcbcbed07d985eed6062e459e23f9e71fd197"}, + {file = "pyarrow-15.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:b116e7fd7889294cbd24eb90cd9bdd3850be3738d61297855a71ac3b8124ee38"}, + {file = "pyarrow-15.0.2-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:25335e6f1f07fdaa026a61c758ee7d19ce824a866b27bba744348fa73bb5a440"}, + {file = "pyarrow-15.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90f19e976d9c3d8e73c80be84ddbe2f830b6304e4c576349d9360e335cd627fc"}, + {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a22366249bf5fd40ddacc4f03cd3160f2d7c247692945afb1899bab8a140ddfb"}, + {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2a335198f886b07e4b5ea16d08ee06557e07db54a8400cc0d03c7f6a22f785f"}, + {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e6d459c0c22f0b9c810a3917a1de3ee704b021a5fb8b3bacf968eece6df098f"}, + {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:033b7cad32198754d93465dcfb71d0ba7cb7cd5c9afd7052cab7214676eec38b"}, + {file = "pyarrow-15.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:29850d050379d6e8b5a693098f4de7fd6a2bea4365bfd073d7c57c57b95041ee"}, + {file = "pyarrow-15.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:7167107d7fb6dcadb375b4b691b7e316f4368f39f6f45405a05535d7ad5e5058"}, + {file = "pyarrow-15.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e85241b44cc3d365ef950432a1b3bd44ac54626f37b2e3a0cc89c20e45dfd8bf"}, + {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:248723e4ed3255fcd73edcecc209744d58a9ca852e4cf3d2577811b6d4b59818"}, + {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff3bdfe6f1b81ca5b73b70a8d482d37a766433823e0c21e22d1d7dde76ca33f"}, + {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:f3d77463dee7e9f284ef42d341689b459a63ff2e75cee2b9302058d0d98fe142"}, + {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:8c1faf2482fb89766e79745670cbca04e7018497d85be9242d5350cba21357e1"}, + {file = "pyarrow-15.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:28f3016958a8e45a1069303a4a4f6a7d4910643fc08adb1e2e4a7ff056272ad3"}, + {file = "pyarrow-15.0.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:89722cb64286ab3d4daf168386f6968c126057b8c7ec3ef96302e81d8cdb8ae4"}, + {file = "pyarrow-15.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd0ba387705044b3ac77b1b317165c0498299b08261d8122c96051024f953cd5"}, + {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad2459bf1f22b6a5cdcc27ebfd99307d5526b62d217b984b9f5c974651398832"}, + {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58922e4bfece8b02abf7159f1f53a8f4d9f8e08f2d988109126c17c3bb261f22"}, + {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:adccc81d3dc0478ea0b498807b39a8d41628fa9210729b2f718b78cb997c7c91"}, + {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:8bd2baa5fe531571847983f36a30ddbf65261ef23e496862ece83bdceb70420d"}, + {file = "pyarrow-15.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6669799a1d4ca9da9c7e06ef48368320f5856f36f9a4dd31a11839dda3f6cc8c"}, + {file = "pyarrow-15.0.2.tar.gz", hash = "sha256:9c9bc803cb3b7bfacc1e96ffbfd923601065d9d3f911179d81e72d99fd74a3d9"}, ] [package.dependencies] @@ -4231,13 +4201,13 @@ files = [ [[package]] name = "pydantic" -version = "2.6.3" +version = "2.6.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"}, - {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"}, + {file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"}, + {file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"}, ] [package.dependencies] @@ -4539,41 +4509,15 @@ files = [ [package.dependencies] tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -[[package]] -name = "pytelegrambotapi" -version = "4.16.1" -description = "Python Telegram bot api." -optional = true -python-versions = ">=3.8" -files = [ - {file = "pytelegrambotapi-4.16.1-py3-none-any.whl", hash = "sha256:85451b4fa1a47d99318a50aef361d177d2eb580c5ea6429fadb071cfad17fb35"}, - {file = "pytelegrambotapi-4.16.1.tar.gz", hash = "sha256:7ecfdac60de4a4c254059fc0f1997ceeb5da72803ffe4f35544b3ec9e9629edb"}, -] - -[package.dependencies] -requests = "*" - -[package.extras] -aiohttp = ["aiohttp"] -aioredis = ["aioredis"] -coloredlogs = ["coloredlogs"] -fastapi = ["fastapi"] -json = ["ujson"] -pil = ["pillow"] -psutil = ["psutil"] -redis = ["redis (>=3.4.1)"] -uvicorn = ["uvicorn"] -watchdog = ["watchdog"] - [[package]] name = "pytest" -version = "8.0.2" +version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, - {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, + {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, + {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] @@ -4581,21 +4525,21 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.3.0,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.4,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.23.5" +version = "0.23.5.post1" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.23.5.tar.gz", hash = "sha256:3a048872a9c4ba14c3e90cc1aa20cbc2def7d01c7c8db3777ec281ba9c057675"}, - {file = "pytest_asyncio-0.23.5-py3-none-any.whl", hash = "sha256:4e7093259ba018d58ede7d5315131d21923a60f8a6e9ee266ce1589685c89eac"}, + {file = "pytest-asyncio-0.23.5.post1.tar.gz", hash = "sha256:b9a8806bea78c21276bc34321bbf234ba1b2ea5b30d9f0ce0f2dea45e4685813"}, + {file = "pytest_asyncio-0.23.5.post1-py3-none-any.whl", hash = "sha256:30f54d27774e79ac409778889880242b0403d09cabd65b727ce90fe92dd5d80e"}, ] [package.dependencies] @@ -4685,13 +4629,13 @@ tests = ["mock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -4724,13 +4668,13 @@ files = [ [[package]] name = "python-on-whales" -version = "0.69.0" +version = "0.70.0" description = "A Docker client for Python, designed to be fun and intuitive!" optional = false python-versions = "<4,>=3.8" files = [ - {file = "python-on-whales-0.69.0.tar.gz", hash = "sha256:86bef044568e6abd381e63731e03a6536709be129c5934020da403b99f489b5e"}, - {file = "python_on_whales-0.69.0-py3-none-any.whl", hash = "sha256:73cf63377fbcbfee1f4a5e58148a1a0293f2ba153c2b862b830d0d9fedd5e223"}, + {file = "python-on-whales-0.70.0.tar.gz", hash = "sha256:bb89e91c86e049f9c04e2636f2d40faa000ff5b17d54f71e68581201e449eda5"}, + {file = "python_on_whales-0.70.0-py3-none-any.whl", hash = "sha256:492325387d7686adc6669e911820bd4da1cd672bc5a7fb6d54c32ee849bfe7e6"}, ] [package.dependencies] @@ -4743,6 +4687,31 @@ typing-extensions = "*" [package.extras] test = ["pytest"] +[[package]] +name = "python-telegram-bot" +version = "21.0.1" +description = "We have made you a wrapper you can't refuse" +optional = true +python-versions = ">=3.8" +files = [ + {file = "python-telegram-bot-21.0.1.tar.gz", hash = "sha256:3e005962c9fda01b09480044c49b3dd70870ee0c63340374bf3d5191e3910be9"}, + {file = "python_telegram_bot-21.0.1-py3-none-any.whl", hash = "sha256:b282544d1a51bf228b868e2ce0285b8448982878e2362175836429722d6f8795"}, +] + +[package.dependencies] +httpx = ">=0.27,<1.0" + +[package.extras] +all = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"] +callback-data = ["cachetools (>=5.3.3,<5.4.0)"] +ext = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"] +http2 = ["httpx[http2]"] +job-queue = ["APScheduler (>=3.10.4,<3.11.0)", "pytz (>=2018.6)"] +passport = ["cryptography (>=39.0.1)"] +rate-limiter = ["aiolimiter (>=1.1.0,<1.2.0)"] +socks = ["httpx[socks]"] +webhooks = ["tornado (>=6.4,<7.0)"] + [[package]] name = "pytz" version = "2024.1" @@ -5011,101 +4980,101 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] [[package]] name = "rapidfuzz" -version = "3.6.1" +version = "3.6.2" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.8" files = [ - {file = "rapidfuzz-3.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ac434fc71edda30d45db4a92ba5e7a42c7405e1a54cb4ec01d03cc668c6dcd40"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a791168e119cfddf4b5a40470620c872812042f0621e6a293983a2d52372db0"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5a2f3e9df346145c2be94e4d9eeffb82fab0cbfee85bd4a06810e834fe7c03fa"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23de71e7f05518b0bbeef55d67b5dbce3bcd3e2c81e7e533051a2e9401354eb0"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d056e342989248d2bdd67f1955bb7c3b0ecfa239d8f67a8dfe6477b30872c607"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01835d02acd5d95c1071e1da1bb27fe213c84a013b899aba96380ca9962364bc"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed0f712e0bb5fea327e92aec8a937afd07ba8de4c529735d82e4c4124c10d5a0"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96cd19934f76a1264e8ecfed9d9f5291fde04ecb667faef5f33bdbfd95fe2d1f"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e06c4242a1354cf9d48ee01f6f4e6e19c511d50bb1e8d7d20bcadbb83a2aea90"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d73dcfe789d37c6c8b108bf1e203e027714a239e50ad55572ced3c004424ed3b"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:06e98ff000e2619e7cfe552d086815671ed09b6899408c2c1b5103658261f6f3"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:08b6fb47dd889c69fbc0b915d782aaed43e025df6979b6b7f92084ba55edd526"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a1788ebb5f5b655a15777e654ea433d198f593230277e74d51a2a1e29a986283"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-win32.whl", hash = "sha256:c65f92881753aa1098c77818e2b04a95048f30edbe9c3094dc3707d67df4598b"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:4243a9c35667a349788461aae6471efde8d8800175b7db5148a6ab929628047f"}, - {file = "rapidfuzz-3.6.1-cp310-cp310-win_arm64.whl", hash = "sha256:f59d19078cc332dbdf3b7b210852ba1f5db8c0a2cd8cc4c0ed84cc00c76e6802"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fbc07e2e4ac696497c5f66ec35c21ddab3fc7a406640bffed64c26ab2f7ce6d6"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cced1a8852652813f30fb5d4b8f9b237112a0bbaeebb0f4cc3611502556764"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82300e5f8945d601c2daaaac139d5524d7c1fdf719aa799a9439927739917460"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf97c321fd641fea2793abce0e48fa4f91f3c202092672f8b5b4e781960b891"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7420e801b00dee4a344ae2ee10e837d603461eb180e41d063699fb7efe08faf0"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:060bd7277dc794279fa95522af355034a29c90b42adcb7aa1da358fc839cdb11"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7e3375e4f2bfec77f907680328e4cd16cc64e137c84b1886d547ab340ba6928"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a490cd645ef9d8524090551016f05f052e416c8adb2d8b85d35c9baa9d0428ab"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2e03038bfa66d2d7cffa05d81c2f18fd6acbb25e7e3c068d52bb7469e07ff382"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b19795b26b979c845dba407fe79d66975d520947b74a8ab6cee1d22686f7967"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:064c1d66c40b3a0f488db1f319a6e75616b2e5fe5430a59f93a9a5e40a656d15"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3c772d04fb0ebeece3109d91f6122b1503023086a9591a0b63d6ee7326bd73d9"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:841eafba6913c4dfd53045835545ba01a41e9644e60920c65b89c8f7e60c00a9"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-win32.whl", hash = "sha256:266dd630f12696ea7119f31d8b8e4959ef45ee2cbedae54417d71ae6f47b9848"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:d79aec8aeee02ab55d0ddb33cea3ecd7b69813a48e423c966a26d7aab025cdfe"}, - {file = "rapidfuzz-3.6.1-cp311-cp311-win_arm64.whl", hash = "sha256:484759b5dbc5559e76fefaa9170147d1254468f555fd9649aea3bad46162a88b"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b2ef4c0fd3256e357b70591ffb9e8ed1d439fb1f481ba03016e751a55261d7c1"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:588c4b20fa2fae79d60a4e438cf7133d6773915df3cc0a7f1351da19eb90f720"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7142ee354e9c06e29a2636b9bbcb592bb00600a88f02aa5e70e4f230347b373e"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1dfc557c0454ad22382373ec1b7df530b4bbd974335efe97a04caec936f2956a"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:03f73b381bdeccb331a12c3c60f1e41943931461cdb52987f2ecf46bfc22f50d"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b0ccc2ec1781c7e5370d96aef0573dd1f97335343e4982bdb3a44c133e27786"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da3e8c9f7e64bb17faefda085ff6862ecb3ad8b79b0f618a6cf4452028aa2222"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fde9b14302a31af7bdafbf5cfbb100201ba21519be2b9dedcf4f1048e4fbe65d"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1a23eee225dfb21c07f25c9fcf23eb055d0056b48e740fe241cbb4b22284379"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e49b9575d16c56c696bc7b06a06bf0c3d4ef01e89137b3ddd4e2ce709af9fe06"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:0a9fc714b8c290261669f22808913aad49553b686115ad0ee999d1cb3df0cd66"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:a3ee4f8f076aa92184e80308fc1a079ac356b99c39408fa422bbd00145be9854"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f056ba42fd2f32e06b2c2ba2443594873cfccc0c90c8b6327904fc2ddf6d5799"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-win32.whl", hash = "sha256:5d82b9651e3d34b23e4e8e201ecd3477c2baa17b638979deeabbb585bcb8ba74"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:dad55a514868dae4543ca48c4e1fc0fac704ead038dafedf8f1fc0cc263746c1"}, - {file = "rapidfuzz-3.6.1-cp312-cp312-win_arm64.whl", hash = "sha256:3c84294f4470fcabd7830795d754d808133329e0a81d62fcc2e65886164be83b"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e19d519386e9db4a5335a4b29f25b8183a1c3f78cecb4c9c3112e7f86470e37f"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01eb03cd880a294d1bf1a583fdd00b87169b9cc9c9f52587411506658c864d73"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:be368573255f8fbb0125a78330a1a40c65e9ba3c5ad129a426ff4289099bfb41"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3e5af946f419c30f5cb98b69d40997fe8580efe78fc83c2f0f25b60d0e56efb"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f382f7ffe384ce34345e1c0b2065451267d3453cadde78946fbd99a59f0cc23c"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be156f51f3a4f369e758505ed4ae64ea88900dcb2f89d5aabb5752676d3f3d7e"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1936d134b6c513fbe934aeb668b0fee1ffd4729a3c9d8d373f3e404fbb0ce8a0"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ff8eaf4a9399eb2bebd838f16e2d1ded0955230283b07376d68947bbc2d33d"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae598a172e3a95df3383634589660d6b170cc1336fe7578115c584a99e0ba64d"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cd4ba4c18b149da11e7f1b3584813159f189dc20833709de5f3df8b1342a9759"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:0402f1629e91a4b2e4aee68043a30191e5e1b7cd2aa8dacf50b1a1bcf6b7d3ab"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:1e12319c6b304cd4c32d5db00b7a1e36bdc66179c44c5707f6faa5a889a317c0"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0bbfae35ce4de4c574b386c43c78a0be176eeddfdae148cb2136f4605bebab89"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-win32.whl", hash = "sha256:7fec74c234d3097612ea80f2a80c60720eec34947066d33d34dc07a3092e8105"}, - {file = "rapidfuzz-3.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:a553cc1a80d97459d587529cc43a4c7c5ecf835f572b671107692fe9eddf3e24"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:757dfd7392ec6346bd004f8826afb3bf01d18a723c97cbe9958c733ab1a51791"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2963f4a3f763870a16ee076796be31a4a0958fbae133dbc43fc55c3968564cf5"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d2f0274595cc5b2b929c80d4e71b35041104b577e118cf789b3fe0a77b37a4c5"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f211e366e026de110a4246801d43a907cd1a10948082f47e8a4e6da76fef52"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a59472b43879012b90989603aa5a6937a869a72723b1bf2ff1a0d1edee2cc8e6"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a03863714fa6936f90caa7b4b50ea59ea32bb498cc91f74dc25485b3f8fccfe9"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd95b6b7bfb1584f806db89e1e0c8dbb9d25a30a4683880c195cc7f197eaf0c"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7183157edf0c982c0b8592686535c8b3e107f13904b36d85219c77be5cefd0d8"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ad9d74ef7c619b5b0577e909582a1928d93e07d271af18ba43e428dc3512c2a1"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b53137d81e770c82189e07a8f32722d9e4260f13a0aec9914029206ead38cac3"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:49b9ed2472394d306d5dc967a7de48b0aab599016aa4477127b20c2ed982dbf9"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:dec307b57ec2d5054d77d03ee4f654afcd2c18aee00c48014cb70bfed79597d6"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4381023fa1ff32fd5076f5d8321249a9aa62128eb3f21d7ee6a55373e672b261"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-win32.whl", hash = "sha256:8d7a072f10ee57c8413c8ab9593086d42aaff6ee65df4aa6663eecdb7c398dca"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:ebcfb5bfd0a733514352cfc94224faad8791e576a80ffe2fd40b2177bf0e7198"}, - {file = "rapidfuzz-3.6.1-cp39-cp39-win_arm64.whl", hash = "sha256:1c47d592e447738744905c18dda47ed155620204714e6df20eb1941bb1ba315e"}, - {file = "rapidfuzz-3.6.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:eef8b346ab331bec12bbc83ac75641249e6167fab3d84d8f5ca37fd8e6c7a08c"}, - {file = "rapidfuzz-3.6.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53251e256017e2b87f7000aee0353ba42392c442ae0bafd0f6b948593d3f68c6"}, - {file = "rapidfuzz-3.6.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6dede83a6b903e3ebcd7e8137e7ff46907ce9316e9d7e7f917d7e7cdc570ee05"}, - {file = "rapidfuzz-3.6.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4da90e4c2b444d0a171d7444ea10152e07e95972bb40b834a13bdd6de1110c"}, - {file = "rapidfuzz-3.6.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ca3dfcf74f2b6962f411c33dd95b0adf3901266e770da6281bc96bb5a8b20de9"}, - {file = "rapidfuzz-3.6.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bcc957c0a8bde8007f1a8a413a632a1a409890f31f73fe764ef4eac55f59ca87"}, - {file = "rapidfuzz-3.6.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:692c9a50bea7a8537442834f9bc6b7d29d8729a5b6379df17c31b6ab4df948c2"}, - {file = "rapidfuzz-3.6.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c23ceaea27e790ddd35ef88b84cf9d721806ca366199a76fd47cfc0457a81b"}, - {file = "rapidfuzz-3.6.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b155e67fff215c09f130555002e42f7517d0ea72cbd58050abb83cb7c880cec"}, - {file = "rapidfuzz-3.6.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3028ee8ecc48250607fa8a0adce37b56275ec3b1acaccd84aee1f68487c8557b"}, - {file = "rapidfuzz-3.6.1.tar.gz", hash = "sha256:35660bee3ce1204872574fa041c7ad7ec5175b3053a4cb6e181463fc07013de7"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a5637e6bf11b15b5aff6ee818c76bdec99ad208511b78985e6209ba648a6e3ee"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:380586664f2f63807050ddb95e7702888b4f0b425abf17655940c411f39287ad"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3168ff565d4b8c239cf11fb604dd2507d30e9bcaac76a4077c0ac23cf2c866ed"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be69f7fd46b5c6467fe5e2fd4cff3816b0c03048eed8a4becb9a73e6000960e7"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cbd5894f23fdf5697499cf759523639838ac822bd1600e343fdce7313baa02ae"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85a5b6e026393fe39fb61146b9c17c5af66fffbe1410e992c4bb06d9ec327bd3"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab269adfc64480f209e99f253391a10735edd5c09046e04899adab5fb132f20e"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35aeac852bca06023d6bbd50c1fc504ca5a9a3613d5e75a140f0be7601fa34ef"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e706f302c6a3ae0d74edd0d6ace46aee1ae07c563b436ccf5ff04db2b3571e60"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bec353f022011e6e5cd28ccb8700fbd2a33918197af0d4e0abb3c3f4845cc864"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ef3925daaa93eed20401012e219f569ff0c039ed5bf4ce2d3737b4f75d441622"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6ee98d88ae9ccc77ff61992ed33b2496478def5dc0da55c9a9aa06fcb725a352"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:423c7c588b09d618601097b7a0017dfcb91132a2076bef29023c5f3cd2dc3de1"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-win32.whl", hash = "sha256:c17c5efee347a40a6f4c1eec59e3d7d1e22f7613a97f8b8a07733ef723483a04"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:4209816626d8d6ff8ae7dc248061c6059e618b70c6e6f6e4d7444ae3740b2b85"}, + {file = "rapidfuzz-3.6.2-cp310-cp310-win_arm64.whl", hash = "sha256:1c54d3c85e522d3ac9ee39415f183c8fa184c4f87e7e5a37938f15a6d50e853a"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e06f6d270112f5db001f1cba5a97e1a48aee3d3dbdcbea3ec027c230462dbf9b"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:080cb71b50cb6aff11d1c6aeb157f273e2da0b2bdb3f9d7b01257e49e69a8576"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7895e04a22d6515bc91a850e0831f2405547605aa311d1ffec51e4818abc3c1"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82f9838519136b7083dd1e3149ee80344521f3dc37f744f227505ff0883efb"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a945567c2b0b6e069454c9782d5234b0b6795718adf7a9f868bd3144afa6a023"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673ba2c343644805acdae1cb949c6a4de71aa2f62a998978551ebea59603af3f"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d457c89bac1471442002e70551e8268e639b3870b4a4521eae363c07253be87"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:495c0d8e14e6f12520eb7fc71b9ba9fcaafb47fc23a654e6e89b6c7985ec0020"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d67b649bf3e1b1722d04eca44d37919aef88305ce7ad05564502d013cf550fd"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e48dde8ca83d11daa00900cf6a5d281a1297aef9b7bfa73801af6e8822be5019"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:824cc381cf81cbf8d158f6935664ec2a69e6ac3b1d39fa201988bf81a257f775"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfe4c24957474ce0ac75d886387e30e292b4be39228a6d71f76de414dc187db"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d57b98013b802621bbc8b12a46bfc9d36ac552ab51ca207f7ce167ad46adabeb"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-win32.whl", hash = "sha256:9a07dffac439223b4f1025dbfc68f4445a3460a859309c9858c2a3fa29617cdc"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:95a49c6b8bf1229743ae585dd5b7d57f0d15a7eb6e826866d5c9965ba958503c"}, + {file = "rapidfuzz-3.6.2-cp311-cp311-win_arm64.whl", hash = "sha256:af7c19ec86e11488539380d3db1755be5d561a3c0e7b04ff9d07abd7f9a8e9d8"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:de8adc12161bf282c60f12dc9233bb31632f71d446a010fe7469a69b8153427f"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:337e357f693130c4c6be740652542b260e36f622c59e01fa33d58f1d2750c930"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6468f8bc8c3c50604f43631550ef9cfec873515dba5023ca34d461be94669fc8"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74c6773b11445b5e5cf93ca383171cd0ac0cdeafea11a7b2a5688f8bf8d813e6"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1507fc5769aa109dda4de3a15f822a0f6a03e18d627bd0ba3ddbb253cf70e07"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:617949a70150e6fffdaed19253dd49f7a53528411dc8bf7663d499ba21e0f61e"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8b77779174b1b40aa70827692571ab457061897846255ad7d5d559e2edb1932"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80e51b22a7da83f9c87a97e92df07ed0612c74c35496590255f4b5d5b4212dfe"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3ae7c86914cb6673e97e187ba431b9c4cf4177d9ae77f8a1e5b2ba9a5628839e"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ddc380ffaa90f204cc9ddcb779114b9ab6f015246d549de9d47871a97ef9f18a"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c1dc078ef371fce09f9f3eec2ca4eaa2a8cd412ec53941015b4f39f14d34407"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:9a74102fc5a2534fe91f7507838623e1f3a149d8e05648389c42bb42e14b1c3f"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:48e1eaea8fcd522fca7f04f0480663f0f0cfb77957092cce60a93f4462864996"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-win32.whl", hash = "sha256:66b008bf2972740cd2dda5d382eb8bdb87265cd88198e71c7797bdc0d1f79d20"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:87ac3a87f2251ae2e95fc9478ca5c759de6d141d04c84d3fec9f9cdcfc167b33"}, + {file = "rapidfuzz-3.6.2-cp312-cp312-win_arm64.whl", hash = "sha256:b593cc51aed887e93b78c2f94dfae9008be2b23d17afd3b1f1d3eb3913b58f26"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d830bc7a9b586a374147ec60b08b1f9ae5996b43f75cc514f37faef3866b519"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dbee7f5ff11872b76505cbd87c814abc823e8757f11c69062eb3b25130a283da"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c011fb31f2c3f82f503aedd6097d3d3854e574e327a119a3b7eb2cf90b79ca"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cda81d0e0ce0c13abfa46b24e10c1e85f9c6acb628f0a9a948f5779f9c2076a2"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c279928651ce0e9e5220dcb25a00cc53b65e592a0861336a38299bcdca3a596"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35bd4bc9c40e6994c5d6edea4b9319388b4d9711c13c66d543bb4c37624b4184"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d07899506a5a8760448d9df036d528b55a554bf571714173635c79eef4a86e58"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb2e51d01b9c6d6954a3e055c57a80d4685b4fc82719db5519fc153566bcd6bb"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:153d065e353371cc0aeff32b99999a5758266a64e958d1364189367c1c9f6814"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4edcceebb85ebfa49a3ddcde20ad891d36c08dc0fd592efdab0e7d313a4e36af"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3549123fca5bb817341025f98e8e49ca99f84596c7c4f92b658f8e5836040d4a"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:84c1032ae42628465b7a5cc35249906061e18a8193c9c27cbd2db54e9823a9a6"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9bcc91ebd8fc69a6bd3b5711c8250f5f4e70606b4da75ef415f57ad209978205"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-win32.whl", hash = "sha256:f3a70f341c4c111bad910d2df69c78577a98af140319a996af24c9385939335d"}, + {file = "rapidfuzz-3.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:354ad5fe655beb7b279390cb58334903931c5452ecbad1b1666ffb06786498e2"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1b86b93d93020c2b3edc1665d75c8855784845fc0a739b312c26c3a4bf0c80d5"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28243086ed0e50808bb56632e5442c457241646aeafafd501ac87901f40a3237"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed52461ae5a9ea4c400d38e2649c74a413f1a6d8fb8308b66f1fbd122514732f"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a46220f86a5f9cb016af31525e0d0865cad437d02239aa0d8aed2ab8bff1f1c"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81a630ed2fc3ec5fc7400eb66bab1f87e282b4d47f0abe3e48c6634dfa13b5e4"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8e5a437b9089df6242a718d9c31ab1742989e9400a0977af012ef483b63b4c2"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16270b5529de83b7bae7457e952e4d9cf3fbf029a837dd32d415bb9e0eb8e599"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5378c04102c7f084cde30a100154fa6d7e2baf0d51a6bdd2f912545559c1fb35"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f18397c8d6a65fc0b288d2fc29bc7baeea6ba91eeb95163a3cd98f23cd3bc85"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2acd2514defce81e6ff4bbff50252d5e7df8e85a731442c4b83e44c86cf1c916"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:1df2faf80201952e252413b6fac6f3e146080dcebb87bb1bb722508e67558ed8"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6440ed0b3007c1c9286b0b88fe2ab2d9e83edd60cd62293b3dfabb732b4e8a30"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4fcfa23b5553b27f4016df77c53172ea743454cf12c28cfa7c35a309a2be93b3"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-win32.whl", hash = "sha256:2d580d937146e803c8e5e1b87916cab8d6f84013b6392713e201efcda335c7d8"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:fe2a68be734e8e88af23385c68d6467e15818b6b1df1cbfebf7bff577226c957"}, + {file = "rapidfuzz-3.6.2-cp39-cp39-win_arm64.whl", hash = "sha256:6478f7803efebf5f644d0b758439c5b25728550fdfbb19783d150004c46a75a9"}, + {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:36ce7b68a7b90b787cdd73480a68d2f1ca63c31a3a9d5a79a8736f978e1e9344"}, + {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53597fd72a9340bcdd80d3620f4957c2b92f9b569313b969a3abdaffd193aae6"}, + {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4f6de745fe6ce46a422d353ee10599013631d7d714a36d025f164b2d4e8c000"}, + {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62df2136068e2515ed8beb01756381ff62c29384d785e3bf46e3111d4ea3ba1e"}, + {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7382c90170f60c846c81a07ddd80bb2e8c43c8383754486fa37f67391a571897"}, + {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f31314fd2e2f3dc3e519e6f93669462ce7953df2def1c344aa8f5345976d0eb2"}, + {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012221629d54d3bee954148247f711eb86d4d390b589ebfe03172ea0b37a7531"}, + {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41dd59a70decfce6595315367a2fea2af660d92a9d144acc6479030501014d7"}, + {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9fa14136a5b0cba1ec42531f7c3e0b0d3edb7fd6bc5e5ae7b498541f3855ab"}, + {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:259364199cbfeca33b1af369fc7951f71717aa285184a3fa5a7b1772da1b89db"}, + {file = "rapidfuzz-3.6.2.tar.gz", hash = "sha256:cf911e792ab0c431694c9bf2648afabfd92099103f2e31492893e078ddca5e1a"}, ] [package.extras] @@ -5113,17 +5082,17 @@ full = ["numpy"] [[package]] name = "redis" -version = "5.0.2" +version = "5.0.3" description = "Python client for Redis database and key-value store" optional = true python-versions = ">=3.7" files = [ - {file = "redis-5.0.2-py3-none-any.whl", hash = "sha256:4caa8e1fcb6f3c0ef28dba99535101d80934b7d4cd541bbb47f4a3826ee472d1"}, - {file = "redis-5.0.2.tar.gz", hash = "sha256:3f82cc80d350e93042c8e6e7a5d0596e4dd68715babffba79492733e1f367037"}, + {file = "redis-5.0.3-py3-none-any.whl", hash = "sha256:5da9b8fe9e1254293756c16c008e8620b3d15fcc6dde6babde9541850e72a32d"}, + {file = "redis-5.0.3.tar.gz", hash = "sha256:4973bae7444c0fbed64a06b87446f79361cb7e4ec1538c022d696ed7a5015580"}, ] [package.dependencies] -async-timeout = ">=4.0.3" +async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""} [package.extras] hiredis = ["hiredis (>=1.0.0)"] @@ -5131,13 +5100,13 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "referencing" -version = "0.33.0" +version = "0.34.0" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, - {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, + {file = "referencing-0.34.0-py3-none-any.whl", hash = "sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4"}, + {file = "referencing-0.34.0.tar.gz", hash = "sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844"}, ] [package.dependencies] @@ -5388,18 +5357,18 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "69.1.1" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -5715,60 +5684,60 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.27" +version = "2.0.28" description = "Database Abstraction Library" optional = true python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d04e579e911562f1055d26dab1868d3e0bb905db3bccf664ee8ad109f035618a"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c7a596d0be71b7baa037f4ac10d5e057d276f65a9a611c46970f012752ebf2d"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954d9735ee9c3fa74874c830d089a815b7b48df6f6b6e357a74130e478dbd951"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5cd20f58c29bbf2680039ff9f569fa6d21453fbd2fa84dbdb4092f006424c2e6"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:03f448ffb731b48323bda68bcc93152f751436ad6037f18a42b7e16af9e91c07"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-win32.whl", hash = "sha256:d997c5938a08b5e172c30583ba6b8aad657ed9901fc24caf3a7152eeccb2f1b4"}, - {file = "SQLAlchemy-2.0.27-cp310-cp310-win_amd64.whl", hash = "sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c5bad7c60a392850d2f0fee8f355953abaec878c483dd7c3836e0089f046bf6"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3012ab65ea42de1be81fff5fb28d6db893ef978950afc8130ba707179b4284a"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbcd77c4d94b23e0753c5ed8deba8c69f331d4fd83f68bfc9db58bc8983f49cd"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d177b7e82f6dd5e1aebd24d9c3297c70ce09cd1d5d37b43e53f39514379c029c"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:680b9a36029b30cf063698755d277885d4a0eab70a2c7c6e71aab601323cba45"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1306102f6d9e625cebaca3d4c9c8f10588735ef877f0360b5cdb4fdfd3fd7131"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-win32.whl", hash = "sha256:5b78aa9f4f68212248aaf8943d84c0ff0f74efc65a661c2fc68b82d498311fd5"}, - {file = "SQLAlchemy-2.0.27-cp311-cp311-win_amd64.whl", hash = "sha256:15e19a84b84528f52a68143439d0c7a3a69befcd4f50b8ef9b7b69d2628ae7c4"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0de1263aac858f288a80b2071990f02082c51d88335a1db0d589237a3435fe71"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce850db091bf7d2a1f2fdb615220b968aeff3849007b1204bf6e3e50a57b3d32"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dfc936870507da96aebb43e664ae3a71a7b96278382bcfe84d277b88e379b18"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4fbe6a766301f2e8a4519f4500fe74ef0a8509a59e07a4085458f26228cd7cc"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4535c49d961fe9a77392e3a630a626af5baa967172d42732b7a43496c8b28876"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0fb3bffc0ced37e5aa4ac2416f56d6d858f46d4da70c09bb731a246e70bff4d5"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-win32.whl", hash = "sha256:7f470327d06400a0aa7926b375b8e8c3c31d335e0884f509fe272b3c700a7254"}, - {file = "SQLAlchemy-2.0.27-cp312-cp312-win_amd64.whl", hash = "sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e97cf143d74a7a5a0f143aa34039b4fecf11343eed66538610debc438685db4a"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7b5a3e2120982b8b6bd1d5d99e3025339f7fb8b8267551c679afb39e9c7c7f1"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e36aa62b765cf9f43a003233a8c2d7ffdeb55bc62eaa0a0380475b228663a38f"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5ada0438f5b74c3952d916c199367c29ee4d6858edff18eab783b3978d0db16d"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b1d9d1bfd96eef3c3faedb73f486c89e44e64e40e5bfec304ee163de01cf996f"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-win32.whl", hash = "sha256:ca891af9f3289d24a490a5fde664ea04fe2f4984cd97e26de7442a4251bd4b7c"}, - {file = "SQLAlchemy-2.0.27-cp37-cp37m-win_amd64.whl", hash = "sha256:fd8aafda7cdff03b905d4426b714601c0978725a19efc39f5f207b86d188ba01"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec1f5a328464daf7a1e4e385e4f5652dd9b1d12405075ccba1df842f7774b4fc"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ad862295ad3f644e3c2c0d8b10a988e1600d3123ecb48702d2c0f26771f1c396"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48217be1de7d29a5600b5c513f3f7664b21d32e596d69582be0a94e36b8309cb"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e56afce6431450442f3ab5973156289bd5ec33dd618941283847c9fd5ff06bf"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:611068511b5531304137bcd7fe8117c985d1b828eb86043bd944cebb7fae3910"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b86abba762ecfeea359112b2bb4490802b340850bbee1948f785141a5e020de8"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-win32.whl", hash = "sha256:30d81cc1192dc693d49d5671cd40cdec596b885b0ce3b72f323888ab1c3863d5"}, - {file = "SQLAlchemy-2.0.27-cp38-cp38-win_amd64.whl", hash = "sha256:120af1e49d614d2525ac247f6123841589b029c318b9afbfc9e2b70e22e1827d"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d07ee7793f2aeb9b80ec8ceb96bc8cc08a2aec8a1b152da1955d64e4825fcbac"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb0845e934647232b6ff5150df37ceffd0b67b754b9fdbb095233deebcddbd4a"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc19ae2e07a067663dd24fca55f8ed06a288384f0e6e3910420bf4b1270cc51"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b90053be91973a6fb6020a6e44382c97739736a5a9d74e08cc29b196639eb979"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2f5c9dfb0b9ab5e3a8a00249534bdd838d943ec4cfb9abe176a6c33408430230"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33e8bde8fff203de50399b9039c4e14e42d4d227759155c21f8da4a47fc8053c"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-win32.whl", hash = "sha256:d873c21b356bfaf1589b89090a4011e6532582b3a8ea568a00e0c3aab09399dd"}, - {file = "SQLAlchemy-2.0.27-cp39-cp39-win_amd64.whl", hash = "sha256:ff2f1b7c963961d41403b650842dc2039175b906ab2093635d8319bef0b7d620"}, - {file = "SQLAlchemy-2.0.27-py3-none-any.whl", hash = "sha256:1ab4e0448018d01b142c916cc7119ca573803a4745cfe341b8f95657812700ac"}, - {file = "SQLAlchemy-2.0.27.tar.gz", hash = "sha256:86a6ed69a71fe6b88bf9331594fa390a2adda4a49b5c06f98e47bf0d392534f8"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0b148ab0438f72ad21cb004ce3bdaafd28465c4276af66df3b9ecd2037bf252"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbda76961eb8f27e6ad3c84d1dc56d5bc61ba8f02bd20fcf3450bd421c2fcc9c"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feea693c452d85ea0015ebe3bb9cd15b6f49acc1a31c28b3c50f4db0f8fb1e71"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da98815f82dce0cb31fd1e873a0cb30934971d15b74e0d78cf21f9e1b05953f"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5adf383c73f2d49ad15ff363a8748319ff84c371eed59ffd0127355d6ea1da"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56856b871146bfead25fbcaed098269d90b744eea5cb32a952df00d542cdd368"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-win32.whl", hash = "sha256:943aa74a11f5806ab68278284a4ddd282d3fb348a0e96db9b42cb81bf731acdc"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-win_amd64.whl", hash = "sha256:c6c4da4843e0dabde41b8f2e8147438330924114f541949e6318358a56d1875a"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46a3d4e7a472bfff2d28db838669fc437964e8af8df8ee1e4548e92710929adc"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3dd67b5d69794cfe82862c002512683b3db038b99002171f624712fa71aeaa"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61e2e41656a673b777e2f0cbbe545323dbe0d32312f590b1bc09da1de6c2a02"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0315d9125a38026227f559488fe7f7cee1bd2fbc19f9fd637739dc50bb6380b2"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af8ce2d31679006e7b747d30a89cd3ac1ec304c3d4c20973f0f4ad58e2d1c4c9"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81ba314a08c7ab701e621b7ad079c0c933c58cdef88593c59b90b996e8b58fa5"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-win32.whl", hash = "sha256:1ee8bd6d68578e517943f5ebff3afbd93fc65f7ef8f23becab9fa8fb315afb1d"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-win_amd64.whl", hash = "sha256:ad7acbe95bac70e4e687a4dc9ae3f7a2f467aa6597049eeb6d4a662ecd990bb6"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d3499008ddec83127ab286c6f6ec82a34f39c9817f020f75eca96155f9765097"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b66fcd38659cab5d29e8de5409cdf91e9986817703e1078b2fdaad731ea66f5"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea30da1e76cb1acc5b72e204a920a3a7678d9d52f688f087dc08e54e2754c67"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:124202b4e0edea7f08a4db8c81cc7859012f90a0d14ba2bf07c099aff6e96462"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e23b88c69497a6322b5796c0781400692eca1ae5532821b39ce81a48c395aae9"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b6303bfd78fb3221847723104d152e5972c22367ff66edf09120fcde5ddc2e2"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-win32.whl", hash = "sha256:a921002be69ac3ab2cf0c3017c4e6a3377f800f1fca7f254c13b5f1a2f10022c"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-win_amd64.whl", hash = "sha256:b4a2cf92995635b64876dc141af0ef089c6eea7e05898d8d8865e71a326c0385"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e91b5e341f8c7f1e5020db8e5602f3ed045a29f8e27f7f565e0bdee3338f2c7"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c7b78dfc7278329f27be02c44abc0d69fe235495bb8e16ec7ef1b1a17952db"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eba73ef2c30695cb7eabcdb33bb3d0b878595737479e152468f3ba97a9c22a4"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5df5d1dafb8eee89384fb7a1f79128118bc0ba50ce0db27a40750f6f91aa99d5"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2858bbab1681ee5406650202950dc8f00e83b06a198741b7c656e63818633526"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-win32.whl", hash = "sha256:9461802f2e965de5cff80c5a13bc945abea7edaa1d29360b485c3d2b56cdb075"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-win_amd64.whl", hash = "sha256:a6bec1c010a6d65b3ed88c863d56b9ea5eeefdf62b5e39cafd08c65f5ce5198b"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:843a882cadebecc655a68bd9a5b8aa39b3c52f4a9a5572a3036fb1bb2ccdc197"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dbb990612c36163c6072723523d2be7c3eb1517bbdd63fe50449f56afafd1133"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7e4baf9161d076b9a7e432fce06217b9bd90cfb8f1d543d6e8c4595627edb9"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0a5354cb4de9b64bccb6ea33162cb83e03dbefa0d892db88a672f5aad638a75"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fffcc8edc508801ed2e6a4e7b0d150a62196fd28b4e16ab9f65192e8186102b6"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aca7b6d99a4541b2ebab4494f6c8c2f947e0df4ac859ced575238e1d6ca5716b"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-win32.whl", hash = "sha256:8c7f10720fc34d14abad5b647bc8202202f4948498927d9f1b4df0fb1cf391b7"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-win_amd64.whl", hash = "sha256:243feb6882b06a2af68ecf4bec8813d99452a1b62ba2be917ce6283852cf701b"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc4974d3684f28b61b9a90fcb4c41fb340fd4b6a50c04365704a4da5a9603b05"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87724e7ed2a936fdda2c05dbd99d395c91ea3c96f029a033a4a20e008dd876bf"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68722e6a550f5de2e3cfe9da6afb9a7dd15ef7032afa5651b0f0c6b3adb8815d"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328529f7c7f90adcd65aed06a161851f83f475c2f664a898af574893f55d9e53"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:df40c16a7e8be7413b885c9bf900d402918cc848be08a59b022478804ea076b8"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:426f2fa71331a64f5132369ede5171c52fd1df1bd9727ce621f38b5b24f48750"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-win32.whl", hash = "sha256:33157920b233bc542ce497a81a2e1452e685a11834c5763933b440fedd1d8e2d"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-win_amd64.whl", hash = "sha256:2f60843068e432311c886c5f03c4664acaef507cf716f6c60d5fde7265be9d7b"}, + {file = "SQLAlchemy-2.0.28-py3-none-any.whl", hash = "sha256:78bb7e8da0183a8301352d569900d9d3594c48ac21dc1c2ec6b3121ed8b6c986"}, + {file = "SQLAlchemy-2.0.28.tar.gz", hash = "sha256:dd53b6c4e6d960600fd6532b79ee28e2da489322fcf6648738134587faf767b6"}, ] [package.dependencies] @@ -5855,13 +5824,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "streamlit" -version = "1.31.1" +version = "1.32.2" description = "A faster way to build and share data apps" optional = false python-versions = ">=3.8, !=3.9.7" files = [ - {file = "streamlit-1.31.1-py2.py3-none-any.whl", hash = "sha256:a1a84249f7a9b854fe356db06c85dc03c3f9da4df06a33aa5a922647b955e8c8"}, - {file = "streamlit-1.31.1.tar.gz", hash = "sha256:dfc43ca85b4b4c31d097c27b983b8ccc960222ad907862b2b2fb4ddf04c50fdc"}, + {file = "streamlit-1.32.2-py2.py3-none-any.whl", hash = "sha256:a0b8044e76fec364b07be145f8b40dbd8d083e20ebbb189ceb1fa9423f3dedea"}, + {file = "streamlit-1.32.2.tar.gz", hash = "sha256:1258b9cbc3ff957bf7d09b1bfc85cedc308f1065b30748545295a9af8d5577ab"}, ] [package.dependencies] @@ -5870,7 +5839,6 @@ blinker = ">=1.0.0,<2" cachetools = ">=4.0,<6" click = ">=7.0,<9" gitpython = ">=3.0.7,<3.1.19 || >3.1.19,<4" -importlib-metadata = ">=1.4,<8" numpy = ">=1.19.3,<2" packaging = ">=16.8,<24" pandas = ">=1.3.0,<3" @@ -5878,15 +5846,12 @@ pillow = ">=7.1.0,<11" protobuf = ">=3.20,<5" pyarrow = ">=7.0" pydeck = ">=0.8.0b4,<1" -python-dateutil = ">=2.7.3,<3" requests = ">=2.27,<3" rich = ">=10.14.0,<14" tenacity = ">=8.1.0,<9" toml = ">=0.10.1,<2" tornado = ">=6.0.3,<7" typing-extensions = ">=4.3.0,<5" -tzlocal = ">=1.1,<6" -validators = ">=0.2,<1" watchdog = {version = ">=2.1.5", markers = "platform_system != \"Darwin\""} [package.extras] @@ -5953,13 +5918,13 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "terminado" -version = "0.18.0" +version = "0.18.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." optional = false python-versions = ">=3.8" files = [ - {file = "terminado-0.18.0-py3-none-any.whl", hash = "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e"}, - {file = "terminado-0.18.0.tar.gz", hash = "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded"}, + {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, + {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, ] [package.dependencies] @@ -6076,28 +6041,28 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.14.1" +version = "5.14.2" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, - {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, + {file = "traitlets-5.14.2-py3-none-any.whl", hash = "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80"}, + {file = "traitlets-5.14.2.tar.gz", hash = "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.1)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "trove-classifiers" -version = "2024.2.23" +version = "2024.3.3" description = "Canonical source for classifiers on PyPI (pypi.org)." optional = false python-versions = "*" files = [ - {file = "trove-classifiers-2024.2.23.tar.gz", hash = "sha256:8385160a12aac69c93fff058fb613472ed773a24a27eb3cd4b144cfbdd79f38c"}, - {file = "trove_classifiers-2024.2.23-py3-none-any.whl", hash = "sha256:3094534b8021dc1822aadb1d11d4c7b62a854d464d19458fd0a49d6fe2b68b77"}, + {file = "trove-classifiers-2024.3.3.tar.gz", hash = "sha256:df7edff9c67ff86b733628998330b180e81d125b1e096536d83ac0fd79673fdc"}, + {file = "trove_classifiers-2024.3.3-py3-none-any.whl", hash = "sha256:3a84096861b385ec422c79995d1f6435dde47a9b63adaa3c886e53232ba7e6e0"}, ] [[package]] @@ -6123,13 +6088,13 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. [[package]] name = "types-python-dateutil" -version = "2.8.19.20240106" +version = "2.9.0.20240316" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, - {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, ] [[package]] @@ -6154,24 +6119,6 @@ files = [ {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] -[[package]] -name = "tzlocal" -version = "5.2" -description = "tzinfo object for the local timezone" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, - {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, -] - -[package.dependencies] -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} -tzdata = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] - [[package]] name = "uri-template" version = "1.3.0" @@ -6204,13 +6151,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "uvicorn" -version = "0.27.1" +version = "0.28.0" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"}, - {file = "uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"}, + {file = "uvicorn-0.28.0-py3-none-any.whl", hash = "sha256:6623abbbe6176204a4226e67607b4d52cc60ff62cda0ff177613645cefa2ece1"}, + {file = "uvicorn-0.28.0.tar.gz", hash = "sha256:cab4473b5d1eaeb5a0f6375ac4bc85007ffc75c3cc1768816d9e5d589857b067"}, ] [package.dependencies] @@ -6221,28 +6168,6 @@ typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] -[[package]] -name = "validators" -version = "0.22.0" -description = "Python Data Validation for Humans™" -optional = false -python-versions = ">=3.8" -files = [ - {file = "validators-0.22.0-py3-none-any.whl", hash = "sha256:61cf7d4a62bbae559f2e54aed3b000cea9ff3e2fdbe463f51179b92c58c9585a"}, - {file = "validators-0.22.0.tar.gz", hash = "sha256:77b2689b172eeeb600d9605ab86194641670cdb73b60afd577142a9397873370"}, -] - -[package.extras] -docs-offline = ["myst-parser (>=2.0.0)", "pypandoc-binary (>=1.11)", "sphinx (>=7.1.1)"] -docs-online = ["mkdocs (>=1.5.2)", "mkdocs-git-revision-date-localized-plugin (>=1.2.0)", "mkdocs-material (>=9.2.6)", "mkdocstrings[python] (>=0.22.0)", "pyaml (>=23.7.0)"] -hooks = ["pre-commit (>=3.3.3)"] -package = ["build (>=1.0.0)", "twine (>=4.0.2)"] -runner = ["tox (>=4.11.1)"] -sast = ["bandit[toml] (>=1.7.5)"] -testing = ["pytest (>=7.4.0)"] -tooling = ["black (>=23.7.0)", "pyright (>=1.1.325)", "ruff (>=0.0.287)"] -tooling-extras = ["pyaml (>=23.7.0)", "pypandoc-binary (>=1.11)", "pytest (>=7.4.0)"] - [[package]] name = "virtualenv" version = "20.25.1" @@ -6723,13 +6648,13 @@ multidict = ">=4.0" [[package]] name = "ydb" -version = "3.8.0" +version = "3.8.1" description = "YDB Python SDK" optional = true python-versions = "*" files = [ - {file = "ydb-3.8.0-py2.py3-none-any.whl", hash = "sha256:29d94f4c6047c24440e11a326604f913f1cf3d909f175329e081ac37f90a9152"}, - {file = "ydb-3.8.0.tar.gz", hash = "sha256:d5bdbc7d069977de86d6ceac62602803696d6c911d685d99edc5a9988710aaf5"}, + {file = "ydb-3.8.1-py2.py3-none-any.whl", hash = "sha256:20546e8b3062043cc1ae46e746b6ea339043fcf511890c4fff6610a1219ab998"}, + {file = "ydb-3.8.1.tar.gz", hash = "sha256:524ef8265fa1bcb532da1bda2958437a71a7fec755dc25dd9892b84de2a8ec65"}, ] [package.dependencies] @@ -6743,18 +6668,18 @@ yc = ["yandexcloud"] [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [[package]] name = "zope-event" @@ -6837,10 +6762,10 @@ postgresql = ["asyncpg", "sqlalchemy"] redis = ["redis"] sqlite = ["aiosqlite", "sqlalchemy"] stats = ["omegaconf", "opentelemetry-exporter-otlp", "opentelemetry-instrumentation", "requests", "tqdm"] -telegram = ["pytelegrambotapi"] +telegram = ["python-telegram-bot"] ydb = ["six", "ydb"] [metadata] lock-version = "2.0" python-versions = "^3.8.1,!=3.9.7" -content-hash = "bfc9b006110db970767817b6eec3f44194dc36e29748cb319d75876610a2e1a8" +content-hash = "2bab0798ec48c472886dc47a49d9bab5a0af3dfac810cea1eacf322b0a322eb2" From 771370de5e508f14d3fb95b3523277d63e5d4e72 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 00:34:24 +0100 Subject: [PATCH 024/140] typing fixed --- dff/script/core/message.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 1ab3a6382..3878e7c11 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -5,14 +5,15 @@ DFF. It only contains types and properties that are compatible with most messaging services. """ -from typing import Any, Optional, List, Union +from typing import TYPE_CHECKING, Any, Optional, List, Union from enum import Enum, auto from pathlib import Path from urllib.request import urlopen from pydantic import field_validator, Field, FilePath, HttpUrl, BaseModel, model_validator -from dff.messengers.common.interface import MessengerInterface +if TYPE_CHECKING: + from dff.messengers.common.interface import MessengerInterface class Session(Enum): From 1c850528ee8090d329e6b14cade28b9caedf2e51 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 00:42:47 +0100 Subject: [PATCH 025/140] circular import resolved --- dff/messengers/common/interface.py | 3 ++- dff/script/core/message.py | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index cc1bba876..dca964b9e 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -12,11 +12,12 @@ import uuid from typing import Optional, Any, List, Tuple, TextIO, Hashable, TYPE_CHECKING -from dff.script import Context, Message +from dff.script import Message from dff.messengers.common.types import PollingInterfaceLoopFunction from dff.script.core.message import DataAttachment if TYPE_CHECKING: + from dff.script import Context from dff.pipeline.types import PipelineRunnerFunction logger = logging.getLogger(__name__) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 3878e7c11..1ab3a6382 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -5,15 +5,14 @@ DFF. It only contains types and properties that are compatible with most messaging services. """ -from typing import TYPE_CHECKING, Any, Optional, List, Union +from typing import Any, Optional, List, Union from enum import Enum, auto from pathlib import Path from urllib.request import urlopen from pydantic import field_validator, Field, FilePath, HttpUrl, BaseModel, model_validator -if TYPE_CHECKING: - from dff.messengers.common.interface import MessengerInterface +from dff.messengers.common.interface import MessengerInterface class Session(Enum): From 0cebb97def18331fc5e4bb670e6213b580436568 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 00:58:44 +0100 Subject: [PATCH 026/140] one more attempt to fix circular import --- dff/messengers/common/interface.py | 12 +++++++----- dff/script/core/message.py | 9 ++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index dca964b9e..ae46052b7 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -12,13 +12,11 @@ import uuid from typing import Optional, Any, List, Tuple, TextIO, Hashable, TYPE_CHECKING -from dff.script import Message -from dff.messengers.common.types import PollingInterfaceLoopFunction -from dff.script.core.message import DataAttachment - if TYPE_CHECKING: - from dff.script import Context + from dff.script import Context, Message from dff.pipeline.types import PipelineRunnerFunction + from dff.messengers.common.types import PollingInterfaceLoopFunction + from dff.script.core.message import DataAttachment logger = logging.getLogger(__name__) @@ -174,11 +172,15 @@ def __init__( self._descriptor: Optional[TextIO] = out_descriptor def _request(self) -> List[Tuple[Message, Any]]: + from dff.script import Message return [(Message(input(self._prompt_request)), self._ctx_id)] def _respond(self, responses: List[Context]): print(f"{self._prompt_response}{responses[0].last_response.text}", file=self._descriptor) + async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover + pass + async def connect(self, pipeline_runner: PipelineRunnerFunction, **kwargs): """ The CLIProvider generates new dialog id used to user identification on each `connect` call. diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 1ab3a6382..d81b83c11 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -105,11 +105,14 @@ class DataAttachment(Attachment): source: Optional[Union[HttpUrl, FilePath]] = None id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None - from_messenger_interface: MessengerInterface = Field(exclude=True) + from_messenger_interface: Optional[MessengerInterface] = Field(exclude=True, default=None) async def get_bytes(self) -> Optional[bytes]: if self.source is None: - await self.from_messenger_interface.populate_attachment(self) + if self.from_messenger_interface is None: + return None + else: + await self.from_messenger_interface.populate_attachment(self) if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() @@ -227,7 +230,7 @@ def __init__( self, text: Optional[str] = None, commands: Optional[List[Command]] = None, - attachments: Optional[Attachments] = None, + attachments: Optional[Attachment] = None, annotations: Optional[dict] = None, misc: Optional[dict] = None, **kwargs, From a5f0e02c0be9fc30e9c3a8071083f769de982df5 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 01:09:38 +0100 Subject: [PATCH 027/140] populate attachment method made implemented --- dff/messengers/common/interface.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index ae46052b7..faa6324fa 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -41,9 +41,9 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction): """ raise NotImplementedError - @abc.abstractmethod async def populate_attachment(self, attachment: DataAttachment) -> None: - raise NotImplementedError + if attachment.source is None: + raise NotImplementedError class PollingMessengerInterface(MessengerInterface): @@ -178,9 +178,6 @@ def _request(self) -> List[Tuple[Message, Any]]: def _respond(self, responses: List[Context]): print(f"{self._prompt_response}{responses[0].last_response.text}", file=self._descriptor) - async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover - pass - async def connect(self, pipeline_runner: PipelineRunnerFunction, **kwargs): """ The CLIProvider generates new dialog id used to user identification on each `connect` call. From 01947ddcc4e75f45e5329db2183804f1d1aa6ae7 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 20:05:19 +0100 Subject: [PATCH 028/140] CLI interface separated --- dff/messengers/common/__init__.py | 2 +- dff/messengers/common/interface.py | 44 +---------------- dff/messengers/console.py | 47 +++++++++++++++++++ dff/pipeline/pipeline/pipeline.py | 3 +- tests/pipeline/test_messenger_interface.py | 3 +- .../pipeline/2_pre_and_post_processors.py | 2 +- .../3_pipeline_dict_with_services_full.py | 2 +- 7 files changed, 55 insertions(+), 48 deletions(-) create mode 100644 dff/messengers/console.py diff --git a/dff/messengers/common/__init__.py b/dff/messengers/common/__init__.py index d9c66d921..8bcf7eaa7 100644 --- a/dff/messengers/common/__init__.py +++ b/dff/messengers/common/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -from .interface import MessengerInterface, PollingMessengerInterface, CallbackMessengerInterface, CLIMessengerInterface +from .interface import MessengerInterface, PollingMessengerInterface, CallbackMessengerInterface from .types import PollingInterfaceLoopFunction diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index faa6324fa..e7cd902a6 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -9,8 +9,7 @@ import abc import asyncio import logging -import uuid -from typing import Optional, Any, List, Tuple, TextIO, Hashable, TYPE_CHECKING +from typing import Optional, Any, List, Tuple, Hashable, TYPE_CHECKING if TYPE_CHECKING: from dff.script import Context, Message @@ -149,44 +148,3 @@ def on_request( This method has the same signature as :py:class:`~dff.pipeline.types.PipelineRunnerFunction`. """ return asyncio.run(self.on_request_async(request, ctx_id, update_ctx_misc)) - - -class CLIMessengerInterface(PollingMessengerInterface): - """ - Command line message interface is the default message interface, communicating with user via `STDIN/STDOUT`. - This message interface can maintain dialog with one user at a time only. - """ - - def __init__( - self, - intro: Optional[str] = None, - prompt_request: str = "request: ", - prompt_response: str = "response: ", - out_descriptor: Optional[TextIO] = None, - ): - super().__init__() - self._ctx_id: Optional[Hashable] = None - self._intro: Optional[str] = intro - self._prompt_request: str = prompt_request - self._prompt_response: str = prompt_response - self._descriptor: Optional[TextIO] = out_descriptor - - def _request(self) -> List[Tuple[Message, Any]]: - from dff.script import Message - return [(Message(input(self._prompt_request)), self._ctx_id)] - - def _respond(self, responses: List[Context]): - print(f"{self._prompt_response}{responses[0].last_response.text}", file=self._descriptor) - - async def connect(self, pipeline_runner: PipelineRunnerFunction, **kwargs): - """ - The CLIProvider generates new dialog id used to user identification on each `connect` call. - - :param pipeline_runner: A function that should process user request and return context; - usually it's a :py:meth:`~dff.pipeline.pipeline.pipeline.Pipeline._run_pipeline` function. - :param \\**kwargs: argument, added for compatibility with super class, it shouldn't be used normally. - """ - self._ctx_id = uuid.uuid4() - if self._intro is not None: - print(self._intro) - await super().connect(pipeline_runner, **kwargs) diff --git a/dff/messengers/console.py b/dff/messengers/console.py new file mode 100644 index 000000000..ab30669ad --- /dev/null +++ b/dff/messengers/console.py @@ -0,0 +1,47 @@ +from typing import Any, Hashable, List, Optional, TextIO, Tuple +from uuid import uuid4 +from dff.messengers.common.interface import PollingMessengerInterface +from dff.pipeline.types import PipelineRunnerFunction +from dff.script.core.context import Context +from dff.script.core.message import Message + + +class CLIMessengerInterface(PollingMessengerInterface): + """ + Command line message interface is the default message interface, communicating with user via `STDIN/STDOUT`. + This message interface can maintain dialog with one user at a time only. + """ + + def __init__( + self, + intro: Optional[str] = None, + prompt_request: str = "request: ", + prompt_response: str = "response: ", + out_descriptor: Optional[TextIO] = None, + ): + super().__init__() + self._ctx_id: Optional[Hashable] = None + self._intro: Optional[str] = intro + self._prompt_request: str = prompt_request + self._prompt_response: str = prompt_response + self._descriptor: Optional[TextIO] = out_descriptor + + def _request(self) -> List[Tuple[Message, Any]]: + from dff.script import Message + return [(Message(input(self._prompt_request)), self._ctx_id)] + + def _respond(self, responses: List[Context]): + print(f"{self._prompt_response}{responses[0].last_response.text}", file=self._descriptor) + + async def connect(self, pipeline_runner: PipelineRunnerFunction, **kwargs): + """ + The CLIProvider generates new dialog id used to user identification on each `connect` call. + + :param pipeline_runner: A function that should process user request and return context; + usually it's a :py:meth:`~dff.pipeline.pipeline.pipeline.Pipeline._run_pipeline` function. + :param \\**kwargs: argument, added for compatibility with super class, it shouldn't be used normally. + """ + self._ctx_id = uuid4() + if self._intro is not None: + print(self._intro) + await super().connect(pipeline_runner, **kwargs) diff --git a/dff/pipeline/pipeline/pipeline.py b/dff/pipeline/pipeline/pipeline.py index 94eb52a57..84c22b8a7 100644 --- a/dff/pipeline/pipeline/pipeline.py +++ b/dff/pipeline/pipeline/pipeline.py @@ -23,7 +23,8 @@ from dff.script import NodeLabel2Type, Message from dff.utils.turn_caching import cache_clear -from dff.messengers.common import MessengerInterface, CLIMessengerInterface +from dff.messengers.console import CLIMessengerInterface +from dff.messengers.common import MessengerInterface from ..service.group import ServiceGroup from ..types import ( ServiceBuilder, diff --git a/tests/pipeline/test_messenger_interface.py b/tests/pipeline/test_messenger_interface.py index 855efeb96..2c6459386 100644 --- a/tests/pipeline/test_messenger_interface.py +++ b/tests/pipeline/test_messenger_interface.py @@ -3,7 +3,8 @@ import pathlib from dff.script import RESPONSE, TRANSITIONS, Message -from dff.messengers.common import CLIMessengerInterface, CallbackMessengerInterface +from dff.messengers.console import CLIMessengerInterface +from dff.messengers.common import CallbackMessengerInterface from dff.pipeline import Pipeline import dff.script.conditions as cnd diff --git a/tutorials/pipeline/2_pre_and_post_processors.py b/tutorials/pipeline/2_pre_and_post_processors.py index bc8fe5625..7037d63da 100644 --- a/tutorials/pipeline/2_pre_and_post_processors.py +++ b/tutorials/pipeline/2_pre_and_post_processors.py @@ -14,7 +14,7 @@ # %% import logging -from dff.messengers.common import CLIMessengerInterface +from dff.messengers.console import CLIMessengerInterface from dff.script import Context, Message from dff.pipeline import Pipeline diff --git a/tutorials/pipeline/3_pipeline_dict_with_services_full.py b/tutorials/pipeline/3_pipeline_dict_with_services_full.py index e24999ab9..34070c34f 100644 --- a/tutorials/pipeline/3_pipeline_dict_with_services_full.py +++ b/tutorials/pipeline/3_pipeline_dict_with_services_full.py @@ -19,7 +19,7 @@ import urllib.request from dff.script import Context -from dff.messengers.common import CLIMessengerInterface +from dff.messengers.console import CLIMessengerInterface from dff.pipeline import Service, Pipeline, ServiceRuntimeInfo, ACTOR from dff.utils.testing.common import ( check_happy_path, From 5e35935c5bb848a5b82205ce755c4ff4f9774290 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 20:15:40 +0100 Subject: [PATCH 029/140] data message equation fixed --- dff/script/core/message.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index d81b83c11..f61268b44 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -128,6 +128,9 @@ def __eq__(self, other): return False if self.title != other.title: return False + if self.from_messenger_interface is not None and other.from_messenger_interface is not None: + return self.get_bytes() == other.get_bytes() + return True return NotImplemented @model_validator(mode="before") From 513f77ad2c400be9021695c9cb92701c710564b3 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 19 Mar 2024 20:40:22 +0100 Subject: [PATCH 030/140] lint applied --- dff/messengers/common/conditions.py | 6 +- dff/messengers/console.py | 1 - dff/messengers/telegram.py | 138 +++++++++++++++--- dff/script/core/message.py | 6 - tutorials/messengers/telegram/2_buttons.py | 16 +- .../telegram/3_buttons_with_callback.py | 4 +- tutorials/messengers/telegram/4_conditions.py | 39 ++--- .../telegram/5_conditions_with_media.py | 79 +++++++--- .../telegram/6_conditions_extras.py | 39 ++++- 9 files changed, 240 insertions(+), 88 deletions(-) diff --git a/dff/messengers/common/conditions.py b/dff/messengers/common/conditions.py index f5534f993..dd978ae42 100644 --- a/dff/messengers/common/conditions.py +++ b/dff/messengers/common/conditions.py @@ -1,14 +1,16 @@ from dff.pipeline import Pipeline from dff.script import Context +from dff.script.core.message import CallbackQuery def has_callback_query(expected: str): - def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover last_request = ctx.last_request if last_request is None or last_request.attachments is None or len(last_request.attachments) == 0: return False - callback_query = next((attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None) + callback_query = next( + (attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None + ) if callback_query is None: return False return callback_query.query_string == expected diff --git a/dff/messengers/console.py b/dff/messengers/console.py index ab30669ad..3c6ae2ede 100644 --- a/dff/messengers/console.py +++ b/dff/messengers/console.py @@ -27,7 +27,6 @@ def __init__( self._descriptor: Optional[TextIO] = out_descriptor def _request(self) -> List[Tuple[Message, Any]]: - from dff.script import Message return [(Message(input(self._prompt_request)), self._ctx_id)] def _respond(self, responses: List[Context]): diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index edc783666..c1031b144 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -6,18 +6,42 @@ """ from pathlib import Path from tempfile import gettempdir -from typing import Callable, Optional, Sequence, cast +from typing import Callable, Optional, Sequence from pydantic import FilePath -from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, Update, Message as TelegramMessage +from telegram import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + InputMediaAnimation, + InputMediaAudio, + InputMediaDocument, + InputMediaPhoto, + InputMediaVideo, + Update, + Message as TelegramMessage, +) from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes from telegram.ext.filters import ALL from dff.messengers.common import MessengerInterface -from dff.pipeline import Pipeline from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.context import Context -from dff.script.core.message import Animation, Audio, Button, CallbackQuery, Contact, DataAttachment, Document, Image, Invoice, Keyboard, Location, Message, Poll, PollOption, Video +from dff.script.core.message import ( + Animation, + Audio, + Button, + CallbackQuery, + Contact, + DataAttachment, + Document, + Image, + Invoice, + Keyboard, + Location, + Message, + Poll, + PollOption, + Video, +) class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover @@ -47,44 +71,102 @@ async def extract_message_from_telegram(self, update: TelegramMessage) -> Messag if update.location is not None: message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] if update.contact is not None: - message.attachments += [Contact(phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name)] + message.attachments += [ + Contact( + phone_number=update.contact.phone_number, + first_name=update.contact.first_name, + last_name=update.contact.last_name, + ) + ] if update.invoice is not None: - message.attachments += [Invoice(title=update.invoice.title, description=update.invoice.description, currency=update.invoice.currency, amount=update.invoice.total_amount)] + message.attachments += [ + Invoice( + title=update.invoice.title, + description=update.invoice.description, + currency=update.invoice.currency, + amount=update.invoice.total_amount, + ) + ] if update.poll is not None: - message.attachments += [Poll(question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options])] + message.attachments += [ + Poll( + question=update.poll.question, + options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options], + ) + ] if update.audio is not None: - message.attachments += [Audio(id=update.audio.file_id, title=update.audio.file_unique_id, from_messenger_interface=self)] + message.attachments += [ + Audio(id=update.audio.file_id, title=update.audio.file_unique_id, from_messenger_interface=self) + ] if update.video is not None: - message.attachments += [Video(id=update.video.file_id, title=update.video.file_unique_id, from_messenger_interface=self)] + message.attachments += [ + Video(id=update.video.file_id, title=update.video.file_unique_id, from_messenger_interface=self) + ] if update.animation is not None: - message.attachments += [Animation(id=update.animation.file_id, title=update.animation.file_unique_id, from_messenger_interface=self)] + message.attachments += [ + Animation( + id=update.animation.file_id, title=update.animation.file_unique_id, from_messenger_interface=self + ) + ] if len(update.photo) > 0: - message.attachments += [Image(id=picture.file_id, title=picture.file_unique_id, from_messenger_interface=self) for picture in update.photo] + message.attachments += [ + Image(id=picture.file_id, title=picture.file_unique_id, from_messenger_interface=self) + for picture in update.photo + ] if update.document is not None: - message.attachments += [Document(id=update.document.file_id, title=update.document.file_unique_id, from_messenger_interface=self)] + message.attachments += [ + Document( + id=update.document.file_id, title=update.document.file_unique_id, from_messenger_interface=self + ) + ] return message - def _create_keyboard(self, buttons: Sequence[Sequence[Button]]) -> Optional[InlineKeyboardMarkup]: # pragma: no cover + def _create_keyboard( + self, buttons: Sequence[Sequence[Button]] + ) -> Optional[InlineKeyboardMarkup]: # pragma: no cover button_list = None if len(buttons) > 0: - button_list = [[InlineKeyboardButton(text=button.text, callback_data=button.data if button.data is not None else button.text) for button in row] for row in buttons] + button_list = [ + [ + InlineKeyboardButton( + text=button.text, callback_data=button.data if button.data is not None else button.text + ) + for button in row + ] + for row in buttons + ] if button_list is None: return None else: return InlineKeyboardMarkup(button_list) - async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, message: Message) -> None: # pragma: no cover + async def cast_message_to_telegram_and_send( + self, bot: ExtBot, chat_id: int, message: Message + ) -> None: # pragma: no cover buttons = list() if message.attachments is not None: files = list() for attachment in message.attachments: if isinstance(attachment, Location): - await bot.send_location(chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons)) + await bot.send_location( + chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons) + ) if isinstance(attachment, Contact): - await bot.send_contact(chat_id, attachment.phone_number, attachment.first_name, attachment.last_name, reply_markup=self._create_keyboard(buttons)) + await bot.send_contact( + chat_id, + attachment.phone_number, + attachment.first_name, + attachment.last_name, + reply_markup=self._create_keyboard(buttons), + ) if isinstance(attachment, Poll): - await bot.send_poll(chat_id, attachment.question, [option.text for option in attachment.options], reply_markup=self._create_keyboard(buttons)) + await bot.send_poll( + chat_id, + attachment.question, + [option.text for option in attachment.options], + reply_markup=self._create_keyboard(buttons), + ) if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: @@ -113,19 +195,25 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if message.text is not None: await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) - async def _on_event(self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message]) -> None: + async def _on_event( + self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message] + ) -> None: if update.effective_chat is not None and update.message is not None: message = create_message(update) message.original_message = update resp = await self.callback(message, update.effective_chat.id) if resp.last_response is not None: - await self.cast_message_to_telegram_and_send(self.application.bot, update.effective_chat.id, resp.last_response) + await self.cast_message_to_telegram_and_send( + self.application.bot, update.effective_chat.id, resp.last_response + ) async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: await self._on_event(update, _, lambda u: await self.extract_message_from_telegram(u.message)) async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event(update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)])) + await self._on_event( + update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)]) + ) async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): self.callback = pipeline_runner @@ -139,7 +227,9 @@ def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): await super().connect(pipeline_runner, *args, **kwargs) - self.application.run_polling(poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES) + self.application.run_polling( + poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES + ) class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover @@ -147,7 +237,7 @@ def __init__(self, token: str, host: str = "localhost", port: int = 844): super().__init__(token) self.listen = host self.port = port - + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): await super().connect(pipeline_runner, *args, **kwargs) self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index f61268b44..842ea11b7 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -42,12 +42,10 @@ class Command(DataModel): class Attachment(DataModel): - pass class CallbackQuery(Attachment): - query_string: Optional[str] @@ -70,14 +68,12 @@ def __eq__(self, other): class Contact(Attachment): - phone_number: str first_name: str last_name: Optional[str] class Invoice(Attachment): - title: str description: str currency: str @@ -85,13 +81,11 @@ class Invoice(Attachment): class PollOption(DataModel): - text: str votes: int class Poll(Attachment): - question: str options: List[PollOption] diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index 2c1ae78ed..6ce6c768c 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -77,7 +77,7 @@ class is used to represent telegram message, ], ], ), - ] + ], ), TRANSITIONS: { ("general", "success"): has_callback_query("4"), @@ -89,7 +89,9 @@ class is used to represent telegram message, TRANSITIONS: {("root", "fallback"): cnd.true()}, }, "fail": { - RESPONSE: Message(text="Incorrect answer, type anything to try again"), + RESPONSE: Message( + text="Incorrect answer, type anything to try again" + ), TRANSITIONS: {("general", "native_keyboard"): cnd.true()}, }, }, @@ -103,7 +105,7 @@ class is used to represent telegram message, Message(text="/start"), Message( text="Question: What's 2 + 2?", - attachments= [ + attachments=[ Keyboard( buttons=[ [ @@ -123,7 +125,7 @@ class is used to represent telegram message, Message(text="ok"), Message( text="Question: What's 2 + 2?", - attachments= [ + attachments=[ Keyboard( buttons=[ [ @@ -141,15 +143,13 @@ class is used to represent telegram message, ), ( Message(text="Yay!"), - Message( - text="Finishing test, send /restart command to restart" - ), + Message(text="Finishing test, send /restart command to restart"), ), ( Message(text="/start"), Message( text="Question: What's 2 + 2?", - attachments= [ + attachments=[ Keyboard( buttons=[ [ diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index cd84c016f..acab18508 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -143,9 +143,7 @@ class is used to represent telegram message, ), ( Message(text="Yay!"), - Message( - text="Finishing test, send /restart command to restart" - ), + Message(text="Finishing test, send /restart command to restart"), ), ( Message(text="/restart"), diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index 69641a27c..40a245b4f 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -20,6 +20,7 @@ import dff.script.conditions as cnd from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline +from dff.script.core.context import Context from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -50,6 +51,21 @@ """ +# %% +def check_if_latest_message_test_has_music( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + if ctx.last_request.original_message.message is None: + return False + if ctx.last_request.original_message.message.text is None: + return False + return "music" in ctx.last_request.original_message.message.text + + # %% script = { "greeting_flow": { @@ -65,28 +81,15 @@ }, "node1": { RESPONSE: Message(text="Hi, how are you?"), - TRANSITIONS: { - "node2": cnd.regexp("fine") - }, + TRANSITIONS: {"node2": cnd.regexp("fine")}, }, "node2": { - RESPONSE: Message( - text="Good. What do you want to talk about?" - ), - TRANSITIONS: { - "node3": lambda ctx, _, __, ___: - ctx.last_request.original_message.message is not None - and ctx.last_request.original_message.message.text is not None - and "music" in ctx.last_request.original_message.message.text - }, + RESPONSE: Message(text="Good. What do you want to talk about?"), + TRANSITIONS: {"node3": check_if_latest_message_test_has_music}, }, "node3": { - RESPONSE: Message( - text="Sorry, I can not talk about music now." - ), - TRANSITIONS: { - "node4": lambda _, __, ___, ____: True - }, + RESPONSE: Message(text="Sorry, I can not talk about music now."), + TRANSITIONS: {"node4": lambda _, __, ___, ____: True}, # This condition is true for any type of update }, "node4": { diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 67ecaaebb..a20d19715 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -22,6 +22,7 @@ import dff.script.conditions as cnd from dff.script import TRANSITIONS, RESPONSE +from dff.script.core.context import Context from dff.script.core.message import Message, Image from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline @@ -30,13 +31,16 @@ # %% -picture_url = HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4") +picture_url = HttpUrl( + "https://avatars.githubusercontent.com/u/29918795?s=200&v=4" +) # %% [markdown] """ To filter user messages depending on whether or not media files were sent, -you can use the `content_types` parameter of the `ctx.last_request.original_message.message.document`. +you can use the `content_types` parameter of the +`Context.last_request.original_message.message.document`. """ @@ -44,6 +48,49 @@ interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) +def check_if_latest_message_has_photos( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + if ctx.last_request.original_message.message is None: + return False + if ctx.last_request.original_message.message.photo is None: + return False + return len(ctx.last_request.original_message.message.photo) > 0 + + +def check_if_latest_message_has_image_documents( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + if ctx.last_request.original_message.message is None: + return False + if ctx.last_request.original_message.message.document is None: + return False + return ( + ctx.last_request.original_message.message.document.mime_type + == "image/jpeg" + ) + + +def check_if_latest_message_has_text( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + if ctx.last_request.original_message.message is None: + return False + return ctx.last_request.original_message.message.text is None + + # %% script = { "root": { @@ -81,18 +128,14 @@ # both in 'photo' and 'document' fields. # We should consider both cases # when we check the message for media. - lambda ctx, _, __, ___: - ctx.last_request.original_message.message is not None - and len(ctx.last_request.original_message.message.photo) > 0, - lambda ctx, _, __, ___: - ctx.last_request.original_message.message is not None - and ctx.last_request.original_message.message.document is not None - and ctx.last_request.original_message.message.document.mime_type == "image/jpeg", + check_if_latest_message_has_photos, + check_if_latest_message_has_image_documents, ] ), - ("pics", "send_many"): lambda ctx, _, __, ___: - ctx.last_request.original_message.message is not None - and ctx.last_request.original_message.message.text is not None, + ( + "pics", + "send_many", + ): check_if_latest_message_has_text, ("pics", "ask_picture"): cnd.true(), }, }, @@ -123,9 +166,7 @@ Message(text="Send me a picture"), ), ( - Message( - attachments=[Image(source=picture_url)] - ), + Message(attachments=[Image(source=picture_url)]), Message( text="Here's my picture!", attachments=[Image(source=picture_url)], @@ -133,9 +174,7 @@ ), ( Message(text="ok"), - Message( - text="Finishing test, send /restart command to restart" - ), + Message(text="Finishing test, send /restart command to restart"), ), ( Message(text="/restart"), @@ -150,9 +189,7 @@ ), ( Message(text="ok"), - Message( - text="Finishing test, send /restart command to restart" - ), + Message(text="Finishing test, send /restart command to restart"), ), ( Message(text="/restart"), diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index 7ed535e0a..09a9ba3ed 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -21,6 +21,7 @@ import dff.script.conditions as cnd from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline +from dff.script.core.context import Context from dff.script.core.message import Message from dff.utils.testing.common import is_interactive_mode @@ -55,17 +56,45 @@ """ +# %% +def check_if_latest_message_is_new_chat_member( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + if ctx.last_request.original_message.message is None: + return False + return ( + ctx.last_request.original_message.message.new_chat_members is not None + ) + + +def check_if_latest_message_is_callback_query( + ctx: Context, _: Pipeline, __, ___ +) -> bool: + if ctx.last_request is None: + return False + if ctx.last_request.original_message is None: + return False + return ctx.last_request.original_message.inline_query is not None + + # %% script = { GLOBAL: { TRANSITIONS: { # say hi when someone enters the chat - ("greeting_flow", "node1"): lambda ctx, _, __, ___: - ctx.last_request.original_message.message is not None - and ctx.last_request.original_message.message.new_chat_members is not None, + ( + "greeting_flow", + "node1", + ): check_if_latest_message_is_new_chat_member, # send a message when inline query is received - ("greeting_flow", "node2"): lambda ctx, _, __, ___: - ctx.last_request.original_message.inline_query is not None, + ( + "greeting_flow", + "node2", + ): check_if_latest_message_is_callback_query, }, }, "greeting_flow": { From 48bb29f0fd93b9f0cc0a60a936237f1904101662 Mon Sep 17 00:00:00 2001 From: Roman Zlobin Date: Wed, 20 Mar 2024 13:10:18 +0300 Subject: [PATCH 031/140] move callback query to script.conditions --- dff/messengers/common/conditions.py | 18 ------------------ dff/script/conditions/std_conditions.py | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 18 deletions(-) delete mode 100644 dff/messengers/common/conditions.py diff --git a/dff/messengers/common/conditions.py b/dff/messengers/common/conditions.py deleted file mode 100644 index dd978ae42..000000000 --- a/dff/messengers/common/conditions.py +++ /dev/null @@ -1,18 +0,0 @@ -from dff.pipeline import Pipeline -from dff.script import Context -from dff.script.core.message import CallbackQuery - - -def has_callback_query(expected: str): - def condition(ctx: Context, _: Pipeline, *__, **___) -> bool: # pragma: no cover - last_request = ctx.last_request - if last_request is None or last_request.attachments is None or len(last_request.attachments) == 0: - return False - callback_query = next( - (attachment for attachment in last_request.attachments if isinstance(attachment, CallbackQuery)), None - ) - if callback_query is None: - return False - return callback_query.query_string == expected - - return condition diff --git a/dff/script/conditions/std_conditions.py b/dff/script/conditions/std_conditions.py index d2d23f4e8..c71c600d4 100644 --- a/dff/script/conditions/std_conditions.py +++ b/dff/script/conditions/std_conditions.py @@ -17,6 +17,7 @@ from dff.pipeline import Pipeline from dff.script import NodeLabel2Type, Context, Message +from dff.script.core.message import CallbackQuery logger = logging.getLogger(__name__) @@ -242,3 +243,16 @@ def false_handler(ctx: Context, pipeline: Pipeline) -> bool: """ :py:func:`~neg` is an alias for :py:func:`~negation`. """ + + +def has_callback_query(expected_query_string: str): + """ + Condition that checks if :py:attr:`~.CallbackQuery.query_string` of the last message matches `expected`. + """ + def has_callback_query_handler(ctx: Context, _: Pipeline) -> bool: + last_request = ctx.last_request + if last_request is None or last_request.attachments is None: + return False + return CallbackQuery(query_string=expected_query_string) in last_request.attachments + + return has_callback_query_handler From e2ea3715f0d2c3ec2c21b9e16ac34a7b6f354121 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 21 Mar 2024 10:14:01 +0100 Subject: [PATCH 032/140] condition signature fix --- tutorials/messengers/telegram/4_conditions.py | 4 +--- .../messengers/telegram/5_conditions_with_media.py | 12 +++--------- tutorials/messengers/telegram/6_conditions_extras.py | 8 ++------ 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index 40a245b4f..ae2bb285d 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -52,9 +52,7 @@ # %% -def check_if_latest_message_test_has_music( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index a20d19715..51f80b907 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -48,9 +48,7 @@ interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) -def check_if_latest_message_has_photos( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -62,9 +60,7 @@ def check_if_latest_message_has_photos( return len(ctx.last_request.original_message.message.photo) > 0 -def check_if_latest_message_has_image_documents( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_has_image_documents(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -79,9 +75,7 @@ def check_if_latest_message_has_image_documents( ) -def check_if_latest_message_has_text( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_has_text(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index 09a9ba3ed..a84121090 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -57,9 +57,7 @@ # %% -def check_if_latest_message_is_new_chat_member( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_is_new_chat_member(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -71,9 +69,7 @@ def check_if_latest_message_is_new_chat_member( ) -def check_if_latest_message_is_callback_query( - ctx: Context, _: Pipeline, __, ___ -) -> bool: +def check_if_latest_message_is_callback_query(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: From ea6653750c2de73b4829b23ae61b425eda6bc5bf Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 21 Mar 2024 10:18:50 +0100 Subject: [PATCH 033/140] messenger interface parameter added to `get_bytes` method --- dff/script/core/message.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 842ea11b7..abc4f52a8 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -99,14 +99,10 @@ class DataAttachment(Attachment): source: Optional[Union[HttpUrl, FilePath]] = None id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None - from_messenger_interface: Optional[MessengerInterface] = Field(exclude=True, default=None) - async def get_bytes(self) -> Optional[bytes]: + async def get_bytes(self, from_messenger_interface: MessengerInterface) -> Optional[bytes]: if self.source is None: - if self.from_messenger_interface is None: - return None - else: - await self.from_messenger_interface.populate_attachment(self) + await from_messenger_interface.populate_attachment(self) if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() @@ -122,8 +118,6 @@ def __eq__(self, other): return False if self.title != other.title: return False - if self.from_messenger_interface is not None and other.from_messenger_interface is not None: - return self.get_bytes() == other.get_bytes() return True return NotImplemented From 21feb0c709b3e179dd5052e6e579d397dfca4881 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:45:56 +0300 Subject: [PATCH 034/140] Add/attachment_tutorial --- tutorials/messengers/vk/2_attachments.py | 114 +++++++++++++++++++++++ tutorials/messengers/vk/cat.jpg | Bin 0 -> 93255 bytes 2 files changed, 114 insertions(+) create mode 100644 tutorials/messengers/vk/2_attachments.py create mode 100644 tutorials/messengers/vk/cat.jpg diff --git a/tutorials/messengers/vk/2_attachments.py b/tutorials/messengers/vk/2_attachments.py new file mode 100644 index 000000000..f0065064a --- /dev/null +++ b/tutorials/messengers/vk/2_attachments.py @@ -0,0 +1,114 @@ +# %% [markdown] +""" +# VK: 2. Using Attachments + +In this tutorial we will send messages with different types of attachments. When working with media and documents in VK you should keep in mind platform limitations on size and type of uploaded files. Here is the list of restrictions for each attachment type: + +**Image:** +- Supported types: *JPG, PNG, GIF* +- Max file size: *50 Mb* +- Aspect ratio: *at least 1:20* + +**Audio:** +- Supported types: *MP3* +- Max file size: *200 Mb* + +**Video:** +- Supported types: *AVI, MP4, 3GP, MPEG, MOV, MP3, FLV, WMV* + +**Documents:** +- Executable files are NOT supported (e.g. *.exe*, *.apk*) +- Max file size: *200 Mb* + +**Consider checking latest version [VK documentation](https://dev.vk.com/en/api/upload/overview) for up-to-date file policies.** + +So we advise you sending unsupported files as a link in a `text` field of a Message of via `Document` type attachment. +Here we'll create a simple script that will utilize sending images and files. + +Import necessary modules: +""" + +# %% +from dff.messengers.vk import PollingVKInterface +from dff.script import conditions as cnd +from dff.script import labels as lbl +from dff.script import RESPONSE, TRANSITIONS, Message +from dff.pipeline import Pipeline + +from dff.script.core.message import Document, Image, Message + + +# %% [markdown] +""" +Sending images support both URL source and full local path +""" + + +# %% +script = { + "greeting_flow": { + "start_node": { + TRANSITIONS: { + "greeting_node": cnd.exact_match(Message(text="Hello")) + }, + }, + "greeting_node": { + RESPONSE: Message(text="Hello! What would you like to get?"), + TRANSITIONS: { + "cat_image_node": cnd.exact_match(Message(text="cat")), + "book_file_node": cnd.exact_match(Message(text="book")) + }, + }, + "cat_image_node": { + RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source="cat.jpg"), Image(source="https://d2ph5fj80uercy.cloudfront.net/04/cat2634.jpg")]), + TRANSITIONS: { + "greeting_node": cnd.true() + } + }, + "book_file_node": { + RESPONSE: Message(text="Here is your book!", attachments=[Document(source="book.pdf")]), + TRANSITIONS: { + "greeting_node": cnd.true() + } + }, + "fallback_node": { + RESPONSE: Message(text="Please, repeat the request"), + TRANSITIONS: { + "greeting_node": cnd.exact_match(Message(text="/start")) + }, + }, + } +} + +# %% [markdown] +""" +Here you put your `access_key` and `group_id` of the group your bot connected to. +""" + +# %% +KEY = "" +GROUP_ID = "" + +interface = PollingVKInterface(token=KEY, group_id=GROUP_ID, interval='2') + +# %% + +pipeline = Pipeline.from_script( + script=script, + start_label=("greeting_flow", "start_node"), + fallback_label=("greeting_flow", "fallback_node"), + messenger_interface=interface, + # The interface can be passed as a pipeline argument. +) + +def main(): + pipeline.run() + + +if __name__ == "__main__": + main() + +#%% [markdown] +""" +Knonw issue: when sending an Image with URL make sure it ends with `.png` or any other image extention, otherwise interface will fail fetching image bytes. Also some websites does not allow fetching images from them without registration, so it is more reliable to send data that is stored on your machine. +""" \ No newline at end of file diff --git a/tutorials/messengers/vk/cat.jpg b/tutorials/messengers/vk/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5d6a4d2eb72eb7561957bf46e0f468cdf9dfb961 GIT binary patch literal 93255 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

AvH|6=l12$Os-9I~@QBoe{ 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

-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 Date: Thu, 21 Mar 2024 16:47:52 +0300 Subject: [PATCH 035/140] Fix/deleted match case --- dff/messengers/vk.py | 162 +++++++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 68 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 00911e15a..4e8e0a1e0 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -169,15 +169,19 @@ def close_files(self): class PollingVKInterface(PollingMessengerInterface): - def __init__(self, token: str, group_id: str, interval: str) -> None: + def __init__(self, token: str, group_id: str) -> None: super().__init__() self.token = token self.group_id = group_id - server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json()['response'] - self.server = server_request['server'] - self.ts_base = int(server_request['ts']) + server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + if "response" not in server_request: + raise Exception(f"Errror getting longpoll server\n{server_request}") + + self.server = server_request['response']['server'] + self.ts_base = int(server_request['response']['ts']) self.ts_current = self.ts_base - self.server_key = server_request['key'] + self.server_key = server_request['response']['key'] self.last_update_id = None self._last_processed_update = None @@ -186,81 +190,103 @@ def upload_attachment( self, peer_id, attachment, attachment_type: str ) -> str: #returns json object with `owner_id` and `photo_id` needed to send it - match attachment_type: - case "photo": - upload_url = requests.post( - f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json()["response"]["upload_url"] - attachment_path = str(attachment.source) + if attachment_type == "photo": + upload_url = requests.post( + f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + + if "response" not in upload_url: + raise Exception(f"Error getting upload server for image\n{upload_url}") + + upload_url = upload_url["response"]["upload_url"] + attachment_path = str(attachment.source) - with FilesOpener(attachment_path) as photo_files: - uploaded_photo_data = requests.post(upload_url, files=photo_files).json() + print(f"Uploading {attachment_path}") + with FilesOpener(attachment_path) as photo_files: + uploaded_photo_data = requests.post(upload_url, files=photo_files).json() + print(photo_files) - saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() + saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() + + if "response" not in saved_photo_data: + raise Exception(f"Error saving photo\n{saved_photo_data}") + + return saved_photo_data["response"] + + elif attachment_type == "doc": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + attachment_path = str(attachment.source) + + if "response" not in upload_url: + raise Exception(f"Errror getting upload server for document\n{upload_url}") + + upload_url = upload_url["response"]["upload_url"] - return saved_photo_data["response"] + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + if "response" not in saved_doc_data: + raise Exception(f"Error saving document\n{saved_doc_data}") + + return saved_doc_data["response"] + + elif attachment_type == "audio": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" + ).json() + attachment_path = str(attachment.source) - case "doc": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json()["response"]["upload_url"] - attachment_path = str(attachment.source) - - with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() - - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - return saved_doc_data["response"] + if "response" not in upload_url: + raise Exception(f"Errror getting upload server for audio\n{upload_url}") - case "audio": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" - ).json()["response"]["upload_url"] - attachment_path = str(attachment.source) - - with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() - - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - return saved_doc_data["response"] + upload_url = upload_url["response"]["upload_url"] - case "video": - vid = requests.post(f"https://api.vk.com/method/video.save?link={attachment.source}&group_id={self.group_id}&v=5.81&access_token={self.token}").json()["response"] - return vid + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + return saved_doc_data["response"] + + elif attachment_type == "video": + vid = requests.post(f"https://api.vk.com/method/video.save?link={attachment.source}&group_id={self.group_id}&v=5.81&access_token={self.token}").json()["response"] + return vid def send_message(self, response, id): if response.attachments is not None: attachment_list = [] for attachment in response.attachments: - match attachment: - case Image(): - data_to_send = self.upload_attachment(id, attachment, "photo") - attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() - case Document(): - data_to_send = self.upload_attachment(id, attachment, "doc") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - case Video(): - data_to_send = self.upload_attachment(id, attachment, "video") - attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") - case Audio(): - data_to_send = self.upload_attachment(id, attachment, "audio") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - case Link(): - # link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} - response.text += f"[{attachment.source}|{attachment.title}]" - # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachments=[{link_vk}]&v=5.81&access_token={self.token}").json() - # attachment_list.append(link_vk) - # attachment_list.append(str(link_vk)) - case Poll(): - poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json()["response"] - attachment_list.append({ - "type": "poll", - "poll": poll_obj - }) + if isinstance(attachment, Image): + data_to_send = self.upload_attachment(id, attachment, "photo") + attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() + elif isinstance(attachment, Document): + data_to_send = self.upload_attachment(id, attachment, "doc") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + elif isinstance(attachment, Video): + data_to_send = self.upload_attachment(id, attachment, "video") + attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") + elif isinstance(attachment, Audio): + data_to_send = self.upload_attachment(id, attachment, "audio") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + elif isinstance(attachment, Link): + # link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} + response.text += f"[{attachment.source}|{attachment.title}]" + # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachments=[{link_vk}]&v=5.81&access_token={self.token}").json() + # attachment_list.append(link_vk) + # attachment_list.append(str(link_vk)) + elif isinstance(attachment, Poll): + poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json() + print(poll_obj) + # attachment_list.append({ + # "type": "poll", + # "poll": poll_obj + # }) attachment_string = ','.join(attachment_list).strip(',') From db1de9ad3f05b9fcaf922d20fdf62d5378c02165 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 21 Mar 2024 16:45:48 +0100 Subject: [PATCH 036/140] async def removed from `extract_message_from_telegram` function --- dff/messengers/telegram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index c1031b144..1b942ebdb 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -62,7 +62,7 @@ async def populate_attachment(self, attachment: DataAttachment) -> None: # prag else: raise ValueError(f"For attachment {attachment} title or id is not defined!") - async def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover + def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover message = Message() message.attachments = list() @@ -208,7 +208,7 @@ async def _on_event( ) async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event(update, _, lambda u: await self.extract_message_from_telegram(u.message)) + await self._on_event(update, _, lambda u: self.extract_message_from_telegram(u.message)) async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: await self._on_event( From 19d00f3a9fe265668e115cdaf9a18ba60eaaa9d2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 21 Mar 2024 16:53:50 +0100 Subject: [PATCH 037/140] docs fixed --- tutorials/messengers/telegram/1_basic.py | 2 +- tutorials/messengers/telegram/2_buttons.py | 3 +-- tutorials/messengers/telegram/3_buttons_with_callback.py | 5 ++--- tutorials/messengers/telegram/7_polling_setup.py | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/tutorials/messengers/telegram/1_basic.py b/tutorials/messengers/telegram/1_basic.py index 5f633c500..ce750afea 100644 --- a/tutorials/messengers/telegram/1_basic.py +++ b/tutorials/messengers/telegram/1_basic.py @@ -5,7 +5,7 @@ The following tutorial shows how to run a regular DFF script in Telegram. It asks users for the '/start' command and then loops in one place. -Here, %mddoclink(api,messengers.telegram.interface,PollingTelegramInterface) +Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) library are used for accessing telegram API in polling mode. diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index 6ce6c768c..b8db30676 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -25,7 +25,6 @@ class is used to represent telegram message, from dff.script import TRANSITIONS, RESPONSE from dff.script.core.message import Button, Keyboard, Message from dff.pipeline import Pipeline -from dff.messengers.common.conditions import has_callback_query from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode @@ -80,7 +79,7 @@ class is used to represent telegram message, ], ), TRANSITIONS: { - ("general", "success"): has_callback_query("4"), + ("general", "success"): cnd.has_callback_query("4"), ("general", "fail"): cnd.true(), }, }, diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index acab18508..03ba0b29b 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -26,7 +26,6 @@ class is used to represent telegram message, from dff.script import TRANSITIONS, RESPONSE from dff.pipeline import Pipeline from dff.script.core.message import Button, Keyboard, Message -from dff.messengers.common.conditions import has_callback_query from dff.messengers.telegram import PollingTelegramInterface from dff.utils.testing.common import is_interactive_mode @@ -82,8 +81,8 @@ class is used to represent telegram message, ], ), TRANSITIONS: { - ("general", "success"): has_callback_query("correct"), - ("general", "fail"): has_callback_query("wrong"), + ("general", "success"): cnd.has_callback_query("correct"), + ("general", "fail"): cnd.has_callback_query("wrong"), }, }, "success": { diff --git a/tutorials/messengers/telegram/7_polling_setup.py b/tutorials/messengers/telegram/7_polling_setup.py index 48ceb5ede..81ded86ac 100644 --- a/tutorials/messengers/telegram/7_polling_setup.py +++ b/tutorials/messengers/telegram/7_polling_setup.py @@ -4,7 +4,7 @@ The following tutorial shows how to configure `PollingTelegramInterface`. -See %mddoclink(api,messengers.telegram.interface,PollingTelegramInterface) +See %mddoclink(api,messengers.telegram,PollingTelegramInterface) for more information. """ From 11cc1a38bb5567b0e6263fd0e7f1ce56e0701fa2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 21 Mar 2024 17:00:55 +0100 Subject: [PATCH 038/140] condition import added --- dff/script/conditions/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dff/script/conditions/__init__.py b/dff/script/conditions/__init__.py index 06bebb91a..9b5fe812f 100644 --- a/dff/script/conditions/__init__.py +++ b/dff/script/conditions/__init__.py @@ -14,4 +14,5 @@ false, agg, neg, + has_callback_query, ) From 66f82b1eb989c2f0c635c76923b4cc73c95eaede Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 22 Mar 2024 01:45:20 +0100 Subject: [PATCH 039/140] two attachment tutorials fixed --- tutorials/script/responses/2_buttons.py | 60 ++++++++++++++++--------- tutorials/script/responses/3_media.py | 10 ++--- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/tutorials/script/responses/2_buttons.py b/tutorials/script/responses/2_buttons.py index faa9f60bc..8d8635eb3 100644 --- a/tutorials/script/responses/2_buttons.py +++ b/tutorials/script/responses/2_buttons.py @@ -57,8 +57,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="5", payload="5"), - Button(text="4", payload="4"), + [ + Button(text="5", data="5"), + Button(text="4", data="4"), + ] ] ), }, @@ -77,8 +79,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="38", payload="38"), - Button(text="48", payload="48"), + [ + Button(text="38", data="38"), + Button(text="48", data="48"), + ] ] ), }, @@ -97,8 +101,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="229", payload="229"), - Button(text="283", payload="283"), + [ + Button(text="229", data="229"), + Button(text="283", data="283"), + ] ] ), }, @@ -126,8 +132,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="5", payload="5"), - Button(text="4", payload="4"), + [ + Button(text="5", data="5"), + Button(text="4", data="4"), + ] ] ) }, @@ -143,8 +151,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="5", payload="5"), - Button(text="4", payload="4"), + [ + Button(text="5", data="5"), + Button(text="4", data="4"), + ] ] ), }, @@ -160,8 +170,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="38", payload="38"), - Button(text="48", payload="48"), + [ + Button(text="38", data="38"), + Button(text="48", data="48"), + ] ] ), }, @@ -177,8 +189,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="38", payload="38"), - Button(text="48", payload="48"), + [ + Button(text="38", data="38"), + Button(text="48", data="48"), + ] ] ), }, @@ -194,8 +208,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="229", payload="229"), - Button(text="283", payload="283"), + [ + Button(text="229", data="229"), + Button(text="283", data="283"), + ] ] ), }, @@ -211,8 +227,10 @@ def payload_check_inner(ctx: Context, _: Pipeline): "misc": { "ui": Keyboard( buttons=[ - Button(text="229", payload="229"), - Button(text="283", payload="283"), + [ + Button(text="229", data="229"), + Button(text="283", data="283"), + ] ] ), }, @@ -230,15 +248,15 @@ def process_request(ctx: Context): and ctx.last_response.misc and ctx.last_response.misc.get("ui") ) - if ui and ui.buttons: + if ui and ui.buttons[0]: try: - chosen_button = ui.buttons[int(ctx.last_request.text)] + chosen_button = ui.buttons[0][int(ctx.last_request.text)] except (IndexError, ValueError): raise ValueError( "Type in the index of the correct option " "to choose from the buttons." ) - ctx.last_request = Message(misc={"payload": chosen_button.payload}) + ctx.last_request = Message(misc={"payload": chosen_button.data}) # %% diff --git a/tutorials/script/responses/3_media.py b/tutorials/script/responses/3_media.py index 412363c14..4f46bb130 100644 --- a/tutorials/script/responses/3_media.py +++ b/tutorials/script/responses/3_media.py @@ -18,7 +18,7 @@ from dff.script import RESPONSE, TRANSITIONS from dff.script.conditions import std_conditions as cnd -from dff.script.core.message import Attachments, Image, Message +from dff.script.core.message import Image, Message from dff.pipeline import Pipeline from dff.utils.testing import ( @@ -57,14 +57,14 @@ "send_one": { RESPONSE: Message( text="here's my picture!", - attachments=Attachments(files=[Image(source=img_url)]), + attachments=[Image(source=img_url)], ), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, "send_many": { RESPONSE: Message( text="Look at my pictures", - attachments=Attachments(files=[Image(source=img_url)] * 10), + attachments=[Image(source=img_url)], ), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, @@ -93,7 +93,7 @@ Message(img_url), Message( text="here's my picture!", - attachments=Attachments(files=[Image(source=img_url)]), + attachments=[Image(source=img_url)], ), ), ( @@ -105,7 +105,7 @@ Message(f"{img_url} repeat 10 times"), Message( text="Look at my pictures", - attachments=Attachments(files=[Image(source=img_url)] * 10), + attachments=[Image(source=img_url)], ), ), ( From 2773c9d4c7e8250c8e83fc71fc2f1aede754e987 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 22 Mar 2024 01:48:02 +0100 Subject: [PATCH 040/140] attachment tuples changed to sets --- dff/messengers/console.py | 3 +++ dff/messengers/telegram.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dff/messengers/console.py b/dff/messengers/console.py index 3c6ae2ede..6a9dfcb64 100644 --- a/dff/messengers/console.py +++ b/dff/messengers/console.py @@ -12,6 +12,9 @@ class CLIMessengerInterface(PollingMessengerInterface): This message interface can maintain dialog with one user at a time only. """ + request_attachments = set() + response_attachments = set() + def __init__( self, intro: Optional[str] = None, diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 1b942ebdb..96625e6a7 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -45,8 +45,8 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - accepts_attachments = (Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document) - produces_attachments = (Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard) + request_attachments = {Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document} + response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} def __init__(self, token: str) -> None: self.application = Application.builder().token(token).build() From 80fceb573c5cf2839a7b80f91b43e6995bc8408a Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 22 Mar 2024 01:50:16 +0100 Subject: [PATCH 041/140] lint applied --- dff/script/conditions/std_conditions.py | 1 + tutorials/messengers/telegram/5_conditions_with_media.py | 4 ++-- tutorials/messengers/telegram/6_conditions_extras.py | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dff/script/conditions/std_conditions.py b/dff/script/conditions/std_conditions.py index c71c600d4..aefae6c9f 100644 --- a/dff/script/conditions/std_conditions.py +++ b/dff/script/conditions/std_conditions.py @@ -249,6 +249,7 @@ def has_callback_query(expected_query_string: str): """ Condition that checks if :py:attr:`~.CallbackQuery.query_string` of the last message matches `expected`. """ + def has_callback_query_handler(ctx: Context, _: Pipeline) -> bool: last_request = ctx.last_request if last_request is None or last_request.attachments is None: diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 51f80b907..2828d67d3 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -60,7 +60,7 @@ def check_if_latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: return len(ctx.last_request.original_message.message.photo) > 0 -def check_if_latest_message_has_image_documents(ctx: Context, _: Pipeline) -> bool: +def check_if_latest_message_has_images(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -123,7 +123,7 @@ def check_if_latest_message_has_text(ctx: Context, _: Pipeline) -> bool: # We should consider both cases # when we check the message for media. check_if_latest_message_has_photos, - check_if_latest_message_has_image_documents, + check_if_latest_message_has_images, ] ), ( diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index a84121090..01c5b8811 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -57,7 +57,9 @@ # %% -def check_if_latest_message_is_new_chat_member(ctx: Context, _: Pipeline) -> bool: +def check_if_latest_message_is_new_chat_member( + ctx: Context, _: Pipeline +) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -69,7 +71,9 @@ def check_if_latest_message_is_new_chat_member(ctx: Context, _: Pipeline) -> boo ) -def check_if_latest_message_is_callback_query(ctx: Context, _: Pipeline) -> bool: +def check_if_latest_message_is_callback_query( + ctx: Context, _: Pipeline +) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: From a5fbe60681e3f1c24d1700d0487cdfc9f241a650 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 22 Mar 2024 02:05:39 +0100 Subject: [PATCH 042/140] docs links fixed --- tutorials/messengers/telegram/2_buttons.py | 6 ------ tutorials/messengers/telegram/3_buttons_with_callback.py | 6 ------ tutorials/messengers/telegram/4_conditions.py | 5 +++-- tutorials/messengers/telegram/5_conditions_with_media.py | 5 +++-- tutorials/messengers/telegram/6_conditions_extras.py | 7 +++---- tutorials/script/responses/3_media.py | 2 +- 6 files changed, 10 insertions(+), 21 deletions(-) diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py index b8db30676..e3926df12 100644 --- a/tutorials/messengers/telegram/2_buttons.py +++ b/tutorials/messengers/telegram/2_buttons.py @@ -4,12 +4,6 @@ This tutorial shows how to display and hide a basic keyboard in Telegram. -Here, %mddoclink(api,messengers.telegram.message,TelegramMessage) -class is used to represent telegram message, -%mddoclink(api,messengers.telegram.message,TelegramUI) and -%mddoclink(api,messengers.telegram.message,RemoveKeyboard) -classes are used for configuring additional telegram message features. - Different %mddoclink(api,script.core.message,message) classes are used for representing different common message features, like Attachment, Audio, Button, Image, etc. diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py index 03ba0b29b..d993672a8 100644 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ b/tutorials/messengers/telegram/3_buttons_with_callback.py @@ -5,12 +5,6 @@ This tutorial demonstrates, how to add an inline keyboard and utilize inline queries. -Here, %mddoclink(api,messengers.telegram.message,TelegramMessage) -class is used to represent telegram message, -%mddoclink(api,messengers.telegram.message,TelegramUI) and -%mddoclink(api,messengers.telegram.message,RemoveKeyboard) -classes are used for configuring additional telegram message features. - Different %mddoclink(api,script.core.message,message) classes are used for representing different common message features, like Attachment, Audio, Button, Image, etc. diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index ae2bb285d..4b2937e94 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -5,8 +5,9 @@ This tutorial shows how to process Telegram updates in your script and reuse handler triggers from the `pytelegrambotapi` library. -Here, %mddoclink(api,messengers.telegram.messenger) -function is used for graph navigation according to Telegram events. +Here, %mddoclink(api,messengers.telegram) +message `original_message` component used +for graph navigation according to Telegram events. """ diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 2828d67d3..fb6602f37 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -4,8 +4,9 @@ This tutorial shows how to use media-related logic in your script. -Here, %mddoclink(api,messengers.telegram.messenger) -function is used for graph navigation according to Telegram events. +Here, %mddoclink(api,messengers.telegram) +message `original_message` component used +for graph navigation according to Telegram events. Different %mddoclink(api,script.core.message,message) classes are used for representing different common message features, diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index 01c5b8811..ed9d5b2ff 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -5,10 +5,9 @@ This tutorial shows how to use additional update filters inherited from the `pytelegrambotapi` library. -%mddoclink(api,messengers.telegram.messenger) -function and different types of -%mddoclink(api,messengers.telegram.messenger,UpdateType) -are used for telegram message type checking. +Here, %mddoclink(api,messengers.telegram) +message `original_message` component +is used for telegram message type checking. """ diff --git a/tutorials/script/responses/3_media.py b/tutorials/script/responses/3_media.py index 4f46bb130..3072c7587 100644 --- a/tutorials/script/responses/3_media.py +++ b/tutorials/script/responses/3_media.py @@ -2,7 +2,7 @@ """ # Responses: 3. Media -Here, %mddoclink(api,script.core.message,Attachments) class is shown. +Here, %mddoclink(api,script.core.message,Attachment) class is shown. Attachments can be used for attaching different media elements (such as %mddoclink(api,script.core.message,Image), %mddoclink(api,script.core.message,Document) From 6a21d354c0402fc3f6681acdaaf2a3c699e10332 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:46:57 +0300 Subject: [PATCH 043/140] Fixed missing document names when uploading --- dff/messengers/vk.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 4e8e0a1e0..37327a860 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -10,6 +10,7 @@ import requests import io +import os from dff.messengers.common import MessengerInterface, PollingMessengerInterface from dff.pipeline import Pipeline @@ -157,7 +158,8 @@ def open_files(self): self.opened_files.append(f) ext = filename.split('.')[-1] - files.append((self.key_format.format(x), (f'file{x}.{ext}', f))) + _, filename = os.path.split(filename) + files.append((self.key_format.format(x), (filename, f))) return files From f8cecdfc3e2f7c5d86eb66799cd13d79337937c6 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 27 Mar 2024 11:34:17 +0100 Subject: [PATCH 044/140] telegram formatted --- dff/messengers/telegram.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py index 96625e6a7..cdb9faeff 100644 --- a/dff/messengers/telegram.py +++ b/dff/messengers/telegram.py @@ -4,6 +4,7 @@ This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` that can be used to interact with the Telegram API. """ + from pathlib import Path from tempfile import gettempdir from typing import Callable, Optional, Sequence From 95019ad83cbedadbbfa7f3a7ce5f3ac732827482 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 27 Mar 2024 11:40:13 +0100 Subject: [PATCH 045/140] lock update --- poetry.lock | 452 ++++++++++++++++++++++------------------------------ 1 file changed, 191 insertions(+), 261 deletions(-) diff --git a/poetry.lock b/poetry.lock index c4e208e2b..03ab5d54c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -342,13 +342,13 @@ test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock [[package]] name = "asgiref" -version = "3.7.2" +version = "3.8.1" description = "ASGI specs, helper code, and adapters" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, - {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, ] [package.dependencies] @@ -594,7 +594,6 @@ lxml = ["lxml"] [[package]] name = "black" version = "24.3.0" -version = "24.3.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" @@ -621,28 +620,6 @@ files = [ {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, - {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, - {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, - {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, - {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, - {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, - {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, - {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, - {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, - {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, - {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, - {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, - {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, - {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, - {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, - {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, - {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, - {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, - {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, - {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, - {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, - {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, - {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, ] [package.dependencies] @@ -1502,18 +1479,18 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.13.1" +version = "3.13.3" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.13.3-py3-none-any.whl", hash = "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb"}, + {file = "filelock-3.13.3.tar.gz", hash = "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] @@ -2169,13 +2146,13 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs [[package]] name = "importlib-resources" -version = "6.3.1" +version = "6.4.0" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.3.1-py3-none-any.whl", hash = "sha256:4811639ca7fa830abdb8e9ca0a104dc6ad13de691d9fe0d3173a71304f068159"}, - {file = "importlib_resources-6.3.1.tar.gz", hash = "sha256:29a3d16556e330c3c8fb8202118c5ff41241cc34cbfb25989bbad226d99b7995"}, + {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, + {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, ] [package.dependencies] @@ -2183,7 +2160,7 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["jaraco.collections", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -2795,16 +2772,13 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-ena [[package]] name = "locust" -version = "2.24.0" -version = "2.24.0" +version = "2.24.1" description = "Developer friendly load testing framework" optional = false python-versions = ">=3.8" files = [ - {file = "locust-2.24.0-py3-none-any.whl", hash = "sha256:1b6b878b4fd0108fec956120815e69775d2616c8f4d1e9f365c222a7a5c17d9a"}, - {file = "locust-2.24.0.tar.gz", hash = "sha256:6cffa378d995244a7472af6be1d6139331f19aee44e907deee73e0281252804d"}, - {file = "locust-2.24.0-py3-none-any.whl", hash = "sha256:1b6b878b4fd0108fec956120815e69775d2616c8f4d1e9f365c222a7a5c17d9a"}, - {file = "locust-2.24.0.tar.gz", hash = "sha256:6cffa378d995244a7472af6be1d6139331f19aee44e907deee73e0281252804d"}, + {file = "locust-2.24.1-py3-none-any.whl", hash = "sha256:7f6ed4dc289aad66c304582e6d25e4de5d7c3b175b580332442ab2be35b9d916"}, + {file = "locust-2.24.1.tar.gz", hash = "sha256:094161d44d94839bf1120fd7898b7abb9c143833743ba7c096beb470a236b9a7"}, ] [package.dependencies] @@ -2821,7 +2795,6 @@ pyzmq = ">=25.0.0" requests = ">=2.26.0" roundrobin = ">=0.0.2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} Werkzeug = ">=2.0.0" [[package]] @@ -3012,13 +2985,13 @@ files = [ [[package]] name = "motor" -version = "3.3.2" +version = "3.4.0" description = "Non-blocking MongoDB driver for Tornado or asyncio" optional = true python-versions = ">=3.7" files = [ - {file = "motor-3.3.2-py3-none-any.whl", hash = "sha256:6fe7e6f0c4f430b9e030b9d22549b732f7c2226af3ab71ecc309e4a1b7d19953"}, - {file = "motor-3.3.2.tar.gz", hash = "sha256:d2fc38de15f1c8058f389c1a44a4d4105c0405c48c061cd492a654496f7bc26a"}, + {file = "motor-3.4.0-py3-none-any.whl", hash = "sha256:4b1e1a0cc5116ff73be2c080a72da078f2bb719b53bc7a6bb9e9a2f7dcd421ed"}, + {file = "motor-3.4.0.tar.gz", hash = "sha256:c89b4e4eb2e711345e91c7c9b122cb68cce0e5e869ed0387dd0acb10775e3131"}, ] [package.dependencies] @@ -3031,7 +3004,7 @@ gssapi = ["pymongo[gssapi] (>=4.5,<5)"] ocsp = ["pymongo[ocsp] (>=4.5,<5)"] snappy = ["pymongo[snappy] (>=4.5,<5)"] srv = ["pymongo[srv] (>=4.5,<5)"] -test = ["aiohttp (<3.8.6)", "mockupdb", "motor[encryption]", "pytest (>=7)", "tornado (>=5)"] +test = ["aiohttp (!=3.8.6)", "mockupdb", "motor[encryption]", "pytest (>=7)", "tornado (>=5)"] zstd = ["pymongo[zstd] (>=4.5,<5)"] [[package]] @@ -3201,7 +3174,6 @@ files = [ [[package]] name = "mypy" version = "1.9.0" -version = "1.9.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" @@ -3233,33 +3205,6 @@ files = [ {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, - {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, - {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, - {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, - {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, - {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, - {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, - {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, - {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, - {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, - {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, - {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, - {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, - {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, - {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, - {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, - {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, - {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, - {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, - {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] @@ -3308,13 +3253,13 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= [[package]] name = "nbconvert" -version = "7.16.2" +version = "7.16.3" description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." optional = false python-versions = ">=3.8" files = [ - {file = "nbconvert-7.16.2-py3-none-any.whl", hash = "sha256:0c01c23981a8de0220255706822c40b751438e32467d6a686e26be08ba784382"}, - {file = "nbconvert-7.16.2.tar.gz", hash = "sha256:8310edd41e1c43947e4ecf16614c61469ebc024898eb808cce0999860fc9fb16"}, + {file = "nbconvert-7.16.3-py3-none-any.whl", hash = "sha256:ddeff14beeeedf3dd0bc506623e41e4507e551736de59df69a91f86700292b3b"}, + {file = "nbconvert-7.16.3.tar.gz", hash = "sha256:a6733b78ce3d47c3f85e504998495b07e6ea9cf9bf6ec1c98dda63ec6ad19142"}, ] [package.dependencies] @@ -3341,7 +3286,7 @@ docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sp qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] webpdf = ["playwright"] [[package]] @@ -3693,8 +3638,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -4049,13 +3994,13 @@ files = [ [[package]] name = "poetry-plugin-export" -version = "1.7.0" +version = "1.7.1" description = "Poetry plugin to export the dependencies to various formats" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "poetry_plugin_export-1.7.0-py3-none-any.whl", hash = "sha256:2283b28e0209f9f9598c6fe44f30586ec91329ea1558f908708261e0516bf427"}, - {file = "poetry_plugin_export-1.7.0.tar.gz", hash = "sha256:e73f207fc0e08c2f59ead82cbe39ef259b351a318d5c0bddcec13990bcd324a7"}, + {file = "poetry_plugin_export-1.7.1-py3-none-any.whl", hash = "sha256:b2258e53ae0d369a73806f957ed0e726eb95c571a0ce8b1f273da686528cc1da"}, + {file = "poetry_plugin_export-1.7.1.tar.gz", hash = "sha256:cf62cfb6218a904290ba6db3bc1a24aa076d10f81c48c6e48b2ded430131e22e"}, ] [package.dependencies] @@ -4223,13 +4168,13 @@ numpy = ">=1.16.6,<2" [[package]] name = "pyasn1" -version = "0.5.1" +version = "0.6.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.8" files = [ - {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"}, - {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"}, + {file = "pyasn1-0.6.0-py2.py3-none-any.whl", hash = "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473"}, + {file = "pyasn1-0.6.0.tar.gz", hash = "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c"}, ] [[package]] @@ -4567,15 +4512,12 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [[package]] name = "pytest" version = "8.1.1" -version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, - {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, - {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] @@ -4585,22 +4527,19 @@ iniconfig = "*" packaging = "*" pluggy = ">=1.4,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} -pluggy = ">=1.4,<2.0" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] -testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.23.5.post1" +version = "0.23.6" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.23.5.post1.tar.gz", hash = "sha256:b9a8806bea78c21276bc34321bbf234ba1b2ea5b30d9f0ce0f2dea45e4685813"}, - {file = "pytest_asyncio-0.23.5.post1-py3-none-any.whl", hash = "sha256:30f54d27774e79ac409778889880242b0403d09cabd65b727ce90fe92dd5d80e"}, + {file = "pytest-asyncio-0.23.6.tar.gz", hash = "sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f"}, + {file = "pytest_asyncio-0.23.6-py3-none-any.whl", hash = "sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a"}, ] [package.dependencies] @@ -4729,16 +4668,13 @@ files = [ [[package]] name = "python-on-whales" -version = "0.70.0" -version = "0.70.0" +version = "0.70.1" description = "A Docker client for Python, designed to be fun and intuitive!" optional = false python-versions = "<4,>=3.8" files = [ - {file = "python-on-whales-0.70.0.tar.gz", hash = "sha256:bb89e91c86e049f9c04e2636f2d40faa000ff5b17d54f71e68581201e449eda5"}, - {file = "python_on_whales-0.70.0-py3-none-any.whl", hash = "sha256:492325387d7686adc6669e911820bd4da1cd672bc5a7fb6d54c32ee849bfe7e6"}, - {file = "python-on-whales-0.70.0.tar.gz", hash = "sha256:bb89e91c86e049f9c04e2636f2d40faa000ff5b17d54f71e68581201e449eda5"}, - {file = "python_on_whales-0.70.0-py3-none-any.whl", hash = "sha256:492325387d7686adc6669e911820bd4da1cd672bc5a7fb6d54c32ee849bfe7e6"}, + {file = "python-on-whales-0.70.1.tar.gz", hash = "sha256:1e7ac35cd16afaad8d23f01be860cb3ff906ee81816d032a327d4d07da1f9341"}, + {file = "python_on_whales-0.70.1-py3-none-any.whl", hash = "sha256:3cecd833359d90fd564cadf7f5e3c88209f8baf998316e0731f3d375d17af2f2"}, ] [package.dependencies] @@ -5045,101 +4981,101 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] [[package]] name = "rapidfuzz" -version = "3.6.2" +version = "3.7.0" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.8" files = [ - {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a5637e6bf11b15b5aff6ee818c76bdec99ad208511b78985e6209ba648a6e3ee"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:380586664f2f63807050ddb95e7702888b4f0b425abf17655940c411f39287ad"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3168ff565d4b8c239cf11fb604dd2507d30e9bcaac76a4077c0ac23cf2c866ed"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be69f7fd46b5c6467fe5e2fd4cff3816b0c03048eed8a4becb9a73e6000960e7"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cbd5894f23fdf5697499cf759523639838ac822bd1600e343fdce7313baa02ae"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85a5b6e026393fe39fb61146b9c17c5af66fffbe1410e992c4bb06d9ec327bd3"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab269adfc64480f209e99f253391a10735edd5c09046e04899adab5fb132f20e"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35aeac852bca06023d6bbd50c1fc504ca5a9a3613d5e75a140f0be7601fa34ef"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e706f302c6a3ae0d74edd0d6ace46aee1ae07c563b436ccf5ff04db2b3571e60"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bec353f022011e6e5cd28ccb8700fbd2a33918197af0d4e0abb3c3f4845cc864"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ef3925daaa93eed20401012e219f569ff0c039ed5bf4ce2d3737b4f75d441622"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6ee98d88ae9ccc77ff61992ed33b2496478def5dc0da55c9a9aa06fcb725a352"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:423c7c588b09d618601097b7a0017dfcb91132a2076bef29023c5f3cd2dc3de1"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-win32.whl", hash = "sha256:c17c5efee347a40a6f4c1eec59e3d7d1e22f7613a97f8b8a07733ef723483a04"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:4209816626d8d6ff8ae7dc248061c6059e618b70c6e6f6e4d7444ae3740b2b85"}, - {file = "rapidfuzz-3.6.2-cp310-cp310-win_arm64.whl", hash = "sha256:1c54d3c85e522d3ac9ee39415f183c8fa184c4f87e7e5a37938f15a6d50e853a"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e06f6d270112f5db001f1cba5a97e1a48aee3d3dbdcbea3ec027c230462dbf9b"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:080cb71b50cb6aff11d1c6aeb157f273e2da0b2bdb3f9d7b01257e49e69a8576"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7895e04a22d6515bc91a850e0831f2405547605aa311d1ffec51e4818abc3c1"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82f9838519136b7083dd1e3149ee80344521f3dc37f744f227505ff0883efb"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a945567c2b0b6e069454c9782d5234b0b6795718adf7a9f868bd3144afa6a023"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673ba2c343644805acdae1cb949c6a4de71aa2f62a998978551ebea59603af3f"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d457c89bac1471442002e70551e8268e639b3870b4a4521eae363c07253be87"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:495c0d8e14e6f12520eb7fc71b9ba9fcaafb47fc23a654e6e89b6c7985ec0020"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d67b649bf3e1b1722d04eca44d37919aef88305ce7ad05564502d013cf550fd"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e48dde8ca83d11daa00900cf6a5d281a1297aef9b7bfa73801af6e8822be5019"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:824cc381cf81cbf8d158f6935664ec2a69e6ac3b1d39fa201988bf81a257f775"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfe4c24957474ce0ac75d886387e30e292b4be39228a6d71f76de414dc187db"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d57b98013b802621bbc8b12a46bfc9d36ac552ab51ca207f7ce167ad46adabeb"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-win32.whl", hash = "sha256:9a07dffac439223b4f1025dbfc68f4445a3460a859309c9858c2a3fa29617cdc"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:95a49c6b8bf1229743ae585dd5b7d57f0d15a7eb6e826866d5c9965ba958503c"}, - {file = "rapidfuzz-3.6.2-cp311-cp311-win_arm64.whl", hash = "sha256:af7c19ec86e11488539380d3db1755be5d561a3c0e7b04ff9d07abd7f9a8e9d8"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:de8adc12161bf282c60f12dc9233bb31632f71d446a010fe7469a69b8153427f"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:337e357f693130c4c6be740652542b260e36f622c59e01fa33d58f1d2750c930"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6468f8bc8c3c50604f43631550ef9cfec873515dba5023ca34d461be94669fc8"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74c6773b11445b5e5cf93ca383171cd0ac0cdeafea11a7b2a5688f8bf8d813e6"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1507fc5769aa109dda4de3a15f822a0f6a03e18d627bd0ba3ddbb253cf70e07"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:617949a70150e6fffdaed19253dd49f7a53528411dc8bf7663d499ba21e0f61e"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8b77779174b1b40aa70827692571ab457061897846255ad7d5d559e2edb1932"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80e51b22a7da83f9c87a97e92df07ed0612c74c35496590255f4b5d5b4212dfe"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3ae7c86914cb6673e97e187ba431b9c4cf4177d9ae77f8a1e5b2ba9a5628839e"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ddc380ffaa90f204cc9ddcb779114b9ab6f015246d549de9d47871a97ef9f18a"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c1dc078ef371fce09f9f3eec2ca4eaa2a8cd412ec53941015b4f39f14d34407"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:9a74102fc5a2534fe91f7507838623e1f3a149d8e05648389c42bb42e14b1c3f"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:48e1eaea8fcd522fca7f04f0480663f0f0cfb77957092cce60a93f4462864996"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-win32.whl", hash = "sha256:66b008bf2972740cd2dda5d382eb8bdb87265cd88198e71c7797bdc0d1f79d20"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:87ac3a87f2251ae2e95fc9478ca5c759de6d141d04c84d3fec9f9cdcfc167b33"}, - {file = "rapidfuzz-3.6.2-cp312-cp312-win_arm64.whl", hash = "sha256:b593cc51aed887e93b78c2f94dfae9008be2b23d17afd3b1f1d3eb3913b58f26"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d830bc7a9b586a374147ec60b08b1f9ae5996b43f75cc514f37faef3866b519"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dbee7f5ff11872b76505cbd87c814abc823e8757f11c69062eb3b25130a283da"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c011fb31f2c3f82f503aedd6097d3d3854e574e327a119a3b7eb2cf90b79ca"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cda81d0e0ce0c13abfa46b24e10c1e85f9c6acb628f0a9a948f5779f9c2076a2"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c279928651ce0e9e5220dcb25a00cc53b65e592a0861336a38299bcdca3a596"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35bd4bc9c40e6994c5d6edea4b9319388b4d9711c13c66d543bb4c37624b4184"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d07899506a5a8760448d9df036d528b55a554bf571714173635c79eef4a86e58"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb2e51d01b9c6d6954a3e055c57a80d4685b4fc82719db5519fc153566bcd6bb"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:153d065e353371cc0aeff32b99999a5758266a64e958d1364189367c1c9f6814"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4edcceebb85ebfa49a3ddcde20ad891d36c08dc0fd592efdab0e7d313a4e36af"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3549123fca5bb817341025f98e8e49ca99f84596c7c4f92b658f8e5836040d4a"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:84c1032ae42628465b7a5cc35249906061e18a8193c9c27cbd2db54e9823a9a6"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9bcc91ebd8fc69a6bd3b5711c8250f5f4e70606b4da75ef415f57ad209978205"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-win32.whl", hash = "sha256:f3a70f341c4c111bad910d2df69c78577a98af140319a996af24c9385939335d"}, - {file = "rapidfuzz-3.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:354ad5fe655beb7b279390cb58334903931c5452ecbad1b1666ffb06786498e2"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1b86b93d93020c2b3edc1665d75c8855784845fc0a739b312c26c3a4bf0c80d5"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28243086ed0e50808bb56632e5442c457241646aeafafd501ac87901f40a3237"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed52461ae5a9ea4c400d38e2649c74a413f1a6d8fb8308b66f1fbd122514732f"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a46220f86a5f9cb016af31525e0d0865cad437d02239aa0d8aed2ab8bff1f1c"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81a630ed2fc3ec5fc7400eb66bab1f87e282b4d47f0abe3e48c6634dfa13b5e4"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8e5a437b9089df6242a718d9c31ab1742989e9400a0977af012ef483b63b4c2"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16270b5529de83b7bae7457e952e4d9cf3fbf029a837dd32d415bb9e0eb8e599"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5378c04102c7f084cde30a100154fa6d7e2baf0d51a6bdd2f912545559c1fb35"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f18397c8d6a65fc0b288d2fc29bc7baeea6ba91eeb95163a3cd98f23cd3bc85"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2acd2514defce81e6ff4bbff50252d5e7df8e85a731442c4b83e44c86cf1c916"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:1df2faf80201952e252413b6fac6f3e146080dcebb87bb1bb722508e67558ed8"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6440ed0b3007c1c9286b0b88fe2ab2d9e83edd60cd62293b3dfabb732b4e8a30"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4fcfa23b5553b27f4016df77c53172ea743454cf12c28cfa7c35a309a2be93b3"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-win32.whl", hash = "sha256:2d580d937146e803c8e5e1b87916cab8d6f84013b6392713e201efcda335c7d8"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:fe2a68be734e8e88af23385c68d6467e15818b6b1df1cbfebf7bff577226c957"}, - {file = "rapidfuzz-3.6.2-cp39-cp39-win_arm64.whl", hash = "sha256:6478f7803efebf5f644d0b758439c5b25728550fdfbb19783d150004c46a75a9"}, - {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:36ce7b68a7b90b787cdd73480a68d2f1ca63c31a3a9d5a79a8736f978e1e9344"}, - {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53597fd72a9340bcdd80d3620f4957c2b92f9b569313b969a3abdaffd193aae6"}, - {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4f6de745fe6ce46a422d353ee10599013631d7d714a36d025f164b2d4e8c000"}, - {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62df2136068e2515ed8beb01756381ff62c29384d785e3bf46e3111d4ea3ba1e"}, - {file = "rapidfuzz-3.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7382c90170f60c846c81a07ddd80bb2e8c43c8383754486fa37f67391a571897"}, - {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f31314fd2e2f3dc3e519e6f93669462ce7953df2def1c344aa8f5345976d0eb2"}, - {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012221629d54d3bee954148247f711eb86d4d390b589ebfe03172ea0b37a7531"}, - {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41dd59a70decfce6595315367a2fea2af660d92a9d144acc6479030501014d7"}, - {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9fa14136a5b0cba1ec42531f7c3e0b0d3edb7fd6bc5e5ae7b498541f3855ab"}, - {file = "rapidfuzz-3.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:259364199cbfeca33b1af369fc7951f71717aa285184a3fa5a7b1772da1b89db"}, - {file = "rapidfuzz-3.6.2.tar.gz", hash = "sha256:cf911e792ab0c431694c9bf2648afabfd92099103f2e31492893e078ddca5e1a"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:860f438238f1807532aa5c5c25e74c284232ccc115fe84697b78e25d48f364f7"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bb9285abeb0477cdb2f8ea0cf7fd4b5f72ed5a9a7d3f0c0bb4a5239db2fc1ed"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:08671280e0c04d2bb3f39511f13cae5914e6690036fd1eefc3d47a47f9fae634"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04bae4d9c16ce1bab6447d196fb8258d98139ed8f9b288a38b84887985e4227b"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1efa2268b51b68156fb84d18ca1720311698a58051c4a19c40d670057ce60519"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:600b4d4315f33ec0356c0dab3991a5d5761102420bcff29e0773706aa48936e8"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18bc2f13c73d5d34499ff6ada55b052c445d3aa64d22c2639e5ab45472568046"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e11c5e6593be41a555475c9c20320342c1f5585d635a064924956944c465ad4"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d7878025248b99ccca3285891899373f98548f2ca13835d83619ffc42241c626"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4a7e37fe136022d944374fcd8a2f72b8a19f7b648d2cdfb946667e9ede97f9f"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b5881856f830351aaabd869151124f64a80bf61560546d9588a630a4e933a5de"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:c788b11565cc176fab8fab6dfcd469031e906927db94bf7e422afd8ef8f88a5a"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9e17a3092e74025d896ef1d67ac236c83494da37a78ef84c712e4e2273c115f1"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-win32.whl", hash = "sha256:e499c823206c9ffd9d89aa11f813a4babdb9219417d4efe4c8a6f8272da00e98"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:91f798cc00cd94a0def43e9befc6e867c9bd8fa8f882d1eaa40042f528b7e2c7"}, + {file = "rapidfuzz-3.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:d5a3872f35bec89f07b993fa1c5401d11b9e68bcdc1b9737494e279308a38a5f"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ef6b6ab64c4c91c57a6b58e1d690b59453bfa1f1e9757a7e52e59b4079e36631"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f9070b42c0ba030b045bba16a35bdb498a0d6acb0bdb3ff4e325960e685e290"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:63044c63565f50818d885bfcd40ac369947da4197de56b4d6c26408989d48edf"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b0c47860c733a3d73a4b70b97b35c8cbf24ef24f8743732f0d1c412a8c85de"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1b14489b038f007f425a06fcf28ac6313c02cb603b54e3a28d9cfae82198cc0"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be08f39e397a618aab907887465d7fabc2d1a4d15d1a67cb8b526a7fb5202a3e"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16895dc62a7b92028f9c8b6d22830f1cbc77306ee794f461afc6028e1a8d7539"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:579cce49dfa57ffd8c8227b3fb53cced54b4df70cec502e63e9799b4d1f44004"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:40998c8dc35fdd221790b8b5134a8d7499adbfab9a5dd9ec626c7e92e17a43ed"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:dc3fdb4738a6b83ae27f1d8923b00d3a9c2b5c50da75b9f8b81841839c6e3e1f"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:92b8146fbfb37ac358ef7e0f6b79619e4f793fbbe894b99ea87920f9c0a9d77d"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1dfceaa7c2914585bb8a043265c39ec09078f13fbf53b5525722fc074306b6fa"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f332d61f51b0b9c8b55a0fb052b4764b6ad599ea8ce948ac47a4388e9083c35e"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-win32.whl", hash = "sha256:dfd1e4819f1f3c47141f86159b44b7360ecb19bf675080b3b40437bf97273ab9"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:594b9c33fc1a86784962043ee3fbaaed875fbaadff72e467c2f7a83cd6c5d69d"}, + {file = "rapidfuzz-3.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b13a6823a1b83ae43f8bf35955df35032bee7bec0daf9b5ab836e0286067434"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:075a419a0ec29be44b3d7f4bcfa5cb7e91e419379a85fc05eb33de68315bd96f"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:51a5b96d2081c3afbef1842a61d63e55d0a5a201473e6975a80190ff2d6f22ca"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9460d8fddac7ea46dff9298eee9aa950dbfe79f2eb509a9f18fbaefcd10894c"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f39eb1513ee139ba6b5c01fe47ddf2d87e9560dd7fdee1068f7f6efbae70de34"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eace9fdde58a425d4c9a93021b24a0cac830df167a5b2fc73299e2acf9f41493"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cc77237242303733de47829028a0a8b6ab9188b23ec9d9ff0a674fdcd3c8e7f"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74e692357dd324dff691d379ef2c094c9ec526c0ce83ed43a066e4e68fe70bf6"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2075ac9ee5c15d33d24a1efc8368d095602b5fd9634c5b5f24d83e41903528"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5a8ba64d72329a940ff6c74b721268c2004eecc48558f648a38e96915b5d1c1b"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a1f268a2a37cd22573b4a06eccd481c04504b246d3cadc2d8e8dfa64b575636d"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:42c2e8a2341363c7caf276efdbe1a673fc5267a02568c47c8e980f12e9bc8727"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:a9acca34b34fb895ee6a84c436bb919f3b9cd8f43e7003d43e9573a1d990ff74"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9bad6a0fe3bc1753dacaa6229a8ba7d9844eb7ae24d44d17c5f4c51c91a8a95e"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-win32.whl", hash = "sha256:c86bc4b1d2380739e6485396195e30021df509b4923f3f757914e171587bce7c"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:d7361608c8e73a1dc0203a87d151cddebdade0098a047c46da43c469c07df964"}, + {file = "rapidfuzz-3.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:8fdc26e7863e0f63c2185d53bb61f5173ad4451c1c8287b535b30ea25a419a5a"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9b6167468f76779a14b9af66210f68741af94d32d086f19118de4e919f00585c"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bd394e28ff221557ea4d8152fcec3e66d9f620557feca5f2bedc4c21f8cf2f9"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8e70f876ca89a6df344f8157ac60384e8c05a0dfb442da2490c3f1c45238ccf5"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c837f89d86a5affe9ee6574dad6b195475676a6ab171a67920fc99966f2ab2c"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cda4550a98658f9a8bcdc03d0498ed1565c1563880e3564603a9eaae28d51b2a"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecd70212fd9f1f8b1d3bdd8bcb05acc143defebd41148bdab43e573b043bb241"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187db4cc8fb54f8c49c67b7f38ef3a122ce23be273032fa2ff34112a2694c3d8"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4604dfc1098920c4eb6d0c6b5cc7bdd4bf95b48633e790c1d3f100a25870691d"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01581b688c5f4f6665b779135e32db0edab1d78028abf914bb91469928efa383"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0828b55ec8ad084febdf4ab0c942eb1f81c97c0935f1cb0be0b4ea84ce755988"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:150c98b65faff17b917b9d36bff8a4d37b6173579c6bc2e38ff2044e209d37a4"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7e4eea225d2bff1aff4c85fcc44716596d3699374d99eb5906b7a7560297460e"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7bc944d7e830cfce0f8b4813875f05904207017b66e25ab7ee757507001310a9"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-win32.whl", hash = "sha256:3e55f02105c451ab6ff0edaaba57cab1b6c0a0241cfb2b306d4e8e1503adba50"}, + {file = "rapidfuzz-3.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:41851620d2900791d66d9b6092fc163441d7dd91a460c73b07957ff1c517bc30"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e8041c6b2d339766efe6298fa272f79d6dd799965df364ef4e50f488c101c899"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e09d81008e212fc824ea23603ff5270d75886e72372fa6c7c41c1880bcb57ed"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:419c8961e861fb5fc5590056c66a279623d1ea27809baea17e00cdc313f1217a"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1522eaab91b9400b3ef16eebe445940a19e70035b5bc5d98aef23d66e9ac1df0"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:611278ce3136f4544d596af18ab8849827d64372e1d8888d9a8d071bf4a3f44d"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4efa9bfc5b955b6474ee077eee154e240441842fa304f280b06e6b6aa58a1d1e"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0cc9d3c8261457af3f8756b1f71a9fdc4892978a9e8b967976d2803e08bf972"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce728e2b582fd396bc2559160ee2e391e6a4b5d2e455624044699d96abe8a396"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a6a36c9299e059e0bee3409218bc5235a46570c20fc980cdee5ed21ea6110ad"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9ea720db8def684c1eb71dadad1f61c9b52f4d979263eb5d443f2b22b0d5430a"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:358692f1df3f8aebcd48e69c77c948c9283b44c0efbaf1eeea01739efe3cd9a6"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:faded69ffe79adcefa8da08f414a0fd52375e2b47f57be79471691dad9656b5a"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7f9f3dc14fadbd553975f824ac48c381f42192cec9d7e5711b528357662a8d8e"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-win32.whl", hash = "sha256:7be5f460ff42d7d27729115bfe8a02e83fa0284536d8630ee900d17b75c29e65"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:dd5ad2c12dab2b98340c4b7b9592c8f349730bda9a2e49675ea592bbcbc1360b"}, + {file = "rapidfuzz-3.7.0-cp39-cp39-win_arm64.whl", hash = "sha256:aa163257a0ac4e70f9009d25e5030bdd83a8541dfa3ba78dc86b35c9e16a80b4"}, + {file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4e50840a8a8e0229563eeaf22e21a203359859557db8829f4d0285c17126c5fb"}, + {file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:632f09e19365ace5ff2670008adc8bf23d03d668b03a30230e5b60ff9317ee93"}, + {file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:209dda6ae66b702f74a78cef555397cdc2a83d7f48771774a20d2fc30808b28c"}, + {file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bc0b78572626af6ab134895e4dbfe4f4d615d18dcc43b8d902d8e45471aabba"}, + {file = "rapidfuzz-3.7.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ba14850cc8258b3764ea16b8a4409ac2ba16d229bde7a5f495dd479cd9ccd56"}, + {file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b917764fd2b267addc9d03a96d26f751f6117a95f617428c44a069057653b528"}, + {file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1252ca156e1b053e84e5ae1c8e9e062ee80468faf23aa5c543708212a42795fd"}, + {file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86c7676a32d7524e40bc73546e511a408bc831ae5b163029d325ea3a2027d089"}, + {file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20e7d729af2e5abb29caa070ec048aba042f134091923d9ca2ac662b5604577e"}, + {file = "rapidfuzz-3.7.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86eea3e6c314a9238de568254a9c591ec73c2985f125675ed5f171d869c47773"}, + {file = "rapidfuzz-3.7.0.tar.gz", hash = "sha256:620df112c39c6d27316dc1e22046dc0382d6d91fd60d7c51bd41ca0333d867e9"}, ] [package.extras] @@ -5749,60 +5685,60 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.28" +version = "2.0.29" description = "Database Abstraction Library" optional = true python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0b148ab0438f72ad21cb004ce3bdaafd28465c4276af66df3b9ecd2037bf252"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbda76961eb8f27e6ad3c84d1dc56d5bc61ba8f02bd20fcf3450bd421c2fcc9c"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feea693c452d85ea0015ebe3bb9cd15b6f49acc1a31c28b3c50f4db0f8fb1e71"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da98815f82dce0cb31fd1e873a0cb30934971d15b74e0d78cf21f9e1b05953f"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5adf383c73f2d49ad15ff363a8748319ff84c371eed59ffd0127355d6ea1da"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56856b871146bfead25fbcaed098269d90b744eea5cb32a952df00d542cdd368"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-win32.whl", hash = "sha256:943aa74a11f5806ab68278284a4ddd282d3fb348a0e96db9b42cb81bf731acdc"}, - {file = "SQLAlchemy-2.0.28-cp310-cp310-win_amd64.whl", hash = "sha256:c6c4da4843e0dabde41b8f2e8147438330924114f541949e6318358a56d1875a"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46a3d4e7a472bfff2d28db838669fc437964e8af8df8ee1e4548e92710929adc"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3dd67b5d69794cfe82862c002512683b3db038b99002171f624712fa71aeaa"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61e2e41656a673b777e2f0cbbe545323dbe0d32312f590b1bc09da1de6c2a02"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0315d9125a38026227f559488fe7f7cee1bd2fbc19f9fd637739dc50bb6380b2"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af8ce2d31679006e7b747d30a89cd3ac1ec304c3d4c20973f0f4ad58e2d1c4c9"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81ba314a08c7ab701e621b7ad079c0c933c58cdef88593c59b90b996e8b58fa5"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-win32.whl", hash = "sha256:1ee8bd6d68578e517943f5ebff3afbd93fc65f7ef8f23becab9fa8fb315afb1d"}, - {file = "SQLAlchemy-2.0.28-cp311-cp311-win_amd64.whl", hash = "sha256:ad7acbe95bac70e4e687a4dc9ae3f7a2f467aa6597049eeb6d4a662ecd990bb6"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d3499008ddec83127ab286c6f6ec82a34f39c9817f020f75eca96155f9765097"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b66fcd38659cab5d29e8de5409cdf91e9986817703e1078b2fdaad731ea66f5"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea30da1e76cb1acc5b72e204a920a3a7678d9d52f688f087dc08e54e2754c67"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:124202b4e0edea7f08a4db8c81cc7859012f90a0d14ba2bf07c099aff6e96462"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e23b88c69497a6322b5796c0781400692eca1ae5532821b39ce81a48c395aae9"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b6303bfd78fb3221847723104d152e5972c22367ff66edf09120fcde5ddc2e2"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-win32.whl", hash = "sha256:a921002be69ac3ab2cf0c3017c4e6a3377f800f1fca7f254c13b5f1a2f10022c"}, - {file = "SQLAlchemy-2.0.28-cp312-cp312-win_amd64.whl", hash = "sha256:b4a2cf92995635b64876dc141af0ef089c6eea7e05898d8d8865e71a326c0385"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e91b5e341f8c7f1e5020db8e5602f3ed045a29f8e27f7f565e0bdee3338f2c7"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c7b78dfc7278329f27be02c44abc0d69fe235495bb8e16ec7ef1b1a17952db"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eba73ef2c30695cb7eabcdb33bb3d0b878595737479e152468f3ba97a9c22a4"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5df5d1dafb8eee89384fb7a1f79128118bc0ba50ce0db27a40750f6f91aa99d5"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2858bbab1681ee5406650202950dc8f00e83b06a198741b7c656e63818633526"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-win32.whl", hash = "sha256:9461802f2e965de5cff80c5a13bc945abea7edaa1d29360b485c3d2b56cdb075"}, - {file = "SQLAlchemy-2.0.28-cp37-cp37m-win_amd64.whl", hash = "sha256:a6bec1c010a6d65b3ed88c863d56b9ea5eeefdf62b5e39cafd08c65f5ce5198b"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:843a882cadebecc655a68bd9a5b8aa39b3c52f4a9a5572a3036fb1bb2ccdc197"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dbb990612c36163c6072723523d2be7c3eb1517bbdd63fe50449f56afafd1133"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7e4baf9161d076b9a7e432fce06217b9bd90cfb8f1d543d6e8c4595627edb9"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0a5354cb4de9b64bccb6ea33162cb83e03dbefa0d892db88a672f5aad638a75"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fffcc8edc508801ed2e6a4e7b0d150a62196fd28b4e16ab9f65192e8186102b6"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aca7b6d99a4541b2ebab4494f6c8c2f947e0df4ac859ced575238e1d6ca5716b"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-win32.whl", hash = "sha256:8c7f10720fc34d14abad5b647bc8202202f4948498927d9f1b4df0fb1cf391b7"}, - {file = "SQLAlchemy-2.0.28-cp38-cp38-win_amd64.whl", hash = "sha256:243feb6882b06a2af68ecf4bec8813d99452a1b62ba2be917ce6283852cf701b"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc4974d3684f28b61b9a90fcb4c41fb340fd4b6a50c04365704a4da5a9603b05"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87724e7ed2a936fdda2c05dbd99d395c91ea3c96f029a033a4a20e008dd876bf"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68722e6a550f5de2e3cfe9da6afb9a7dd15ef7032afa5651b0f0c6b3adb8815d"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328529f7c7f90adcd65aed06a161851f83f475c2f664a898af574893f55d9e53"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:df40c16a7e8be7413b885c9bf900d402918cc848be08a59b022478804ea076b8"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:426f2fa71331a64f5132369ede5171c52fd1df1bd9727ce621f38b5b24f48750"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-win32.whl", hash = "sha256:33157920b233bc542ce497a81a2e1452e685a11834c5763933b440fedd1d8e2d"}, - {file = "SQLAlchemy-2.0.28-cp39-cp39-win_amd64.whl", hash = "sha256:2f60843068e432311c886c5f03c4664acaef507cf716f6c60d5fde7265be9d7b"}, - {file = "SQLAlchemy-2.0.28-py3-none-any.whl", hash = "sha256:78bb7e8da0183a8301352d569900d9d3594c48ac21dc1c2ec6b3121ed8b6c986"}, - {file = "SQLAlchemy-2.0.28.tar.gz", hash = "sha256:dd53b6c4e6d960600fd6532b79ee28e2da489322fcf6648738134587faf767b6"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win32.whl", hash = "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win_amd64.whl", hash = "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win32.whl", hash = "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win_amd64.whl", hash = "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win32.whl", hash = "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win_amd64.whl", hash = "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win32.whl", hash = "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win_amd64.whl", hash = "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win32.whl", hash = "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win_amd64.whl", hash = "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win32.whl", hash = "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win_amd64.whl", hash = "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c"}, + {file = "SQLAlchemy-2.0.29-py3-none-any.whl", hash = "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305"}, + {file = "SQLAlchemy-2.0.29.tar.gz", hash = "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0"}, ] [package.dependencies] @@ -5890,15 +5826,12 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "streamlit" version = "1.32.2" -version = "1.32.2" description = "A faster way to build and share data apps" optional = false python-versions = ">=3.8, !=3.9.7" files = [ {file = "streamlit-1.32.2-py2.py3-none-any.whl", hash = "sha256:a0b8044e76fec364b07be145f8b40dbd8d083e20ebbb189ceb1fa9423f3dedea"}, {file = "streamlit-1.32.2.tar.gz", hash = "sha256:1258b9cbc3ff957bf7d09b1bfc85cedc308f1065b30748545295a9af8d5577ab"}, - {file = "streamlit-1.32.2-py2.py3-none-any.whl", hash = "sha256:a0b8044e76fec364b07be145f8b40dbd8d083e20ebbb189ceb1fa9423f3dedea"}, - {file = "streamlit-1.32.2.tar.gz", hash = "sha256:1258b9cbc3ff957bf7d09b1bfc85cedc308f1065b30748545295a9af8d5577ab"}, ] [package.dependencies] @@ -6124,35 +6057,32 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "trove-classifiers" -version = "2024.3.3" +version = "2024.3.25" description = "Canonical source for classifiers on PyPI (pypi.org)." optional = false python-versions = "*" files = [ - {file = "trove-classifiers-2024.3.3.tar.gz", hash = "sha256:df7edff9c67ff86b733628998330b180e81d125b1e096536d83ac0fd79673fdc"}, - {file = "trove_classifiers-2024.3.3-py3-none-any.whl", hash = "sha256:3a84096861b385ec422c79995d1f6435dde47a9b63adaa3c886e53232ba7e6e0"}, + {file = "trove-classifiers-2024.3.25.tar.gz", hash = "sha256:6de68d06edd6fec5032162b6af22e818a4bb6f4ae2258e74699f8a41064b7cad"}, + {file = "trove_classifiers-2024.3.25-py3-none-any.whl", hash = "sha256:c400e0bdceb018913339d53b07682d09a42aada687d070e90ee3c08477bec024"}, ] [[package]] name = "typer" -version = "0.9.0" +version = "0.11.0" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, - {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, + {file = "typer-0.11.0-py3-none-any.whl", hash = "sha256:049cc47bef39f46b043eddd9165492209fdd9bc7d79afa7ba9cc5cd017caa817"}, + {file = "typer-0.11.0.tar.gz", hash = "sha256:a6ce173c0f03d3a41b49c0a945874cc489e91f88faabf76517b2b91c670fcde7"}, ] [package.dependencies] -click = ">=7.1.1,<9.0.0" +click = ">=8.0.0" typing-extensions = ">=3.7.4.3" [package.extras] all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] -dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] -doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] -test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] [[package]] name = "types-python-dateutil" @@ -6219,13 +6149,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "uvicorn" -version = "0.28.0" +version = "0.29.0" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.28.0-py3-none-any.whl", hash = "sha256:6623abbbe6176204a4226e67607b4d52cc60ff62cda0ff177613645cefa2ece1"}, - {file = "uvicorn-0.28.0.tar.gz", hash = "sha256:cab4473b5d1eaeb5a0f6375ac4bc85007ffc75c3cc1768816d9e5d589857b067"}, + {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, + {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, ] [package.dependencies] From 8c90763ed1aadc50af2b5a8a69d40780d11492c4 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 27 Mar 2024 14:01:37 +0100 Subject: [PATCH 046/140] tuples replaced with sets everywhere --- dff/messengers/common/interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index e7cd902a6..1530d630e 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -26,8 +26,8 @@ class MessengerInterface(abc.ABC): It is responsible for connection between user and pipeline, as well as for request-response transactions. """ - accepts_attachments = tuple() - produces_attachments = tuple() + request_attachments = set() + response_attachments = set() @abc.abstractmethod async def connect(self, pipeline_runner: PipelineRunnerFunction): From de1982fc16d7e3196873efc8b014cb2a85dd48cb Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 28 Mar 2024 17:32:18 +0300 Subject: [PATCH 047/140] Switched debug to logging, cleared unused code and imports, changed the attachment to the web one --- dff/messengers/vk.py | 136 +++++------------------ tutorials/messengers/vk/2_attachments.py | 2 +- 2 files changed, 27 insertions(+), 111 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 37327a860..a93694b38 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -8,22 +8,17 @@ import aiofiles import aiohttp +import logging import requests import io import os -from dff.messengers.common import MessengerInterface, PollingMessengerInterface -from dff.pipeline import Pipeline +from dff.messengers.common import PollingMessengerInterface -# from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.context import Context from dff.script.core.message import ( Audio, - Button, Document, Image, - Keyboard, - Location, Message, Video, Link @@ -31,11 +26,12 @@ from dff.script.extra_types import Poll +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) async def vk_api_call(method, payload={}, headers={}): async with aiohttp.ClientSession() as session: async with session.post(method) as response: - # print(response.json()) return response.json() @@ -45,85 +41,6 @@ def extract_vk_update(update): return message, int(id) - -class _AbstractVKInterface(MessengerInterface): - async def __init__(self, token: str, group_id: str) -> None: - self.token = token - self.group_id = group_id - await vk_api_call( - f"https://api.vk.com/method/status.get?user_id={self.group_id}&v=5.131&access_token={self.token}" - ) - - async def _create_keyboard(self, buttons: Sequence[Sequence[Button]]): - keyboard = Keyboard(inline=False) - keyboard.add_button(label="123") - - - - async def extract_message_from_vk(self, message_vk: dict[str, str]) -> Message: - message = Message() - message.attachments = list() - - if message_vk["text"] is not None: - message.text = message_vk["text"] - - if message_vk["attachments"] is not []: - for element in message_vk["attachments"]: - match element["type"]: - case "photo": - message.attachments += [ - Image( - source=HttpUrl( - element[element["type"]]["sizes"][-1]["url"] - ) - ) - ] - case "video": - pass - case "audio": - message.attachments += [ - Audio(source=HttpUrl(element[element["type"]]["url"])) - ] - case "doc": - message.attachments += [ - Document(source=HttpUrl(element[element["type"]]["url"])) - ] - case "link": - message.text = element[element["type"]]["url"] - case _: - pass - - return message - - async def cast_message_to_vk_and_send( - self, bot, orig_message, message: Message - ) -> None: - if message.attachments is not None: - for attachment in message.attachments: - if isinstance(attachment, Image): - bot.send_api_method( - "send", - { - "peer_id": orig_message["peer_id"], - "photo_id": self._upload_attachment( - orig_message["peer_id"], - ), - }, - ) - if message.text is not None: - bot.send_message(peer_id=orig_message["peer_id"], text=message.text) - - async def on_message(self, _, event) -> None: - message = self.extract_message_from_vk(event) - message.original_message = event - resp = self.callback(message, event["peer_id"]) - if resp.last_response is not None: - self.cast_message_to_vk_and_send(self.bot, event, resp.last_response) - - async def connect(self, callback, *args, **kwargs): - self.callback = callback - - class FilesOpener(object): def __init__(self, paths, key_format='file{}'): if not isinstance(paths, list): @@ -191,27 +108,30 @@ def __init__(self, token: str, group_id: str) -> None: def upload_attachment( self, peer_id, attachment, attachment_type: str ) -> str: - #returns json object with `owner_id` and `photo_id` needed to send it + """ + Return json object with `owner_id` and `photo_id` needed to send it + """ if attachment_type == "photo": upload_url = requests.post( f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" ).json() if "response" not in upload_url: - raise Exception(f"Error getting upload server for image\n{upload_url}") + logger.error(f"Error getting upload server for image\n{upload_url}") + raise Exception() upload_url = upload_url["response"]["upload_url"] attachment_path = str(attachment.source) - print(f"Uploading {attachment_path}") + logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path) as photo_files: uploaded_photo_data = requests.post(upload_url, files=photo_files).json() - print(photo_files) saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() if "response" not in saved_photo_data: - raise Exception(f"Error saving photo\n{saved_photo_data}") + logger.error(f"Error saving photo\n{saved_photo_data}") + raise Exception() return saved_photo_data["response"] @@ -222,17 +142,20 @@ def upload_attachment( attachment_path = str(attachment.source) if "response" not in upload_url: - raise Exception(f"Errror getting upload server for document\n{upload_url}") + logger.error(f"Errror getting upload server for document\n{upload_url}") + raise Exception() upload_url = upload_url["response"]["upload_url"] + logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = requests.post(upload_url, files=files).json() saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() if "response" not in saved_doc_data: - raise Exception(f"Error saving document\n{saved_doc_data}") + logger.error(f"Error saving document\n{saved_doc_data}") + raise Exception() return saved_doc_data["response"] @@ -243,15 +166,21 @@ def upload_attachment( attachment_path = str(attachment.source) if "response" not in upload_url: - raise Exception(f"Errror getting upload server for audio\n{upload_url}") + logger.error(f"Errror getting upload server for audio\n{upload_url}") + raise Exception() upload_url = upload_url["response"]["upload_url"] + logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = requests.post(upload_url, files=files).json() saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + if "response" not in saved_doc_data: + logger.error(f"Error saving audio\n{saved_doc_data}") + raise Exception() + return saved_doc_data["response"] elif attachment_type == "video": @@ -266,7 +195,6 @@ def send_message(self, response, id): if isinstance(attachment, Image): data_to_send = self.upload_attachment(id, attachment, "photo") attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment=photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}&v=5.81&access_token={self.token}").json() elif isinstance(attachment, Document): data_to_send = self.upload_attachment(id, attachment, "doc") attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") @@ -277,18 +205,10 @@ def send_message(self, response, id): data_to_send = self.upload_attachment(id, attachment, "audio") attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") elif isinstance(attachment, Link): - # link_vk = {"type": "link", "link": {"url": attachment.source, "title": attachment.title}} response.text += f"[{attachment.source}|{attachment.title}]" - # requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachments=[{link_vk}]&v=5.81&access_token={self.token}").json() - # attachment_list.append(link_vk) - # attachment_list.append(str(link_vk)) + elif isinstance(attachment, Poll): poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json() - print(poll_obj) - # attachment_list.append({ - # "type": "poll", - # "poll": poll_obj - # }) attachment_string = ','.join(attachment_list).strip(',') @@ -312,12 +232,8 @@ def _respond(self, response): for resp in response: self.send_message(resp.last_response, resp.id) - # update_id = getattr(resp.last_request, "update_id", None) - # if update_id is not None: - # if update_id != self._last_processed_update: - # self._last_processed_update = update_idnest_asyncio - print("Responded") + logger.info("Responded.") async def connect(self, callback, loop: Optional[Callable] = None, *args, **kwargs): diff --git a/tutorials/messengers/vk/2_attachments.py b/tutorials/messengers/vk/2_attachments.py index f0065064a..2d80d9f70 100644 --- a/tutorials/messengers/vk/2_attachments.py +++ b/tutorials/messengers/vk/2_attachments.py @@ -60,7 +60,7 @@ }, }, "cat_image_node": { - RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source="cat.jpg"), Image(source="https://d2ph5fj80uercy.cloudfront.net/04/cat2634.jpg")]), + RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source="https://media.tenor.com/ff2BZlCK0SwAAAAM/gatin.gif"), Image(source="https://d2ph5fj80uercy.cloudfront.net/04/cat2634.jpg")]), TRANSITIONS: { "greeting_node": cnd.true() } From 30db35a6cd7d1f65edb5be200571ded1603b030a Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 4 Apr 2024 21:57:25 +0200 Subject: [PATCH 048/140] telegram-specific request attachments added --- dff/messengers/telegram/__init__.py | 12 ++ dff/messengers/telegram/abstract.py | 273 +++++++++++++++++++++++++ dff/messengers/telegram/attachments.py | 54 +++++ dff/messengers/telegram/interface.py | 29 +++ 4 files changed, 368 insertions(+) create mode 100644 dff/messengers/telegram/__init__.py create mode 100644 dff/messengers/telegram/abstract.py create mode 100644 dff/messengers/telegram/attachments.py create mode 100644 dff/messengers/telegram/interface.py diff --git a/dff/messengers/telegram/__init__.py b/dff/messengers/telegram/__init__.py new file mode 100644 index 000000000..dd8a7cdfd --- /dev/null +++ b/dff/messengers/telegram/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from .attachments import ( + TelegramContact, + TelegramPoll, + TelegramAudio, + TelegramVideo, + TelegramAnimation, + TelegramImage, + TelegramDocument, +) +from .interface import PollingTelegramInterface, CallbackTelegramInterface diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py new file mode 100644 index 000000000..b23d06681 --- /dev/null +++ b/dff/messengers/telegram/abstract.py @@ -0,0 +1,273 @@ +""" +Interface +------------ +This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` +that can be used to interact with the Telegram API. +""" + +from pathlib import Path +from tempfile import gettempdir +from typing import Callable, Optional, Sequence +from pydantic import FilePath + +from telegram import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + InputMediaAnimation, + InputMediaAudio, + InputMediaDocument, + InputMediaPhoto, + InputMediaVideo, + Update, + Message as TelegramMessage, +) +from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes +from telegram.ext.filters import ALL + +from dff.messengers.common import MessengerInterface +from dff.pipeline.types import PipelineRunnerFunction +from dff.script.core.message import ( + Animation, + Audio, + Button, + CallbackQuery, + Contact, + DataAttachment, + Document, + Image, + Invoice, + Keyboard, + Location, + Message, + Poll, + PollOption, + Video, +) +from .attachments import ( + TelegramContact, + TelegramPoll, + TelegramAudio, + TelegramVideo, + TelegramAnimation, + TelegramImage, + TelegramDocument, +) + + +class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover + request_attachments = {Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document} + response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} + + def __init__(self, token: str) -> None: + self.application = Application.builder().token(token).build() + self.application.add_handler(MessageHandler(ALL, self.on_message)) + self.application.add_handler(CallbackQueryHandler(self.on_callback)) + + async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover + if attachment.title is not None and attachment.id is not None: + file_name = Path(gettempdir()) / str(attachment.title) + if not file_name.exists(): + await (await self.application.bot.get_file(attachment.id)).download_to_drive(file_name) + attachment.source = FilePath(file_name) + else: + raise ValueError(f"For attachment {attachment} title or id is not defined!") + + def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover + message = Message() + message.attachments = list() + + if update.text is not None: + message.text = update.text + if update.location is not None: + message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] + if update.contact is not None: + message.attachments += [ + TelegramContact( + phone_number=update.contact.phone_number, + first_name=update.contact.first_name, + last_name=update.contact.last_name, + user_id=update.contact.user_id, + ) + ] + if update.invoice is not None: + message.attachments += [ + Invoice( + title=update.invoice.title, + description=update.invoice.description, + currency=update.invoice.currency, + amount=update.invoice.total_amount, + ) + ] + if update.poll is not None: + message.attachments += [ + TelegramPoll( + question=update.poll.question, + options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options], + is_closed=update.poll.is_closed, + is_anonymous=update.poll.is_anonymous, + type=update.poll.type, + multiple_answers=update.poll.allows_multiple_answers, + correct_option_id=update.poll.correct_option_id, + explanation=update.poll.explanation, + open_period=update.poll.open_period, + ) + ] + if update.audio is not None: + thumbnail = Image(id=update.audio.thumbnail.file_id, title=update.audio.thumbnail.file_unique_id) if update.audio.thumbnail is not None else None + message.attachments += [ + TelegramAudio( + id=update.audio.file_id, + title=update.audio.file_unique_id, + duration=update.audio.duration, + performer=update.audio.performer, + file_name=update.audio.file_name, + mime_type=update.audio.mime_type, + thumbnail=thumbnail, + ) + ] + if update.video is not None: + thumbnail = Image(id=update.video.thumbnail.file_id, title=update.video.thumbnail.file_unique_id) if update.video.thumbnail is not None else None + message.attachments += [ + TelegramVideo( + id=update.video.file_id, + title=update.video.file_unique_id, + width=update.video.width, + height=update.video.height, + duration=update.video.duration, + file_name=update.video.file_name, + mime_type=update.video.mime_type, + thumbnail=thumbnail, + ) + ] + if update.animation is not None: + thumbnail = Image(id=update.animation.thumbnail.file_id, title=update.animation.thumbnail.file_unique_id) if update.animation.thumbnail is not None else None + message.attachments += [ + TelegramAnimation( + id=update.animation.file_id, + title=update.animation.file_unique_id, + width=update.animation.width, + height=update.animation.height, + duration=update.animation.duration, + file_name=update.animation.file_name, + mime_type=update.animation.mime_type, + thumbnail=thumbnail, + ) + ] + if len(update.photo) > 0: + message.attachments += [ + TelegramImage( + id=picture.file_id, + title=picture.file_unique_id, + width=picture.width, + height=picture.height, + ) for picture in update.photo + ] + if update.document is not None: + thumbnail = Image(id=update.document.thumbnail.file_id, title=update.document.thumbnail.file_unique_id) if update.document.thumbnail is not None else None + message.attachments += [ + TelegramDocument( + id=update.document.file_id, + title=update.document.file_unique_id, + file_name=update.document.file_name, + mime_type=update.document.mime_type, + thumbnail=thumbnail, + ) + ] + + return message + + def _create_keyboard( + self, buttons: Sequence[Sequence[Button]] + ) -> Optional[InlineKeyboardMarkup]: # pragma: no cover + button_list = None + if len(buttons) > 0: + button_list = [ + [ + InlineKeyboardButton( + text=button.text, callback_data=button.data if button.data is not None else button.text + ) + for button in row + ] + for row in buttons + ] + if button_list is None: + return None + else: + return InlineKeyboardMarkup(button_list) + + async def cast_message_to_telegram_and_send( + self, bot: ExtBot, chat_id: int, message: Message + ) -> None: # pragma: no cover + buttons = list() + if message.attachments is not None: + files = list() + for attachment in message.attachments: + if isinstance(attachment, Location): + await bot.send_location( + chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons) + ) + if isinstance(attachment, Contact): + await bot.send_contact( + chat_id, + attachment.phone_number, + attachment.first_name, + attachment.last_name, + reply_markup=self._create_keyboard(buttons), + ) + if isinstance(attachment, Poll): + await bot.send_poll( + chat_id, + attachment.question, + [option.text for option in attachment.options], + reply_markup=self._create_keyboard(buttons), + ) + if isinstance(attachment, Audio): + attachment_bytes = await attachment.get_bytes(self) + if attachment_bytes is not None: + files += [InputMediaAudio(attachment_bytes)] + if isinstance(attachment, Video): + attachment_bytes = await attachment.get_bytes(self) + if attachment_bytes is not None: + files += [InputMediaVideo(attachment_bytes)] + if isinstance(attachment, Animation): + attachment_bytes = await attachment.get_bytes(self) + if attachment_bytes is not None: + files += [InputMediaAnimation(attachment_bytes)] + if isinstance(attachment, Image): + attachment_bytes = await attachment.get_bytes(self) + if attachment_bytes is not None: + files += [InputMediaPhoto(attachment_bytes)] + if isinstance(attachment, Document): + attachment_bytes = await attachment.get_bytes(self) + if attachment_bytes is not None: + files += [InputMediaDocument(attachment_bytes)] + if isinstance(attachment, Keyboard): + buttons = attachment.buttons + if len(files) > 0: + await bot.send_media_group(chat_id, files, caption=message.text) + return + if message.text is not None: + await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) + + async def _on_event( + self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message] + ) -> None: + if update.effective_chat is not None and update.message is not None: + message = create_message(update) + message.original_message = update + resp = await self.callback(message, update.effective_chat.id) + if resp.last_response is not None: + await self.cast_message_to_telegram_and_send( + self.application.bot, update.effective_chat.id, resp.last_response + ) + + async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + await self._on_event(update, _, lambda u: self.extract_message_from_telegram(u.message)) + + async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: + await self._on_event( + update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)]) + ) + + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + self.callback = pipeline_runner diff --git a/dff/messengers/telegram/attachments.py b/dff/messengers/telegram/attachments.py new file mode 100644 index 000000000..4340ca996 --- /dev/null +++ b/dff/messengers/telegram/attachments.py @@ -0,0 +1,54 @@ +from typing import Optional + +from dff.script.core.message import Animation, Audio, Contact, Document, Image, Poll, Video + + +class TelegramContact(Contact): + user_id: Optional[int] + + +class TelegramPoll(Poll): + is_closed: bool + is_anonymous: bool + type: str + multiple_answers: bool + correct_option_id: Optional[int] + explanation: Optional[str] + open_period: Optional[int] + + +class TelegramAudio(Audio): + duration: int + performer: Optional[str] + file_name: Optional[str] + mime_type: Optional[str] + thumbnail: Optional[Image] + + +class TelegramVideo(Video): + width: int + height: int + duration: int + file_name: Optional[str] + mime_type: Optional[str] + thumbnail: Optional[Image] + + +class TelegramAnimation(Animation): + width: int + height: int + duration: int + file_name: Optional[str] + mime_type: Optional[str] + thumbnail: Optional[Image] + + +class TelegramImage(Image): + width: int + height: int + + +class TelegramDocument(Document): + file_name: Optional[str] + mime_type: Optional[str] + thumbnail: Optional[Image] diff --git a/dff/messengers/telegram/interface.py b/dff/messengers/telegram/interface.py new file mode 100644 index 000000000..76597a65e --- /dev/null +++ b/dff/messengers/telegram/interface.py @@ -0,0 +1,29 @@ +from telegram import Update + +from dff.pipeline.types import PipelineRunnerFunction + +from .abstract import _AbstractTelegramInterface + + +class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover + def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: + super().__init__(token) + self.interval = interval + self.timeout = timeout + + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + await super().connect(pipeline_runner, *args, **kwargs) + self.application.run_polling( + poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES + ) + + +class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover + def __init__(self, token: str, host: str = "localhost", port: int = 844): + super().__init__(token) + self.listen = host + self.port = port + + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): + await super().connect(pipeline_runner, *args, **kwargs) + self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) From 1432893e768ae9fccdca18cb16e6df4c1e48ccc0 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 10 Apr 2024 00:13:49 +0200 Subject: [PATCH 049/140] attachment subclasses moved to extras --- dff/messengers/telegram.py | 244 ------------------------- dff/messengers/telegram/abstract.py | 23 +-- dff/messengers/telegram/attachments.py | 54 ------ 3 files changed, 7 insertions(+), 314 deletions(-) delete mode 100644 dff/messengers/telegram.py delete mode 100644 dff/messengers/telegram/attachments.py diff --git a/dff/messengers/telegram.py b/dff/messengers/telegram.py deleted file mode 100644 index cdb9faeff..000000000 --- a/dff/messengers/telegram.py +++ /dev/null @@ -1,244 +0,0 @@ -""" -Interface ------------- -This module implements various interfaces for :py:class:`~dff.messengers.telegram.messenger.TelegramMessenger` -that can be used to interact with the Telegram API. -""" - -from pathlib import Path -from tempfile import gettempdir -from typing import Callable, Optional, Sequence -from pydantic import FilePath - -from telegram import ( - InlineKeyboardButton, - InlineKeyboardMarkup, - InputMediaAnimation, - InputMediaAudio, - InputMediaDocument, - InputMediaPhoto, - InputMediaVideo, - Update, - Message as TelegramMessage, -) -from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes -from telegram.ext.filters import ALL - -from dff.messengers.common import MessengerInterface -from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.message import ( - Animation, - Audio, - Button, - CallbackQuery, - Contact, - DataAttachment, - Document, - Image, - Invoice, - Keyboard, - Location, - Message, - Poll, - PollOption, - Video, -) - - -class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - request_attachments = {Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document} - response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} - - def __init__(self, token: str) -> None: - self.application = Application.builder().token(token).build() - self.application.add_handler(MessageHandler(ALL, self.on_message)) - self.application.add_handler(CallbackQueryHandler(self.on_callback)) - - async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover - if attachment.title is not None and attachment.id is not None: - file_name = Path(gettempdir()) / str(attachment.title) - if not file_name.exists(): - await (await self.application.bot.get_file(attachment.id)).download_to_drive(file_name) - attachment.source = FilePath(file_name) - else: - raise ValueError(f"For attachment {attachment} title or id is not defined!") - - def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover - message = Message() - message.attachments = list() - - if update.text is not None: - message.text = update.text - if update.location is not None: - message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] - if update.contact is not None: - message.attachments += [ - Contact( - phone_number=update.contact.phone_number, - first_name=update.contact.first_name, - last_name=update.contact.last_name, - ) - ] - if update.invoice is not None: - message.attachments += [ - Invoice( - title=update.invoice.title, - description=update.invoice.description, - currency=update.invoice.currency, - amount=update.invoice.total_amount, - ) - ] - if update.poll is not None: - message.attachments += [ - Poll( - question=update.poll.question, - options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options], - ) - ] - if update.audio is not None: - message.attachments += [ - Audio(id=update.audio.file_id, title=update.audio.file_unique_id, from_messenger_interface=self) - ] - if update.video is not None: - message.attachments += [ - Video(id=update.video.file_id, title=update.video.file_unique_id, from_messenger_interface=self) - ] - if update.animation is not None: - message.attachments += [ - Animation( - id=update.animation.file_id, title=update.animation.file_unique_id, from_messenger_interface=self - ) - ] - if len(update.photo) > 0: - message.attachments += [ - Image(id=picture.file_id, title=picture.file_unique_id, from_messenger_interface=self) - for picture in update.photo - ] - if update.document is not None: - message.attachments += [ - Document( - id=update.document.file_id, title=update.document.file_unique_id, from_messenger_interface=self - ) - ] - - return message - - def _create_keyboard( - self, buttons: Sequence[Sequence[Button]] - ) -> Optional[InlineKeyboardMarkup]: # pragma: no cover - button_list = None - if len(buttons) > 0: - button_list = [ - [ - InlineKeyboardButton( - text=button.text, callback_data=button.data if button.data is not None else button.text - ) - for button in row - ] - for row in buttons - ] - if button_list is None: - return None - else: - return InlineKeyboardMarkup(button_list) - - async def cast_message_to_telegram_and_send( - self, bot: ExtBot, chat_id: int, message: Message - ) -> None: # pragma: no cover - buttons = list() - if message.attachments is not None: - files = list() - for attachment in message.attachments: - if isinstance(attachment, Location): - await bot.send_location( - chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons) - ) - if isinstance(attachment, Contact): - await bot.send_contact( - chat_id, - attachment.phone_number, - attachment.first_name, - attachment.last_name, - reply_markup=self._create_keyboard(buttons), - ) - if isinstance(attachment, Poll): - await bot.send_poll( - chat_id, - attachment.question, - [option.text for option in attachment.options], - reply_markup=self._create_keyboard(buttons), - ) - if isinstance(attachment, Audio): - attachment_bytes = await attachment.get_bytes(self) - if attachment_bytes is not None: - files += [InputMediaAudio(attachment_bytes)] - if isinstance(attachment, Video): - attachment_bytes = await attachment.get_bytes(self) - if attachment_bytes is not None: - files += [InputMediaVideo(attachment_bytes)] - if isinstance(attachment, Animation): - attachment_bytes = await attachment.get_bytes(self) - if attachment_bytes is not None: - files += [InputMediaAnimation(attachment_bytes)] - if isinstance(attachment, Image): - attachment_bytes = await attachment.get_bytes(self) - if attachment_bytes is not None: - files += [InputMediaPhoto(attachment_bytes)] - if isinstance(attachment, Document): - attachment_bytes = await attachment.get_bytes(self) - if attachment_bytes is not None: - files += [InputMediaDocument(attachment_bytes)] - if isinstance(attachment, Keyboard): - buttons = attachment.buttons - if len(files) > 0: - await bot.send_media_group(chat_id, files, caption=message.text) - return - if message.text is not None: - await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) - - async def _on_event( - self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message] - ) -> None: - if update.effective_chat is not None and update.message is not None: - message = create_message(update) - message.original_message = update - resp = await self.callback(message, update.effective_chat.id) - if resp.last_response is not None: - await self.cast_message_to_telegram_and_send( - self.application.bot, update.effective_chat.id, resp.last_response - ) - - async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event(update, _, lambda u: self.extract_message_from_telegram(u.message)) - - async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event( - update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)]) - ) - - async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): - self.callback = pipeline_runner - - -class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: - super().__init__(token) - self.interval = interval - self.timeout = timeout - - async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): - await super().connect(pipeline_runner, *args, **kwargs) - self.application.run_polling( - poll_interval=self.interval, timeout=self.timeout, allowed_updates=Update.ALL_TYPES - ) - - -class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, host: str = "localhost", port: int = 844): - super().__init__(token) - self.listen = host - self.port = port - - async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): - await super().connect(pipeline_runner, *args, **kwargs) - self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index b23d06681..da0d2ab44 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -43,15 +43,6 @@ PollOption, Video, ) -from .attachments import ( - TelegramContact, - TelegramPoll, - TelegramAudio, - TelegramVideo, - TelegramAnimation, - TelegramImage, - TelegramDocument, -) class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover @@ -82,7 +73,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # message.attachments += [Location(latitude=update.location.latitude, longitude=update.location.longitude)] if update.contact is not None: message.attachments += [ - TelegramContact( + Contact( phone_number=update.contact.phone_number, first_name=update.contact.first_name, last_name=update.contact.last_name, @@ -100,7 +91,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # ] if update.poll is not None: message.attachments += [ - TelegramPoll( + Poll( question=update.poll.question, options=[PollOption(text=option.text, votes=option.voter_count) for option in update.poll.options], is_closed=update.poll.is_closed, @@ -115,7 +106,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # if update.audio is not None: thumbnail = Image(id=update.audio.thumbnail.file_id, title=update.audio.thumbnail.file_unique_id) if update.audio.thumbnail is not None else None message.attachments += [ - TelegramAudio( + Audio( id=update.audio.file_id, title=update.audio.file_unique_id, duration=update.audio.duration, @@ -128,7 +119,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # if update.video is not None: thumbnail = Image(id=update.video.thumbnail.file_id, title=update.video.thumbnail.file_unique_id) if update.video.thumbnail is not None else None message.attachments += [ - TelegramVideo( + Video( id=update.video.file_id, title=update.video.file_unique_id, width=update.video.width, @@ -142,7 +133,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # if update.animation is not None: thumbnail = Image(id=update.animation.thumbnail.file_id, title=update.animation.thumbnail.file_unique_id) if update.animation.thumbnail is not None else None message.attachments += [ - TelegramAnimation( + Animation( id=update.animation.file_id, title=update.animation.file_unique_id, width=update.animation.width, @@ -155,7 +146,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # ] if len(update.photo) > 0: message.attachments += [ - TelegramImage( + Image( id=picture.file_id, title=picture.file_unique_id, width=picture.width, @@ -165,7 +156,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # if update.document is not None: thumbnail = Image(id=update.document.thumbnail.file_id, title=update.document.thumbnail.file_unique_id) if update.document.thumbnail is not None else None message.attachments += [ - TelegramDocument( + Document( id=update.document.file_id, title=update.document.file_unique_id, file_name=update.document.file_name, diff --git a/dff/messengers/telegram/attachments.py b/dff/messengers/telegram/attachments.py deleted file mode 100644 index 4340ca996..000000000 --- a/dff/messengers/telegram/attachments.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import Optional - -from dff.script.core.message import Animation, Audio, Contact, Document, Image, Poll, Video - - -class TelegramContact(Contact): - user_id: Optional[int] - - -class TelegramPoll(Poll): - is_closed: bool - is_anonymous: bool - type: str - multiple_answers: bool - correct_option_id: Optional[int] - explanation: Optional[str] - open_period: Optional[int] - - -class TelegramAudio(Audio): - duration: int - performer: Optional[str] - file_name: Optional[str] - mime_type: Optional[str] - thumbnail: Optional[Image] - - -class TelegramVideo(Video): - width: int - height: int - duration: int - file_name: Optional[str] - mime_type: Optional[str] - thumbnail: Optional[Image] - - -class TelegramAnimation(Animation): - width: int - height: int - duration: int - file_name: Optional[str] - mime_type: Optional[str] - thumbnail: Optional[Image] - - -class TelegramImage(Image): - width: int - height: int - - -class TelegramDocument(Document): - file_name: Optional[str] - mime_type: Optional[str] - thumbnail: Optional[Image] From 1bfe52493224645d09195b6df9d20f85d94a7eac Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 11 Apr 2024 01:05:38 +0200 Subject: [PATCH 050/140] extras added --- dff/messengers/telegram/__init__.py | 9 --- dff/messengers/telegram/abstract.py | 99 ++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/dff/messengers/telegram/__init__.py b/dff/messengers/telegram/__init__.py index dd8a7cdfd..68ea21beb 100644 --- a/dff/messengers/telegram/__init__.py +++ b/dff/messengers/telegram/__init__.py @@ -1,12 +1,3 @@ # -*- coding: utf-8 -*- -from .attachments import ( - TelegramContact, - TelegramPoll, - TelegramAudio, - TelegramVideo, - TelegramAnimation, - TelegramImage, - TelegramDocument, -) from .interface import PollingTelegramInterface, CallbackTelegramInterface diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index da0d2ab44..5b8aa467f 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -175,7 +175,9 @@ def _create_keyboard( button_list = [ [ InlineKeyboardButton( - text=button.text, callback_data=button.data if button.data is not None else button.text + text=button.text, + url=button.__pydantic_extra__.get("url", None), + callback_data=button.data if button.data is not None else button.text, ) for button in row ] @@ -195,7 +197,13 @@ async def cast_message_to_telegram_and_send( for attachment in message.attachments: if isinstance(attachment, Location): await bot.send_location( - chat_id, attachment.latitude, attachment.longitude, reply_markup=self._create_keyboard(buttons) + chat_id, + attachment.latitude, + attachment.longitude, + horizontal_accuracy=attachment.__pydantic_extra__.get("horizontal_accuracy", None), + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + protect_content=attachment.__pydantic_extra__.get("protect_content", None), + reply_markup=self._create_keyboard(buttons) ) if isinstance(attachment, Contact): await bot.send_contact( @@ -203,6 +211,9 @@ async def cast_message_to_telegram_and_send( attachment.phone_number, attachment.first_name, attachment.last_name, + vcard=attachment.__pydantic_extra__.get("vcard", None), + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + protect_content=attachment.__pydantic_extra__.get("protect_content", None), reply_markup=self._create_keyboard(buttons), ) if isinstance(attachment, Poll): @@ -210,35 +221,105 @@ async def cast_message_to_telegram_and_send( chat_id, attachment.question, [option.text for option in attachment.options], + is_anonymous=attachment.__pydantic_extra__.get("is_anonymous", None), + type=attachment.__pydantic_extra__.get("type", None), + allows_multiple_answers=attachment.__pydantic_extra__.get("allows_multiple_answers", None), + correct_option_id=attachment.__pydantic_extra__.get("correct_option_id", None), + explanation=attachment.__pydantic_extra__.get("explanation", None), + explanation_parse_mode=attachment.__pydantic_extra__.get("explanation_parse_mode", None), + open_period=attachment.__pydantic_extra__.get("open_period", None), + is_close=attachment.__pydantic_extra__.get("is_close", None), + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + protect_content=attachment.__pydantic_extra__.get("protect_content", None), reply_markup=self._create_keyboard(buttons), ) if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [InputMediaAudio(attachment_bytes)] + files += [ + InputMediaAudio( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + performer=attachment.__pydantic_extra__.get("performer", None), + title=attachment.__pydantic_extra__.get("title", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] if isinstance(attachment, Video): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [InputMediaVideo(attachment_bytes)] + files += [ + InputMediaVideo( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + supports_streaming=attachment.__pydantic_extra__.get("supports_streaming", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] if isinstance(attachment, Animation): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [InputMediaAnimation(attachment_bytes)] + files += [ + InputMediaAnimation( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] if isinstance(attachment, Image): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [InputMediaPhoto(attachment_bytes)] + files += [ + InputMediaPhoto( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + ), + ] if isinstance(attachment, Document): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [InputMediaDocument(attachment_bytes)] + files += [ + InputMediaDocument( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + disable_content_type_detection=attachment.__pydantic_extra__.get("disable_content_type_detection", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] if isinstance(attachment, Keyboard): buttons = attachment.buttons if len(files) > 0: - await bot.send_media_group(chat_id, files, caption=message.text) + await bot.send_media_group( + chat_id, + files, + disable_notification=message.__pydantic_extra__.get("disable_notification", None), + protect_content=message.__pydantic_extra__.get("protect_content", None), + caption=message.text, + ) return if message.text is not None: - await bot.send_message(chat_id, message.text, reply_markup=self._create_keyboard(buttons)) + await bot.send_message( + chat_id, + message.text, + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + disable_notification=message.__pydantic_extra__.get("disable_notification", None), + protect_content=message.__pydantic_extra__.get("protect_content", None), + reply_markup=self._create_keyboard(buttons), + ) async def _on_event( self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message] From 82e7a3efe2288a79295973ffc53ca1c324d289a3 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 11 Apr 2024 10:15:18 +0200 Subject: [PATCH 051/140] lint fixed --- dff/messengers/telegram/abstract.py | 33 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 5b8aa467f..bda827a89 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -104,7 +104,11 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # ) ] if update.audio is not None: - thumbnail = Image(id=update.audio.thumbnail.file_id, title=update.audio.thumbnail.file_unique_id) if update.audio.thumbnail is not None else None + thumbnail = ( + Image(id=update.audio.thumbnail.file_id, title=update.audio.thumbnail.file_unique_id) + if update.audio.thumbnail is not None + else None + ) message.attachments += [ Audio( id=update.audio.file_id, @@ -117,7 +121,11 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # ) ] if update.video is not None: - thumbnail = Image(id=update.video.thumbnail.file_id, title=update.video.thumbnail.file_unique_id) if update.video.thumbnail is not None else None + thumbnail = ( + Image(id=update.video.thumbnail.file_id, title=update.video.thumbnail.file_unique_id) + if update.video.thumbnail is not None + else None + ) message.attachments += [ Video( id=update.video.file_id, @@ -131,7 +139,11 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # ) ] if update.animation is not None: - thumbnail = Image(id=update.animation.thumbnail.file_id, title=update.animation.thumbnail.file_unique_id) if update.animation.thumbnail is not None else None + thumbnail = ( + Image(id=update.animation.thumbnail.file_id, title=update.animation.thumbnail.file_unique_id) + if update.animation.thumbnail is not None + else None + ) message.attachments += [ Animation( id=update.animation.file_id, @@ -151,10 +163,15 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # title=picture.file_unique_id, width=picture.width, height=picture.height, - ) for picture in update.photo + ) + for picture in update.photo ] if update.document is not None: - thumbnail = Image(id=update.document.thumbnail.file_id, title=update.document.thumbnail.file_unique_id) if update.document.thumbnail is not None else None + thumbnail = ( + Image(id=update.document.thumbnail.file_id, title=update.document.thumbnail.file_unique_id) + if update.document.thumbnail is not None + else None + ) message.attachments += [ Document( id=update.document.file_id, @@ -203,7 +220,7 @@ async def cast_message_to_telegram_and_send( horizontal_accuracy=attachment.__pydantic_extra__.get("horizontal_accuracy", None), disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=self._create_keyboard(buttons) + reply_markup=self._create_keyboard(buttons), ) if isinstance(attachment, Contact): await bot.send_contact( @@ -296,7 +313,9 @@ async def cast_message_to_telegram_and_send( filename=attachment.__pydantic_extra__.get("filename", None), caption=attachment.__pydantic_extra__.get("caption", None), parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - disable_content_type_detection=attachment.__pydantic_extra__.get("disable_content_type_detection", None), + disable_content_type_detection=attachment.__pydantic_extra__.get( + "disable_content_type_detection", None + ), thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), ), ] From 2eb8f9578970b8ac6fd7a97bf64f213b17e2af06 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:53:24 +0300 Subject: [PATCH 052/140] feat/Implemented VK_Bot class, working on VK_dummy test class --- dff/messengers/vk.py | 65 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index a93694b38..db247d236 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -41,6 +41,11 @@ def extract_vk_update(update): return message, int(id) +class VK_Poll(): + def __init__(self) -> None: + raise NotImplementedError() + + class FilesOpener(object): def __init__(self, paths, key_format='file{}'): if not isinstance(paths, list): @@ -87,9 +92,8 @@ def close_files(self): self.opened_files = [] -class PollingVKInterface(PollingMessengerInterface): +class VK_Bot: def __init__(self, token: str, group_id: str) -> None: - super().__init__() self.token = token self.group_id = group_id server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() @@ -103,8 +107,7 @@ def __init__(self, token: str, group_id: str) -> None: self.server_key = server_request['response']['key'] self.last_update_id = None self._last_processed_update = None - - + def upload_attachment( self, peer_id, attachment, attachment_type: str ) -> str: @@ -184,9 +187,17 @@ def upload_attachment( return saved_doc_data["response"] elif attachment_type == "video": - vid = requests.post(f"https://api.vk.com/method/video.save?link={attachment.source}&group_id={self.group_id}&v=5.81&access_token={self.token}").json()["response"] - return vid - + raise NotImplementedError() + + def request(self): + updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() + self.ts_current = updates['ts'] + update_list = [] + for i in updates["updates"]: + update_list.append( + extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) + ) + return update_list def send_message(self, response, id): if response.attachments is not None: @@ -208,7 +219,7 @@ def send_message(self, response, id): response.text += f"[{attachment.source}|{attachment.title}]" elif isinstance(attachment, Poll): - poll_obj = requests.post(f"https://api.vk.com/method/polls.create?question={attachment.question}&is_anonymous={attachment.is_anonymous}&is_multiple={attachment.is_multiple}&end_date={attachment.end_date}&owner_id=-{self.group_id}&add_answers={attachment.add_answers}&photo_id={attachment.photo_id}&background_id={attachment.background_id}&disable_unvote={attachment.disable_unvote}&v=5.81&access_token={self.token}").json() + raise NotImplementedError() attachment_string = ','.join(attachment_list).strip(',') @@ -217,21 +228,51 @@ def send_message(self, response, id): requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}").json() - def _request(self): + +class VK_dummy(VK_Bot): + # functionality of the VK_Bot but without actual API calls + def __init__(self, token, group_id) -> None: + self.token = token + self.group_id = group_id + server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + if "response" not in server_request: + raise Exception(f"Errror getting longpoll server\n{server_request}") + + self.server = server_request['response']['server'] + self.ts_base = int(server_request['response']['ts']) + self.ts_current = self.ts_base + self.server_key = server_request['response']['key'] + self.bot_responses = [] + self.requests = [] + + def request(self): updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() - self.ts_current = updates['ts'] update_list = [] for i in updates["updates"]: update_list.append( extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) ) - return update_list + self.requests.append(update_list[-1]) + + def send_message(self, response, id): + self.bot_responses.append(response) + + +class PollingVKInterface(PollingMessengerInterface): + def __init__(self, token: str, group_id: str) -> None: + super().__init__() + self.bot = VK_Bot(token, group_id) + + + def _request(self): + return self.bot.request() def _respond(self, response): for resp in response: - self.send_message(resp.last_response, resp.id) + self.bot.send_message(resp.last_response, resp.id) logger.info("Responded.") From 1866008e011306ff881e7970dabc4d94976ec217 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:11:22 +0300 Subject: [PATCH 053/140] Updated VK_dummy --- dff/messengers/vk.py | 52 +++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index db247d236..017ecc656 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -228,44 +228,46 @@ def send_message(self, response, id): requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}").json() - -class VK_dummy(VK_Bot): +class VK_dummy: # functionality of the VK_Bot but without actual API calls - def __init__(self, token, group_id) -> None: - self.token = token - self.group_id = group_id - server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - if "response" not in server_request: - raise Exception(f"Errror getting longpoll server\n{server_request}") - - self.server = server_request['response']['server'] - self.ts_base = int(server_request['response']['ts']) - self.ts_current = self.ts_base - self.server_key = server_request['response']['key'] + def __init__(self, *args) -> None: self.bot_responses = [] self.requests = [] - def request(self): - updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() - update_list = [] - for i in updates["updates"]: - update_list.append( - extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) - ) - self.requests.append(update_list[-1]) + def request(self, req): + # updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() + # update_list = [] + # for i in updates["updates"]: + # update_list.append( + # extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) + # ) + self.requests.append(req) + return [req] - def send_message(self, response, id): + def send_message(self, response, _): self.bot_responses.append(response) + return response + + def get_dialogue(self): + return zip(self.requests, self.bot_responses) class PollingVKInterface(PollingMessengerInterface): - def __init__(self, token: str, group_id: str) -> None: + def __init__(self, token: str, group_id: str, debug=True, test_path=None) -> None: super().__init__() - self.bot = VK_Bot(token, group_id) + self.test_path = test_path + self.debug = debug + self.step = -1 + if not debug: + self.bot = VK_Bot(token, group_id) + else: + self.bot = VK_dummy(token, group_id) def _request(self): + if self.debug: + self.step += 1 + return self.bot.request(self.test_path[self.step][0]) return self.bot.request() From 72bb23f3132d1cd225522740580083eb730918cc Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:12:09 +0300 Subject: [PATCH 054/140] Added vk_dummy_example.py --- dff/messengers/vk_dummy_example.py | 84 ++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 dff/messengers/vk_dummy_example.py diff --git a/dff/messengers/vk_dummy_example.py b/dff/messengers/vk_dummy_example.py new file mode 100644 index 000000000..536aaf9e0 --- /dev/null +++ b/dff/messengers/vk_dummy_example.py @@ -0,0 +1,84 @@ +from vk import PollingVKInterface +from dff.utils.testing import ( + check_happy_path, + is_interactive_mode, + run_interactive_mode, +) +from dff.script import Message +from dff.script.conditions import exact_match +from dff.script import RESPONSE, TRANSITIONS +from dff.pipeline import Pipeline + + +toy_script = { + "greeting_flow": { + "start_node": { + RESPONSE: Message(text=""), + TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, + }, + "node1": { + RESPONSE: Message(text="Hi, how are you?"), + TRANSITIONS: { + "node2": exact_match(Message(text="i'm fine, how are you?")) + }, + }, + "node2": { + RESPONSE: Message(text="Good. What do you want to talk about?"), + TRANSITIONS: { + "node3": exact_match(Message(text="Let's talk about music.")) + }, + }, + "node3": { + RESPONSE: Message(text="Sorry, I can not talk about music now."), + TRANSITIONS: {"node4": exact_match(Message(text="Ok, goodbye."))}, + }, + "node4": { + RESPONSE: Message(text="bye"), + TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, + }, + "fallback_node": { + RESPONSE: Message(text="Ooops"), + TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, + }, + } +} + +happy_path = ( + (Message(text="Hi"), Message(text="Hi, how are you?")), + ( + Message(text="i'm fine, how are you?"), + Message(text="Good. What do you want to talk about?"), + ), + ( + Message(text="Let's talk about music."), + Message(text="Sorry, I can not talk about music now."), + ), + (Message(text="Ok, goodbye."), Message(text="bye")), + (Message(text="Hi"), Message(text="Hi, how are you?")), + (Message(text="stop"), Message(text="Ooops")), + (Message(text="stop"), Message(text="Ooops")), + (Message(text="Hi"), Message(text="Hi, how are you?")), + ( + Message(text="i'm fine, how are you?"), + Message(text="Good. What do you want to talk about?"), + ), + ( + Message(text="Let's talk about music."), + Message(text="Sorry, I can not talk about music now."), + ), + (Message(text="Ok, goodbye."), Message(text="bye")), +) + +test_dialogue = [] + +test_interface = PollingVKInterface("token", "id", debug=True, test_path=happy_path) + +pipeline = Pipeline.from_script( + script=toy_script, + start_label=("greeting_flow", "start_node"), + fallback_label=("greeting_flow", "fallback_node"), + messenger_interface=test_interface +) + +def main(): + pipeline.run() From 334cd745f80c3e3be43d52f39e2224d88c94f7fe Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:29:36 +0200 Subject: [PATCH 055/140] ui replaced with keyboard --- tutorials/script/responses/2_buttons.py | 88 ++++++++++--------------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/tutorials/script/responses/2_buttons.py b/tutorials/script/responses/2_buttons.py index 8d8635eb3..f12a73675 100644 --- a/tutorials/script/responses/2_buttons.py +++ b/tutorials/script/responses/2_buttons.py @@ -29,8 +29,8 @@ class is demonstrated. # %% def check_button_payload(value: str): def payload_check_inner(ctx: Context, _: Pipeline): - if ctx.last_request.misc is not None: - return ctx.last_request.misc.get("payload") == value + if ctx.last_request.text is not None: + return ctx.last_request.text == value else: return False @@ -54,8 +54,8 @@ def payload_check_inner(ctx: Context, _: Pipeline): **{ "text": "Starting test! What's 2 + 2?" " (type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="5", data="5"), @@ -63,7 +63,7 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), TRANSITIONS: { @@ -76,8 +76,8 @@ def payload_check_inner(ctx: Context, _: Pipeline): **{ "text": "Next question: what's 6 * 8?" " (type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="38", data="38"), @@ -85,7 +85,7 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), TRANSITIONS: { @@ -98,8 +98,8 @@ def payload_check_inner(ctx: Context, _: Pipeline): **{ "text": "What's 114 + 115? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="229", data="229"), @@ -107,7 +107,7 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), TRANSITIONS: { @@ -129,8 +129,8 @@ def payload_check_inner(ctx: Context, _: Pipeline): **{ "text": "Starting test! What's 2 + 2? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="5", data="5"), @@ -138,18 +138,18 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ) - }, + ], } ), ), ( - Message("0"), + Message("5"), Message( **{ "text": "Starting test! What's 2 + 2? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="5", data="5"), @@ -157,18 +157,18 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), ), ( - Message("1"), + Message("4"), Message( **{ "text": "Next question: what's 6 * 8? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="38", data="38"), @@ -176,18 +176,18 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), ), ( - Message("0"), + Message("38"), Message( **{ "text": "Next question: what's 6 * 8? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="38", data="38"), @@ -195,18 +195,18 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), ), ( - Message("1"), + Message("48"), Message( **{ "text": "What's 114 + 115? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="229", data="229"), @@ -214,18 +214,18 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), ), ( - Message("1"), + Message("283"), Message( **{ "text": "What's 114 + 115? " "(type in the index of the correct option)", - "misc": { - "ui": Keyboard( + "attachments": [ + Keyboard( buttons=[ [ Button(text="229", data="229"), @@ -233,38 +233,20 @@ def payload_check_inner(ctx: Context, _: Pipeline): ] ] ), - }, + ], } ), ), - (Message("0"), Message("Success!")), + (Message("229"), Message("Success!")), (Message("ok"), Message("Finishing test")), ) -def process_request(ctx: Context): - ui = ( - ctx.last_response - and ctx.last_response.misc - and ctx.last_response.misc.get("ui") - ) - if ui and ui.buttons[0]: - try: - chosen_button = ui.buttons[0][int(ctx.last_request.text)] - except (IndexError, ValueError): - raise ValueError( - "Type in the index of the correct option " - "to choose from the buttons." - ) - ctx.last_request = Message(misc={"payload": chosen_button.data}) - - # %% pipeline = Pipeline.from_script( toy_script, start_label=("root", "start"), fallback_label=("root", "fallback"), - pre_services=[process_request], ) if __name__ == "__main__": From bc406f6c4920ca6ea64fcadc2acf8b601c54be53 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:32:04 +0200 Subject: [PATCH 056/140] "check_if_" removed --- tutorials/messengers/telegram/4_conditions.py | 4 ++-- .../messengers/telegram/5_conditions_with_media.py | 12 ++++++------ tutorials/messengers/telegram/6_conditions_extras.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index 4b2937e94..5e03f52a0 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -53,7 +53,7 @@ # %% -def check_if_latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: +def latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -84,7 +84,7 @@ def check_if_latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: }, "node2": { RESPONSE: Message(text="Good. What do you want to talk about?"), - TRANSITIONS: {"node3": check_if_latest_message_test_has_music}, + TRANSITIONS: {"node3": latest_message_test_has_music}, }, "node3": { RESPONSE: Message(text="Sorry, I can not talk about music now."), diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index fb6602f37..5c26deb2c 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -49,7 +49,7 @@ interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) -def check_if_latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: +def latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -61,7 +61,7 @@ def check_if_latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: return len(ctx.last_request.original_message.message.photo) > 0 -def check_if_latest_message_has_images(ctx: Context, _: Pipeline) -> bool: +def latest_message_has_images(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -76,7 +76,7 @@ def check_if_latest_message_has_images(ctx: Context, _: Pipeline) -> bool: ) -def check_if_latest_message_has_text(ctx: Context, _: Pipeline) -> bool: +def latest_message_has_text(ctx: Context, _: Pipeline) -> bool: if ctx.last_request is None: return False if ctx.last_request.original_message is None: @@ -123,14 +123,14 @@ def check_if_latest_message_has_text(ctx: Context, _: Pipeline) -> bool: # both in 'photo' and 'document' fields. # We should consider both cases # when we check the message for media. - check_if_latest_message_has_photos, - check_if_latest_message_has_images, + latest_message_has_photos, + latest_message_has_images, ] ), ( "pics", "send_many", - ): check_if_latest_message_has_text, + ): latest_message_has_text, ("pics", "ask_picture"): cnd.true(), }, }, diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py index ed9d5b2ff..f74faa993 100644 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ b/tutorials/messengers/telegram/6_conditions_extras.py @@ -56,7 +56,7 @@ # %% -def check_if_latest_message_is_new_chat_member( +def latest_message_is_new_chat_member( ctx: Context, _: Pipeline ) -> bool: if ctx.last_request is None: @@ -70,7 +70,7 @@ def check_if_latest_message_is_new_chat_member( ) -def check_if_latest_message_is_callback_query( +def latest_message_is_callback_query( ctx: Context, _: Pipeline ) -> bool: if ctx.last_request is None: @@ -88,12 +88,12 @@ def check_if_latest_message_is_callback_query( ( "greeting_flow", "node1", - ): check_if_latest_message_is_new_chat_member, + ): latest_message_is_new_chat_member, # send a message when inline query is received ( "greeting_flow", "node2", - ): check_if_latest_message_is_callback_query, + ): latest_message_is_callback_query, }, }, "greeting_flow": { From b08e8f370f8d50e26dc619a8681402b8c91987f6 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:34:27 +0200 Subject: [PATCH 057/140] undefined message removed --- dff/messengers/telegram/abstract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index bda827a89..847341ba4 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -334,7 +334,7 @@ async def cast_message_to_telegram_and_send( await bot.send_message( chat_id, message.text, - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + parse_mode=message.__pydantic_extra__.get("parse_mode", None), disable_notification=message.__pydantic_extra__.get("disable_notification", None), protect_content=message.__pydantic_extra__.get("protect_content", None), reply_markup=self._create_keyboard(buttons), From c79a732ded736bc360628cc2d5a348b4df307841 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:37:26 +0200 Subject: [PATCH 058/140] unnecessary type casting removed --- tutorials/messengers/telegram/5_conditions_with_media.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py index 5c26deb2c..646df8f39 100644 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ b/tutorials/messengers/telegram/5_conditions_with_media.py @@ -146,7 +146,7 @@ def latest_message_has_text(ctx: Context, _: Pipeline) -> bool: RESPONSE: Message( text="Look at my pictures!", # An HTTP path or a path to a local file can be used here. - attachments=list(tuple([Image(source=picture_url)] * 2)), + attachments=[Image(source=picture_url)] * 2, ), TRANSITIONS: {("root", "fallback"): cnd.true()}, }, From 7853dbc19c17856237d446f4d012d700e609b224 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:39:06 +0200 Subject: [PATCH 059/140] args and kwargs removed --- tutorials/messengers/telegram/4_conditions.py | 4 ++-- tutorials/utils/1_cache.py | 2 +- tutorials/utils/2_lru_cache.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py index 5e03f52a0..38d65d894 100644 --- a/tutorials/messengers/telegram/4_conditions.py +++ b/tutorials/messengers/telegram/4_conditions.py @@ -88,12 +88,12 @@ def latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: }, "node3": { RESPONSE: Message(text="Sorry, I can not talk about music now."), - TRANSITIONS: {"node4": lambda _, __, ___, ____: True}, + TRANSITIONS: {"node4": lambda _, __: True}, # This condition is true for any type of update }, "node4": { RESPONSE: Message(text="bye"), - TRANSITIONS: {"node1": lambda _, __, ___, ____: True}, + TRANSITIONS: {"node1": lambda _, __: True}, # This condition is true if the last update is of type `message` }, "fallback_node": { diff --git a/tutorials/utils/1_cache.py b/tutorials/utils/1_cache.py index 871c9a939..c6d02bc0a 100644 --- a/tutorials/utils/1_cache.py +++ b/tutorials/utils/1_cache.py @@ -47,7 +47,7 @@ def cached_response(_): return external_data["counter"] -def response(ctx: Context, _, *__, **___) -> Message: +def response(ctx: Context, _) -> Message: if ctx.validation: return Message() return Message( diff --git a/tutorials/utils/2_lru_cache.py b/tutorials/utils/2_lru_cache.py index 40e59715f..f6d735dc8 100644 --- a/tutorials/utils/2_lru_cache.py +++ b/tutorials/utils/2_lru_cache.py @@ -46,7 +46,7 @@ def cached_response(_): return external_data["counter"] -def response(ctx: Context, _, *__, **___) -> Message: +def response(ctx: Context, _) -> Message: if ctx.validation: return Message() return Message( From 5b9992f3eb7fb0654d100ac1f95f06ffd8344659 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:42:05 +0200 Subject: [PATCH 060/140] default poll option voter count added --- dff/script/core/message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index abc4f52a8..91e8e60d4 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -82,7 +82,7 @@ class Invoice(Attachment): class PollOption(DataModel): text: str - votes: int + votes: int = Field(default=0) class Poll(Attachment): From a3beac94c16a7db5b022a39a06ba4e755e0ed145 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:47:58 +0200 Subject: [PATCH 061/140] telegram import check added --- dff/messengers/telegram/abstract.py | 72 ++++++++++++++++------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 847341ba4..ecdb7c758 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -10,39 +10,44 @@ from typing import Callable, Optional, Sequence from pydantic import FilePath -from telegram import ( - InlineKeyboardButton, - InlineKeyboardMarkup, - InputMediaAnimation, - InputMediaAudio, - InputMediaDocument, - InputMediaPhoto, - InputMediaVideo, - Update, - Message as TelegramMessage, -) -from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes -from telegram.ext.filters import ALL +try: + from telegram import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + InputMediaAnimation, + InputMediaAudio, + InputMediaDocument, + InputMediaPhoto, + InputMediaVideo, + Update, + Message as TelegramMessage, + ) + from telegram.ext import Application, ExtBot, MessageHandler, CallbackQueryHandler, ContextTypes + from telegram.ext.filters import ALL -from dff.messengers.common import MessengerInterface -from dff.pipeline.types import PipelineRunnerFunction -from dff.script.core.message import ( - Animation, - Audio, - Button, - CallbackQuery, - Contact, - DataAttachment, - Document, - Image, - Invoice, - Keyboard, - Location, - Message, - Poll, - PollOption, - Video, -) + from dff.messengers.common import MessengerInterface + from dff.pipeline.types import PipelineRunnerFunction + from dff.script.core.message import ( + Animation, + Audio, + Button, + CallbackQuery, + Contact, + DataAttachment, + Document, + Image, + Invoice, + Keyboard, + Location, + Message, + Poll, + PollOption, + Video, + ) + + telegram_available = True +except ImportError: + telegram_available = False class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover @@ -50,6 +55,9 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} def __init__(self, token: str) -> None: + if not telegram_available: + raise ImportError("`python-telegram-bot` package is missing.\nTry to run `pip install dff[telegram]`.") + self.application = Application.builder().token(token).build() self.application.add_handler(MessageHandler(ALL, self.on_message)) self.application.add_handler(CallbackQueryHandler(self.on_callback)) From 5dd075152e78982d8ae6600d3b9e123e832447c1 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:49:18 +0200 Subject: [PATCH 062/140] interface attachments sorted --- dff/messengers/telegram/abstract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index ecdb7c758..564c62e99 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -51,7 +51,7 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - request_attachments = {Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document} + request_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Invoice} response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} def __init__(self, token: str) -> None: From b9517724df677d15a7cf850ce64cb9aad64250db Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 16 Apr 2024 23:58:13 +0200 Subject: [PATCH 063/140] temp attachment dir warning added --- dff/messengers/common/interface.py | 9 +++++++++ dff/messengers/telegram/abstract.py | 6 +++--- dff/messengers/telegram/interface.py | 10 ++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 1530d630e..2c80e968a 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -9,6 +9,8 @@ import abc import asyncio import logging +from pathlib import Path +from tempfile import gettempdir from typing import Optional, Any, List, Tuple, Hashable, TYPE_CHECKING if TYPE_CHECKING: @@ -29,6 +31,13 @@ class MessengerInterface(abc.ABC): request_attachments = set() response_attachments = set() + def __init__(self, attachments_directory: Optional[Path] = None) -> None: + if attachments_directory is not None: + self.attachments_directory = attachments_directory + else: + self.attachments_directory = Path(gettempdir()) + logger.warning(f"Attachments directory for {type(self)} messenger interface is set to tempdir!") + @abc.abstractmethod async def connect(self, pipeline_runner: PipelineRunnerFunction): """ diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 564c62e99..81de01615 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -6,7 +6,6 @@ """ from pathlib import Path -from tempfile import gettempdir from typing import Callable, Optional, Sequence from pydantic import FilePath @@ -54,7 +53,8 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover request_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Invoice} response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} - def __init__(self, token: str) -> None: + def __init__(self, token: str, attachments_directory: Optional[Path] = None) -> None: + super().__init__(attachments_directory) if not telegram_available: raise ImportError("`python-telegram-bot` package is missing.\nTry to run `pip install dff[telegram]`.") @@ -64,7 +64,7 @@ def __init__(self, token: str) -> None: async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover if attachment.title is not None and attachment.id is not None: - file_name = Path(gettempdir()) / str(attachment.title) + file_name = self.attachments_directory / str(attachment.title) if not file_name.exists(): await (await self.application.bot.get_file(attachment.id)).download_to_drive(file_name) attachment.source = FilePath(file_name) diff --git a/dff/messengers/telegram/interface.py b/dff/messengers/telegram/interface.py index 76597a65e..6234956b4 100644 --- a/dff/messengers/telegram/interface.py +++ b/dff/messengers/telegram/interface.py @@ -1,3 +1,5 @@ +from pathlib import Path +from typing import Optional from telegram import Update from dff.pipeline.types import PipelineRunnerFunction @@ -6,8 +8,8 @@ class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, interval: int = 2, timeout: int = 20) -> None: - super().__init__(token) + def __init__(self, token: str, attachments_directory: Optional[Path] = None, interval: int = 2, timeout: int = 20) -> None: + super().__init__(token, attachments_directory) self.interval = interval self.timeout = timeout @@ -19,8 +21,8 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, host: str = "localhost", port: int = 844): - super().__init__(token) + def __init__(self, token: str, attachments_directory: Optional[Path] = None, host: str = "localhost", port: int = 844): + super().__init__(token, attachments_directory) self.listen = host self.port = port From fe99c4c05523e116fbda50e65fa6626cb9ca7566 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 17 Apr 2024 00:06:12 +0200 Subject: [PATCH 064/140] attachment message clarified --- dff/messengers/common/interface.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 2c80e968a..f820b0e5a 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -32,11 +32,18 @@ class MessengerInterface(abc.ABC): response_attachments = set() def __init__(self, attachments_directory: Optional[Path] = None) -> None: - if attachments_directory is not None: + tempdir = gettempdir() + if attachments_directory is not None and not str(attachments_directory.absolute()).startswith(tempdir): self.attachments_directory = attachments_directory else: - self.attachments_directory = Path(gettempdir()) - logger.warning(f"Attachments directory for {type(self)} messenger interface is set to tempdir!") + warning_start = f"Attachments directory for {type(self)} messenger interface" + warning_end = "attachment data won't be preserved locally!" + if attachments_directory is None: + self.attachments_directory = Path(tempdir) + logger.warning(f"{warning_start} is None, so will be set to tempdir and {warning_end}") + else: + self.attachments_directory = attachments_directory + logger.warning(f"{warning_start} is in tempdir, so {warning_end}") @abc.abstractmethod async def connect(self, pipeline_runner: PipelineRunnerFunction): From 595d55d8e43a5279c92f386a691e4ceb3eb2e4ac Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 18 Apr 2024 10:57:38 +0200 Subject: [PATCH 065/140] single attachment sending proposal + sticker --- dff/messengers/telegram/abstract.py | 196 +++++++++++++++++----------- dff/script/core/message.py | 38 +----- 2 files changed, 129 insertions(+), 105 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index bda827a89..9df97a32a 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -7,12 +7,10 @@ from pathlib import Path from tempfile import gettempdir -from typing import Callable, Optional, Sequence +from typing import Callable from pydantic import FilePath from telegram import ( - InlineKeyboardButton, - InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, @@ -29,18 +27,17 @@ from dff.script.core.message import ( Animation, Audio, - Button, CallbackQuery, Contact, DataAttachment, Document, Image, Invoice, - Keyboard, Location, Message, Poll, PollOption, + Sticker, Video, ) @@ -184,31 +181,9 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # return message - def _create_keyboard( - self, buttons: Sequence[Sequence[Button]] - ) -> Optional[InlineKeyboardMarkup]: # pragma: no cover - button_list = None - if len(buttons) > 0: - button_list = [ - [ - InlineKeyboardButton( - text=button.text, - url=button.__pydantic_extra__.get("url", None), - callback_data=button.data if button.data is not None else button.text, - ) - for button in row - ] - for row in buttons - ] - if button_list is None: - return None - else: - return InlineKeyboardMarkup(button_list) - async def cast_message_to_telegram_and_send( self, bot: ExtBot, chat_id: int, message: Message ) -> None: # pragma: no cover - buttons = list() if message.attachments is not None: files = list() for attachment in message.attachments: @@ -220,7 +195,7 @@ async def cast_message_to_telegram_and_send( horizontal_accuracy=attachment.__pydantic_extra__.get("horizontal_accuracy", None), disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=self._create_keyboard(buttons), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), ) if isinstance(attachment, Contact): await bot.send_contact( @@ -231,7 +206,7 @@ async def cast_message_to_telegram_and_send( vcard=attachment.__pydantic_extra__.get("vcard", None), disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=self._create_keyboard(buttons), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), ) if isinstance(attachment, Poll): await bot.send_poll( @@ -245,82 +220,157 @@ async def cast_message_to_telegram_and_send( explanation=attachment.__pydantic_extra__.get("explanation", None), explanation_parse_mode=attachment.__pydantic_extra__.get("explanation_parse_mode", None), open_period=attachment.__pydantic_extra__.get("open_period", None), - is_close=attachment.__pydantic_extra__.get("is_close", None), + is_closed=attachment.__pydantic_extra__.get("is_closed", None), disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=self._create_keyboard(buttons), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + ) + if isinstance(attachment, Sticker): + sticker = await attachment.get_bytes(self) if attachment.id is None else attachment.id + await bot.send_sticker( + chat_id, + sticker, + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + emoji=attachment.__pydantic_extra__.get("emoji", None), ) if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [ - InputMediaAudio( - attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + if len(message.attachments) > 1: + files += [ + InputMediaAudio( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + performer=attachment.__pydantic_extra__.get("performer", None), + title=attachment.__pydantic_extra__.get("title", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] + else: + await bot.send_audio( + chat_id, + audio=attachment_bytes, performer=attachment.__pydantic_extra__.get("performer", None), title=attachment.__pydantic_extra__.get("title", None), + caption=message.text, + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - ), - ] + ) + return if isinstance(attachment, Video): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [ - InputMediaVideo( + if len(message.attachments) > 1: + files += [ + InputMediaVideo( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + supports_streaming=attachment.__pydantic_extra__.get("supports_streaming", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] + else: + await bot.send_video( + chat_id, attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), + caption=message.text, + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), supports_streaming=attachment.__pydantic_extra__.get("supports_streaming", None), has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - ), - ] + filename=attachment.__pydantic_extra__.get("filename", None), + ) + return if isinstance(attachment, Animation): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [ - InputMediaAnimation( + if len(message.attachments) > 1: + files += [ + InputMediaAnimation( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] + else: + await bot.send_animation( + chat_id, attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), + caption=message.text, parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - ), - ] + filename=attachment.__pydantic_extra__.get("filename", None), + ) + return if isinstance(attachment, Image): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [ - InputMediaPhoto( + if len(message.attachments) > 1: + files += [ + InputMediaPhoto( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + ), + ] + else: + await bot.send_photo( + chat_id, attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), + caption=message.text, + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - ), - ] + filename=attachment.__pydantic_extra__.get("filename", None), + ) + return if isinstance(attachment, Document): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - files += [ - InputMediaDocument( + if len(message.attachments) > 1: + files += [ + InputMediaDocument( + attachment_bytes, + filename=attachment.__pydantic_extra__.get("filename", None), + caption=attachment.__pydantic_extra__.get("caption", None), + parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + disable_content_type_detection=attachment.__pydantic_extra__.get( + "disable_content_type_detection", None + ), + thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + ), + ] + else: + await bot.send_document( + chat_id, attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), + caption=message.text, + disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), + reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - disable_content_type_detection=attachment.__pydantic_extra__.get( - "disable_content_type_detection", None - ), thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - ), - ] - if isinstance(attachment, Keyboard): - buttons = attachment.buttons + filename=attachment.__pydantic_extra__.get("filename", None), + ) + return if len(files) > 0: await bot.send_media_group( chat_id, @@ -334,10 +384,10 @@ async def cast_message_to_telegram_and_send( await bot.send_message( chat_id, message.text, - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), + parse_mode=message.__pydantic_extra__.get("parse_mode", None), disable_notification=message.__pydantic_extra__.get("disable_notification", None), protect_content=message.__pydantic_extra__.get("protect_content", None), - reply_markup=self._create_keyboard(buttons), + reply_markup=message.__pydantic_extra__.get("reply_markup", None), ) async def _on_event( @@ -346,7 +396,7 @@ async def _on_event( if update.effective_chat is not None and update.message is not None: message = create_message(update) message.original_message = update - resp = await self.callback(message, update.effective_chat.id) + resp = await self.pipeline_runner(message, update.effective_chat.id) if resp.last_response is not None: await self.cast_message_to_telegram_and_send( self.application.bot, update.effective_chat.id, resp.last_response @@ -361,4 +411,4 @@ async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> Non ) async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): - self.callback = pipeline_runner + self.pipeline_runner = pipeline_runner diff --git a/dff/script/core/message.py b/dff/script/core/message.py index abc4f52a8..4702f8f87 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -10,7 +10,7 @@ from pathlib import Path from urllib.request import urlopen -from pydantic import field_validator, Field, FilePath, HttpUrl, BaseModel, model_validator +from pydantic import field_validator, FilePath, HttpUrl, BaseModel, model_validator from dff.messengers.common.interface import MessengerInterface @@ -162,42 +162,16 @@ class Image(DataAttachment): pass -class Document(DataAttachment): - """Represents a document file attachment.""" +class Sticker(Image): + """Represents a sticker as a file attachment.""" pass -class Button(DataModel): - """Represents a button of an inline keyboard.""" - - text: str - data: Optional[str] = None - - @field_validator("data") - @classmethod - def data_length_should_be_constrained(cls, value: Optional[str]) -> Optional[str]: - if value is None: - return value - value_size = len(value.encode("utf-8")) - if 1 <= value_size <= 64 and value: - return value - else: - raise ValueError(f"Unexpected data length: {value_size} bytes") - - -class Keyboard(Attachment): - """ - This class is an Attachment that represents a keyboard object - that can be used for a chatbot or messaging application. - """ - - buttons: List[List[Button]] = Field(default_factory=list, min_length=1) +class Document(DataAttachment): + """Represents a document file attachment.""" - def __eq__(self, other): - if isinstance(other, Keyboard): - return self.buttons == other.buttons - return NotImplemented + pass class Message(DataModel): From b31ea18df88bf4374162d6f68acd2adcc2f5d757 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 18 Apr 2024 11:06:03 +0200 Subject: [PATCH 066/140] request and response attachments sorted --- dff/messengers/telegram/abstract.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 9df97a32a..53d5a0081 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -43,8 +43,8 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - request_attachments = {Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Document} - response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Keyboard} + request_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Invoice} + response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document} def __init__(self, token: str) -> None: self.application = Application.builder().token(token).build() From 084ca65f95e673ad3b4f528bc7e44acf116b135b Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 18 Apr 2024 17:53:09 +0300 Subject: [PATCH 067/140] Added dummy data to the requests --- JXK5IiyaUUc.jpg | Bin 0 -> 598152 bytes bot_test.py | 65 +++++++++++++ dff/messengers/vk.py | 168 +++++++++++++++++++++++++++++----- photo_2024-02-29_23-14-08.jpg | Bin 0 -> 98258 bytes 4 files changed, 211 insertions(+), 22 deletions(-) create mode 100644 JXK5IiyaUUc.jpg create mode 100644 bot_test.py create mode 100644 photo_2024-02-29_23-14-08.jpg diff --git a/JXK5IiyaUUc.jpg b/JXK5IiyaUUc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5d85299eac88494f65853bd5916f35ecae7f5b20 GIT binary patch literal 598152 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

Kxr868&o`81l=zn26`gBms zHMIQ3o{7o3?`JO6NG*oHd6R5oTYn`goju(~{C*FzU?;&N)5LsNx_eGO+FLPS$cV^p zsil<{sAO9|#&L&Iv5cIYc+Unk>dp7#P@7MdA_a$FBqi=fz8G8;KFxnbiQ=_q?G%~miA=lz^V5e3r)3!ZFVMUx6O=&;^hKR4 z1+{s1RM)$v!k}?@$2>6lG9w0Z9Uxf1t-h?Ji5}tw2E~`sc8Gi!^q{i0r5BIZz0I{2 z!Gv}7q4Z*OVR~=Gj%PlX#W&f{#nQO1+d!=S-{d({yP|LSN{K+hqh{PSLgC?C4+il8 zti&?peSiw#Uz9Cb5#0cPyGh;2mj$=LTNg_kZitkL)7_S35pd;>LcL)*Q2>~HrqV9m zTDk2MLsh)NGO}G0uCRYmP;1ZM)#D_aS|^jz-ai@#w%L~vE(d0kbHZ8?UpU~213Yx3 zdts21jEu%cK~3w1V|ZN@K<)*P7S-M6UwCaT__0G+h`U~(lD^h;2E2-}m}OHajw@_; zr}tYwj<~H)2bGRS*K2%C=PkUO*fJs$rlA#s2Nh17@)(VCQQ!{>JF{B<(ppY7(UiS4VW9btKqiMO=02=wa&%Vmk-wHWK2SN zVA)a*0>sk(H%dYRL&Ko2P-g14S+uT%`xNS^^Xv*OjyOgMP;j}tZ=5Pvig{mW?(E7i>jF&#g`lsuvhgBV%gLPghlHGf%$_Dmh}!{n^&tQv^?|; z`Gjp%-l_AC=qmHo2y5sv!hM4ON6-=9tcM0N2V;XQew2ae+mr;NQU!{c>U8#<>XFk~ zIoLxsr@PNSjf}2K%P7$B)bq5z+5B*ZAV+MHR@1fG2uQDjJl>;Yc{!fU$eNSye``v; zL62g{ThYEXQT6>ZjZ0ndq)>Ar2%*Ei>9Ddpz<2DkcxM{|Yz zO8EXFosiga<<$HaNzSw{#HX4%FTE$^n8?*|UtF!22d^4KU_=Vm`e%Q`V?E>AqNhD> zSJ2(iZ^KK|fM{s)mJS-EmER}Ot*?ajH$2gg zp8x)|*FJ49m@+(=KSrnnqUxc?>V%Ky(D{1#tXY`sh05z{;TpDTsVrf4Md3xF(#6

sdQ&^he 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

=d+7Df@_yToxl67}YqUKAtKoa| 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

=v51v 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[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

YBYaZ4g7MXaEbER| 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 None: - self.bot_responses = [] - self.requests = [] - - def request(self, req): - # updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() - # update_list = [] - # for i in updates["updates"]: - # update_list.append( - # extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) - # ) - self.requests.append(req) - return [req] + def __init__(self, token: str, group_id: str) -> None: + self.token = token + self.group_id = group_id + + self.dialogue = {} + self.other_requests = [] + # server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + server_request = f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" + self.other_requests.append(server_request) + self.server = server_request['response']['server'] + self.ts_base = int(server_request['response']['ts']) + self.ts_current = self.ts_base + self.server_key = server_request['response']['key'] + self.last_update_id = None + self._last_processed_update = None + - def send_message(self, response, _): - self.bot_responses.append(response) - return response + def upload_attachment( + self, peer_id, attachment, attachment_type: str + ) -> str: + """ + Return json object with `owner_id` and `photo_id` needed to send it + """ + if attachment_type == "photo": + upload_url = f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + + self.other_requests.append(upload_url) + + upload_url = generate_random_data("url") + attachment_path = str(attachment.source) + + logger.info(f"Uploading {attachment_path}") + with FilesOpener(attachment_path) as photo_files: + uploaded_photo_data = {'photo': generate_random_data("num"), 'server': generate_random_data("url"), 'hash': generate_random_data("num")} + + saved_photo_data = f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}" + + self.other_requests.append(saved_photo_data) + + return saved_photo_data["response"] + + elif attachment_type == "doc": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + attachment_path = str(attachment.source) + + if "response" not in upload_url: + logger.error(f"Errror getting upload server for document\n{upload_url}") + raise Exception() + + upload_url = upload_url["response"]["upload_url"] + + logger.info(f"Uploading {attachment_path}") + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + if "response" not in saved_doc_data: + logger.error(f"Error saving document\n{saved_doc_data}") + raise Exception() + + return saved_doc_data["response"] + + elif attachment_type == "audio": + upload_url = requests.post( + f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" + ).json() + attachment_path = str(attachment.source) + + if "response" not in upload_url: + logger.error(f"Errror getting upload server for audio\n{upload_url}") + raise Exception() + + upload_url = upload_url["response"]["upload_url"] + + logger.info(f"Uploading {attachment_path}") + with FilesOpener(attachment_path, key_format="file") as files: + uploaded_photo_data = requests.post(upload_url, files=files).json() + + saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + if "response" not in saved_doc_data: + logger.error(f"Error saving audio\n{saved_doc_data}") + raise Exception() + + return saved_doc_data["response"] + + elif attachment_type == "video": + raise NotImplementedError() + + def request(self): + updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() + self.ts_current = updates['ts'] + update_list = extract_vk_update(updates["updates"]) + + return updates, update_list + + def send_message(self, response, id): + if response.attachments is not None: + attachment_list = [] + for attachment in response.attachments: + if isinstance(attachment, Image): + data_to_send = self.upload_attachment(id, attachment, "photo") + attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + elif isinstance(attachment, Document): + data_to_send = self.upload_attachment(id, attachment, "doc") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + elif isinstance(attachment, Video): + data_to_send = self.upload_attachment(id, attachment, "video") + attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") + elif isinstance(attachment, Audio): + data_to_send = self.upload_attachment(id, attachment, "audio") + attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + elif isinstance(attachment, Link): + response.text += f"[{attachment.source}|{attachment.title}]" + + elif isinstance(attachment, Poll): + raise NotImplementedError() + + attachment_string = ','.join(attachment_list).strip(',') + + return f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" + else: + return f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}" + def get_dialogue(self): - return zip(self.requests, self.bot_responses) + return self.dialogue + + def get_requests(self): + return self.other_requests class PollingVKInterface(PollingMessengerInterface): diff --git a/photo_2024-02-29_23-14-08.jpg b/photo_2024-02-29_23-14-08.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bae458e82ca6e288f1b4e32259f85efdd246ac4b GIT binary patch literal 98258 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 Date: Tue, 23 Apr 2024 00:34:56 +0200 Subject: [PATCH 068/140] attachments tutorial added --- dff/messengers/common/interface.py | 2 +- dff/messengers/telegram/abstract.py | 13 +- dff/script/core/message.py | 11 +- .../messengers/telegram/2_attachments.py | 211 ++++++++++++++++++ 4 files changed, 229 insertions(+), 8 deletions(-) create mode 100644 tutorials/messengers/telegram/2_attachments.py diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index f820b0e5a..5c9d8fc07 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -36,7 +36,7 @@ def __init__(self, attachments_directory: Optional[Path] = None) -> None: if attachments_directory is not None and not str(attachments_directory.absolute()).startswith(tempdir): self.attachments_directory = attachments_directory else: - warning_start = f"Attachments directory for {type(self)} messenger interface" + warning_start = f"Attachments directory for {type(self).__name__} messenger interface" warning_end = "attachment data won't be preserved locally!" if attachments_directory is None: self.attachments_directory = Path(tempdir) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index cb9bd35fb..a1faca25d 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -49,8 +49,8 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - request_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document, Invoice} - response_attachments = {Location, Contact, Poll, Audio, Video, Animation, Image, Document} + request_attachments = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document, Invoice} + response_attachments = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document} def __init__(self, token: str, attachments_directory: Optional[Path] = None) -> None: super().__init__(attachments_directory) @@ -110,6 +110,15 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # open_period=update.poll.open_period, ) ] + if update.sticker is not None: + message.attachments += [ + Sticker( + id=update.sticker.file_id, + is_animated=update.sticker.is_animated, + is_video=update.sticker.is_video, + type=update.sticker.type, + ) + ] if update.audio is not None: thumbnail = ( Image(id=update.audio.thumbnail.file_id, title=update.audio.thumbnail.file_unique_id) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 3a9540818..5d437fcfc 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -10,7 +10,8 @@ from pathlib import Path from urllib.request import urlopen -from pydantic import field_validator, FilePath, HttpUrl, BaseModel, model_validator +from pydantic import Field, field_validator, FilePath, HttpUrl, BaseModel, model_validator +from pydantic_core import Url from dff.messengers.common.interface import MessengerInterface @@ -106,9 +107,9 @@ async def get_bytes(self, from_messenger_interface: MessengerInterface) -> Optio if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() - elif isinstance(self.source, HttpUrl): - with urlopen(self.source.unicode_string()) as file: - return file.read() + elif isinstance(self.source, Url): + with urlopen(self.source.unicode_string()) as url: + return url.read() else: return None @@ -162,7 +163,7 @@ class Image(DataAttachment): pass -class Sticker(Image): +class Sticker(DataAttachment): """Represents a sticker as a file attachment.""" pass diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py new file mode 100644 index 000000000..23b675352 --- /dev/null +++ b/tutorials/messengers/telegram/2_attachments.py @@ -0,0 +1,211 @@ +# %% [markdown] +""" +# Telegram: 2. Attachments + +The following tutorial shows how to run a regular DFF script in Telegram. +It asks users for the '/start' command and then loops in one place. + +Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) +class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) +library are used for accessing telegram API in polling mode. + +Telegram API token is required to access telegram API. +""" + +# %pip install dff[telegram] + +# %% +import os + +from pydantic import HttpUrl + +from dff.script import conditions as cnd +from dff.script import GLOBAL, RESPONSE, TRANSITIONS, Message +from dff.messengers.telegram import PollingTelegramInterface +from dff.pipeline import Pipeline +from dff.script.core.message import Animation, Audio, Contact, Document, Location, Image, Poll, PollOption, Sticker, Video +from dff.utils.testing.common import is_interactive_mode + + +# %% [markdown] +""" +In order to integrate your script with Telegram, you need an instance of +`TelegramMessenger` class and one of the following interfaces: +`PollingMessengerInterface` or `WebhookMessengerInterface`. + +`TelegramMessenger` encapsulates the bot logic. Like Telebot, +`TelegramMessenger` only requires a token to run. However, all parameters +from the Telebot class can be passed as keyword arguments. + +The two interfaces connect the bot to Telegram. They can be passed directly +to the DFF `Pipeline` instance. +""" + +# %% + +location_data = {"latitude": 50.65, "longitude": 3.916667} + +contact_data = {"phone_number": "8-900-555-35-35", "first_name": "Hope", "last_name": "Credit"} + +sticker_data = { + "id": "CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE", + "title": "A sticker I've just found", +} + +audio_data = { + "source": HttpUrl("https://commondatastorage.googleapis.com/codeskulptor-assets/Evillaugh.ogg"), + "title": "Evil laughter (scary alert!)", +} + +video_data = { + # TODO: I need help, this video results in doenloading timeout, we need another example. + "source": HttpUrl("https://archive.org/download/Rick_Astley_Never_Gonna_Give_You_Up/Rick_Astley_Never_Gonna_Give_You_Up.mp4"), + "title": "Totally not suspicious video...", +} + +animation_data = { + # For some reason, if we don't define filename explicitly, animation is sent as file. + "source": HttpUrl("https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFuMGk5ODY0dG5pd242ODR6anB4bm4wZGN3cjg1N3A1M2ZxMjluYiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/SvP3FgHsFVm7zwMdH6/giphy.gif"), + "title": "Some random free gif :/", + "filename": "random.gif", +} + +image_data = { + "source": HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4"), + "title": "DeepPavlov logo", +} + +document_data = { + "source": HttpUrl("https://aclanthology.org/P18-4021.pdf"), + "title": "DeepPavlov article", +} + + +# %% +script = { + GLOBAL: { + TRANSITIONS: { + ("main_flow", "location_node"): cnd.exact_match(Message("location")), + ("main_flow", "contact_node"): cnd.exact_match(Message("contact")), + ("main_flow", "poll_node"): cnd.exact_match(Message("poll")), + ("main_flow", "sticker_node"): cnd.exact_match(Message("sticker")), + ("main_flow", "audio_node"): cnd.exact_match(Message("audio")), + ("main_flow", "video_node"): cnd.exact_match(Message("video")), + ("main_flow", "animation_node"): cnd.exact_match(Message("animation")), + ("main_flow", "image_node"): cnd.exact_match(Message("image")), + ("main_flow", "document_node"): cnd.exact_match(Message("document")), + } + }, + "main_flow": { + "start_node": { + TRANSITIONS: {"intro_node": cnd.exact_match(Message("/start"))}, + }, + "intro_node": { + RESPONSE: Message( + 'Type "location", "contact", "poll", "sticker" ' + '"audio", "video", "animation", "image", ' + '"document" or to receive a corresponding attachment!' + ), + }, + "location_node": { + RESPONSE: Message( + "Here's your location!", + attachments=[Location(**location_data)], + ), + }, + "contact_node": { + RESPONSE: Message( + "Here's your contact!", + attachments=[Contact(**contact_data)], + ), + }, + "poll_node": { + RESPONSE: Message( + "Here's your poll!", + attachments=[ + Poll( + question="What is the poll question?", + options=[ + PollOption(text="This one!"), + PollOption(text="Not this one :("), + ], + ), + ], + ), + }, + "sticker_node": { + RESPONSE: Message( + "Here's your sticker!", + attachments=[Sticker(**sticker_data)], + ), + }, + "audio_node": { + RESPONSE: Message( + "Here's your audio!", + attachments=[Audio(**audio_data)], + ), + }, + "video_node": { + RESPONSE: Message( + "Here's your video!", + attachments=[Video(**video_data)], + ), + }, + "animation_node": { + RESPONSE: Message( + "Here's your animation!", + attachments=[Animation(**animation_data)], + ), + }, + "image_node": { + RESPONSE: Message( + "Here's your image!", + attachments=[Image(**image_data)], + ), + }, + "document_node": { + RESPONSE: Message( + "Here's your document!", + attachments=[Document(**document_data)], + ), + }, + "fallback_node": { + RESPONSE: Message( + "Unknown attachment type, try again! " + 'Supported attachments are: "location", ' + '"contact", "poll", "sticker", "audio", ' + '"video", "animation", "image" and "document".' + ), + }, + } +} + +# this variable is only for testing +happy_path = ( + (Message("/start"), Message("Hi")), + (Message("Hi"), Message("Hi")), + (Message("Bye"), Message("Hi")), +) + + +# %% +interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) + + +# %% +pipeline = Pipeline.from_script( + script=script, + start_label=("main_flow", "start_node"), + fallback_label=("main_flow", "fallback_node"), + messenger_interface=interface, + # The interface can be passed as a pipeline argument. +) + + +def main(): + pipeline.run() + + +if __name__ == "__main__" and is_interactive_mode(): + # prevent run during doc building + main() From 33c72cb1792cc36db6cdfb478d1aed9f4f5c4ca7 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 23 Apr 2024 21:36:56 +0200 Subject: [PATCH 069/140] advanced tutorial added --- dff/messengers/telegram/abstract.py | 3 +- tutorials/messengers/telegram/2_buttons.py | 175 --------------- tutorials/messengers/telegram/3_advanced.py | 187 ++++++++++++++++ .../telegram/3_buttons_with_callback.py | 177 --------------- tutorials/messengers/telegram/4_conditions.py | 148 ------------ .../telegram/5_conditions_with_media.py | 211 ------------------ .../telegram/6_conditions_extras.py | 144 ------------ .../messengers/telegram/7_polling_setup.py | 61 ----- .../messengers/telegram/8_webhook_setup.py | 59 ----- 9 files changed, 189 insertions(+), 976 deletions(-) delete mode 100644 tutorials/messengers/telegram/2_buttons.py create mode 100644 tutorials/messengers/telegram/3_advanced.py delete mode 100644 tutorials/messengers/telegram/3_buttons_with_callback.py delete mode 100644 tutorials/messengers/telegram/4_conditions.py delete mode 100644 tutorials/messengers/telegram/5_conditions_with_media.py delete mode 100644 tutorials/messengers/telegram/6_conditions_extras.py delete mode 100644 tutorials/messengers/telegram/7_polling_setup.py delete mode 100644 tutorials/messengers/telegram/8_webhook_setup.py diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index a1faca25d..6b62ccdfc 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -412,7 +412,8 @@ async def cast_message_to_telegram_and_send( async def _on_event( self, update: Update, _: ContextTypes.DEFAULT_TYPE, create_message: Callable[[Update], Message] ) -> None: - if update.effective_chat is not None and update.message is not None: + data_available = update.message is not None or update.callback_query is not None + if update.effective_chat is not None and data_available: message = create_message(update) message.original_message = update resp = await self.pipeline_runner(message, update.effective_chat.id) diff --git a/tutorials/messengers/telegram/2_buttons.py b/tutorials/messengers/telegram/2_buttons.py deleted file mode 100644 index e3926df12..000000000 --- a/tutorials/messengers/telegram/2_buttons.py +++ /dev/null @@ -1,175 +0,0 @@ -# %% [markdown] -""" -# Telegram: 2. Buttons - -This tutorial shows how to display and hide a basic keyboard in Telegram. - -Different %mddoclink(api,script.core.message,message) -classes are used for representing different common message features, -like Attachment, Audio, Button, Image, etc. -""" - - -# %pip install dff[telegram] - -# %% -import os - -import dff.script.conditions as cnd -from dff.script import TRANSITIONS, RESPONSE -from dff.script.core.message import Button, Keyboard, Message -from dff.pipeline import Pipeline -from dff.messengers.telegram import PollingTelegramInterface -from dff.utils.testing.common import is_interactive_mode - - -# %% [markdown] -""" -To display or hide a keyboard, you can utilize the `ui` field of the -`TelegramMessage` class. It can be initialized either with -a `TelegramUI` instance or with a custom telebot keyboard. - -Passing an instance of `RemoveKeyboard` to the `ui` field -will indicate that the keyboard should be removed. -""" - - -# %% -script = { - "root": { - "start": { - TRANSITIONS: { - ("general", "native_keyboard"): ( - lambda ctx, _: ctx.last_request.text - in ("/start", "/restart") - ), - }, - }, - "fallback": { - RESPONSE: Message( - text="Finishing test, send /restart command to restart" - ), - TRANSITIONS: { - ("general", "native_keyboard"): ( - lambda ctx, _: ctx.last_request.text - in ("/start", "/restart") - ), - }, - }, - }, - "general": { - "native_keyboard": { - RESPONSE: Message( - text="Question: What's 2 + 2?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="5"), - Button(text="4"), - ], - ], - ), - ], - ), - TRANSITIONS: { - ("general", "success"): cnd.has_callback_query("4"), - ("general", "fail"): cnd.true(), - }, - }, - "success": { - RESPONSE: Message(text="Success!"), - TRANSITIONS: {("root", "fallback"): cnd.true()}, - }, - "fail": { - RESPONSE: Message( - text="Incorrect answer, type anything to try again" - ), - TRANSITIONS: {("general", "native_keyboard"): cnd.true()}, - }, - }, -} - -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - -# this variable is only for testing -happy_path = ( - ( - Message(text="/start"), - Message( - text="Question: What's 2 + 2?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="5"), - Button(text="4"), - ], - ], - ), - ], - ), - ), - ( - Message(text="5"), - Message(text="Incorrect answer, type anything to try again"), - ), - ( - Message(text="ok"), - Message( - text="Question: What's 2 + 2?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="5"), - Button(text="4"), - ], - ], - ), - ], - ), - ), - ( - Message(text="4"), - Message(text="Success!"), - ), - ( - Message(text="Yay!"), - Message(text="Finishing test, send /restart command to restart"), - ), - ( - Message(text="/start"), - Message( - text="Question: What's 2 + 2?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="5"), - Button(text="4"), - ], - ], - ), - ], - ), - ), -) - - -# %% -pipeline = Pipeline.from_script( - script=script, - start_label=("root", "start"), - fallback_label=("root", "fallback"), - messenger_interface=interface, -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py new file mode 100644 index 000000000..72bc54d4f --- /dev/null +++ b/tutorials/messengers/telegram/3_advanced.py @@ -0,0 +1,187 @@ +# %% [markdown] +""" +# Telegram: 3. Advanced + +The following tutorial shows how to run a regular DFF script in Telegram. +It asks users for the '/start' command and then loops in one place. + +Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) +class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) +library are used for accessing telegram API in polling mode. + +Telegram API token is required to access telegram API. +""" + +# %pip install dff[telegram] + +# %% +import asyncio +import os + +from pydantic import HttpUrl +from telegram import InlineKeyboardButton, InlineKeyboardMarkup +from telegram.constants import ParseMode + +from dff.script import conditions as cnd +from dff.script import RESPONSE, TRANSITIONS, Message +from dff.messengers.telegram import PollingTelegramInterface +from dff.pipeline import Pipeline +from dff.script.core.keywords import GLOBAL +from dff.script.core.message import Document, Image, Location, Sticker +from dff.utils.testing.common import is_interactive_mode + + +# %% [markdown] +""" +In order to integrate your script with Telegram, you need an instance of +`TelegramMessenger` class and one of the following interfaces: +`PollingMessengerInterface` or `WebhookMessengerInterface`. + +`TelegramMessenger` encapsulates the bot logic. Like Telebot, +`TelegramMessenger` only requires a token to run. However, all parameters +from the Telebot class can be passed as keyword arguments. + +The two interfaces connect the bot to Telegram. They can be passed directly +to the DFF `Pipeline` instance. +""" + +#%% + +image_url = HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4") + +formatted_text = r""" +Here's your formatted text\! +You can see **text in bold** and _text in italic_\. +\> Here's a [link](https://github.com/deeppavlov/dialog_flow_framework) in a quote\. +Run /start command again to restart\. +""" + +location_data = {"latitude": 59.9386, "longitude": 30.3141} + +sticker_data = { + "id": "CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE", +} + +image_data = { + "source": image_url, + "title": "DeepPavlov logo", + "has_spoiler": True, + "filename": "deeppavlov_logo.png", +} + +document_thumbnail = asyncio.run(Image(source=image_url).get_bytes(None)) + +document_data = { + "source": HttpUrl("https://aclanthology.org/P18-4021.pdf"), + "title": "DeepPavlov article", + "filename": "deeppavlov_article.pdf", + "thumbnail": document_thumbnail, +} + + +# %% +script = { + GLOBAL: { + TRANSITIONS: { + ("main_flow", "hmmm_node"): cnd.exact_match(Message("/start")), + } + }, + "main_flow": { + "start_node": {}, + "hmmm_node": { + RESPONSE: Message( + attachments=[ + Location( + latitude=58.431610, + longitude=27.792887, + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("Cute formatted text!", callback_data="formatted"), + ], + [ + InlineKeyboardButton("Multiple attachments!", callback_data="attachments"), + ], + [ + InlineKeyboardButton("Secret image!", callback_data="secret"), + ], + [ + InlineKeyboardButton("Document with thumbnail!", callback_data="thumbnail"), + ], + [ + InlineKeyboardButton("Restart!", callback_data="restart"), + InlineKeyboardButton("Quit!", callback_data="quit"), + ], + ], + ), + ), + ], + ), + TRANSITIONS: { + "formatted_node": cnd.has_callback_query("formatted"), + "attachments_node": cnd.has_callback_query("attachments"), + "secret_node": cnd.has_callback_query("secret"), + "thumbnail_node": cnd.has_callback_query("thumbnail"), + "hmmm_node": cnd.has_callback_query("restart"), + "fallback_node": cnd.has_callback_query("quit"), + } + }, + "formatted_node": { + RESPONSE: Message(formatted_text, parse_mode=ParseMode.MARKDOWN_V2), + }, + "attachments_node": { + RESPONSE: Message( + "Here's your message with multiple attachments (a location and a sticker)!\nRun /start command again to restart.", + attachments=[ + Location(**location_data), + Sticker(**sticker_data), + ], + ), + }, + "secret_node": { + RESPONSE: Message( + "Here's your secret image! Run /start command again to restart.", + attachments=[Image(**image_data)], + ), + }, + "thumbnail_node": { + RESPONSE: Message( + "Here's your document with tumbnail! Run /start command again to restart.", + attachments=[Document(**document_data)], + ), + }, + "fallback_node": { + RESPONSE: Message("Bot has entered unrecoverable state :/\nRun /start command again to restart."), + }, + } +} + +# this variable is only for testing +happy_path = ( + (Message("/start"), Message("Hi")), + (Message("Hi"), Message("Hi")), + (Message("Bye"), Message("Hi")), +) + + +# %% +interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) + + +# %% +pipeline = Pipeline.from_script( + script=script, + start_label=("main_flow", "start_node"), + fallback_label=("main_flow", "fallback_node"), + messenger_interface=interface, + # The interface can be passed as a pipeline argument. +) + + +def main(): + pipeline.run() + + +if __name__ == "__main__" and is_interactive_mode(): + # prevent run during doc building + main() diff --git a/tutorials/messengers/telegram/3_buttons_with_callback.py b/tutorials/messengers/telegram/3_buttons_with_callback.py deleted file mode 100644 index d993672a8..000000000 --- a/tutorials/messengers/telegram/3_buttons_with_callback.py +++ /dev/null @@ -1,177 +0,0 @@ -# %% [markdown] -""" -# Telegram: 3. Buttons with Callback - -This tutorial demonstrates, how to add an inline keyboard and utilize -inline queries. - -Different %mddoclink(api,script.core.message,message) -classes are used for representing different common message features, -like Attachment, Audio, Button, Image, etc. -""" - - -# %pip install dff[telegram] - -# %% -import os - -import dff.script.conditions as cnd -from dff.script import TRANSITIONS, RESPONSE -from dff.pipeline import Pipeline -from dff.script.core.message import Button, Keyboard, Message -from dff.messengers.telegram import PollingTelegramInterface -from dff.utils.testing.common import is_interactive_mode - - -# %% [markdown] -""" -If you want to send an inline keyboard to your Telegram chat, -set `is_inline` field of the `TelegramUI` instance to `True` -(note that it is inline by default, so you could also omit it). - -Pushing a button of an inline keyboard results in a callback -query being sent to your bot. The data of the query -is stored in the `callback_query` field of a user `TelegramMessage`. -""" - - -# %% -script = { - "root": { - "start": { - TRANSITIONS: { - ("general", "keyboard"): ( - lambda ctx, _: ctx.last_request.text - in ("/start", "/restart") - ), - }, - }, - "fallback": { - RESPONSE: Message( - text="Finishing test, send /restart command to restart" - ), - TRANSITIONS: { - ("general", "keyboard"): ( - lambda ctx, _: ctx.last_request.text - in ("/start", "/restart") - ) - }, - }, - }, - "general": { - "keyboard": { - RESPONSE: Message( - text="Starting test! What's 9 + 10?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="19", data="correct"), - Button(text="21", data="wrong"), - ], - ], - ), - ], - ), - TRANSITIONS: { - ("general", "success"): cnd.has_callback_query("correct"), - ("general", "fail"): cnd.has_callback_query("wrong"), - }, - }, - "success": { - RESPONSE: Message(text="Success!"), - TRANSITIONS: {("root", "fallback"): cnd.true()}, - }, - "fail": { - RESPONSE: Message( - text="Incorrect answer, type anything to try again" - ), - TRANSITIONS: {("general", "keyboard"): cnd.true()}, - }, - }, -} - -# this variable is only for testing -happy_path = ( - ( - Message(text="/start"), - Message( - text="Starting test! What's 9 + 10?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="19", data="correct"), - Button(text="21", data="wrong"), - ], - ], - ), - ], - ), - ), - ( - Message(text="wrong"), - Message(text="Incorrect answer, type anything to try again"), - ), - ( - Message(text="try again"), - Message( - text="Starting test! What's 9 + 10?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="19", data="correct"), - Button(text="21", data="wrong"), - ], - ], - ), - ], - ), - ), - ( - Message(text="correct"), - Message(text="Success!"), - ), - ( - Message(text="Yay!"), - Message(text="Finishing test, send /restart command to restart"), - ), - ( - Message(text="/restart"), - Message( - text="Starting test! What's 9 + 10?", - attachments=[ - Keyboard( - buttons=[ - [ - Button(text="19", data="correct"), - Button(text="21", data="wrong"), - ], - ], - ), - ], - ), - ), -) - -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - - -# %% -pipeline = Pipeline.from_script( - script=script, - start_label=("root", "start"), - fallback_label=("root", "fallback"), - messenger_interface=interface, -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/4_conditions.py b/tutorials/messengers/telegram/4_conditions.py deleted file mode 100644 index 38d65d894..000000000 --- a/tutorials/messengers/telegram/4_conditions.py +++ /dev/null @@ -1,148 +0,0 @@ -# %% [markdown] -""" -# Telegram: 4. Conditions - -This tutorial shows how to process Telegram updates in your script -and reuse handler triggers from the `pytelegrambotapi` library. - -Here, %mddoclink(api,messengers.telegram) -message `original_message` component used -for graph navigation according to Telegram events. -""" - - -# %pip install dff[telegram] - -# %% -import os - -from dff.script import TRANSITIONS, RESPONSE - -import dff.script.conditions as cnd -from dff.messengers.telegram import PollingTelegramInterface -from dff.pipeline import Pipeline -from dff.script.core.context import Context -from dff.script.core.message import Message -from dff.utils.testing.common import is_interactive_mode - - -# %% [markdown] -""" -In our Telegram module, we adopted the system of filters -available in the `pytelegrambotapi` library. - -- Setting the `update_type` will allow filtering by update type: - if you want the condition to trigger only on updates of the type - `edited_message`, set it to `UpdateType.EDITED_MESSAGE`. - The field defaults to `message`. -- `func` argument on the other hand allows you to define arbitrary conditions. -- `regexp` creates a regular expression filter, etc. - -Note: -It is possible to use `cnd.exact_match` as a condition -(as seen in previous tutorials). However, the functionality -of that approach is lacking: - -At this moment only two fields of `Message` are set during update processing: - -- `text` stores the `text` field of `message` updates -- `callback_query` stores the `data` field of `callback_query` updates - -For more information see tutorial `3_buttons_with_callback.py`. -""" - - -# %% -def latest_message_test_has_music(ctx: Context, _: Pipeline) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - if ctx.last_request.original_message.message is None: - return False - if ctx.last_request.original_message.message.text is None: - return False - return "music" in ctx.last_request.original_message.message.text - - -# %% -script = { - "greeting_flow": { - "start_node": { - TRANSITIONS: { - "node1": cnd.any( - [ - cnd.exact_match(Message(text="/start")), - cnd.exact_match(Message(text="/restart")), - ] - ) - }, - }, - "node1": { - RESPONSE: Message(text="Hi, how are you?"), - TRANSITIONS: {"node2": cnd.regexp("fine")}, - }, - "node2": { - RESPONSE: Message(text="Good. What do you want to talk about?"), - TRANSITIONS: {"node3": latest_message_test_has_music}, - }, - "node3": { - RESPONSE: Message(text="Sorry, I can not talk about music now."), - TRANSITIONS: {"node4": lambda _, __: True}, - # This condition is true for any type of update - }, - "node4": { - RESPONSE: Message(text="bye"), - TRANSITIONS: {"node1": lambda _, __: True}, - # This condition is true if the last update is of type `message` - }, - "fallback_node": { - RESPONSE: Message(text="Ooops"), - TRANSITIONS: { - "node1": cnd.any( - [ - cnd.exact_match(Message(text="/start")), - cnd.exact_match(Message(text="/restart")), - ] - ) - }, - }, - } -} - -# this variable is only for testing -happy_path = ( - (Message(text="/start"), Message(text="Hi, how are you?")), - ( - Message(text="I'm fine"), - Message(text="Good. What do you want to talk about?"), - ), - ( - Message(text="About music"), - Message(text="Sorry, I can not talk about music now."), - ), - (Message(text="ok"), Message(text="bye")), - (Message(text="bye"), Message(text="Hi, how are you?")), -) - - -# %% -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - - -# %% -pipeline = Pipeline.from_script( - script=script, - start_label=("greeting_flow", "start_node"), - fallback_label=("greeting_flow", "fallback_node"), - messenger_interface=interface, -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/5_conditions_with_media.py b/tutorials/messengers/telegram/5_conditions_with_media.py deleted file mode 100644 index 646df8f39..000000000 --- a/tutorials/messengers/telegram/5_conditions_with_media.py +++ /dev/null @@ -1,211 +0,0 @@ -# %% [markdown] -""" -# Telegram: 5. Conditions with Media - -This tutorial shows how to use media-related logic in your script. - -Here, %mddoclink(api,messengers.telegram) -message `original_message` component used -for graph navigation according to Telegram events. - -Different %mddoclink(api,script.core.message,message) -classes are used for representing different common message features, -like Attachment, Audio, Button, Image, etc. -""" - - -# %pip install dff[telegram] - -# %% -import os - -from pydantic import HttpUrl - -import dff.script.conditions as cnd -from dff.script import TRANSITIONS, RESPONSE -from dff.script.core.context import Context -from dff.script.core.message import Message, Image -from dff.messengers.telegram import PollingTelegramInterface -from dff.pipeline import Pipeline -from dff.utils.testing.common import is_interactive_mode - - -# %% - -picture_url = HttpUrl( - "https://avatars.githubusercontent.com/u/29918795?s=200&v=4" -) - - -# %% [markdown] -""" -To filter user messages depending on whether or not media files were sent, -you can use the `content_types` parameter of the -`Context.last_request.original_message.message.document`. -""" - - -# %% -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - - -def latest_message_has_photos(ctx: Context, _: Pipeline) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - if ctx.last_request.original_message.message is None: - return False - if ctx.last_request.original_message.message.photo is None: - return False - return len(ctx.last_request.original_message.message.photo) > 0 - - -def latest_message_has_images(ctx: Context, _: Pipeline) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - if ctx.last_request.original_message.message is None: - return False - if ctx.last_request.original_message.message.document is None: - return False - return ( - ctx.last_request.original_message.message.document.mime_type - == "image/jpeg" - ) - - -def latest_message_has_text(ctx: Context, _: Pipeline) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - if ctx.last_request.original_message.message is None: - return False - return ctx.last_request.original_message.message.text is None - - -# %% -script = { - "root": { - "start": { - TRANSITIONS: { - ("pics", "ask_picture"): cnd.any( - [ - cnd.exact_match(Message(text="/start")), - cnd.exact_match(Message(text="/restart")), - ] - ) - }, - }, - "fallback": { - RESPONSE: Message( - text="Finishing test, send /restart command to restart" - ), - TRANSITIONS: { - ("pics", "ask_picture"): cnd.any( - [ - cnd.exact_match(Message(text="/start")), - cnd.exact_match(Message(text="/restart")), - ] - ) - }, - }, - }, - "pics": { - "ask_picture": { - RESPONSE: Message(text="Send me a picture"), - TRANSITIONS: { - ("pics", "send_one"): cnd.any( - [ - # Telegram can put photos - # both in 'photo' and 'document' fields. - # We should consider both cases - # when we check the message for media. - latest_message_has_photos, - latest_message_has_images, - ] - ), - ( - "pics", - "send_many", - ): latest_message_has_text, - ("pics", "ask_picture"): cnd.true(), - }, - }, - "send_one": { - # An HTTP path or a path to a local file can be used here. - RESPONSE: Message( - text="Here's my picture!", - attachments=[Image(source=picture_url)], - ), - TRANSITIONS: {("root", "fallback"): cnd.true()}, - }, - "send_many": { - RESPONSE: Message( - text="Look at my pictures!", - # An HTTP path or a path to a local file can be used here. - attachments=[Image(source=picture_url)] * 2, - ), - TRANSITIONS: {("root", "fallback"): cnd.true()}, - }, - }, -} - - -# testing -happy_path = ( - ( - Message(text="/start"), - Message(text="Send me a picture"), - ), - ( - Message(attachments=[Image(source=picture_url)]), - Message( - text="Here's my picture!", - attachments=[Image(source=picture_url)], - ), - ), - ( - Message(text="ok"), - Message(text="Finishing test, send /restart command to restart"), - ), - ( - Message(text="/restart"), - Message(text="Send me a picture"), - ), - ( - Message(text="No"), - Message( - text="Look at my pictures!", - attachments=list(tuple([Image(source=picture_url)] * 2)), - ), - ), - ( - Message(text="ok"), - Message(text="Finishing test, send /restart command to restart"), - ), - ( - Message(text="/restart"), - Message(text="Send me a picture"), - ), -) - - -# %% -pipeline = Pipeline.from_script( - script=script, - start_label=("root", "start"), - fallback_label=("root", "fallback"), - messenger_interface=interface, -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/6_conditions_extras.py b/tutorials/messengers/telegram/6_conditions_extras.py deleted file mode 100644 index f74faa993..000000000 --- a/tutorials/messengers/telegram/6_conditions_extras.py +++ /dev/null @@ -1,144 +0,0 @@ -# %% [markdown] -""" -# Telegram: 6. Conditions Extras - -This tutorial shows how to use additional update filters -inherited from the `pytelegrambotapi` library. - -Here, %mddoclink(api,messengers.telegram) -message `original_message` component -is used for telegram message type checking. -""" - - -# %pip install dff[telegram] - -# %% -import os - -from dff.script import TRANSITIONS, RESPONSE, GLOBAL -import dff.script.conditions as cnd -from dff.messengers.telegram import PollingTelegramInterface -from dff.pipeline import Pipeline -from dff.script.core.context import Context -from dff.script.core.message import Message -from dff.utils.testing.common import is_interactive_mode - - -# %% [markdown] -""" -In our Telegram module, we adopted the system of filters -available in the `pytelegrambotapi` library. - -Aside from `MESSAGE` you can use -other triggers to interact with the api. In this tutorial, we use -handlers of other type as global conditions that trigger a response -from the bot. - -Here, we use the following triggers: - -* `chat_join_request`: join request is sent to the chat where the bot is. -* `my_chat_member`: triggered when the bot is invited to a chat. -* `inline_query`: triggered when an inline query is being sent to the bot. - -The other available conditions are: - -* `channel_post`: new post is created in a channel the bot is subscribed to; -* `edited_channel_post`: post is edited in a channel the bot is subscribed to; -* `shipping_query`: shipping query is sent by the user; -* `pre_checkout_query`: order confirmation is sent by the user; -* `poll`: poll is sent to the chat; -* `poll_answer`: users answered the poll sent by the bot. - -You can read more on those in the Telegram documentation -or in the docs for the `telebot` library. -""" - - -# %% -def latest_message_is_new_chat_member( - ctx: Context, _: Pipeline -) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - if ctx.last_request.original_message.message is None: - return False - return ( - ctx.last_request.original_message.message.new_chat_members is not None - ) - - -def latest_message_is_callback_query( - ctx: Context, _: Pipeline -) -> bool: - if ctx.last_request is None: - return False - if ctx.last_request.original_message is None: - return False - return ctx.last_request.original_message.inline_query is not None - - -# %% -script = { - GLOBAL: { - TRANSITIONS: { - # say hi when someone enters the chat - ( - "greeting_flow", - "node1", - ): latest_message_is_new_chat_member, - # send a message when inline query is received - ( - "greeting_flow", - "node2", - ): latest_message_is_callback_query, - }, - }, - "greeting_flow": { - "start_node": { - TRANSITIONS: { - "node1": cnd.any( - [ - cnd.exact_match(Message(text="/start")), - cnd.exact_match(Message(text="/restart")), - ] - ) - }, - }, - "node1": { - RESPONSE: Message(text="Hi"), - TRANSITIONS: {"start_node": cnd.true()}, - }, - "node2": { - RESPONSE: Message(text="Inline query received."), - TRANSITIONS: {"start_node": cnd.true()}, - }, - "fallback_node": { - RESPONSE: Message(text="Ooops"), - }, - }, -} - - -# %% -interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - - -# %% -pipeline = Pipeline.from_script( - script=script, - start_label=("greeting_flow", "start_node"), - fallback_label=("greeting_flow", "fallback_node"), - messenger_interface=interface, -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/7_polling_setup.py b/tutorials/messengers/telegram/7_polling_setup.py deleted file mode 100644 index 81ded86ac..000000000 --- a/tutorials/messengers/telegram/7_polling_setup.py +++ /dev/null @@ -1,61 +0,0 @@ -# %% [markdown] -""" -# Telegram: 7. Polling Setup - -The following tutorial shows how to configure `PollingTelegramInterface`. - -See %mddoclink(api,messengers.telegram,PollingTelegramInterface) -for more information. -""" - -# %pip install dff[telegram] - -# %% -import os - -from dff.messengers.telegram import PollingTelegramInterface -from dff.pipeline import Pipeline - -from dff.utils.testing.common import is_interactive_mode -from dff.utils.testing.toy_script import TOY_SCRIPT_ARGS, HAPPY_PATH - - -# %% [markdown] -""" -`PollingTelegramInterface` can be configured with the same parameters -that are used in the `pytelegrambotapi` library, specifically: - -* interval - time between calls to the API. -* allowed updates - updates that should be fetched. -* timeout - general timeout. -* long polling timeout - timeout for polling. -""" - - -# %% -interface = PollingTelegramInterface( - token=os.environ["TG_BOT_TOKEN"], - interval=2, - timeout=30, -) - - -# testing -happy_path = HAPPY_PATH - - -# %% -pipeline = Pipeline.from_script( - *TOY_SCRIPT_ARGS, - messenger_interface=interface, - # The interface can be passed as a pipeline argument -) - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() diff --git a/tutorials/messengers/telegram/8_webhook_setup.py b/tutorials/messengers/telegram/8_webhook_setup.py deleted file mode 100644 index f29e24620..000000000 --- a/tutorials/messengers/telegram/8_webhook_setup.py +++ /dev/null @@ -1,59 +0,0 @@ -# %% [markdown] -""" -# Telegram: 8. Webhook Setup - -The following tutorial shows how to use `CallbackTelegramInterface` -that makes your bot accessible through a public webhook. - -See %mddoclink(api,messengers.common.interface,CallbackMessengerInterface) -for more information. -""" - -# %pip install dff[telegram] flask - -# %% -import os - -from dff.messengers.telegram import CallbackTelegramInterface -from dff.pipeline import Pipeline -from dff.utils.testing.toy_script import TOY_SCRIPT_ARGS, HAPPY_PATH -from dff.utils.testing.common import is_interactive_mode - - -# %% [markdown] -""" -To set up a webhook, you need a messenger and a web application instance. -This class can be configured with the following parameters: - -* app - Flask application. You can pass an application with an arbitrary - number of pre-configured routes. Created automatically if not set. -* host - application host. -* port - application port. -* endpoint - bot access endpoint. -* full_uri - full public address of the endpoint. HTTPS should be enabled - for successful configuration. -""" - - -# %% -interface = CallbackTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) - - -# %% -pipeline = Pipeline.from_script( - *TOY_SCRIPT_ARGS, - messenger_interface=interface, - # The interface can be passed as a pipeline argument -) - -# testing -happy_path = HAPPY_PATH - - -def main(): - pipeline.run() - - -if __name__ == "__main__" and is_interactive_mode(): - # prevent run during doc building - main() From 3035cf127fea5ef876785de39d1e32ebbf833b96 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Wed, 24 Apr 2024 14:07:37 +0300 Subject: [PATCH 070/140] Redone VK_Bot, updated VK_dummy --- dff/messengers/vk.py | 219 +++++---------------------- tests/messengers/vk/__init__.py | 0 tests/messengers/vk/test_incoming.py | 0 tests/messengers/vk/test_outgoing.py | 0 tests/messengers/vk/vk_dummy.py | 71 +++++++++ 5 files changed, 107 insertions(+), 183 deletions(-) create mode 100644 tests/messengers/vk/__init__.py create mode 100644 tests/messengers/vk/test_incoming.py create mode 100644 tests/messengers/vk/test_outgoing.py create mode 100644 tests/messengers/vk/vk_dummy.py diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index a9e5637a6..98687a6b5 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -34,11 +34,6 @@ async def vk_api_call(method, payload={}, headers={}): async with session.post(method) as response: return response.json() -def generate_random_data(data_type): - if data_type == "url": - return "https://www.something.com/" - elif data_type == "num": - return 12345 def extract_vk_update(updates): upds = [] @@ -202,178 +197,22 @@ def upload_attachment( def request(self): updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() self.ts_current = updates['ts'] - update_list = [] - for i in updates["updates"]: - update_list.append( - extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) - ) - return update_list - - def send_message(self, response, id): - if response.attachments is not None: - attachment_list = [] - for attachment in response.attachments: - if isinstance(attachment, Image): - data_to_send = self.upload_attachment(id, attachment, "photo") - attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Document): - data_to_send = self.upload_attachment(id, attachment, "doc") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Video): - data_to_send = self.upload_attachment(id, attachment, "video") - attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") - elif isinstance(attachment, Audio): - data_to_send = self.upload_attachment(id, attachment, "audio") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Link): - response.text += f"[{attachment.source}|{attachment.title}]" - - elif isinstance(attachment, Poll): - raise NotImplementedError() - - attachment_string = ','.join(attachment_list).strip(',') + return updates["updates"] + + def send_message(self, response, id, attachment_list): + if attachment_list != []: + for attachment in attachment_list: + data_to_send = self.upload_attachment(id, attachment["source"], attachment["type"]) + attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + # elif isinstance(attachment, Link): + # response.text += f"[{attachment.source}|{attachment.title}]" + attachment_string = ','.join(attachment_list).strip(',') - requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() + api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" else: - requests.post(f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}").json() - - -class VK_dummy: - # functionality of the VK_Bot but without actual API calls - def __init__(self, token: str, group_id: str) -> None: - self.token = token - self.group_id = group_id - - self.dialogue = {} - self.other_requests = [] - # server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - server_request = f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" - self.other_requests.append(server_request) - self.server = server_request['response']['server'] - self.ts_base = int(server_request['response']['ts']) - self.ts_current = self.ts_base - self.server_key = server_request['response']['key'] - self.last_update_id = None - self._last_processed_update = None - - - def upload_attachment( - self, peer_id, attachment, attachment_type: str - ) -> str: - """ - Return json object with `owner_id` and `photo_id` needed to send it - """ - if attachment_type == "photo": - upload_url = f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - - self.other_requests.append(upload_url) - - upload_url = generate_random_data("url") - attachment_path = str(attachment.source) - - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path) as photo_files: - uploaded_photo_data = {'photo': generate_random_data("num"), 'server': generate_random_data("url"), 'hash': generate_random_data("num")} - - saved_photo_data = f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}" - - self.other_requests.append(saved_photo_data) - - return saved_photo_data["response"] - - elif attachment_type == "doc": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() - attachment_path = str(attachment.source) - - if "response" not in upload_url: - logger.error(f"Errror getting upload server for document\n{upload_url}") - raise Exception() - - upload_url = upload_url["response"]["upload_url"] - - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() - - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - if "response" not in saved_doc_data: - logger.error(f"Error saving document\n{saved_doc_data}") - raise Exception() - - return saved_doc_data["response"] + api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}" - elif attachment_type == "audio": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" - ).json() - attachment_path = str(attachment.source) - - if "response" not in upload_url: - logger.error(f"Errror getting upload server for audio\n{upload_url}") - raise Exception() - - upload_url = upload_url["response"]["upload_url"] - - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() - - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - if "response" not in saved_doc_data: - logger.error(f"Error saving audio\n{saved_doc_data}") - raise Exception() - - return saved_doc_data["response"] - - elif attachment_type == "video": - raise NotImplementedError() - - def request(self): - updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() - self.ts_current = updates['ts'] - update_list = extract_vk_update(updates["updates"]) - - return updates, update_list - - def send_message(self, response, id): - if response.attachments is not None: - attachment_list = [] - for attachment in response.attachments: - if isinstance(attachment, Image): - data_to_send = self.upload_attachment(id, attachment, "photo") - attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Document): - data_to_send = self.upload_attachment(id, attachment, "doc") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Video): - data_to_send = self.upload_attachment(id, attachment, "video") - attachment_list.append(f"video{data_to_send['owner_id']}_{data_to_send['id']}_{data_to_send['access_key']}") - elif isinstance(attachment, Audio): - data_to_send = self.upload_attachment(id, attachment, "audio") - attachment_list.append(f"doc{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") - elif isinstance(attachment, Link): - response.text += f"[{attachment.source}|{attachment.title}]" - - elif isinstance(attachment, Poll): - raise NotImplementedError() - - attachment_string = ','.join(attachment_list).strip(',') - - return f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" - else: - return f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}" - - - def get_dialogue(self): - return self.dialogue - - def get_requests(self): - return self.other_requests + return requests.post(api_request).json class PollingVKInterface(PollingMessengerInterface): @@ -384,21 +223,35 @@ def __init__(self, token: str, group_id: str, debug=True, test_path=None) -> Non self.step = -1 if not debug: self.bot = VK_Bot(token, group_id) - else: - self.bot = VK_dummy(token, group_id) + # else: + # self.bot = VK_dummy(token, group_id) def _request(self): - if self.debug: - self.step += 1 - return self.bot.request(self.test_path[self.step][0]) - return self.bot.request() + update_list = [] + for i in self.bot.request(): + update_list.append( + extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) + ) + return update_list def _respond(self, response): - for resp in response: - self.bot.send_message(resp.last_response, resp.id) + if response.attachments is not None: + attachment_list = [] + for attachment in response.attachments: + if isinstance(attachment, Image): + attachment_list.append({"type": "photo", "source": attachment.source}) + elif isinstance(attachment, Document): + attachment_list.append({"doc": "photo", "source": attachment.source}) + elif isinstance(attachment, Video): + raise NotImplementedError() + elif isinstance(attachment, Audio): + attachment_list.append({"audio": "photo", "source": attachment.source}) + # elif isinstance(attachment, Link): + # response.text += f"[{attachment.source}|{attachment.title}]" + self.bot.send_message(resp.last_response, resp.id, attachment_list) logger.info("Responded.") @@ -406,4 +259,4 @@ def _respond(self, response): async def connect(self, callback, loop: Optional[Callable] = None, *args, **kwargs): await super().connect( callback, loop=lambda: True, timeout=1 - ) + ) \ No newline at end of file diff --git a/tests/messengers/vk/__init__.py b/tests/messengers/vk/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_incoming.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/messengers/vk/test_outgoing.py b/tests/messengers/vk/test_outgoing.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/messengers/vk/vk_dummy.py b/tests/messengers/vk/vk_dummy.py new file mode 100644 index 000000000..2e6e910d4 --- /dev/null +++ b/tests/messengers/vk/vk_dummy.py @@ -0,0 +1,71 @@ +import logging +import requests +import io +import os + +from dff.messengers.vk import extract_vk_update +from dff.script.core.message import ( + Audio, + Document, + Image, + Message, + Video, + Link +) + + +def generate_random_data(data_type): + if data_type == "url": + return "https://www.something.com/" + elif data_type == "num": + return 12345 + +class VK_dummy: + # functionality of the VK_Bot but without actual API calls + def __init__(self) -> None: + self.parsed_updates = {} + self.parsed_updates_count = 0 + self.responses = {} + self.responses_count = 0 + + def _request(self, updates=None): + update_list = [] + self.parsed_updates[self.parsed_updates_count] = [] + if updates is None: + self.bot.request() + + for u in updates: + parsed_upd = extract_vk_update((u['object']['message']['text'], u['object']['message']['from_id'])) + update_list.append( + parsed_upd + ) + self.parsed_updates[self.parsed_updates_count].append((u, parsed_upd)) + + self.parsed_updates_count += 1 + return update_list + + def _respond(self, response): + self.responses[self.responses_count] = [] + for resp in response: + if response.attachments is not None: + attachment_list = [] + for attachment in response.attachments: + if isinstance(attachment, Image): + attachment_list.append({"type": "photo", "source": attachment.source}) + elif isinstance(attachment, Document): + attachment_list.append({"doc": "photo", "source": attachment.source}) + elif isinstance(attachment, Video): + raise NotImplementedError() + elif isinstance(attachment, Audio): + attachment_list.append({"audio": "photo", "source": attachment.source}) + # elif isinstance(attachment, Link): + # response.text += f"[{attachment.source}|{attachment.title}]" + send_request = self.bot.send_message(resp.last_response, resp.id, attachment_list) + self.responses[self.responses_count].append((resp, send_request)) + self.responses_count += 1 + + def get_dialogue(self): + return self.responses + + def get_requests(self): + return self.parsed_updates \ No newline at end of file From 28959f48e9dc4de266b236ecb0a33d88ba857111 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 25 Apr 2024 18:09:56 +0300 Subject: [PATCH 071/140] Updated VKDummy, redone VK_Bot as VKWrapper --- dff/messengers/vk.py | 224 ++++++++++++++------------------ tests/messengers/vk/vk_dummy.py | 76 +---------- 2 files changed, 107 insertions(+), 193 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 98687a6b5..8aae5b0ac 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -2,10 +2,10 @@ Interface ------------ """ -from typing import Callable, Optional, Sequence, cast -from pydantic import HttpUrl -import asyncio -import aiofiles + +from typing import Callable, Optional +# import asyncio +# import aiofiles import aiohttp import logging @@ -15,20 +15,12 @@ from dff.messengers.common import PollingMessengerInterface -from dff.script.core.message import ( - Audio, - Document, - Image, - Message, - Video, - Link -) - -from dff.script.extra_types import Poll +from dff.script.core.message import Audio, Document, Image, Message, Video logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) + async def vk_api_call(method, payload={}, headers={}): async with aiohttp.ClientSession() as session: async with session.post(method) as response: @@ -38,21 +30,14 @@ async def vk_api_call(method, payload={}, headers={}): def extract_vk_update(updates): upds = [] for i in updates["updates"]: - text, id = i['object']['message']['text'], i['object']['message']['from_id'] + text, id = i["object"]["message"]["text"], i["object"]["message"]["from_id"] message = Message(text=text) - upds.append( - message, int(id) - ) + upds.append(message, int(id)) return upds -class VK_Poll(): - def __init__(self) -> None: - raise NotImplementedError() - - class FilesOpener(object): - def __init__(self, paths, key_format='file{}'): + def __init__(self, paths, key_format="file{}"): if not isinstance(paths, list): paths = [paths] @@ -72,19 +57,19 @@ def open_files(self): files = [] for x, file in enumerate(self.paths): - if hasattr(file, 'read'): + if hasattr(file, "read"): f = file - filename = file.name if hasattr(file, 'name') else '.jpg' + filename = file.name if hasattr(file, "name") else ".jpg" else: filename = file if "http" in filename: f = io.BytesIO(requests.get(filename).content) else: - f = open(filename, 'rb') + f = open(filename, "rb") self.opened_files.append(f) - ext = filename.split('.')[-1] + ext = filename.split(".")[-1] _, filename = os.path.split(filename) files.append((self.key_format.format(x), (filename, f))) @@ -97,166 +82,157 @@ def close_files(self): self.opened_files = [] -class VK_Bot: +class VKWrapper: def __init__(self, token: str, group_id: str) -> None: self.token = token self.group_id = group_id - server_request = requests.post(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}").json() + + def connect(self): + server_request = self.get_longpoll_server() + if "response" not in server_request: raise Exception(f"Errror getting longpoll server\n{server_request}") - - self.server = server_request['response']['server'] - self.ts_base = int(server_request['response']['ts']) + + self.server = server_request["response"]["server"] + self.ts_base = int(server_request["response"]["ts"]) self.ts_current = self.ts_base - self.server_key = server_request['response']['key'] + self.server_key = server_request["response"]["key"] self.last_update_id = None self._last_processed_update = None - - def upload_attachment( - self, peer_id, attachment, attachment_type: str - ) -> str: + + def get_longpoll_server(self): + return requests.post( + f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + + def get_upload_server(self, data_type, peer_id): + upload_url = requests.post( + f"https://api.vk.com/method/{data_type}.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + + if "response" not in upload_url: + logger.error(f"Error getting upload server for attachment\n{upload_url}") + raise Exception() + + return upload_url["response"]["upload_url"] + + def save_attachment(self, uploaded_data, data_type): + if data_type == "photos": + saved_data = requests.post( + f"https://api.vk.com/method/{data_type}.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_data['photo']}&server={uploaded_data['server']}&hash={uploaded_data['hash']}" + ).json() + else: + saved_data = requests.post( + f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ).json() + + if "response" not in saved_data: + logger.error(f"Error saving attachment\n{saved_data}") + raise Exception() + + return saved_data["response"] + + def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: """ Return json object with `owner_id` and `photo_id` needed to send it """ if attachment_type == "photo": - upload_url = requests.post( - f"https://api.vk.com/method/photos.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() - - if "response" not in upload_url: - logger.error(f"Error getting upload server for image\n{upload_url}") - raise Exception() - - upload_url = upload_url["response"]["upload_url"] + upload_url = self.get_upload_server("photos", peer_id) attachment_path = str(attachment.source) logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path) as photo_files: - uploaded_photo_data = requests.post(upload_url, files=photo_files).json() - - saved_photo_data = requests.post(f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_photo_data['photo']}&server={uploaded_photo_data['server']}&hash={uploaded_photo_data['hash']}").json() - - if "response" not in saved_photo_data: - logger.error(f"Error saving photo\n{saved_photo_data}") - raise Exception() - - return saved_photo_data["response"] - - elif attachment_type == "doc": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() - attachment_path = str(attachment.source) - - if "response" not in upload_url: - logger.error(f"Errror getting upload server for document\n{upload_url}") - raise Exception() - - upload_url = upload_url["response"]["upload_url"] + uploaded_photo_data = requests.post( + upload_url, files=photo_files + ).json() - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() + saved_photo_data = self.save_attachment(uploaded_photo_data, "photos") - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - if "response" not in saved_doc_data: - logger.error(f"Error saving document\n{saved_doc_data}") - raise Exception() - - return saved_doc_data["response"] - - elif attachment_type == "audio": - upload_url = requests.post( - f"https://api.vk.com/method/docs.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}&type=audio_message" - ).json() + return saved_photo_data + + elif attachment_type == "doc" or attachment_type == "audio": + upload_url = self.get_upload_server("docs", peer_id) attachment_path = str(attachment.source) - - if "response" not in upload_url: - logger.error(f"Errror getting upload server for audio\n{upload_url}") - raise Exception() - - upload_url = upload_url["response"]["upload_url"] - + logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = requests.post(upload_url, files=files).json() - saved_doc_data = requests.post(f"https://api.vk.com/method/docs.save?file={uploaded_photo_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}").json() - - if "response" not in saved_doc_data: - logger.error(f"Error saving audio\n{saved_doc_data}") - raise Exception() - + saved_doc_data = self.save_attachment(uploaded_photo_data, "docs") + return saved_doc_data["response"] - + elif attachment_type == "video": raise NotImplementedError() - + def request(self): - updates = requests.post(f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50").json() - self.ts_current = updates['ts'] + updates = requests.post( + f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50" + ).json() + self.ts_current = updates["ts"] return updates["updates"] def send_message(self, response, id, attachment_list): if attachment_list != []: for attachment in attachment_list: - data_to_send = self.upload_attachment(id, attachment["source"], attachment["type"]) - attachment_list.append(f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}") + data_to_send = self.upload_attachment( + id, attachment["source"], attachment["type"] + ) + attachment_list.append( + f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}" + ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" - attachment_string = ','.join(attachment_list).strip(',') - + attachment_string = ",".join(attachment_list).strip(",") + api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" else: api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}" - - return requests.post(api_request).json + + return requests.post(api_request).json() class PollingVKInterface(PollingMessengerInterface): - def __init__(self, token: str, group_id: str, debug=True, test_path=None) -> None: + def __init__(self, token: str, group_id: str) -> None: super().__init__() - self.test_path = test_path - self.debug = debug - self.step = -1 - if not debug: - self.bot = VK_Bot(token, group_id) - # else: - # self.bot = VK_dummy(token, group_id) - + self.bot = VKWrapper(token, group_id) def _request(self): update_list = [] for i in self.bot.request(): update_list.append( - extract_vk_update((i['object']['message']['text'], i['object']['message']['from_id'])) + extract_vk_update( + (i["object"]["message"]["text"], i["object"]["message"]["from_id"]) + ) ) return update_list - def _respond(self, response): for resp in response: if response.attachments is not None: attachment_list = [] for attachment in response.attachments: if isinstance(attachment, Image): - attachment_list.append({"type": "photo", "source": attachment.source}) + attachment_list.append( + {"type": "photo", "source": attachment.source} + ) elif isinstance(attachment, Document): - attachment_list.append({"doc": "photo", "source": attachment.source}) + attachment_list.append( + {"doc": "photo", "source": attachment.source} + ) elif isinstance(attachment, Video): raise NotImplementedError() elif isinstance(attachment, Audio): - attachment_list.append({"audio": "photo", "source": attachment.source}) + attachment_list.append( + {"audio": "photo", "source": attachment.source} + ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" self.bot.send_message(resp.last_response, resp.id, attachment_list) logger.info("Responded.") - async def connect(self, callback, loop: Optional[Callable] = None, *args, **kwargs): - await super().connect( - callback, loop=lambda: True, timeout=1 - ) \ No newline at end of file + self.bot.connect() + await super().connect(callback, loop=lambda: True, timeout=1) diff --git a/tests/messengers/vk/vk_dummy.py b/tests/messengers/vk/vk_dummy.py index 2e6e910d4..1f7dc6361 100644 --- a/tests/messengers/vk/vk_dummy.py +++ b/tests/messengers/vk/vk_dummy.py @@ -1,71 +1,9 @@ -import logging -import requests -import io -import os - -from dff.messengers.vk import extract_vk_update -from dff.script.core.message import ( - Audio, - Document, - Image, - Message, - Video, - Link -) - - -def generate_random_data(data_type): - if data_type == "url": - return "https://www.something.com/" - elif data_type == "num": - return 12345 - -class VK_dummy: - # functionality of the VK_Bot but without actual API calls - def __init__(self) -> None: - self.parsed_updates = {} - self.parsed_updates_count = 0 - self.responses = {} - self.responses_count = 0 - - def _request(self, updates=None): - update_list = [] - self.parsed_updates[self.parsed_updates_count] = [] - if updates is None: - self.bot.request() - - for u in updates: - parsed_upd = extract_vk_update((u['object']['message']['text'], u['object']['message']['from_id'])) - update_list.append( - parsed_upd - ) - self.parsed_updates[self.parsed_updates_count].append((u, parsed_upd)) - - self.parsed_updates_count += 1 - return update_list - - def _respond(self, response): - self.responses[self.responses_count] = [] - for resp in response: - if response.attachments is not None: - attachment_list = [] - for attachment in response.attachments: - if isinstance(attachment, Image): - attachment_list.append({"type": "photo", "source": attachment.source}) - elif isinstance(attachment, Document): - attachment_list.append({"doc": "photo", "source": attachment.source}) - elif isinstance(attachment, Video): - raise NotImplementedError() - elif isinstance(attachment, Audio): - attachment_list.append({"audio": "photo", "source": attachment.source}) - # elif isinstance(attachment, Link): - # response.text += f"[{attachment.source}|{attachment.title}]" - send_request = self.bot.send_message(resp.last_response, resp.id, attachment_list) - self.responses[self.responses_count].append((resp, send_request)) - self.responses_count += 1 +class VKDummy: + def __init__(self): + self.requests = [] - def get_dialogue(self): - return self.responses + def __getattribute__(self, name): + def send_message(*args, **kwargs): + self.requests.append((name, args, kwargs)) + return send_message - def get_requests(self): - return self.parsed_updates \ No newline at end of file From 17280e37046986f4d3ebe36693089190fcc0e9ed Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 26 Apr 2024 15:00:19 +0200 Subject: [PATCH 072/140] `cached_filename` field added --- dff/messengers/common/interface.py | 8 +++++--- dff/messengers/telegram/abstract.py | 13 ++++++------- dff/script/core/message.py | 21 ++++++++++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 5c9d8fc07..01ec650ba 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -56,9 +56,8 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction): """ raise NotImplementedError - async def populate_attachment(self, attachment: DataAttachment) -> None: - if attachment.source is None: - raise NotImplementedError + async def populate_attachment(self, attachment: DataAttachment) -> bytes: + raise RuntimeError(f"Messanger interface {type(self).__name__} can't populate attachment {attachment}!") class PollingMessengerInterface(MessengerInterface): @@ -135,6 +134,9 @@ async def connect( self._on_exception(e) break + async def populate_attachment(self, attachment: DataAttachment) -> bytes: + raise RuntimeError(f"Plain pollin") + class CallbackMessengerInterface(MessengerInterface): """ diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 6b62ccdfc..23f83977f 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -61,14 +61,13 @@ def __init__(self, token: str, attachments_directory: Optional[Path] = None) -> self.application.add_handler(MessageHandler(ALL, self.on_message)) self.application.add_handler(CallbackQueryHandler(self.on_callback)) - async def populate_attachment(self, attachment: DataAttachment) -> None: # pragma: no cover - if attachment.title is not None and attachment.id is not None: - file_name = self.attachments_directory / str(attachment.title) - if not file_name.exists(): - await (await self.application.bot.get_file(attachment.id)).download_to_drive(file_name) - attachment.source = FilePath(file_name) + async def populate_attachment(self, attachment: DataAttachment) -> bytes: # pragma: no cover + if attachment.id is not None: + file = await self.application.bot.get_file(attachment.id) + data = await file.download_as_bytearray() + return bytes(data) else: - raise ValueError(f"For attachment {attachment} title or id is not defined!") + raise ValueError(f"For attachment {attachment} id is not defined!") def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover message = Message() diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 5d437fcfc..73e8bc1fa 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -9,6 +9,7 @@ from enum import Enum, auto from pathlib import Path from urllib.request import urlopen +from uuid import uuid4 from pydantic import Field, field_validator, FilePath, HttpUrl, BaseModel, model_validator from pydantic_core import Url @@ -98,20 +99,30 @@ class DataAttachment(Attachment): """ source: Optional[Union[HttpUrl, FilePath]] = None + cached_filename: Optional[FilePath] = None id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None - async def get_bytes(self, from_messenger_interface: MessengerInterface) -> Optional[bytes]: - if self.source is None: - await from_messenger_interface.populate_attachment(self) + async def _cache_attachment(self, data: bytes, directory: Path) -> None: + title = str(uuid4()) if self.title is None else self.title + self.cached_filename = directory / title + with open(self.cached_filename, "wb") as file: + file.write(data) + + async def get_bytes(self, from_interface: MessengerInterface) -> Optional[bytes]: if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() + elif isinstance(self.cached_filename, Path): + with open(self.cached_filename, "rb") as file: + return file.read() elif isinstance(self.source, Url): with urlopen(self.source.unicode_string()) as url: - return url.read() + attachment_data = url.read() else: - return None + attachment_data = await from_interface.populate_attachment(self) + await self._cache_attachment(attachment_data, from_interface.attachments_directory) + return attachment_data def __eq__(self, other): if isinstance(other, DataAttachment): From 2a1f01a0f4d0b7303ab0d99f54f1ec5e2052b69d Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 26 Apr 2024 17:12:36 +0200 Subject: [PATCH 073/140] Tutorial texts altered. --- tutorials/messengers/telegram/1_basic.py | 12 ++-- .../messengers/telegram/2_attachments.py | 26 ++++----- tutorials/messengers/telegram/3_advanced.py | 56 ++++++++++++++----- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/tutorials/messengers/telegram/1_basic.py b/tutorials/messengers/telegram/1_basic.py index ce750afea..9252e96f1 100644 --- a/tutorials/messengers/telegram/1_basic.py +++ b/tutorials/messengers/telegram/1_basic.py @@ -5,8 +5,8 @@ The following tutorial shows how to run a regular DFF script in Telegram. It asks users for the '/start' command and then loops in one place. -Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) -class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) +Here, %mddoclink(api,messengers.telegram.interface,PollingTelegramInterface) +class and [python-telegram-bot](https://docs.python-telegram-bot.org/) library are used for accessing telegram API in polling mode. Telegram API token is required to access telegram API. @@ -29,11 +29,11 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) """ In order to integrate your script with Telegram, you need an instance of `TelegramMessenger` class and one of the following interfaces: -`PollingMessengerInterface` or `WebhookMessengerInterface`. +`PollingMessengerInterface` or `CallbackTelegramInterface`. -`TelegramMessenger` encapsulates the bot logic. Like Telebot, -`TelegramMessenger` only requires a token to run. However, all parameters -from the Telebot class can be passed as keyword arguments. +`TelegramMessenger` encapsulates the bot logic. The` only required +argument for a bot to run is a token. Some other parameters +(such as host, port, interval, etc.) can be passed as keyword arguments. The two interfaces connect the bot to Telegram. They can be passed directly to the DFF `Pipeline` instance. diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index 23b675352..7e144c29a 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -2,11 +2,11 @@ """ # Telegram: 2. Attachments -The following tutorial shows how to run a regular DFF script in Telegram. -It asks users for the '/start' command and then loops in one place. +The following tutorial shows how to send different attachments using +telegram interfaces. -Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) -class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) +Here, %mddoclink(api,messengers.telegram.interface,PollingTelegramInterface) +class and [python-telegram-bot](https://docs.python-telegram-bot.org/) library are used for accessing telegram API in polling mode. Telegram API token is required to access telegram API. @@ -29,16 +29,9 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) # %% [markdown] """ -In order to integrate your script with Telegram, you need an instance of -`TelegramMessenger` class and one of the following interfaces: -`PollingMessengerInterface` or `WebhookMessengerInterface`. - -`TelegramMessenger` encapsulates the bot logic. Like Telebot, -`TelegramMessenger` only requires a token to run. However, all parameters -from the Telebot class can be passed as keyword arguments. - -The two interfaces connect the bot to Telegram. They can be passed directly -to the DFF `Pipeline` instance. +Example attachment data is specified below in form of dictionaries. +List of attachments that telegram messenger interface can send can be found here: +%mddoclink(api,messengers.telegram.abstract,_AbstractTelegramInterface#response_attachments). """ # %% @@ -81,6 +74,11 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) } +# %% [markdown] +""" +The bot below sends different attachments on request. +""" + # %% script = { GLOBAL: { diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 72bc54d4f..be6b90336 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -2,11 +2,10 @@ """ # Telegram: 3. Advanced -The following tutorial shows how to run a regular DFF script in Telegram. -It asks users for the '/start' command and then loops in one place. +The following tutorial shows several advanced cases of user-to-bot interaction. -Here, %mddoclink(api,messengers.telegram,PollingTelegramInterface) -class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) +Here, %mddoclink(api,messengers.telegram.interface,PollingTelegramInterface) +class and [python-telegram-bot](https://docs.python-telegram-bot.org/) library are used for accessing telegram API in polling mode. Telegram API token is required to access telegram API. @@ -26,6 +25,7 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) from dff.script import RESPONSE, TRANSITIONS, Message from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline +from dff.script.core.context import Context from dff.script.core.keywords import GLOBAL from dff.script.core.message import Document, Image, Location, Sticker from dff.utils.testing.common import is_interactive_mode @@ -33,16 +33,19 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) # %% [markdown] """ -In order to integrate your script with Telegram, you need an instance of -`TelegramMessenger` class and one of the following interfaces: -`PollingMessengerInterface` or `WebhookMessengerInterface`. - -`TelegramMessenger` encapsulates the bot logic. Like Telebot, -`TelegramMessenger` only requires a token to run. However, all parameters -from the Telebot class can be passed as keyword arguments. - -The two interfaces connect the bot to Telegram. They can be passed directly -to the DFF `Pipeline` instance. +This bot shows different special telegram messenger interface use cases, +such as: + +1. Interactive keyboard with buttons. +2. Text formatted with Markdown V2. +3. Multiple attachments of different kind handling. +4. Image with a spoiler. +5. Document with a thumbnail. +6. Raw representation of different data user can send to the bot. + +Last option ("Raw attachments!") button might be especially interesting, +because it shows how bot precepts different telegram attachments sent by user +in terms and datastructures of Dialog Flow Framework. """ #%% @@ -79,6 +82,20 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) } +# %% +formatted_request = r""" +Here's your previous request\! +```json +{} +``` +Run /start command again to restart\. +""" + +def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: + dump = ctx.last_request.model_dump_json(indent=4) + return Message(formatted_request.format(dump), parse_mode=ParseMode.MARKDOWN_V2) + + # %% script = { GLOBAL: { @@ -108,6 +125,9 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) [ InlineKeyboardButton("Document with thumbnail!", callback_data="thumbnail"), ], + [ + InlineKeyboardButton("Raw attachments!", callback_data="raw"), + ], [ InlineKeyboardButton("Restart!", callback_data="restart"), InlineKeyboardButton("Quit!", callback_data="quit"), @@ -122,6 +142,7 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) "attachments_node": cnd.has_callback_query("attachments"), "secret_node": cnd.has_callback_query("secret"), "thumbnail_node": cnd.has_callback_query("thumbnail"), + "raw_init_node": cnd.has_callback_query("raw"), "hmmm_node": cnd.has_callback_query("restart"), "fallback_node": cnd.has_callback_query("quit"), } @@ -150,6 +171,13 @@ class and [telebot](https://pytba.readthedocs.io/en/latest/index.html) attachments=[Document(**document_data)], ), }, + "raw_init_node": { + RESPONSE: Message("Alright! Now send me any message and I'll send you it's raw data!"), + TRANSITIONS: { "raw_request_node": cnd.true }, + }, + "raw_request_node": { + RESPONSE: stringify_previous_request, + }, "fallback_node": { RESPONSE: Message("Bot has entered unrecoverable state :/\nRun /start command again to restart."), }, From fb58bda9bc8f1a913478186d6b403c3eb8085e3e Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 26 Apr 2024 21:41:09 +0200 Subject: [PATCH 074/140] happy path removed, use cache flag added --- dff/script/core/message.py | 6 ++++-- tutorials/messengers/telegram/1_basic.py | 7 ------- tutorials/messengers/telegram/2_attachments.py | 7 ------- tutorials/messengers/telegram/3_advanced.py | 7 ------- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 73e8bc1fa..d02742cbf 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -102,6 +102,7 @@ class DataAttachment(Attachment): cached_filename: Optional[FilePath] = None id: Optional[str] = None # id field is made separate to simplify type validation title: Optional[str] = None + use_cache: bool = True async def _cache_attachment(self, data: bytes, directory: Path) -> None: title = str(uuid4()) if self.title is None else self.title @@ -113,7 +114,7 @@ async def get_bytes(self, from_interface: MessengerInterface) -> Optional[bytes] if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() - elif isinstance(self.cached_filename, Path): + elif self.cached_filename is not None: with open(self.cached_filename, "rb") as file: return file.read() elif isinstance(self.source, Url): @@ -121,7 +122,8 @@ async def get_bytes(self, from_interface: MessengerInterface) -> Optional[bytes] attachment_data = url.read() else: attachment_data = await from_interface.populate_attachment(self) - await self._cache_attachment(attachment_data, from_interface.attachments_directory) + if self.use_cache: + await self._cache_attachment(attachment_data, from_interface.attachments_directory) return attachment_data def __eq__(self, other): diff --git a/tutorials/messengers/telegram/1_basic.py b/tutorials/messengers/telegram/1_basic.py index 9252e96f1..5d557c604 100644 --- a/tutorials/messengers/telegram/1_basic.py +++ b/tutorials/messengers/telegram/1_basic.py @@ -57,13 +57,6 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) } } -# this variable is only for testing -happy_path = ( - (Message("/start"), Message("Hi")), - (Message("Hi"), Message("Hi")), - (Message("Bye"), Message("Hi")), -) - # %% interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index 7e144c29a..9694bbba8 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -178,13 +178,6 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) } } -# this variable is only for testing -happy_path = ( - (Message("/start"), Message("Hi")), - (Message("Hi"), Message("Hi")), - (Message("Bye"), Message("Hi")), -) - # %% interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index be6b90336..1ba3bf5a9 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -184,13 +184,6 @@ def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: } } -# this variable is only for testing -happy_path = ( - (Message("/start"), Message("Hi")), - (Message("Hi"), Message("Hi")), - (Message("Bye"), Message("Hi")), -) - # %% interface = PollingTelegramInterface(token=os.environ["TG_BOT_TOKEN"]) From 2f3c52833039c55c7b05961d13d582ea7acad4d3 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Sat, 27 Apr 2024 13:44:20 +0300 Subject: [PATCH 075/140] Implementing tests with VKDummy --- dff/messengers/vk.py | 5 ++++- tests/messengers/vk/test_incoming.py | 23 +++++++++++++++++++++++ tests/messengers/vk/vk_dummy.py | 11 ++++++----- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 8aae5b0ac..ff16b8624 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -210,6 +210,7 @@ def _request(self): def _respond(self, response): for resp in response: + attachment_list = [] if response.attachments is not None: attachment_list = [] for attachment in response.attachments: @@ -229,7 +230,9 @@ def _respond(self, response): ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" - self.bot.send_message(resp.last_response, resp.id, attachment_list) + # self.bot.send_message(resp.last_response, resp.id, attachment_list) + self.bot.send_message("resp", "id", attachment_list) + logger.info("Responded.") diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_incoming.py index e69de29bb..236eb1d9c 100644 --- a/tests/messengers/vk/test_incoming.py +++ b/tests/messengers/vk/test_incoming.py @@ -0,0 +1,23 @@ +import pytest +import json +from vk_dummy import VKDummy +from dff.messengers.vk import PollingVKInterface + +@pytest.fixture +def patch_interface(): + iface = PollingVKInterface(token="", group_id="") + iface.bot = VKDummy() + return iface + +# incoming_data.json {"case1": [], "case2": []} + +# incoming_data.json {"case1": [incoming_http_request, parsed_dff_request], "case2": []} +with open("incoming_data.json") as f: + incoming_data = json.load(f) + +# incoming_data = map({...}) +@pytest.mark.parametrize("incoming_http_request,parsed_dff_request", list(map(tuple, incoming_data.values()))) +def test_data_parsing(incoming_http_request, parsed_dff_request, patched_interface): + assert parsed_dff_request == patched_interface._request(incoming_http_request) + + diff --git a/tests/messengers/vk/vk_dummy.py b/tests/messengers/vk/vk_dummy.py index 1f7dc6361..6e44d610e 100644 --- a/tests/messengers/vk/vk_dummy.py +++ b/tests/messengers/vk/vk_dummy.py @@ -1,9 +1,10 @@ class VKDummy: def __init__(self): - self.requests = [] + self.responses = [] def __getattribute__(self, name): - def send_message(*args, **kwargs): - self.requests.append((name, args, kwargs)) - return send_message - + def method(*args, **kwargs): + self.responses.append((name, args, kwargs)) + if name in ("responses",): + return super(self).__getattribute__(name) + return method From a2e0ca3e2d40d7888676fd3c261540be527af4c2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 2 May 2024 01:08:30 +0200 Subject: [PATCH 076/140] literals added + tests started --- dff/messengers/telegram/abstract.py | 3 - dff/script/core/message.py | 20 ++++-- .../messengers/telegram/test_happy_paths.json | 11 +++ tests/messengers/telegram/test_tutorials.py | 18 +++++ tests/messengers/telegram/utils.py | 69 +++++++++++++++++++ 5 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 tests/messengers/telegram/test_happy_paths.json create mode 100644 tests/messengers/telegram/test_tutorials.py create mode 100644 tests/messengers/telegram/utils.py diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 23f83977f..3033f7f10 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -7,12 +7,9 @@ from pathlib import Path from typing import Callable, Optional -from pydantic import FilePath try: from telegram import ( - InlineKeyboardButton, - InlineKeyboardMarkup, InputMediaAnimation, InputMediaAudio, InputMediaDocument, diff --git a/dff/script/core/message.py b/dff/script/core/message.py index d02742cbf..8abb05fa2 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -5,7 +5,7 @@ DFF. It only contains types and properties that are compatible with most messaging services. """ -from typing import Any, Optional, List, Union +from typing import Any, Literal, Optional, List, Union from enum import Enum, auto from pathlib import Path from urllib.request import urlopen @@ -49,6 +49,7 @@ class Attachment(DataModel): class CallbackQuery(Attachment): query_string: Optional[str] + type: Literal["callback_query"] = "callback_query" class Location(Attachment): @@ -62,6 +63,7 @@ class Location(Attachment): longitude: float latitude: float + type: Literal["location"] = "location" def __eq__(self, other): if isinstance(other, Location): @@ -73,6 +75,7 @@ class Contact(Attachment): phone_number: str first_name: str last_name: Optional[str] + type: Literal["contact"] = "contact" class Invoice(Attachment): @@ -80,16 +83,19 @@ class Invoice(Attachment): description: str currency: str amount: int + type: Literal["invoice"] = "invoice" class PollOption(DataModel): text: str votes: int = Field(default=0) + type: Literal["poll_option"] = "poll_option" class Poll(Attachment): question: str options: List[PollOption] + type: Literal["poll"] = "poll" class DataAttachment(Attachment): @@ -155,37 +161,37 @@ def validate_source(cls, value): class Audio(DataAttachment): """Represents an audio file attachment.""" - pass + type: Literal["audio"] = "audio" class Video(DataAttachment): """Represents a video file attachment.""" - pass + type: Literal["video"] = "video" class Animation(DataAttachment): """Represents an animation file attachment.""" - pass + type: Literal["animation"] = "animation" class Image(DataAttachment): """Represents an image file attachment.""" - pass + type: Literal["image"] = "image" class Sticker(DataAttachment): """Represents a sticker as a file attachment.""" - pass + type: Literal["sticker"] = "sticker" class Document(DataAttachment): """Represents a document file attachment.""" - pass + type: Literal["document"] = "document" class Message(DataModel): diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json new file mode 100644 index 000000000..145f62094 --- /dev/null +++ b/tests/messengers/telegram/test_happy_paths.json @@ -0,0 +1,11 @@ +{ + "1_basic": { + + }, + "2_attachments": { + + }, + "3_advanced": { + + } +} diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py new file mode 100644 index 000000000..17d20074a --- /dev/null +++ b/tests/messengers/telegram/test_tutorials.py @@ -0,0 +1,18 @@ +from importlib import import_module +from pathlib import Path +import pytest + +from tests.test_utils import get_path_from_tests_to_current_dir + +dot_path_to_addon = get_path_from_tests_to_current_dir(__file__) +happy_paths_file = Path(__file__).parent / "test_happy_paths.json" + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + ["tutorial_module_name"], + [("1_basic"), ("2_attachments"), ("3_advanced")], +) +async def test_tutorials_memory(tutorial_module_name: str): + module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") + module.interface.application diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py new file mode 100644 index 000000000..b087cd1b3 --- /dev/null +++ b/tests/messengers/telegram/utils.py @@ -0,0 +1,69 @@ +from asyncio import get_event_loop +from typing import Any, Dict, Hashable, List, Optional, Tuple, TypeAlias +from pydantic import BaseModel + +from telegram import File, Update +from telegram.ext import ExtBot + +from dff.messengers.telegram.abstract import _AbstractTelegramInterface +from dff.script import Message +from dff.script.core.context import Context + +PathStep: TypeAlias = Tuple[Dict, Message, Message, Tuple[str, Tuple, Dict]] + + +class MockBot(BaseModel): + _original_bot: ExtBot + _latest_trace: Optional[Tuple[str, Tuple, Dict]] = None + + async def get_file(self, file_id: str) -> File: + return await self._original_bot.get_file(file_id) + + def __getattribute__(self, name: str) -> Any: + def set_trace(*args, **kwargs): + self._latest_trace = (name, args, kwargs) + + if hasattr(self, name): + return super().__getattribute__(name) + else: + return set_trace + + +class MockApplication(BaseModel): + mock_bot: MockBot + happy_path: List[PathStep] + _interface: _AbstractTelegramInterface + _latest_ctx: Optional[Context] = None + + @classmethod + def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep]) -> "MockApplication": + mock_bot = MockBot(_original_bot=interface.application.bot) + instance = cls(mock_bot=mock_bot, happy_path=happy_path, _interface=interface) + interface.pipeline_runner = instance._wrapped_pipeline_runner + return instance + + async def _wrapped_pipeline_runner(self, message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None) -> Context: + self._latest_ctx = await self._interface.pipeline_runner(message, ctx_id, update_ctx_misc) + return self._latest_ctx + + def _run_bot(self) -> None: + loop = get_event_loop() + for update, received, response, trace in self.happy_path: + if update["is_message"]: + update = Update() + loop.run_until_complete(self._interface.on_message(update, None)) # type: ignore + else: + update = Update() + loop.run_until_complete(self._interface.on_callback(update, None)) # type: ignore + assert self._latest_ctx is not None, "During pipeline runner execution, no context was produced!" + assert self._latest_ctx.last_request == received, "Expected request message is not equal to expected!" + assert self._latest_ctx.last_response == response, "Expected response message is not equal to expected!" + assert self.mock_bot._latest_trace == trace, "Expected trace is not equal to expected!" + self.mock_bot._latest_trace = None + self._latest_ctx = None + + def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: + return self._run_bot() + + def run_webhook(self, listen: str, port: str, allowed_updates: List[str]) -> None: + return self._run_bot() From decbef82c1e912bf7f1b420e70b82577cbc1d363 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Fri, 3 May 2024 18:02:52 +0300 Subject: [PATCH 077/140] Added test data --- tests/messengers/vk/incoming_data.json | 42 ++++++++++++++++++++++++++ tests/messengers/vk/outgoing_data.json | 10 ++++++ tests/messengers/vk/test_incoming.py | 12 +++----- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/messengers/vk/incoming_data.json create mode 100644 tests/messengers/vk/outgoing_data.json diff --git a/tests/messengers/vk/incoming_data.json b/tests/messengers/vk/incoming_data.json new file mode 100644 index 000000000..49270ceda --- /dev/null +++ b/tests/messengers/vk/incoming_data.json @@ -0,0 +1,42 @@ +{ + "case_1": [ + { + "ts": "4", + "updates": [ + { + "type": "message_new", + "event_id": "c68dfb983247fea8ac98ea0ea59717df71d8064f", + "v": "5.131", + "object": { + "message": { + "text": "hello", + "from_id": 1234 + }, + "client_info": {} + } + } + ] + }, + {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null} + ], + "case_2": [ + { + "ts": "4", + "updates": [ + { + "type": "message_new", + "event_id": "c68dfb983247fea8ac98ea0ea59717df71d8064f", + "v": "5.131", + "object": { + "message": { + "text": "goodbye", + "from_id": 1234 + }, + "client_info": {} + } + } + ] + }, + {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null} + ] +} \ No newline at end of file diff --git a/tests/messengers/vk/outgoing_data.json b/tests/messengers/vk/outgoing_data.json new file mode 100644 index 000000000..eb21f7979 --- /dev/null +++ b/tests/messengers/vk/outgoing_data.json @@ -0,0 +1,10 @@ +{ + "case_1": [ + {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null}, + "https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message=\"hello\"&v=5.81&access_token={self.token}" + ], + "case_2": [ + {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null}, + "https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message=\"goodbye\"&v=5.81&access_token={self.token}" + ] +} \ No newline at end of file diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_incoming.py index 236eb1d9c..2f500adb5 100644 --- a/tests/messengers/vk/test_incoming.py +++ b/tests/messengers/vk/test_incoming.py @@ -1,5 +1,6 @@ import pytest import json +from dff.script import Message from vk_dummy import VKDummy from dff.messengers.vk import PollingVKInterface @@ -9,15 +10,12 @@ def patch_interface(): iface.bot = VKDummy() return iface -# incoming_data.json {"case1": [], "case2": []} - -# incoming_data.json {"case1": [incoming_http_request, parsed_dff_request], "case2": []} with open("incoming_data.json") as f: - incoming_data = json.load(f) + incoming_data = json.load(f) + +for i in incoming_data: + incoming_data[i][1] = Message(text=incoming_data[i][1]["text"]) -# incoming_data = map({...}) @pytest.mark.parametrize("incoming_http_request,parsed_dff_request", list(map(tuple, incoming_data.values()))) def test_data_parsing(incoming_http_request, parsed_dff_request, patched_interface): assert parsed_dff_request == patched_interface._request(incoming_http_request) - - From 53e693e77f11674e95800d68a812cccebc573efb Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 6 May 2024 09:55:50 +0300 Subject: [PATCH 078/140] Pre-merge commit --- bot_test.py | 66 ++++++++++++++------------- dff/messengers/vk.py | 6 +-- test.py | 104 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 35 deletions(-) create mode 100644 test.py diff --git a/bot_test.py b/bot_test.py index f682df37f..00662f52e 100644 --- a/bot_test.py +++ b/bot_test.py @@ -9,36 +9,24 @@ script = { "greeting_flow": { - "start_node": { - TRANSITIONS: { - "greeting_node": cnd.exact_match(Message(text="Hello")) - }, + "start_node": { + RESPONSE: Message(), + TRANSITIONS: {"node1", cnd.exact_match(Message("Hi"))} }, - "greeting_node": { - RESPONSE: Message(text="Hello! What would you like to get?"), + "node1": { + RESPONSE: Message( + text="Hi, how are you?" + ), TRANSITIONS: { - "cat_image_node": cnd.exact_match(Message(text="cat")), - "book_file_node": cnd.exact_match(Message(text="book")) + "start_node": cnd.exact_match(Message("Nice")) }, }, - "cat_image_node": { - RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source="https://media.tenor.com/ff2BZlCK0SwAAAAM/gatin.gif"), Image(source="https://d2ph5fj80uercy.cloudfront.net/04/cat2634.jpg")]), - TRANSITIONS: { - "greeting_node": cnd.true() - } - }, - "book_file_node": { - RESPONSE: Message(text="Here is your book!", attachments=[Document(source="/home/askatasuna/Documents/DeepPavlov/DFF/dialog_flow_framework/LICENSE")]), - TRANSITIONS: { - "greeting_node": cnd.true() - } - }, "fallback_node": { - RESPONSE: Message(text="Please, repeat the request"), + RESPONSE: Message(text="Sorry, I don't understand."), TRANSITIONS: { - "greeting_node": cnd.exact_match(Message(text="/start")) - }, - }, + "start_node": cnd.true(), + } + } } } @@ -46,20 +34,34 @@ KEY = "vk1.a.BvmniZCwChZfKGPWTUtHiFOC1GOQ7M7ePur6y9cs9YpKuKXLKQLDGZDy5fxhiJAFWXNLAKazSRjFqpw5WByX1x-KiEU3HcIb4QHSG_utQMjnqQ4UOYXcT7pn-8nUeo4hnf-nH4BIB3fdwq0WhZLTcnlLAok2sxd_yR2q8LVzElc-7rhZAuyNDcLzOxFx9Z9P3xsg5EEhDFBcWRvGk_1R1Q" GROUP_ID = "224377718" -interface = PollingVKInterface(token=KEY, group_id=GROUP_ID) +# interface = PollingVKInterface(token=KEY, group_id=GROUP_ID) + + +# def main(): +# pipeline.run() +# if __name__ == "__main__": +# main() + +from dff.messengers.vk import PollingVKInterface +from dff.script.core.message import Message +from tests.messengers.vk.vk_dummy import VKDummy + +vk_dummy = VKDummy() +vk_interface = PollingVKInterface(KEY, GROUP_ID) +# vk_interface.bot = vk_dummy + pipeline = Pipeline.from_script( script=script, start_label=("greeting_flow", "start_node"), fallback_label=("greeting_flow", "fallback_node"), - messenger_interface=interface, + messenger_interface=vk_interface, # The interface can be passed as a pipeline argument. ) +pipeline.run() +# vk_interface._respond(Message(text="text")) +# from tests.messengers.vk.vk_dummy import responses +# print(responses) -def main(): - pipeline.run() - - -if __name__ == "__main__": - main() +# vk_dummy.requests == [("send_message", None, {"id": 1212, "message": "text})] \ No newline at end of file diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index ff16b8624..79f5960ea 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -173,7 +173,7 @@ def request(self): self.ts_current = updates["ts"] return updates["updates"] - def send_message(self, response, id, attachment_list): + def send_message(self, response: str, id, attachment_list): if attachment_list != []: for attachment in attachment_list: data_to_send = self.upload_attachment( @@ -186,9 +186,9 @@ def send_message(self, response, id, attachment_list): # response.text += f"[{attachment.source}|{attachment.title}]" attachment_string = ",".join(attachment_list).strip(",") - api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" + api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" else: - api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response.text}&v=5.81&access_token={self.token}" + api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response}&v=5.81&access_token={self.token}" return requests.post(api_request).json() diff --git a/test.py b/test.py new file mode 100644 index 000000000..50a465349 --- /dev/null +++ b/test.py @@ -0,0 +1,104 @@ +from dff.script import TRANSITIONS, RESPONSE, Message +from dff.pipeline import Pipeline +import dff.script.conditions as cnd + +from dff.utils.testing.common import ( + check_happy_path, + is_interactive_mode, + run_interactive_mode, +) + +toy_script = { + "greeting_flow": { + "start_node": { # This is the initial node, + # it doesn't contain a `RESPONSE`. + RESPONSE: Message(), + TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))}, + # If "Hi" == request of the user then we make the transition. + }, + "node1": { + RESPONSE: Message( + text="Hi, how are you?" + ), # When the agent enters node1, + # return "Hi, how are you?". + TRANSITIONS: { + "node2": cnd.exact_match(Message("I'm fine, how are you?")) + }, + }, + "node2": { + RESPONSE: Message("Good. What do you want to talk about?"), + TRANSITIONS: { + "node3": cnd.exact_match(Message("Let's talk about music.")) + }, + }, + "node3": { + RESPONSE: Message("Sorry, I can not talk about music now."), + TRANSITIONS: {"node4": cnd.exact_match(Message("Ok, goodbye."))}, + }, + "node4": { + RESPONSE: Message("Bye"), + TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))}, + }, + "fallback_node": { + # We get to this node if the conditions + # for switching to other nodes are not performed. + RESPONSE: Message("Ooops"), + TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))}, + }, + } +} + + +happy_path = ( + ( + Message("Hi"), + Message("Hi, how are you?"), + ), # start_node -> node1 + ( + Message("I'm fine, how are you?"), + Message("Good. What do you want to talk about?"), + ), # node1 -> node2 + ( + Message("Let's talk about music."), + Message("Sorry, I can not talk about music now."), + ), # node2 -> node3 + (Message("Ok, goodbye."), Message("Bye")), # node3 -> node4 + (Message("Hi"), Message("Hi, how are you?")), # node4 -> node1 + (Message("stop"), Message("Ooops")), # node1 -> fallback_node + ( + Message("stop"), + Message("Ooops"), + ), # fallback_node -> fallback_node + ( + Message("Hi"), + Message("Hi, how are you?"), + ), # fallback_node -> node1 + ( + Message("I'm fine, how are you?"), + Message("Good. What do you want to talk about?"), + ), # node1 -> node2 + ( + Message("Let's talk about music."), + Message("Sorry, I can not talk about music now."), + ), # node2 -> node3 + (Message("Ok, goodbye."), Message("Bye")), # node3 -> node4 +) + +pipeline = Pipeline.from_script( + toy_script, + start_label=("greeting_flow", "start_node"), + fallback_label=("greeting_flow", "fallback_node"), +) + +if __name__ == "__main__": + check_happy_path( + pipeline, + happy_path, + ) # This is a function for automatic tutorial + # running (testing tutorial) with `happy_path`. + + # Run tutorial in interactive mode if not in IPython env + # and if `DISABLE_INTERACTIVE_MODE` is not set. + if is_interactive_mode(): + run_interactive_mode(pipeline) + # This runs tutorial in interactive mode. \ No newline at end of file From 08a7389a76c13e7d95ee4794d6dd0fd4bf7b9938 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 6 May 2024 10:47:10 +0300 Subject: [PATCH 079/140] Added dummy_post function to VKDummy --- dff/script/core/message.py | 4 ---- tests/messengers/vk/vk_dummy.py | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 5c7929402..8abb05fa2 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -202,11 +202,7 @@ class level variables to store message information. text: Optional[str] = None commands: Optional[List[Command]] = None -<<<<<<< HEAD - attachments: Optional[List[DataModel]] = None -======= attachments: Optional[List[Attachment]] = None ->>>>>>> origin/feat/telegram_interface_upgrade annotations: Optional[dict] = None misc: Optional[dict] = None original_message: Optional[Any] = None diff --git a/tests/messengers/vk/vk_dummy.py b/tests/messengers/vk/vk_dummy.py index 6e44d610e..0b6d6eec4 100644 --- a/tests/messengers/vk/vk_dummy.py +++ b/tests/messengers/vk/vk_dummy.py @@ -1,10 +1,30 @@ class VKDummy: + """Class for logging VK_Interface requests. + """ def __init__(self): self.responses = [] + self.requests = [] def __getattribute__(self, name): def method(*args, **kwargs): self.responses.append((name, args, kwargs)) - if name in ("responses",): + if hasattr(self, name): return super(self).__getattribute__(name) return method + + + def dummy_post(self, request_method: str, data: dict): + """Function for logging POST requests that will override original `requests.post` method. + Willl return dummy objects for requests that require response. + + Args: + request (_str_): method to request + data (_dict_): data to post + """ + self.requests.append((request_method, data)) + if "getMessagesUploadServer" in request_method: + return {"response": {"upload_url": "https://dummy_url"}} + elif "save" in request_method: + return {"response": [{"owner": "dummy", "id": "123"}]} + elif "getLongPollServer" in request_method: + return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} From 134a23fd2894d7857547973c8b0ea2353f359201 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Mon, 6 May 2024 11:09:53 +0300 Subject: [PATCH 080/140] Delete bot_test.py --- bot_test.py | 67 ----------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 bot_test.py diff --git a/bot_test.py b/bot_test.py deleted file mode 100644 index 00662f52e..000000000 --- a/bot_test.py +++ /dev/null @@ -1,67 +0,0 @@ -from dff.messengers.vk import PollingVKInterface -from dff.script import conditions as cnd -from dff.script import labels as lbl -from dff.script import RESPONSE, TRANSITIONS, Message -from dff.pipeline import Pipeline - -from dff.script.core.message import Image, Message, Document - - -script = { - "greeting_flow": { - "start_node": { - RESPONSE: Message(), - TRANSITIONS: {"node1", cnd.exact_match(Message("Hi"))} - }, - "node1": { - RESPONSE: Message( - text="Hi, how are you?" - ), - TRANSITIONS: { - "start_node": cnd.exact_match(Message("Nice")) - }, - }, - "fallback_node": { - RESPONSE: Message(text="Sorry, I don't understand."), - TRANSITIONS: { - "start_node": cnd.true(), - } - } - } -} - - -KEY = "vk1.a.BvmniZCwChZfKGPWTUtHiFOC1GOQ7M7ePur6y9cs9YpKuKXLKQLDGZDy5fxhiJAFWXNLAKazSRjFqpw5WByX1x-KiEU3HcIb4QHSG_utQMjnqQ4UOYXcT7pn-8nUeo4hnf-nH4BIB3fdwq0WhZLTcnlLAok2sxd_yR2q8LVzElc-7rhZAuyNDcLzOxFx9Z9P3xsg5EEhDFBcWRvGk_1R1Q" -GROUP_ID = "224377718" - -# interface = PollingVKInterface(token=KEY, group_id=GROUP_ID) - - -# def main(): -# pipeline.run() - - -# if __name__ == "__main__": -# main() - -from dff.messengers.vk import PollingVKInterface -from dff.script.core.message import Message -from tests.messengers.vk.vk_dummy import VKDummy - -vk_dummy = VKDummy() -vk_interface = PollingVKInterface(KEY, GROUP_ID) -# vk_interface.bot = vk_dummy - -pipeline = Pipeline.from_script( - script=script, - start_label=("greeting_flow", "start_node"), - fallback_label=("greeting_flow", "fallback_node"), - messenger_interface=vk_interface, - # The interface can be passed as a pipeline argument. -) -pipeline.run() -# vk_interface._respond(Message(text="text")) -# from tests.messengers.vk.vk_dummy import responses -# print(responses) - -# vk_dummy.requests == [("send_message", None, {"id": 1212, "message": "text})] \ No newline at end of file From a07b73bbbef35f97de15cf0acb94b86d9f9724f5 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 7 May 2024 19:51:35 +0200 Subject: [PATCH 081/140] Attachment links updated --- .../messengers/telegram/2_attachments.py | 19 +++++++++---------- tutorials/messengers/telegram/3_advanced.py | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index 9694bbba8..a2bb077bd 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -46,30 +46,29 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) } audio_data = { - "source": HttpUrl("https://commondatastorage.googleapis.com/codeskulptor-assets/Evillaugh.ogg"), - "title": "Evil laughter (scary alert!)", + "source": HttpUrl("https://github.com/deeppavlov/dialog_flow_framework/blob/example-attachments/separation-william-king.mp3"), + "title": '"Separation" melody by William King', } video_data = { - # TODO: I need help, this video results in doenloading timeout, we need another example. - "source": HttpUrl("https://archive.org/download/Rick_Astley_Never_Gonna_Give_You_Up/Rick_Astley_Never_Gonna_Give_You_Up.mp4"), - "title": "Totally not suspicious video...", + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4"), + "title": "Epic Dota2 gameplay by Nkognit0", } animation_data = { # For some reason, if we don't define filename explicitly, animation is sent as file. - "source": HttpUrl("https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFuMGk5ODY0dG5pd242ODR6anB4bm4wZGN3cjg1N3A1M2ZxMjluYiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/SvP3FgHsFVm7zwMdH6/giphy.gif"), - "title": "Some random free gif :/", - "filename": "random.gif", + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.mp4"), + "title": "Hong Kong skyscraper views by Simplyart4794", + "filename": "hk.mp4", } image_data = { - "source": HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4"), + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png"), "title": "DeepPavlov logo", } document_data = { - "source": HttpUrl("https://aclanthology.org/P18-4021.pdf"), + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf"), "title": "DeepPavlov article", } diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 1ba3bf5a9..fff967218 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -50,7 +50,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) #%% -image_url = HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4") +image_url = HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png") formatted_text = r""" Here's your formatted text\! @@ -75,7 +75,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) document_thumbnail = asyncio.run(Image(source=image_url).get_bytes(None)) document_data = { - "source": HttpUrl("https://aclanthology.org/P18-4021.pdf"), + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf"), "title": "DeepPavlov article", "filename": "deeppavlov_article.pdf", "thumbnail": document_thumbnail, From 87001c0df6c77cef658ab5ffc15b671eaf982d76 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 7 May 2024 20:38:28 +0200 Subject: [PATCH 082/140] new_attachment_tests_added --- .gitignore | 3 + tests/script/core/test_message.py | 235 +++++++++++----- tutorials/messengers/telegram/3_advanced.py | 28 +- tutorials/script/responses/2_buttons.py | 259 ------------------ .../responses/{3_media.py => 2_media.py} | 2 +- ...{4_multi_message.py => 3_multi_message.py} | 2 +- 6 files changed, 196 insertions(+), 333 deletions(-) delete mode 100644 tutorials/script/responses/2_buttons.py rename tutorials/script/responses/{3_media.py => 2_media.py} (99%) rename tutorials/script/responses/{4_multi_message.py => 3_multi_message.py} (99%) diff --git a/.gitignore b/.gitignore index 7f6151613..bed9d05fb 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ dbs benchmarks benchmark_results_files.json uploaded_benchmarks +tests/script/core/serialization_database.json +tests/script/core/cache/ +tests/script/core/local/ diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 96134e6fb..e3e75d424 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -1,72 +1,169 @@ +from pathlib import Path +from shutil import rmtree +from typing import Hashable, Optional, TextIO +from urllib.request import urlopen + import pytest from pydantic import ValidationError, HttpUrl, FilePath -from dff.script.core.message import Location, DataAttachment, Keyboard, Button - - -def test_location(): - loc1 = Location(longitude=-0.1, latitude=-0.1) - loc2 = Location(longitude=-0.09999, latitude=-0.09998) - loc3 = Location(longitude=-0.10002, latitude=-0.10001) - - assert loc1 == loc2 - assert loc3 == loc1 - assert loc2 != loc3 - - assert loc1 != 1 - - -@pytest.mark.parametrize( - "attachment1,attachment2,equal", - [ - ( - DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), - DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File"), - True, - ), - ( - DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), - DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2"), - False, - ), - ( - DataAttachment(source=__file__, title="File"), - DataAttachment(source=__file__, title="File"), - True, - ), - ( - DataAttachment(source=__file__, title="1"), - DataAttachment(source=__file__, title="2"), - False, - ), - ( - DataAttachment(id="1", title="File"), - DataAttachment(id="2", title="File"), - False, - ), - ], -) -def test_attachment(attachment1, attachment2, equal): - assert (attachment1 == attachment2) == equal - - -def test_missing_error(): - with pytest.raises(ValidationError) as e: - _ = DataAttachment(source=HttpUrl("http://google.com"), id="123") - assert e - - with pytest.raises(ValidationError) as e: - _ = DataAttachment(source=FilePath("/etc/missing_file")) - assert e - - -def test_empty_keyboard(): - with pytest.raises(ValidationError) as e: - _ = Keyboard(buttons=[]) - assert e - - -def test_long_button_data(): - with pytest.raises(ValidationError) as error: - Button(text="", data="test" * 64) - assert error +from dff.context_storages import DBContextStorage, JSONContextStorage +from dff.messengers.common.interface import MessengerInterface +from dff.messengers.console import CLIMessengerInterface +from dff.script.core.context import Context +from dff.script.core.message import Animation, Audio, CallbackQuery, Contact, Document, Image, Invoice, Location, DataAttachment, Message, Poll, PollOption, Sticker, Video + +EXAMPLE_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" + + +class DFFCLIMessengerInterface(CLIMessengerInterface): + example_attachments_repo = "" + + def __init__(self, attachments_directory: Optional[Path] = None): + MessengerInterface.__init__(self, attachments_directory) + self._ctx_id: Optional[Hashable] = None + self._intro: Optional[str] = None + self._prompt_request: str = "request: " + self._prompt_response: str = "response: " + self._descriptor: Optional[TextIO] = None + + async def populate_attachment(self, attachment: DataAttachment) -> bytes: + if attachment.id is not None: + with urlopen(f"{EXAMPLE_SOURCE}/{attachment.id}") as url: + return url.read() + else: + raise ValueError(f"For attachment {attachment} id is not defined!") + + +class TestMessage: + @pytest.fixture + def json_context_storage(self) -> DBContextStorage: + return JSONContextStorage(str(Path(__file__).parent / "serialization_database.json")) + + def clear_and_create_dir(self, dir: Path) -> Path: + rmtree(dir, ignore_errors=True) + dir.mkdir(parents=True, exist_ok=True) + return dir + + def test_location(self): + loc1 = Location(longitude=-0.1, latitude=-0.1) + loc2 = Location(longitude=-0.09999, latitude=-0.09998) + loc3 = Location(longitude=-0.10002, latitude=-0.10001) + + assert loc1 == loc2 + assert loc3 == loc1 + assert loc2 != loc3 + + assert loc1 != 1 + + @pytest.mark.parametrize( + "attachment1,attachment2,equal", + [ + ( + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), + DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File"), + True, + ), + ( + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), + DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2"), + False, + ), + ( + DataAttachment(source=__file__, title="File"), + DataAttachment(source=__file__, title="File"), + True, + ), + ( + DataAttachment(source=__file__, title="1"), + DataAttachment(source=__file__, title="2"), + False, + ), + ( + DataAttachment(id="1", title="File"), + DataAttachment(id="2", title="File"), + False, + ), + ], + ) + def test_attachment_equal(self, attachment1: DataAttachment, attachment2: DataAttachment, equal: bool): + assert (attachment1 == attachment2) == equal + + @pytest.mark.parametrize( + "attachment", + [ + ( + CallbackQuery(query_string="some_callback_query_data"), + ), + ( + Location(longitude=53.055955, latitude=102.891407), + ), + ( + Contact(phone_number="8-900-555-35-35", first_name="Hope", last_name="Credit") + ), + ( + Invoice(title="Payment", description="No comment", currency="USD", amount=300) + ), + ( + Poll(question="Which?", options=[PollOption(text="1", votes=2), PollOption(text="2", votes=5)]) + ), + ( + Audio(source="https://github.com/deeppavlov/dialog_flow_framework/blob/example-attachments/separation-william-king.mp3") + ), + ( + Video(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4") + ), + ( + Animation(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.mp4") + ), + ( + Image(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png") + ), + ( + Sticker(id="some_sticker_identifier") + ), + ( + Document(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf") + ), + ], + ) + def test_attachment_serialize(self, json_context_storage: DBContextStorage, attachment: DataAttachment): + name = type(attachment).__name__ + json_context_storage[name] = Context(requests={0: Message(attachments=[attachment])}) + retrieved = json_context_storage[name].requests[0].attachments[0] + assert attachment == retrieved + + def test_getting_attachment_bytes(self): + root_dir = Path(__file__).parent + local_path = self.clear_and_create_dir(root_dir / "local") + local_document = local_path / "pre-saved-document.pdf" + cache_path = self.clear_and_create_dir(root_dir / "cache") + cache_document = cache_path / "pre-saved-document.pdf" + cli_iface = DFFCLIMessengerInterface(cache_path) + + document_name = "deeppavlov-article.pdf" + remote_document_url = f"{EXAMPLE_SOURCE}/{document_name}" + with urlopen(remote_document_url) as url: + document_bytes = url.read() + local_document.write_bytes(document_bytes) + cache_document.write_bytes(document_bytes) + + remote_document_att = Document(source=HttpUrl(remote_document_url)) + cached_document_att = Document(cached_filename=HttpUrl(remote_document_url)) + local_document_att = Document(source=FilePath(local_document)) + iface_document_att = Document(id=document_name) + + for document in (remote_document_att, cached_document_att, local_document_att, iface_document_att): + doc_bytes = document.get_bytes(cli_iface) + assert document_bytes, doc_bytes + if not isinstance(document.source, Path): + cached_bytes = document.cached_filename.read_bytes() + assert document_bytes, cached_bytes + + def test_missing_error(self): + with pytest.raises(ValidationError) as e: + _ = DataAttachment(source=HttpUrl("http://google.com"), id="123") + assert e + + with pytest.raises(ValidationError) as e: + _ = DataAttachment(source=FilePath("/etc/missing_file")) + assert e diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 1ba3bf5a9..3cbea64f5 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -27,7 +27,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) from dff.pipeline import Pipeline from dff.script.core.context import Context from dff.script.core.keywords import GLOBAL -from dff.script.core.message import Document, Image, Location, Sticker +from dff.script.core.message import DataAttachment, Document, Image, Location, Sticker from dff.utils.testing.common import is_interactive_mode @@ -50,7 +50,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) #%% -image_url = HttpUrl("https://avatars.githubusercontent.com/u/29918795?s=200&v=4") +image_url = HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png") formatted_text = r""" Here's your formatted text\! @@ -75,7 +75,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) document_thumbnail = asyncio.run(Image(source=image_url).get_bytes(None)) document_data = { - "source": HttpUrl("https://aclanthology.org/P18-4021.pdf"), + "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf"), "title": "DeepPavlov article", "filename": "deeppavlov_article.pdf", "thumbnail": document_thumbnail, @@ -96,6 +96,17 @@ def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: return Message(formatted_request.format(dump), parse_mode=ParseMode.MARKDOWN_V2) +# %% +def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: + atch = [a for a in ctx.last_request.attachments if isinstance(a, DataAttachment)] + if len(atch) > 0: + atch_hash = hash(atch[0].get_bytes(pipe.messenger_interface)) + resp_format = r"Here's your previous request hash: `{}`\!\nRun /start command again to restart\." + return Message(resp_format.format(atch_hash, parse_mode=ParseMode.MARKDOWN_V2)) + else: + return Message("Last request did not contain any data attachment!\nRun /start command again to restart.") + + # %% script = { GLOBAL: { @@ -128,6 +139,9 @@ def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: [ InlineKeyboardButton("Raw attachments!", callback_data="raw"), ], + [ + InlineKeyboardButton("Attachment bytes hash!", callback_data="hash"), + ], [ InlineKeyboardButton("Restart!", callback_data="restart"), InlineKeyboardButton("Quit!", callback_data="quit"), @@ -143,6 +157,7 @@ def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: "secret_node": cnd.has_callback_query("secret"), "thumbnail_node": cnd.has_callback_query("thumbnail"), "raw_init_node": cnd.has_callback_query("raw"), + "hash_init_node": cnd.has_callback_query("hash"), "hmmm_node": cnd.has_callback_query("restart"), "fallback_node": cnd.has_callback_query("quit"), } @@ -178,6 +193,13 @@ def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: "raw_request_node": { RESPONSE: stringify_previous_request, }, + "hash_init_node": { + RESPONSE: Message("Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!"), + TRANSITIONS: { "hash_request_node": cnd.true }, + }, + "hash_request_node": { + RESPONSE: hash_data_attachment_request, + }, "fallback_node": { RESPONSE: Message("Bot has entered unrecoverable state :/\nRun /start command again to restart."), }, diff --git a/tutorials/script/responses/2_buttons.py b/tutorials/script/responses/2_buttons.py deleted file mode 100644 index f12a73675..000000000 --- a/tutorials/script/responses/2_buttons.py +++ /dev/null @@ -1,259 +0,0 @@ -# %% [markdown] -""" -# Responses: 2. Buttons - -In this tutorial %mddoclink(api,script.core.message,Button) -class is demonstrated. -Buttons are one of %mddoclink(api,script.core.message,Message) fields. -They can be attached to any message but will only work if the chosen -[messenger interface](%doclink(api,index_messenger_interfaces)) supports them. -""" - - -# %pip install dff - -# %% -import dff.script.conditions as cnd -import dff.script.labels as lbl -from dff.script import Context, TRANSITIONS, RESPONSE - -from dff.script.core.message import Button, Keyboard, Message -from dff.pipeline import Pipeline -from dff.utils.testing import ( - check_happy_path, - is_interactive_mode, - run_interactive_mode, -) - - -# %% -def check_button_payload(value: str): - def payload_check_inner(ctx: Context, _: Pipeline): - if ctx.last_request.text is not None: - return ctx.last_request.text == value - else: - return False - - return payload_check_inner - - -# %% -toy_script = { - "root": { - "start": { - RESPONSE: Message(""), - TRANSITIONS: { - ("general", "question_1"): cnd.true(), - }, - }, - "fallback": {RESPONSE: Message("Finishing test")}, - }, - "general": { - "question_1": { - RESPONSE: Message( - **{ - "text": "Starting test! What's 2 + 2?" - " (type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="5", data="5"), - Button(text="4", data="4"), - ] - ] - ), - ], - } - ), - TRANSITIONS: { - lbl.forward(): check_button_payload("4"), - ("general", "question_1"): check_button_payload("5"), - }, - }, - "question_2": { - RESPONSE: Message( - **{ - "text": "Next question: what's 6 * 8?" - " (type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="38", data="38"), - Button(text="48", data="48"), - ] - ] - ), - ], - } - ), - TRANSITIONS: { - lbl.forward(): check_button_payload("48"), - ("general", "question_2"): check_button_payload("38"), - }, - }, - "question_3": { - RESPONSE: Message( - **{ - "text": "What's 114 + 115? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="229", data="229"), - Button(text="283", data="283"), - ] - ] - ), - ], - } - ), - TRANSITIONS: { - lbl.forward(): check_button_payload("229"), - ("general", "question_3"): check_button_payload("283"), - }, - }, - "success": { - RESPONSE: Message("Success!"), - TRANSITIONS: {("root", "fallback"): cnd.true()}, - }, - }, -} - -happy_path = ( - ( - Message("Hi"), - Message( - **{ - "text": "Starting test! What's 2 + 2? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="5", data="5"), - Button(text="4", data="4"), - ] - ] - ) - ], - } - ), - ), - ( - Message("5"), - Message( - **{ - "text": "Starting test! What's 2 + 2? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="5", data="5"), - Button(text="4", data="4"), - ] - ] - ), - ], - } - ), - ), - ( - Message("4"), - Message( - **{ - "text": "Next question: what's 6 * 8? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="38", data="38"), - Button(text="48", data="48"), - ] - ] - ), - ], - } - ), - ), - ( - Message("38"), - Message( - **{ - "text": "Next question: what's 6 * 8? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="38", data="38"), - Button(text="48", data="48"), - ] - ] - ), - ], - } - ), - ), - ( - Message("48"), - Message( - **{ - "text": "What's 114 + 115? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="229", data="229"), - Button(text="283", data="283"), - ] - ] - ), - ], - } - ), - ), - ( - Message("283"), - Message( - **{ - "text": "What's 114 + 115? " - "(type in the index of the correct option)", - "attachments": [ - Keyboard( - buttons=[ - [ - Button(text="229", data="229"), - Button(text="283", data="283"), - ] - ] - ), - ], - } - ), - ), - (Message("229"), Message("Success!")), - (Message("ok"), Message("Finishing test")), -) - - -# %% -pipeline = Pipeline.from_script( - toy_script, - start_label=("root", "start"), - fallback_label=("root", "fallback"), -) - -if __name__ == "__main__": - check_happy_path( - pipeline, - happy_path, - ) # For response object with `happy_path` string comparing, - # a special `generics_comparer` comparator is used - if is_interactive_mode(): - run_interactive_mode(pipeline) diff --git a/tutorials/script/responses/3_media.py b/tutorials/script/responses/2_media.py similarity index 99% rename from tutorials/script/responses/3_media.py rename to tutorials/script/responses/2_media.py index 3072c7587..0179a35ef 100644 --- a/tutorials/script/responses/3_media.py +++ b/tutorials/script/responses/2_media.py @@ -1,6 +1,6 @@ # %% [markdown] """ -# Responses: 3. Media +# Responses: 2. Media Here, %mddoclink(api,script.core.message,Attachment) class is shown. Attachments can be used for attaching different media elements diff --git a/tutorials/script/responses/4_multi_message.py b/tutorials/script/responses/3_multi_message.py similarity index 99% rename from tutorials/script/responses/4_multi_message.py rename to tutorials/script/responses/3_multi_message.py index 323ccffec..e8642f276 100644 --- a/tutorials/script/responses/4_multi_message.py +++ b/tutorials/script/responses/3_multi_message.py @@ -1,6 +1,6 @@ # %% [markdown] """ -# Responses: 4. Multi Message +# Responses: 3. Multi Message This tutorial shows how to store several messages inside a single one. This might be useful if you want DFF Pipeline to send `response` candidates From f1a140adb11f668bc680780d883ba3be6d026ab8 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 7 May 2024 23:13:14 +0200 Subject: [PATCH 083/140] parametrize fixed for telegram testing --- tests/messengers/telegram/test_tutorials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index 17d20074a..137df360b 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -11,7 +11,7 @@ @pytest.mark.asyncio @pytest.mark.parametrize( ["tutorial_module_name"], - [("1_basic"), ("2_attachments"), ("3_advanced")], + [("1_basic",), ("2_attachments",), ("3_advanced",)], ) async def test_tutorials_memory(tutorial_module_name: str): module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") From 3b04c0364453b117f19edfda8cf2c2bd5934b41d Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 7 May 2024 23:26:13 +0200 Subject: [PATCH 084/140] Some lint fixed --- dff/messengers/common/interface.py | 3 - dff/messengers/telegram/interface.py | 8 +- tests/messengers/telegram/test_tutorials.py | 2 +- tests/messengers/telegram/utils.py | 8 +- tests/script/core/test_message.py | 69 +++++++------- .../messengers/telegram/2_attachments.py | 54 ++++++++--- tutorials/messengers/telegram/3_advanced.py | 95 ++++++++++++++----- 7 files changed, 156 insertions(+), 83 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 01ec650ba..e7255a416 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -134,9 +134,6 @@ async def connect( self._on_exception(e) break - async def populate_attachment(self, attachment: DataAttachment) -> bytes: - raise RuntimeError(f"Plain pollin") - class CallbackMessengerInterface(MessengerInterface): """ diff --git a/dff/messengers/telegram/interface.py b/dff/messengers/telegram/interface.py index 6234956b4..af294a62c 100644 --- a/dff/messengers/telegram/interface.py +++ b/dff/messengers/telegram/interface.py @@ -8,7 +8,9 @@ class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, attachments_directory: Optional[Path] = None, interval: int = 2, timeout: int = 20) -> None: + def __init__( + self, token: str, attachments_directory: Optional[Path] = None, interval: int = 2, timeout: int = 20 + ) -> None: super().__init__(token, attachments_directory) self.interval = interval self.timeout = timeout @@ -21,7 +23,9 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover - def __init__(self, token: str, attachments_directory: Optional[Path] = None, host: str = "localhost", port: int = 844): + def __init__( + self, token: str, attachments_directory: Optional[Path] = None, host: str = "localhost", port: int = 844 + ): super().__init__(token, attachments_directory) self.listen = host self.port = port diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index 137df360b..a8bb2ff43 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -5,7 +5,7 @@ from tests.test_utils import get_path_from_tests_to_current_dir dot_path_to_addon = get_path_from_tests_to_current_dir(__file__) -happy_paths_file = Path(__file__).parent / "test_happy_paths.json" +happy_paths_file = Path(__file__).parent / "test_happy_paths.json" @pytest.mark.asyncio diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index b087cd1b3..257b5db25 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -18,7 +18,7 @@ class MockBot(BaseModel): async def get_file(self, file_id: str) -> File: return await self._original_bot.get_file(file_id) - + def __getattribute__(self, name: str) -> Any: def set_trace(*args, **kwargs): self._latest_trace = (name, args, kwargs) @@ -42,7 +42,9 @@ def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep interface.pipeline_runner = instance._wrapped_pipeline_runner return instance - async def _wrapped_pipeline_runner(self, message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None) -> Context: + async def _wrapped_pipeline_runner( + self, message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None + ) -> Context: self._latest_ctx = await self._interface.pipeline_runner(message, ctx_id, update_ctx_misc) return self._latest_ctx @@ -55,7 +57,7 @@ def _run_bot(self) -> None: else: update = Update() loop.run_until_complete(self._interface.on_callback(update, None)) # type: ignore - assert self._latest_ctx is not None, "During pipeline runner execution, no context was produced!" + assert self._latest_ctx is not None, "During pipeline runner execution, no context was produced!" assert self._latest_ctx.last_request == received, "Expected request message is not equal to expected!" assert self._latest_ctx.last_response == response, "Expected response message is not equal to expected!" assert self.mock_bot._latest_trace == trace, "Expected trace is not equal to expected!" diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index e3e75d424..1fd5c3100 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -10,7 +10,22 @@ from dff.messengers.common.interface import MessengerInterface from dff.messengers.console import CLIMessengerInterface from dff.script.core.context import Context -from dff.script.core.message import Animation, Audio, CallbackQuery, Contact, Document, Image, Invoice, Location, DataAttachment, Message, Poll, PollOption, Sticker, Video +from dff.script.core.message import ( + Animation, + Audio, + CallbackQuery, + Contact, + Document, + Image, + Invoice, + Location, + DataAttachment, + Message, + Poll, + PollOption, + Sticker, + Video, +) EXAMPLE_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" @@ -60,12 +75,16 @@ def test_location(self): [ ( DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), - DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File"), + DataAttachment( + source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File" + ), True, ), ( DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), - DataAttachment(source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2"), + DataAttachment( + source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2" + ), False, ), ( @@ -91,39 +110,17 @@ def test_attachment_equal(self, attachment1: DataAttachment, attachment2: DataAt @pytest.mark.parametrize( "attachment", [ - ( - CallbackQuery(query_string="some_callback_query_data"), - ), - ( - Location(longitude=53.055955, latitude=102.891407), - ), - ( - Contact(phone_number="8-900-555-35-35", first_name="Hope", last_name="Credit") - ), - ( - Invoice(title="Payment", description="No comment", currency="USD", amount=300) - ), - ( - Poll(question="Which?", options=[PollOption(text="1", votes=2), PollOption(text="2", votes=5)]) - ), - ( - Audio(source="https://github.com/deeppavlov/dialog_flow_framework/blob/example-attachments/separation-william-king.mp3") - ), - ( - Video(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4") - ), - ( - Animation(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.mp4") - ), - ( - Image(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png") - ), - ( - Sticker(id="some_sticker_identifier") - ), - ( - Document(source="https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf") - ), + (CallbackQuery(query_string="some_callback_query_data"),), + (Location(longitude=53.055955, latitude=102.891407),), + (Contact(phone_number="8-900-555-35-35", first_name="Hope", last_name="Credit")), + (Invoice(title="Payment", description="No comment", currency="USD", amount=300)), + (Poll(question="Which?", options=[PollOption(text="1", votes=2), PollOption(text="2", votes=5)])), + (Audio(source="https://example.com/some_audio.mp3")), + (Video(source="https://example.com/some_video.mp4")), + (Animation(source="https://example.com/some_animation.gif")), + (Image(source="https://example.com/some_image.png")), + (Sticker(id="some_sticker_identifier")), + (Document(source="https://example.com/some_document.pdf")), ], ) def test_attachment_serialize(self, json_context_storage: DBContextStorage, attachment: DataAttachment): diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index a2bb077bd..dd5a38349 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -23,22 +23,40 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) from dff.script import GLOBAL, RESPONSE, TRANSITIONS, Message from dff.messengers.telegram import PollingTelegramInterface from dff.pipeline import Pipeline -from dff.script.core.message import Animation, Audio, Contact, Document, Location, Image, Poll, PollOption, Sticker, Video +from dff.script.core.message import ( + Animation, + Audio, + Contact, + Document, + Location, + Image, + Poll, + PollOption, + Sticker, + Video, +) from dff.utils.testing.common import is_interactive_mode # %% [markdown] """ Example attachment data is specified below in form of dictionaries. -List of attachments that telegram messenger interface can send can be found here: +List of attachments that telegram messenger interface can send can +be found here: %mddoclink(api,messengers.telegram.abstract,_AbstractTelegramInterface#response_attachments). """ # %% +EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" + location_data = {"latitude": 50.65, "longitude": 3.916667} -contact_data = {"phone_number": "8-900-555-35-35", "first_name": "Hope", "last_name": "Credit"} +contact_data = { + "phone_number": "8-900-555-35-35", + "first_name": "Hope", + "last_name": "Credit", +} sticker_data = { "id": "CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE", @@ -46,29 +64,35 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) } audio_data = { - "source": HttpUrl("https://github.com/deeppavlov/dialog_flow_framework/blob/example-attachments/separation-william-king.mp3"), + "source": HttpUrl( + f"{EXAMPLE_ATTACHMENT_SOURCE}/separation-william-king.mp3" + ), "title": '"Separation" melody by William King', } video_data = { - "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4"), + "source": HttpUrl( + f"{EXAMPLE_ATTACHMENT_SOURCE}/crownfall-lags-nkognit0.mp4" + ), "title": "Epic Dota2 gameplay by Nkognit0", } animation_data = { # For some reason, if we don't define filename explicitly, animation is sent as file. - "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.mp4"), + "source": HttpUrl( + f"{EXAMPLE_ATTACHMENT_SOURCE}/hong-kong-simplyart4794.mp4" + ), "title": "Hong Kong skyscraper views by Simplyart4794", "filename": "hk.mp4", } image_data = { - "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png"), + "source": HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov.png"), "title": "DeepPavlov logo", } document_data = { - "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf"), + "source": HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov-article.pdf"), "title": "DeepPavlov article", } @@ -82,15 +106,21 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) script = { GLOBAL: { TRANSITIONS: { - ("main_flow", "location_node"): cnd.exact_match(Message("location")), + ("main_flow", "location_node"): cnd.exact_match( + Message("location") + ), ("main_flow", "contact_node"): cnd.exact_match(Message("contact")), ("main_flow", "poll_node"): cnd.exact_match(Message("poll")), ("main_flow", "sticker_node"): cnd.exact_match(Message("sticker")), ("main_flow", "audio_node"): cnd.exact_match(Message("audio")), ("main_flow", "video_node"): cnd.exact_match(Message("video")), - ("main_flow", "animation_node"): cnd.exact_match(Message("animation")), + ("main_flow", "animation_node"): cnd.exact_match( + Message("animation") + ), ("main_flow", "image_node"): cnd.exact_match(Message("image")), - ("main_flow", "document_node"): cnd.exact_match(Message("document")), + ("main_flow", "document_node"): cnd.exact_match( + Message("document") + ), } }, "main_flow": { @@ -174,7 +204,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) '"video", "animation", "image" and "document".' ), }, - } + }, } diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 3cbea64f5..486272312 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -27,7 +27,13 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) from dff.pipeline import Pipeline from dff.script.core.context import Context from dff.script.core.keywords import GLOBAL -from dff.script.core.message import DataAttachment, Document, Image, Location, Sticker +from dff.script.core.message import ( + DataAttachment, + Document, + Image, + Location, + Sticker, +) from dff.utils.testing.common import is_interactive_mode @@ -48,14 +54,16 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) in terms and datastructures of Dialog Flow Framework. """ -#%% +# %% + +EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" -image_url = HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png") +image_url = HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov.png") formatted_text = r""" -Here's your formatted text\! -You can see **text in bold** and _text in italic_\. -\> Here's a [link](https://github.com/deeppavlov/dialog_flow_framework) in a quote\. +Here's your formatted text\! +You can see **text in bold** and _text in italic_\. +\> Here's a [link](https://github.com/deeppavlov/dialog_flow_framework) in a quote\. Run /start command again to restart\. """ @@ -75,7 +83,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) document_thumbnail = asyncio.run(Image(source=image_url).get_bytes(None)) document_data = { - "source": HttpUrl("https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf"), + "source": HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov-article.pdf"), "title": "DeepPavlov article", "filename": "deeppavlov_article.pdf", "thumbnail": document_thumbnail, @@ -91,20 +99,29 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) Run /start command again to restart\. """ + def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: dump = ctx.last_request.model_dump_json(indent=4) - return Message(formatted_request.format(dump), parse_mode=ParseMode.MARKDOWN_V2) + return Message( + formatted_request.format(dump), parse_mode=ParseMode.MARKDOWN_V2 + ) # %% def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: - atch = [a for a in ctx.last_request.attachments if isinstance(a, DataAttachment)] + atch = [ + a for a in ctx.last_request.attachments if isinstance(a, DataAttachment) + ] if len(atch) > 0: atch_hash = hash(atch[0].get_bytes(pipe.messenger_interface)) resp_format = r"Here's your previous request hash: `{}`\!\nRun /start command again to restart\." - return Message(resp_format.format(atch_hash, parse_mode=ParseMode.MARKDOWN_V2)) + return Message( + resp_format.format(atch_hash, parse_mode=ParseMode.MARKDOWN_V2) + ) else: - return Message("Last request did not contain any data attachment!\nRun /start command again to restart.") + return Message( + "Last request did not contain any data attachment!\nRun /start command again to restart." + ) # %% @@ -125,26 +142,46 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: reply_markup=InlineKeyboardMarkup( [ [ - InlineKeyboardButton("Cute formatted text!", callback_data="formatted"), + InlineKeyboardButton( + "Cute formatted text!", + callback_data="formatted", + ), ], [ - InlineKeyboardButton("Multiple attachments!", callback_data="attachments"), + InlineKeyboardButton( + "Multiple attachments!", + callback_data="attachments", + ), ], [ - InlineKeyboardButton("Secret image!", callback_data="secret"), + InlineKeyboardButton( + "Secret image!", callback_data="secret" + ), ], [ - InlineKeyboardButton("Document with thumbnail!", callback_data="thumbnail"), + InlineKeyboardButton( + "Document with thumbnail!", + callback_data="thumbnail", + ), ], [ - InlineKeyboardButton("Raw attachments!", callback_data="raw"), + InlineKeyboardButton( + "Raw attachments!", callback_data="raw" + ), ], [ - InlineKeyboardButton("Attachment bytes hash!", callback_data="hash"), + InlineKeyboardButton( + "Attachment bytes hash!", + callback_data="hash", + ), ], [ - InlineKeyboardButton("Restart!", callback_data="restart"), - InlineKeyboardButton("Quit!", callback_data="quit"), + InlineKeyboardButton( + "Restart!", callback_data="restart" + ), + InlineKeyboardButton( + "Quit!", callback_data="quit" + ), ], ], ), @@ -160,7 +197,7 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: "hash_init_node": cnd.has_callback_query("hash"), "hmmm_node": cnd.has_callback_query("restart"), "fallback_node": cnd.has_callback_query("quit"), - } + }, }, "formatted_node": { RESPONSE: Message(formatted_text, parse_mode=ParseMode.MARKDOWN_V2), @@ -187,23 +224,29 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: ), }, "raw_init_node": { - RESPONSE: Message("Alright! Now send me any message and I'll send you it's raw data!"), - TRANSITIONS: { "raw_request_node": cnd.true }, + RESPONSE: Message( + "Alright! Now send me any message and I'll send you it's raw data!" + ), + TRANSITIONS: {"raw_request_node": cnd.true}, }, "raw_request_node": { RESPONSE: stringify_previous_request, }, "hash_init_node": { - RESPONSE: Message("Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!"), - TRANSITIONS: { "hash_request_node": cnd.true }, + RESPONSE: Message( + "Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!" + ), + TRANSITIONS: {"hash_request_node": cnd.true}, }, "hash_request_node": { RESPONSE: hash_data_attachment_request, }, "fallback_node": { - RESPONSE: Message("Bot has entered unrecoverable state :/\nRun /start command again to restart."), + RESPONSE: Message( + "Bot has entered unrecoverable state :/\nRun /start command again to restart." + ), }, - } + }, } From 4db3d6f9d1275ed999a257f877a6ab442b3192d4 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 7 May 2024 23:44:27 +0200 Subject: [PATCH 085/140] file path fixed --- tests/script/core/test_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 1fd5c3100..b5a3c29c8 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -52,7 +52,7 @@ async def populate_attachment(self, attachment: DataAttachment) -> bytes: class TestMessage: @pytest.fixture def json_context_storage(self) -> DBContextStorage: - return JSONContextStorage(str(Path(__file__).parent / "serialization_database.json")) + return JSONContextStorage(f"file://{Path(__file__).parent / 'serialization_database.json'}") def clear_and_create_dir(self, dir: Path) -> Path: rmtree(dir, ignore_errors=True) From 74a0402f78aae7aeeb0f4b0cccaeff1cf7c398dd Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 20:54:03 +0200 Subject: [PATCH 086/140] attachments type fixed --- dff/script/core/message.py | 2 +- tests/script/core/test_message.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 8abb05fa2..2bc0e8c80 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -202,7 +202,7 @@ class level variables to store message information. text: Optional[str] = None commands: Optional[List[Command]] = None - attachments: Optional[List[Attachment]] = None + attachments: Optional[List[Union[CallbackQuery, Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Sticker, Document]]] = None annotations: Optional[dict] = None misc: Optional[dict] = None original_message: Optional[Any] = None diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index b5a3c29c8..d03b625b7 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -110,17 +110,17 @@ def test_attachment_equal(self, attachment1: DataAttachment, attachment2: DataAt @pytest.mark.parametrize( "attachment", [ - (CallbackQuery(query_string="some_callback_query_data"),), - (Location(longitude=53.055955, latitude=102.891407),), - (Contact(phone_number="8-900-555-35-35", first_name="Hope", last_name="Credit")), - (Invoice(title="Payment", description="No comment", currency="USD", amount=300)), - (Poll(question="Which?", options=[PollOption(text="1", votes=2), PollOption(text="2", votes=5)])), - (Audio(source="https://example.com/some_audio.mp3")), - (Video(source="https://example.com/some_video.mp4")), - (Animation(source="https://example.com/some_animation.gif")), - (Image(source="https://example.com/some_image.png")), - (Sticker(id="some_sticker_identifier")), - (Document(source="https://example.com/some_document.pdf")), + CallbackQuery(query_string="some_callback_query_data"), + Location(longitude=53.055955, latitude=102.891407), + Contact(phone_number="8-900-555-35-35", first_name="Hope", last_name="Credit"), + Invoice(title="Payment", description="No comment", currency="USD", amount=300), + Poll(question="Which?", options=[PollOption(text="1", votes=2), PollOption(text="2", votes=5)]), + Audio(source="https://example.com/some_audio.mp3"), + Video(source="https://example.com/some_video.mp4"), + Animation(source="https://example.com/some_animation.gif"), + Image(source="https://example.com/some_image.png"), + Sticker(id="some_sticker_identifier"), + Document(source="https://example.com/some_document.pdf"), ], ) def test_attachment_serialize(self, json_context_storage: DBContextStorage, attachment: DataAttachment): From 9bc4b3c35eb53702b9e8909e77139876e16ac8d2 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 20:57:13 +0200 Subject: [PATCH 087/140] supported attachment sets renamed --- dff/messengers/common/interface.py | 4 ++-- dff/messengers/console.py | 4 ++-- dff/messengers/telegram/abstract.py | 4 ++-- tests/script/core/test_message.py | 2 -- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index e7255a416..c1646ec39 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -28,8 +28,8 @@ class MessengerInterface(abc.ABC): It is responsible for connection between user and pipeline, as well as for request-response transactions. """ - request_attachments = set() - response_attachments = set() + supported_request_attachment_types = set() + supported_response_attachment_types = set() def __init__(self, attachments_directory: Optional[Path] = None) -> None: tempdir = gettempdir() diff --git a/dff/messengers/console.py b/dff/messengers/console.py index 6a9dfcb64..12d3ee669 100644 --- a/dff/messengers/console.py +++ b/dff/messengers/console.py @@ -12,8 +12,8 @@ class CLIMessengerInterface(PollingMessengerInterface): This message interface can maintain dialog with one user at a time only. """ - request_attachments = set() - response_attachments = set() + supported_request_attachment_types = set() + supported_response_attachment_types = set() def __init__( self, diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 3033f7f10..75ad0431f 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -46,8 +46,8 @@ class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover - request_attachments = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document, Invoice} - response_attachments = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document} + supported_request_attachment_types = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document, Invoice} + supported_response_attachment_types = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document} def __init__(self, token: str, attachments_directory: Optional[Path] = None) -> None: super().__init__(attachments_directory) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index d03b625b7..0f79103d4 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -31,8 +31,6 @@ class DFFCLIMessengerInterface(CLIMessengerInterface): - example_attachments_repo = "" - def __init__(self, attachments_directory: Optional[Path] = None): MessengerInterface.__init__(self, attachments_directory) self._ctx_id: Optional[Hashable] = None From cb28fe3849701685fbdff83bc8e2d8fcbea0d75d Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 21:09:10 +0200 Subject: [PATCH 088/140] final message test fixed --- tests/script/core/test_message.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 0f79103d4..12e9cf3c2 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -52,11 +52,6 @@ class TestMessage: def json_context_storage(self) -> DBContextStorage: return JSONContextStorage(f"file://{Path(__file__).parent / 'serialization_database.json'}") - def clear_and_create_dir(self, dir: Path) -> Path: - rmtree(dir, ignore_errors=True) - dir.mkdir(parents=True, exist_ok=True) - return dir - def test_location(self): loc1 = Location(longitude=-0.1, latitude=-0.1) loc2 = Location(longitude=-0.09999, latitude=-0.09998) @@ -130,24 +125,23 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta def test_getting_attachment_bytes(self): root_dir = Path(__file__).parent local_path = self.clear_and_create_dir(root_dir / "local") + rmtree(local_path, ignore_errors=True) + local_path.mkdir() + local_document = local_path / "pre-saved-document.pdf" - cache_path = self.clear_and_create_dir(root_dir / "cache") - cache_document = cache_path / "pre-saved-document.pdf" - cli_iface = DFFCLIMessengerInterface(cache_path) + cli_iface = DFFCLIMessengerInterface(root_dir / "cache") document_name = "deeppavlov-article.pdf" remote_document_url = f"{EXAMPLE_SOURCE}/{document_name}" with urlopen(remote_document_url) as url: document_bytes = url.read() local_document.write_bytes(document_bytes) - cache_document.write_bytes(document_bytes) remote_document_att = Document(source=HttpUrl(remote_document_url)) - cached_document_att = Document(cached_filename=HttpUrl(remote_document_url)) local_document_att = Document(source=FilePath(local_document)) iface_document_att = Document(id=document_name) - for document in (remote_document_att, cached_document_att, local_document_att, iface_document_att): + for document in (remote_document_att, local_document_att, iface_document_att): doc_bytes = document.get_bytes(cli_iface) assert document_bytes, doc_bytes if not isinstance(document.source, Path): From d30358b332bbb84b11e1d1667c9f135d9db14fa4 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 21:12:48 +0200 Subject: [PATCH 089/140] dot path used instead of slash --- tests/messengers/telegram/test_tutorials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index a8bb2ff43..9448ba9ca 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -4,7 +4,7 @@ from tests.test_utils import get_path_from_tests_to_current_dir -dot_path_to_addon = get_path_from_tests_to_current_dir(__file__) +dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") happy_paths_file = Path(__file__).parent / "test_happy_paths.json" From eaad6d26bebae6aef54e2e8eb7b34ee8ab89970e Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 21:34:34 +0200 Subject: [PATCH 090/140] tutorial tests fixed --- tests/messengers/telegram/test_tutorials.py | 5 ++++- tests/messengers/telegram/utils.py | 2 +- tests/script/core/test_message.py | 2 +- tutorials/messengers/telegram/1_basic.py | 6 +----- tutorials/messengers/telegram/2_attachments.py | 6 +----- tutorials/messengers/telegram/3_advanced.py | 12 +++--------- 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index 9448ba9ca..d497e25f0 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -1,7 +1,9 @@ from importlib import import_module from pathlib import Path + import pytest +from tests.messengers.telegram.utils import MockApplication from tests.test_utils import get_path_from_tests_to_current_dir dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") @@ -15,4 +17,5 @@ ) async def test_tutorials_memory(tutorial_module_name: str): module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") - module.interface.application + module.interface.application = MockApplication.create(module.interface, list()) + module.pipeline.run() diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index 257b5db25..0e8aacd3f 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,7 +1,7 @@ from asyncio import get_event_loop from typing import Any, Dict, Hashable, List, Optional, Tuple, TypeAlias -from pydantic import BaseModel +from pydantic import BaseModel from telegram import File, Update from telegram.ext import ExtBot diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 12e9cf3c2..2b160c186 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -124,7 +124,7 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta def test_getting_attachment_bytes(self): root_dir = Path(__file__).parent - local_path = self.clear_and_create_dir(root_dir / "local") + local_path = root_dir / "local" rmtree(local_path, ignore_errors=True) local_path.mkdir() diff --git a/tutorials/messengers/telegram/1_basic.py b/tutorials/messengers/telegram/1_basic.py index 5d557c604..6b7ac7c73 100644 --- a/tutorials/messengers/telegram/1_basic.py +++ b/tutorials/messengers/telegram/1_basic.py @@ -72,10 +72,6 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) ) -def main(): - pipeline.run() - - if __name__ == "__main__" and is_interactive_mode(): # prevent run during doc building - main() + pipeline.run() diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index dd5a38349..b8604b3f9 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -222,10 +222,6 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) ) -def main(): - pipeline.run() - - if __name__ == "__main__" and is_interactive_mode(): # prevent run during doc building - main() + pipeline.run() diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 486272312..f372f019e 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -14,8 +14,8 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %pip install dff[telegram] # %% -import asyncio import os +from urllib.request import urlopen from pydantic import HttpUrl from telegram import InlineKeyboardButton, InlineKeyboardMarkup @@ -80,13 +80,11 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) "filename": "deeppavlov_logo.png", } -document_thumbnail = asyncio.run(Image(source=image_url).get_bytes(None)) - document_data = { "source": HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov-article.pdf"), "title": "DeepPavlov article", "filename": "deeppavlov_article.pdf", - "thumbnail": document_thumbnail, + "thumbnail": urlopen(image_url).read(), } @@ -264,10 +262,6 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: ) -def main(): - pipeline.run() - - if __name__ == "__main__" and is_interactive_mode(): # prevent run during doc building - main() + pipeline.run() From c77f41f3147afefd8ca96a2a44aa7120d7965081 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 22:00:52 +0200 Subject: [PATCH 091/140] fixed getattribute stack overflow exception --- tests/messengers/telegram/utils.py | 12 ++++++------ tutorials/messengers/telegram/3_advanced.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index 0e8aacd3f..f6fc2a1a6 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -23,14 +23,14 @@ def __getattribute__(self, name: str) -> Any: def set_trace(*args, **kwargs): self._latest_trace = (name, args, kwargs) - if hasattr(self, name): - return super().__getattribute__(name) - else: + try: + return object.__getattribute__(self, name) + except AttributeError: return set_trace class MockApplication(BaseModel): - mock_bot: MockBot + bot: MockBot happy_path: List[PathStep] _interface: _AbstractTelegramInterface _latest_ctx: Optional[Context] = None @@ -60,8 +60,8 @@ def _run_bot(self) -> None: assert self._latest_ctx is not None, "During pipeline runner execution, no context was produced!" assert self._latest_ctx.last_request == received, "Expected request message is not equal to expected!" assert self._latest_ctx.last_response == response, "Expected response message is not equal to expected!" - assert self.mock_bot._latest_trace == trace, "Expected trace is not equal to expected!" - self.mock_bot._latest_trace = None + assert self.bot._latest_trace == trace, "Expected trace is not equal to expected!" + self.bot._latest_trace = None self._latest_ctx = None def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index f372f019e..052bc2e75 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -84,7 +84,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) "source": HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov-article.pdf"), "title": "DeepPavlov article", "filename": "deeppavlov_article.pdf", - "thumbnail": urlopen(image_url).read(), + "thumbnail": urlopen(str(image_url)).read(), } From 28d7f8a7237801b952505ae700c2869de4dabd1e Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 22:17:56 +0200 Subject: [PATCH 092/140] true transition fixed --- tests/script/core/test_message.py | 6 +++--- tutorials/messengers/telegram/3_advanced.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 2b160c186..994284f8d 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -122,7 +122,7 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta retrieved = json_context_storage[name].requests[0].attachments[0] assert attachment == retrieved - def test_getting_attachment_bytes(self): + async def test_getting_attachment_bytes(self): root_dir = Path(__file__).parent local_path = root_dir / "local" rmtree(local_path, ignore_errors=True) @@ -142,8 +142,8 @@ def test_getting_attachment_bytes(self): iface_document_att = Document(id=document_name) for document in (remote_document_att, local_document_att, iface_document_att): - doc_bytes = document.get_bytes(cli_iface) - assert document_bytes, doc_bytes + read_bytes = await document.get_bytes(cli_iface) + assert document_bytes, read_bytes if not isinstance(document.source, Path): cached_bytes = document.cached_filename.read_bytes() assert document_bytes, cached_bytes diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 052bc2e75..9d7cdc362 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -225,7 +225,7 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: RESPONSE: Message( "Alright! Now send me any message and I'll send you it's raw data!" ), - TRANSITIONS: {"raw_request_node": cnd.true}, + TRANSITIONS: {"raw_request_node": cnd.true()}, }, "raw_request_node": { RESPONSE: stringify_previous_request, @@ -234,7 +234,7 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: RESPONSE: Message( "Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!" ), - TRANSITIONS: {"hash_request_node": cnd.true}, + TRANSITIONS: {"hash_request_node": cnd.true()}, }, "hash_request_node": { RESPONSE: hash_data_attachment_request, From 786b3c7411d692997bebbd18b739382ca1151aee Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 22:26:26 +0200 Subject: [PATCH 093/140] async function marked --- tests/messengers/telegram/utils.py | 2 +- tests/script/core/test_message.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index f6fc2a1a6..a95f5414c 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -38,7 +38,7 @@ class MockApplication(BaseModel): @classmethod def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep]) -> "MockApplication": mock_bot = MockBot(_original_bot=interface.application.bot) - instance = cls(mock_bot=mock_bot, happy_path=happy_path, _interface=interface) + instance = cls(bot=mock_bot, happy_path=happy_path, _interface=interface) interface.pipeline_runner = instance._wrapped_pipeline_runner return instance diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 994284f8d..89fb22ffa 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -122,6 +122,7 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta retrieved = json_context_storage[name].requests[0].attachments[0] assert attachment == retrieved + @pytest.mark.asyncio async def test_getting_attachment_bytes(self): root_dir = Path(__file__).parent local_path = root_dir / "local" From 2277af7a5c0c931bea0d803ec7a78303bcd6a0e1 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 22:34:06 +0200 Subject: [PATCH 094/140] cache dir clear and create reversed --- tests/script/core/test_message.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 89fb22ffa..1922b5bbf 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -52,6 +52,11 @@ class TestMessage: def json_context_storage(self) -> DBContextStorage: return JSONContextStorage(f"file://{Path(__file__).parent / 'serialization_database.json'}") + def clear_and_create_dir(self, dir: Path) -> Path: + rmtree(dir, ignore_errors=True) + dir.mkdir() + return dir + def test_location(self): loc1 = Location(longitude=-0.1, latitude=-0.1) loc2 = Location(longitude=-0.09999, latitude=-0.09998) @@ -125,12 +130,10 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta @pytest.mark.asyncio async def test_getting_attachment_bytes(self): root_dir = Path(__file__).parent - local_path = root_dir / "local" - rmtree(local_path, ignore_errors=True) - local_path.mkdir() + local_path = self.clear_and_create_dir(root_dir / "local") local_document = local_path / "pre-saved-document.pdf" - cli_iface = DFFCLIMessengerInterface(root_dir / "cache") + cli_iface = DFFCLIMessengerInterface(self.clear_and_create_dir(root_dir / "cache")) document_name = "deeppavlov-article.pdf" remote_document_url = f"{EXAMPLE_SOURCE}/{document_name}" From 6e218b618fc6919b44646673630c0240a615a4e3 Mon Sep 17 00:00:00 2001 From: pseusys Date: Wed, 8 May 2024 22:41:26 +0200 Subject: [PATCH 095/140] pytest warning fixed --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index dd8301879..85ba92404 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ import pytest -def pytest_report_header(config, start_path, startdir): +def pytest_report_header(config, start_path): print(f"allow_skip: {config.getoption('--allow-skip') }") From ff88c462537f1972a2f48d6a69e679438feb71c5 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 16 May 2024 16:59:11 +0300 Subject: [PATCH 096/140] Working on populate attachments --- bot_test.py | 39 ++++----------- dff/messengers/vk.py | 69 ++++++++++++++++---------- tests/messengers/vk/outgoing_data.json | 6 +-- tests/messengers/vk/test_incoming.py | 57 +++++++++++++++++---- tests/messengers/vk/vk_dummy.py | 9 ++-- 5 files changed, 111 insertions(+), 69 deletions(-) diff --git a/bot_test.py b/bot_test.py index 00662f52e..9c6de94db 100644 --- a/bot_test.py +++ b/bot_test.py @@ -1,17 +1,17 @@ -from dff.messengers.vk import PollingVKInterface from dff.script import conditions as cnd -from dff.script import labels as lbl -from dff.script import RESPONSE, TRANSITIONS, Message +from dff.script import RESPONSE, TRANSITIONS, Message, Context from dff.pipeline import Pipeline -from dff.script.core.message import Image, Message, Document +from dff.messengers.vk import PollingVKInterface +from tests.messengers.vk.vk_dummy import VKDummy + script = { "greeting_flow": { "start_node": { RESPONSE: Message(), - TRANSITIONS: {"node1", cnd.exact_match(Message("Hi"))} + TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))} }, "node1": { RESPONSE: Message( @@ -31,37 +31,20 @@ } -KEY = "vk1.a.BvmniZCwChZfKGPWTUtHiFOC1GOQ7M7ePur6y9cs9YpKuKXLKQLDGZDy5fxhiJAFWXNLAKazSRjFqpw5WByX1x-KiEU3HcIb4QHSG_utQMjnqQ4UOYXcT7pn-8nUeo4hnf-nH4BIB3fdwq0WhZLTcnlLAok2sxd_yR2q8LVzElc-7rhZAuyNDcLzOxFx9Z9P3xsg5EEhDFBcWRvGk_1R1Q" -GROUP_ID = "224377718" - -# interface = PollingVKInterface(token=KEY, group_id=GROUP_ID) - +# KEY = "vk1.a.BvmniZCwChZfKGPWTUtHiFOC1GOQ7M7ePur6y9cs9YpKuKXLKQLDGZDy5fxhiJAFWXNLAKazSRjFqpw5WByX1x-KiEU3HcIb4QHSG_utQMjnqQ4UOYXcT7pn-8nUeo4hnf-nH4BIB3fdwq0WhZLTcnlLAok2sxd_yR2q8LVzElc-7rhZAuyNDcLzOxFx9Z9P3xsg5EEhDFBcWRvGk_1R1Q" +# GROUP_ID = "224377718" -# def main(): -# pipeline.run() - - -# if __name__ == "__main__": -# main() - -from dff.messengers.vk import PollingVKInterface -from dff.script.core.message import Message -from tests.messengers.vk.vk_dummy import VKDummy vk_dummy = VKDummy() -vk_interface = PollingVKInterface(KEY, GROUP_ID) -# vk_interface.bot = vk_dummy +vk_interface = PollingVKInterface("KEY", "GROUP_ID") +vk_interface.bot = vk_dummy pipeline = Pipeline.from_script( script=script, start_label=("greeting_flow", "start_node"), fallback_label=("greeting_flow", "fallback_node"), messenger_interface=vk_interface, - # The interface can be passed as a pipeline argument. ) pipeline.run() -# vk_interface._respond(Message(text="text")) -# from tests.messengers.vk.vk_dummy import responses -# print(responses) - -# vk_dummy.requests == [("send_message", None, {"id": 1212, "message": "text})] \ No newline at end of file +# vk_interface._respond(ctx) +print(vk_dummy.responses) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 79f5960ea..481ed3fcd 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -15,13 +15,14 @@ from dff.messengers.common import PollingMessengerInterface -from dff.script.core.message import Audio, Document, Image, Message, Video +from dff.script.core.message import Audio, Document, Image, Message, Video, DataAttachment +from dff.script.core.context import Context as ctx logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) -async def vk_api_call(method, payload={}, headers={}): +async def vk_api_call(method): async with aiohttp.ClientSession() as session: async with session.post(method) as response: return response.json() @@ -36,7 +37,7 @@ def extract_vk_update(updates): return upds -class FilesOpener(object): +class FilesOpener: def __init__(self, paths, key_format="file{}"): if not isinstance(paths, list): paths = [paths] @@ -51,7 +52,7 @@ def __enter__(self): def __exit__(self, type, value, traceback): self.close_files() - def open_files(self): + def open_files(self, just_bytes=False): self.close_files() files = [] @@ -69,6 +70,9 @@ def open_files(self): f = open(filename, "rb") self.opened_files.append(f) + if just_bytes: + return f.read() + ext = filename.split(".")[-1] _, filename = os.path.split(filename) files.append((self.key_format.format(x), (filename, f))) @@ -101,15 +105,16 @@ def connect(self): self.last_update_id = None self._last_processed_update = None - def get_longpoll_server(self): - return requests.post( - f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() + async def get_longpoll_server(self): + return await vk_api_call(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}") + # return requests.post( + # f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" + # ).json() - def get_upload_server(self, data_type, peer_id): - upload_url = requests.post( + async def get_upload_server(self, data_type, peer_id): + upload_url = await vk_api_call( f"https://api.vk.com/method/{data_type}.getMessagesUploadServer?peer_id={peer_id}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() + ) if "response" not in upload_url: logger.error(f"Error getting upload server for attachment\n{upload_url}") @@ -117,15 +122,15 @@ def get_upload_server(self, data_type, peer_id): return upload_url["response"]["upload_url"] - def save_attachment(self, uploaded_data, data_type): + async def save_attachment(self, uploaded_data, data_type): if data_type == "photos": - saved_data = requests.post( + saved_data = await vk_api_call( f"https://api.vk.com/method/{data_type}.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_data['photo']}&server={uploaded_data['server']}&hash={uploaded_data['hash']}" - ).json() + ) else: - saved_data = requests.post( + saved_data = await vk_api_call( f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ).json() + ) if "response" not in saved_data: logger.error(f"Error saving attachment\n{saved_data}") @@ -133,7 +138,7 @@ def save_attachment(self, uploaded_data, data_type): return saved_data["response"] - def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: + async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: """ Return json object with `owner_id` and `photo_id` needed to send it """ @@ -157,7 +162,7 @@ def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path, key_format="file") as files: - uploaded_photo_data = requests.post(upload_url, files=files).json() + uploaded_photo_data = await vk_api_call(upload_url, files=files).json() saved_doc_data = self.save_attachment(uploaded_photo_data, "docs") @@ -166,14 +171,14 @@ def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: elif attachment_type == "video": raise NotImplementedError() - def request(self): - updates = requests.post( + async def request(self): + updates = await vk_api_call( f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50" - ).json() + ) self.ts_current = updates["ts"] return updates["updates"] - def send_message(self, response: str, id, attachment_list): + async def send_message(self, response: str, id, attachment_list): if attachment_list != []: for attachment in attachment_list: data_to_send = self.upload_attachment( @@ -190,15 +195,17 @@ def send_message(self, response: str, id, attachment_list): else: api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response}&v=5.81&access_token={self.token}" - return requests.post(api_request).json() + return await vk_api_call(api_request) class PollingVKInterface(PollingMessengerInterface): + supported_request_attachment_types = {Audio, Image, Document, Image, Document} + supported_response_attachment_types = {Audio, Image, Document, Image, Document} def __init__(self, token: str, group_id: str) -> None: super().__init__() self.bot = VKWrapper(token, group_id) - def _request(self): + async def _request(self): update_list = [] for i in self.bot.request(): update_list.append( @@ -208,7 +215,7 @@ def _request(self): ) return update_list - def _respond(self, response): + async def _respond(self, response: ctx): for resp in response: attachment_list = [] if response.attachments is not None: @@ -236,6 +243,18 @@ def _respond(self, response): logger.info("Responded.") + + async def populate_attachment(self, attachment: DataAttachment) -> bytes: # pragma: no cover + if attachment.id is not None: + # attachment.id is not present??? + # add + file_link = await vk_api_call(f"https://api.vk.com/method/photos.getById?photos={attachment.id}&v=5.81&access_token={self.token}")[0]["sizes"][-1]["url"] + data = FilesOpener(file_link, key_format="file").open_files(just_bytes=True) + return bytes(data) + else: + raise ValueError(f"For attachment {attachment} id is not defined!") + + async def connect(self, callback, loop: Optional[Callable] = None, *args, **kwargs): self.bot.connect() await super().connect(callback, loop=lambda: True, timeout=1) diff --git a/tests/messengers/vk/outgoing_data.json b/tests/messengers/vk/outgoing_data.json index eb21f7979..a97f25f06 100644 --- a/tests/messengers/vk/outgoing_data.json +++ b/tests/messengers/vk/outgoing_data.json @@ -1,10 +1,10 @@ { "case_1": [ {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null}, - "https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message=\"hello\"&v=5.81&access_token={self.token}" + ["messages.send", ["hello"]] ], "case_2": [ - {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null}, - "https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message=\"goodbye\"&v=5.81&access_token={self.token}" + {"text":"goodbye","commands":null,"attachments":null,"annotations":null,"misc":null}, + ["messages.send", ["hello"]] ] } \ No newline at end of file diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_incoming.py index 2f500adb5..3a5ed2351 100644 --- a/tests/messengers/vk/test_incoming.py +++ b/tests/messengers/vk/test_incoming.py @@ -1,21 +1,60 @@ import pytest +import requests import json from dff.script import Message -from vk_dummy import VKDummy +# from vk_dummy import VKDummy from dff.messengers.vk import PollingVKInterface @pytest.fixture def patch_interface(): iface = PollingVKInterface(token="", group_id="") - iface.bot = VKDummy() + # iface.bot = VKDummy() return iface -with open("incoming_data.json") as f: - incoming_data = json.load(f) +# custom class to be the mock return value +# will override the requests.Response returned from requests.get +class MockResponse: + # mock json() method always returns a specific testing dictionary + @staticmethod + def json(): + return {"mock_key": "mock_response"} + + +def test_post(monkeypatch): + # Any arguments may be passed and mock_get() will always return our + # mocked object, which only has the .json() method. + def dummy_post(request_method: str, *args, **kwargs): + """Function for logging POST requests that will override original `requests.post` method. + Will return dummy objects for requests that require response. + + Args: + request (_str_): method to request + data (_dict_): data to post + """ + print((request_method, args, kwargs)) + if "getMessagesUploadServer" in request_method: + return {"response": {"upload_url": "https://dummy_url"}} + elif "save" in request_method: + return {"response": [{"owner": "dummy", "id": "123"}]} + elif "getLongPollServer" in request_method: + return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} + + monkeypatch.setattr(requests, "post", dummy_post) + + # app.get_json, which contains requests.get, uses the monkeypatch + # result = app.get_json("https://fakeurl") + # assert result["mock_key"] == "mock_response" + + iface = PollingVKInterface(token="", group_id="") + iface._respond(Message(text="test")) + + +# with open("incoming_data.json") as f: +# incoming_data = json.load(f) -for i in incoming_data: - incoming_data[i][1] = Message(text=incoming_data[i][1]["text"]) +# for i in incoming_data: +# incoming_data[i][1] = Message(text=incoming_data[i][1]["text"]) -@pytest.mark.parametrize("incoming_http_request,parsed_dff_request", list(map(tuple, incoming_data.values()))) -def test_data_parsing(incoming_http_request, parsed_dff_request, patched_interface): - assert parsed_dff_request == patched_interface._request(incoming_http_request) +# @pytest.mark.parametrize("incoming_http_request,parsed_dff_request", list(map(tuple, incoming_data.values()))) +# def test_data_parsing(incoming_http_request, parsed_dff_request, patched_interface): +# assert parsed_dff_request == patched_interface._request(incoming_http_request) diff --git a/tests/messengers/vk/vk_dummy.py b/tests/messengers/vk/vk_dummy.py index 0b6d6eec4..70190eebc 100644 --- a/tests/messengers/vk/vk_dummy.py +++ b/tests/messengers/vk/vk_dummy.py @@ -9,11 +9,12 @@ def __getattribute__(self, name): def method(*args, **kwargs): self.responses.append((name, args, kwargs)) if hasattr(self, name): - return super(self).__getattribute__(name) - return method + return super().__getattribute__(name) + else: + return method - def dummy_post(self, request_method: str, data: dict): + def dummy_post(self, request_method: str, *args, **kwargs): """Function for logging POST requests that will override original `requests.post` method. Willl return dummy objects for requests that require response. @@ -21,7 +22,7 @@ def dummy_post(self, request_method: str, data: dict): request (_str_): method to request data (_dict_): data to post """ - self.requests.append((request_method, data)) + self.requests.append((request_method, args, kwargs)) if "getMessagesUploadServer" in request_method: return {"response": {"upload_url": "https://dummy_url"}} elif "save" in request_method: From e6d1226471d19c3370910ecc9c3fbe4b19dbb9d3 Mon Sep 17 00:00:00 2001 From: pseusys Date: Tue, 21 May 2024 23:41:39 +0200 Subject: [PATCH 097/140] tutorial testing done --- dff/messengers/telegram/abstract.py | 6 +- dff/script/core/message.py | 78 ++++-- dff/utils/pydantic/__init__.py | 43 ++++ .../messengers/telegram/test_happy_paths.json | 229 +++++++++++++++++- tests/messengers/telegram/test_tutorials.py | 29 ++- tests/messengers/telegram/utils.py | 88 ++++--- .../messengers/telegram/2_attachments.py | 4 +- tutorials/messengers/telegram/3_advanced.py | 40 +-- 8 files changed, 411 insertions(+), 106 deletions(-) create mode 100644 dff/utils/pydantic/__init__.py diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 75ad0431f..6c7e7be83 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -419,12 +419,10 @@ async def _on_event( ) async def on_message(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event(update, _, lambda u: self.extract_message_from_telegram(u.message)) + await self._on_event(update, _, lambda s: self.extract_message_from_telegram(s.message)) async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> None: - await self._on_event( - update, _, lambda u: Message(attachments=[CallbackQuery(query_string=u.callback_query.data)]) - ) + await self._on_event(update, _, lambda s: Message(attachments=[CallbackQuery(query_string=s.callback_query.data)])) async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): self.pipeline_runner = pipeline_runner diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 2bc0e8c80..d982f9d0b 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -5,33 +5,50 @@ DFF. It only contains types and properties that are compatible with most messaging services. """ -from typing import Any, Literal, Optional, List, Union +from typing import Any, Callable, Dict, Literal, Optional, List, Union from enum import Enum, auto from pathlib import Path from urllib.request import urlopen from uuid import uuid4 -from pydantic import Field, field_validator, FilePath, HttpUrl, BaseModel, model_validator +from pydantic import Field, field_validator, FilePath, HttpUrl, BaseModel, model_serializer, model_validator from pydantic_core import Url from dff.messengers.common.interface import MessengerInterface +from dff.utils.pydantic import json_pickle_serializer, json_pickle_validator -class Session(Enum): +class DataModel(BaseModel, extra="allow", arbitrary_types_allowed=True): """ - An enumeration that defines two possible states of a session. + This class is a Pydantic BaseModel that serves as a base class for all DFF models. """ - ACTIVE = auto() - FINISHED = auto() + pass -class DataModel(BaseModel, extra="allow", arbitrary_types_allowed=True): +# TODO: inline once annotated __pydantic_extra__ will be available in pydantic +def _json_extra_serializer(model: DataModel, original_serializer: Callable[[DataModel], Dict[str, Any]]) -> Dict[str, Any]: + model_copy = model.model_copy(deep=True) + for extra_name in model.model_extra.keys(): + delattr(model_copy, extra_name) + model_dict = original_serializer(model_copy) + model_dict.update(json_pickle_serializer(model.model_extra, original_serializer)) + return model_dict + + +# TODO: inline once annotated __pydantic_extra__ will be available in pydantic +def _json_extra_validator(model: DataModel) -> DataModel: + model.__pydantic_extra__ = json_pickle_validator(model.__pydantic_extra__) + return model + + +class Session(Enum): """ - This class is a Pydantic BaseModel that serves as a base class for all DFF models. + An enumeration that defines two possible states of a session. """ - pass + ACTIVE = auto() + FINISHED = auto() class Command(DataModel): @@ -44,12 +61,21 @@ class Command(DataModel): class Attachment(DataModel): - pass + """ + """ + + @model_validator(mode="after") + def extra_validator(self) -> "Attachment": + return _json_extra_validator(self) + + @model_serializer(mode="wrap", when_used="json") + def extra_serializer(self, original_serializer: Callable[["Attachment"], Dict[str, Any]]) -> Dict[str, Any]: + return _json_extra_serializer(self, original_serializer) class CallbackQuery(Attachment): query_string: Optional[str] - type: Literal["callback_query"] = "callback_query" + dff_attachment_type: Literal["callback_query"] = "callback_query" class Location(Attachment): @@ -63,7 +89,7 @@ class Location(Attachment): longitude: float latitude: float - type: Literal["location"] = "location" + dff_attachment_type: Literal["location"] = "location" def __eq__(self, other): if isinstance(other, Location): @@ -75,7 +101,7 @@ class Contact(Attachment): phone_number: str first_name: str last_name: Optional[str] - type: Literal["contact"] = "contact" + dff_attachment_type: Literal["contact"] = "contact" class Invoice(Attachment): @@ -83,19 +109,19 @@ class Invoice(Attachment): description: str currency: str amount: int - type: Literal["invoice"] = "invoice" + dff_attachment_type: Literal["invoice"] = "invoice" class PollOption(DataModel): text: str votes: int = Field(default=0) - type: Literal["poll_option"] = "poll_option" + dff_attachment_type: Literal["poll_option"] = "poll_option" class Poll(Attachment): question: str options: List[PollOption] - type: Literal["poll"] = "poll" + dff_attachment_type: Literal["poll"] = "poll" class DataAttachment(Attachment): @@ -161,37 +187,37 @@ def validate_source(cls, value): class Audio(DataAttachment): """Represents an audio file attachment.""" - type: Literal["audio"] = "audio" + dff_attachment_type: Literal["audio"] = "audio" class Video(DataAttachment): """Represents a video file attachment.""" - type: Literal["video"] = "video" + dff_attachment_type: Literal["video"] = "video" class Animation(DataAttachment): """Represents an animation file attachment.""" - type: Literal["animation"] = "animation" + dff_attachment_type: Literal["animation"] = "animation" class Image(DataAttachment): """Represents an image file attachment.""" - type: Literal["image"] = "image" + dff_attachment_type: Literal["image"] = "image" class Sticker(DataAttachment): """Represents a sticker as a file attachment.""" - type: Literal["sticker"] = "sticker" + dff_attachment_type: Literal["sticker"] = "sticker" class Document(DataAttachment): """Represents a document file attachment.""" - type: Literal["document"] = "document" + dff_attachment_type: Literal["document"] = "document" class Message(DataModel): @@ -236,3 +262,11 @@ def __eq__(self, other): def __repr__(self) -> str: return " ".join([f"{key}='{value}'" for key, value in self.model_dump(exclude_none=True).items()]) + + @model_validator(mode="after") + def extra_validator(self) -> "Message": + return _json_extra_validator(self) + + @model_serializer(mode="wrap", when_used="json") + def extra_serializer(self, original_serializer: Callable[["Message"], Dict[str, Any]]) -> Dict[str, Any]: + return _json_extra_serializer(self, original_serializer) diff --git a/dff/utils/pydantic/__init__.py b/dff/utils/pydantic/__init__.py new file mode 100644 index 000000000..a4d2b09c1 --- /dev/null +++ b/dff/utils/pydantic/__init__.py @@ -0,0 +1,43 @@ +from base64 import decodebytes, encodebytes +from copy import deepcopy +from pickle import dumps, loads +from typing import Annotated, Any, Callable, Dict +from pydantic import PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator + +_JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" + + +def json_pickle_serializer(model: Dict[str, Any], original_serializer: Callable[[Dict[str, Any]], Dict[str, Any]]) -> Dict[str, Any]: + extra_fields = list() + model_copy = deepcopy(model) + + for field_name, field_value in model_copy.items(): + try: + if isinstance(field_value, bytes): + raise PydanticSchemaGenerationError("") + else: + TypeAdapter(type(field_value)) + except PydanticSchemaGenerationError: + model_copy[field_name] = encodebytes(dumps(field_value)).decode() + extra_fields += [field_name] + + original_dump = original_serializer(model_copy) + original_dump[_JSON_EXTRA_FIELDS_KEYS] = extra_fields + return original_dump + + +def json_pickle_validator(model: Dict[str, Any]) -> Dict[str, Any]: + model_copy = deepcopy(model) + + if _JSON_EXTRA_FIELDS_KEYS in model.keys(): + for extra_key in model[_JSON_EXTRA_FIELDS_KEYS]: + extra_value = model[extra_key] + model_copy[extra_key] = loads(decodebytes(extra_value.encode())) + del model_copy[_JSON_EXTRA_FIELDS_KEYS] + + return model_copy + + +JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") +JSONPickleValidator = WrapValidator(json_pickle_validator) +JSONSerializableDict = Annotated[Dict[str, Any], JSONPickleSerializer, JSONPickleValidator] diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index 145f62094..0208daf7a 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -1,11 +1,222 @@ { - "1_basic": { - - }, - "2_attachments": { - - }, - "3_advanced": { - - } + "1_basic": [ + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 8, 21, 5, 30, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=1, supergroup_chat_created=False, text='/start'), update_id=1)", + "received_message": "{\"text\":\"/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_message(42, 'Hi', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update":"Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 8, 21, 5, 31, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=2, supergroup_chat_created=False, text='Hi'), update_id=2)", + "received_message": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_message(42, 'Hi', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + } + ], + "2_attachments": [ + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 14, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=1, supergroup_chat_created=False, text='/start'), update_id=1)", + "received_message": "{\"text\":\"/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Type \\\"location\\\", \\\"contact\\\", \\\"poll\\\", \\\"sticker\\\" \\\"audio\\\", \\\"video\\\", \\\"animation\\\", \\\"image\\\", \\\"document\\\" or to receive a corresponding attachment!\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_message(42, 'Type \"location\", \"contact\", \"poll\", \"sticker\" \"audio\", \"video\", \"animation\", \"image\", \"document\" or to receive a corresponding attachment!', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 25, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=2, supergroup_chat_created=False, text='location'), update_id=2)", + "received_message": "{\"text\":\"location\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your location!\",\"commands\":null,\"attachments\":[{\"longitude\":3.916667,\"latitude\":50.65,\"dff_attachment_type\":\"location\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_location(42, 50.65, 3.916667, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=None)", + "send_message(42, \"Here's your location!\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 32, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=3, supergroup_chat_created=False, text='contact'), update_id=3)", + "received_message": "{\"text\":\"contact\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your contact!\",\"commands\":null,\"attachments\":[{\"phone_number\":\"8-900-555-35-35\",\"first_name\":\"Hope\",\"last_name\":\"Credit\",\"dff_attachment_type\":\"contact\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_contact(42, '8-900-555-35-35', 'Hope', 'Credit', vcard=None, disable_notification=None, protect_content=None, reply_markup=None)", + "send_message(42, \"Here's your contact!\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 36, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=4, supergroup_chat_created=False, text='poll'), update_id=4)", + "received_message": "{\"text\":\"poll\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your poll!\",\"commands\":null,\"attachments\":[{\"question\":\"What is the poll question?\",\"options\":[{\"text\":\"This one!\",\"votes\":0,\"dff_attachment_type\":\"poll_option\"},{\"text\":\"Not this one :(\",\"votes\":0,\"dff_attachment_type\":\"poll_option\"}],\"dff_attachment_type\":\"poll\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_poll(42, 'What is the poll question?', ['This one!', 'Not this one :('], is_anonymous=None, type=None, allows_multiple_answers=None, correct_option_id=None, explanation=None, explanation_parse_mode=None, open_period=None, is_closed=None, disable_notification=None, protect_content=None, reply_markup=None)", + "send_message(42, \"Here's your poll!\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 43, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=5, supergroup_chat_created=False, text='sticker'), update_id=5)", + "received_message": "{\"text\":\"sticker\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your sticker!\",\"commands\":null,\"attachments\":[{\"source\":null,\"cached_filename\":null,\"id\":\"CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE\",\"title\":\"A sticker I've just found\",\"use_cache\":true,\"dff_attachment_type\":\"sticker\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_sticker(42, 'CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE', disable_notification=None, reply_markup=None, emoji=None)", + "send_message(42, \"Here's your sticker!\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 46, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=6, supergroup_chat_created=False, text='audio'), update_id=6)", + "received_message": "{\"text\":\"audio\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_audio(42, audio=<>, performer=None, title=None, caption=\"Here's your audio!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 4, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=7, supergroup_chat_created=False, text='video'), update_id=7)", + "received_message": "{\"text\":\"video\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your video!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4\",\"cached_filename\":null,\"id\":null,\"title\":\"Epic Dota2 gameplay by Nkognit0\",\"use_cache\":true,\"dff_attachment_type\":\"video\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_video(42, <>, caption=\"Here's your video!\", disable_notification=None, reply_markup=None, parse_mode=None, supports_streaming=None, has_spoiler=None, thumbnail=None, filename=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 22, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=8, supergroup_chat_created=False, text='animation'), update_id=8)", + "received_message": "{\"text\":\"animation\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your animation!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.gif\",\"cached_filename\":null,\"id\":null,\"title\":\"Hong Kong skyscraper views by Simplyart4794\",\"use_cache\":true,\"dff_attachment_type\":\"animation\",\"filename\":\"hk.gif\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_animation(42, <>, caption=\"Here's your animation!\", parse_mode=None, disable_notification=None, reply_markup=None, has_spoiler=None, thumbnail=None, filename='hk.gif')" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 35, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='image'), update_id=9)", + "received_message": "{\"text\":\"image\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your image!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_photo(42, <>, caption=\"Here's your image!\", disable_notification=None, reply_markup=None, parse_mode=None, has_spoiler=None, filename=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 2, 19, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=10, supergroup_chat_created=False, text='document'), update_id=10)", + "received_message": "{\"text\":\"document\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your document!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_document(42, <>, caption=\"Here's your document!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None, filename=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 2, 32, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=11, supergroup_chat_created=False, text='something else'), update_id=11)", + "received_message": "{\"text\":\"something else\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Unknown attachment type, try again! Supported attachments are: \\\"location\\\", \\\"contact\\\", \\\"poll\\\", \\\"sticker\\\", \\\"audio\\\", \\\"video\\\", \\\"animation\\\", \\\"image\\\" and \\\"document\\\".\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_functions": [ + "send_message(42, 'Unknown attachment type, try again! Supported attachments are: \"location\", \"contact\", \"poll\", \"sticker\", \"audio\", \"video\", \"animation\", \"image\" and \"document\".', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + } + ], + "3_advanced": [ + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 20, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=1, supergroup_chat_created=False, text='/start'), update_id=1)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='formatted', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='1', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 20, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=2, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=2)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"formatted\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"\\nHere's your formatted text\\\\!\\nYou can see **text in bold** and _text in italic_\\\\.\\n\\\\> Here's a [link](https:\/\/github.com\/deeppavlov\/dialog_flow_framework) in a quote\\\\.\\nRun \/start command again to restart\\\\.\\n\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null,\"parse_mode\":\"MarkdownV2\",\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_message(42, \"\\nHere's your formatted text\\\\!\\nYou can see **text in bold** and _text in italic_\\\\.\\n\\\\> Here's a [link](https://github.com/deeppavlov/dialog_flow_framework) in a quote\\\\.\\nRun /start command again to restart\\\\.\\n\", parse_mode=, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 24, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=3, supergroup_chat_created=False, text='/start'), update_id=3)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='attachments', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='3', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 24, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=4, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=4)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"attachments\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your message with multiple attachments (a location and a sticker)!\\nRun \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"longitude\":30.3141,\"latitude\":59.9386,\"dff_attachment_type\":\"location\",\"__pickled_extra_fields__\":[]},{\"source\":null,\"cached_filename\":null,\"id\":\"CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE\",\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"sticker\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 59.9386, 30.3141, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=None)", + "send_sticker(42, 'CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE', disable_notification=None, reply_markup=None, emoji=None)", + "send_message(42, \"Here's your message with multiple attachments (a location and a sticker)!\\nRun /start command again to restart.\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 28, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=5, supergroup_chat_created=False, text='/start'), update_id=5)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='secret', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='5', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 28, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=6, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=6)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"secret\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your secret image! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/cdn.jsdelivr.net\/gh\/deeppavlov\/dialog_flow_framework@example-attachments\/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\",\"has_spoiler\":true,\"filename\":\"deeppavlov_logo.png\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_photo(42, <>, caption=\"Here's your secret image! Run /start command again to restart.\", disable_notification=None, reply_markup=None, parse_mode=None, has_spoiler=True, filename='deeppavlov_logo.png')" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 34, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=7, supergroup_chat_created=False, text='/start'), update_id=7)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='thumbnail', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='7', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 34, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=8, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=8)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"thumbnail\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your document with tumbnail! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/cdn.jsdelivr.net\/gh\/deeppavlov\/dialog_flow_framework@example-attachments\/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\",\"filename\":\"deeppavlov_article.pdf\",\"thumbnail\":\"gASVySsAAAAAAABCwisAAIlQTkcNChoKAAAADUlIRFIAAADIAAAAyAgCAAAAIjo5yQAAK4lJREFU\\neJzsnXdcFFfXx+\/sbF\/KsnSQLiiIUlSwgo+KYi9RAbvYS4wleZ7EqNFojEaTqOlqLLFh77F3jaCA\\nCEgREJDeWbb394PwIiIus7NTFrPfj3\/g7My9h+U3t557DlWj0QAjRrCGQrYBRj5MjMIyggtGYRnB\\nBaOwjOCCUVhGcMEoLCO4YBSWEVwwCssILhiFZQQXqGQbgBIlf6+qYhHZVuAMbEOzP0NhdifbDjS0\\n1xZLVbmSbBPwR1WuEsSQbQRK2quwgEZCtgWEoBGTbQFK2q2wjBg2RmEZwQWjsIzgglFYRnDBKCw0\\n8GXsEhGPL2PrU4hcRX1a4Y6dUYZFe13H0s7DEu9tTycxYflgp8Ro76sQhOipx2Ve3yZEMWH5KNfY\\nyZ1ua7nzUn7Q7ucjulrm7gz5FbWRNwv9l91fkDl1DuoSDJkPU1ilYh6DIt8QvD\/65qdcunCoS8LG\\nJ5OFCtZnAcddzCrOvex9raB7oHXWbJ+rmxPq9ZfF77Cgy8VyiYVGAzb13jvk3OYulnnPq10flnSh\\nQqqvgw8czw515FQOd31yLCuExxBM9rrDl5mk1zg3VLcrddizKo\/edmmhDsm704Z9HXywWMj74\/mI\\n9cEHm1t1JPM\/D0u7MGH5V0EHM2s6XMzrNanjPZK+Idz5YLtCGqzqyC0Jc46\/Vej\/6YO5tqyavvap\\n824vyxdYr4md8XHXs\/vShqZVO5\/L7ZNe4+zFLVjxYD4AQAMgCqQGQEOnKDtxC77scVitATFZoQo1\\nvDF+MgDgh6cfmdFFzSs6md3vyIuBEzzurX88tUzC\/Tsv6G6R76X8IImS3sKkblYvV\/c4nFdnczwr\\n1MO8JNz5ybGsAcR+K8TxYbZYTYgVTAum8GZhQHKVuylNYsuqiSvtXCs3+eT+Ig5NSgFqAMB837\/N\\naKIfnk4AAMSWek++umplwClvXsHauGl3Cv3rFGwf3qto76urHkUnlHfkyznBdi+aV5FV6xhkm\/Gf\\nDsn97FOTq9wjve5cyO39qNRnR8gvDTeoNRAF0mg0YF\/6kCflncrEFiGOqTym0Ncyj6RvhQg+WGEV\\nCS1\/SxlxIifk0sjVpSIelyGY3OkOC5axqPX\/1vQ8DEEaJ9MKAEB6tVNiRcchzvEAgP4OqSeHbWgo\\n4VhW6Ibgv\/akhQMAmFTFoq7nh1345que9b3bS75dvsCmTMzN4dt15BZtSYi8VeB37VWPdUH1n\/Y5\\nucOGXdPdOhsAcDqnz+K7S4tnRQoVzN3Ph18Yufa\/D+sHVeVi82eV7jIV7XFZpyDbTLK\/LeyB161b\\nR7YNOpNUJLBWbtVyA5WigiDIhCZdH3zQw7w0xDGlQGjzoMS3g0mln3Wuv1XO+dzeVVKzYNuMvzLD\\nxEpmgHXOZ4EnmLDcgV3dyaKwoZBO3MLYMu+JHvd9eK\/sODU+vPwqqfmSbufYNHlcWSeJitnBpJIC\\naUa7xVox6+4U+23svd+HV8BliJmwfIRrnA+vAADAospMaeJ+DmkMWOlrmXe\/2HdOlyte3CKJkpFY\\n4dXLLqNAaNPbLv19v0iB2FvNGsamwzh8i\/gCta9zhQkFdRuu515IqxQvGIFJgb1Pbv8l9OfA162L\\nAbInLXz14+VL+nb4dICLOas9dS\/txtbcasmmG3kH4ksUKizfhEsjV5vSDXo\/u1ai3Hgjb09c8ReD\\nXJf2dyLbHKS0g1mhUqVefTnHc9M\/e+KKsVUVAIDHFNIoKmzLxINSgfyTsy\/cNj688aKabFsQYegt\\n1vnUioWnMorr5GQbYhDk1UjD\/ng6pBNvX4SPgzmDbHO0YbgtVoVQPn5f8ph9yUZVteBaZnWnzY9+\\neVBAtiHaMFBh7Xtc7L0l9kxqBdmGGChCuWrJmRcDfk14Xiok25bWMThhVYrkkw+mRh9LrxIrtNym\\n1iDb\/2vnKFTaFhru5tQG73iy61GRSk2gTcgwLGHdf1nTdWvc0aSyNu88n9uLEIvIRKGCrxcEar9H\\nJFfPP5kxdt+zaq3vIfEY0DrWqr+zt95+pVQjsodNlYY5JVix6vC3ixw0GpBY4ZlU2RHh\/Xam9PPR\\n3Xo6m+NsF1IMQlg1YsWMo2kX0irJNqR9w6RSNg33WB7qTLYhwCCElVkuGrsvOaO8vR5HMTSW9u+w\\nbZQnDSZ5kEOysO69rBn95zO+tB0sUbYj+rtzL0T7kbsFRKaw9sYVLziZoUA2qDKiE64WzDuLAl14\\nLLIMIEdYagDWXc7ZcONDdkgiHWcu88QM3yCShvMkCEupUn95Oee7268IrvdfiCWbejbar58bl\/iq\\nSRDWsrOZO+4XElzpvxZTBnw+2m9ARwuC6yVaWPNPpO+KLSayRiMsGuXvOf4Ea4vQSemS0xlGVRGP\\nRKEevifpQW4NkZUSJ6z\/Xcz65WERYdUZaY5EoR79Z3JCAXEbFQQJ69ubucbROrnUSJRDdydllImI\\nqY4IYR14Urzq75cEVGREO1UixcDfEssEMgLqwl1Yj1\/xF5z8AI83tVNKBPLwXUkiOe5bHfgKK7Nc\\nNHx3klRpeO5C\/2KSioXzTqTLcfbhwlFYApky8mBqlViJXxVG0HEksWzLLXy3PfASlkoN5p\/ISCo2\\nUMdZI19dyb2agaOfEl7C+vFe\/tGnbTuCGiELDQBRh57nVuF1phIXYT15Vbf6cg4eJRvBkBqJctJf\\nKTg5l2AvLIlCFXUoVaY0OsO0A+ILBeuv4tIEYC+sZWdf5ODWwBrBnK+v5z1+xce8WIyFdTWjyrgb\\n2O6IPJgqUWC8soWlsKpE8jnH3xuRx4jBklstXXEuC9sysXSbWXAi\/Y\/22FypVeySZJqwTOQYqDSx\\naf4JpJSZ5j9kVuXAMoGKaS4zcxS49FEzzcizFS9gCDxe1jOwA2a\/GmbCupdTM+j3pwhPBRoU1k\/2\\nmL2KrZ+BQ3DRgM9lPLfGD9Qqu39+4pSlNr9ZRWOV95gtdvAnx1Y88XcwebS0B5OGTZA3bLpChUq9\\n7NyL9qgqWFRl+lpVr18ylVnOraaPOMWJLVRVf79CYvfoF0algQZq04ekYuEvDzHz7MXmhNAfj4qe\\nFrXLRXYNBQYQBWgaN86cLU1H9LTvwGX06GBWEF+5Pe7Nnc4uLr6+vjeuX5fL5X1Lz2\/9JkahUqeW\\nCp8VCwv5sttZNbXSdr95tf5a7pRAOzszDAIkYdAVVork3ltiK0WGFTsAOc4pR2gv6hsqFpt1\/NQp\\nb2\/vhusymWxu9Ox\/Hj4EAMyZO3fFZ5\/S6fSE+PiICRMBAIdjjgb3ehM\/Qq5SpxQLb2fX3M+tvZxR\\nhXmAOMJY3Nfx5\/Gd9S8HA2GtbZ8HubhMamSA7YI+jn4OpokJiTk52UOHDjUzb3lYKutFFpfLtbax\\nbroya\/qM+\/furV67ZmZ0dKslK1TqI4mlx5LKr2RUtUd9PV0R5O9oqmch+naFxXzZd3fy9SyEYAId\\nTRf1dZzZ07HpGHpg98DA7q3HdfH08mxxxdHREQCQnfXeYRYNpszo6TCjp0OZQLb19qtdsUUCWXs6\\n6r3+2sszs\/z0LETfFuvj05k\/Yzfiw5t+buabhnv0d9frvMqd27dTklM6enYcNnw4kvsVKvWeuOLV\\nl3Oq248HUeKKoAD9Gi29hFUqkDl9\/bBdTAaDnM2+Dncf2smSLANEctX2e6++u51f1x4CVQzsaHFz\\nYRuhubSjl7AWn8r49R9DP3hjxoQ3hnss6ONIegAWAMCrGunnl7JjnpYZ\/rv4bGVQNwf0jRZ6YfGl\\nSpu19+SGPf0Z2om3P9IHk\/kzhlxKq1xwMqOQT8ShBtREBdgemeqL+nH0L\/E313MNWVVUCrRrYucr\\n8wIMTVUAgBE+Vokrg0Z3sSLbEG0cfVqWVYE+aBlKYSnVmt1xBrMtqFZRheX0mnxGTV7DP0+W9OHH\\n3ef2ciTbsvdizaGfi\/bbPMKDUfuKKqoAakMceP3+CP04B2VXeCSxdMrh56hr1R8av4hdlsoue04V\\nV9FElZDmzR+mi2+XP\/fvt7Iy6PagiatXrny2YqVIKpOb2Co51mIbH7G9n5JjEMYzqJSqDSEcVCmi\\nUAor8Ic4cvZw1ErT\/Fjuiyt0YWmrn\/fr33\/vgf0UCvnjdOQ8S3q2cN688vLypisSS8+aTsMk9t1I\\ntaue3z7qtKBPBxQPohHW00JB4I+PUVSmJ5xXsVYpJ6jS97o7jhk7dsu2rVSqoedxeZfCgoIJ48ZX\\nVr51bEbKdan0j5JZIg2cjAe9XMweLe2J4kE0b\/aBeKJHV1Rhuf397+2e7NGiqtFjxnz3\/bb2qCoA\\nQAcnp1Nnzzg4ODS\/yKzNd7yzhffsGKQkLelLbH7do7xaFA\/qLCylWnOW2EwkjKoch3tb2eXafFND\\nBwzYvPU7GG5\/CSObcOzQ4fc9u1tsVkJAY5F93fbRzxQ5ac4jp5LR\/Ll1Ftbl9Mr8GuIWYFhlaQ73\\nttIk2mI7+fr6bv9pJ53eMrl3u8PHx+fnX39lMpktrnPK0+zv\/0iRCUix6nRKOYrj+DoL62Ryuc6V\\noIVZnmH\/z06KWtsWm42NzW+7d5ma6rsbbyD06dtn9Vdr373OrM23f7gDaP0qcCK3WhpfoPMxHt2E\\nJVOqL6dX6VoHOmiCUtvHu6C2vsodP\/9kb29PjEnEEBkVNSli0rvXmTV5No93k2ER2BWr84KWbsJK\\nKKirIMahT6O2jt9HlbURge6T5ct7BgURYQ+xrFm3zt3D493rpkUJJv\/vSE0kt7J1DjOpm7CQ5OXC\\nBIv0i6zqNk7oevv4fPzJUmLsIRgWi7Xz558gqJXUedaJByGllGB78qqlz4p0G+HpJqzrmUQkJKbI\\nBOY5N9u4h0LZvnMHAcaQRWdv70VLlrx7naKScTOvEG\/PZR1D0+ggrIwyUaYeu5LI4WZegeVthMpc\\nsGihR0cyVw4JYM68ue7u7u9et3hxBaiIPmHwIFe38bsOwnpCSMxdSCExzX+o\/R4nZ+ely5YRYAy5\\nmJqafva\/\/757HVIrTfP\/IdiY6y+qq0Q6rNPqICxiFhpYFZnUthYD5y9c0E5X2HUlbOjQ3n36vHud\\nU5RIsCVyleZ5qQ4Rl3UQVjIh4fk4JUnab+js7T1u\/HgCLDEQlq9c8e5FZlU28b3h5QwdVpqQCiu9\\nVJRXg\/9kRKNhad26AQDMmh3NYBic7x5+BHbv7u\/f8kQ\/rJKxKl8QbEkaHi3Wy2oiQl5RheU0sbbX\\nwsbGZviIEQRYYlAsXd7KgJImIjrT8a2cGhniANhIhXU3h4hMLLCijVlnRFQki0Vackey6NO3r5OT\\nU4uLlLYmzpgjlKmQJ7ZAKqzCWiIW5WCtm80wDE+KiCDADEODSqV+NHFCi4uwhIg1xRZkI47ViHRu\\ndVP3RX0UwFrngz2Dguzf9lgiHpXghFp0UcsNsNl0CnsQ5vWOHT9+5\/YdavWbngjSkJCW4V5OzUfd\\nbJDciUhYLyvF5UIi5iCQVnfWEaNGEmCDdjTyFLXwmJYbKKw+AGAvrA4dOvQMCoqLfbNR2Mp2D\/5U\\nId4pRiSsKjH5kWRodNrgsDCyrQAAdoAYAVpvwOscxKDBg5oLixSQZ4RAJCxDiILs69vV2tqabCsA\\nlbsAcBeQUnW\/kBAAviGl6iYyKjAdvCcUkuO72JzQ0FCyTSAZLy8vNptNrg0qNRAgiy+HqMWqM4BY\\ndZ28MYgGpj+qugMqgbYxFsxdBHPwGguGDR1y7sxZnApHSEa5qKdzyyhi74JIWHyyhUWj0VrdMiMe\\njSJHI7ml7Q6TMfjVHhgYSLqwXlZJMBPWS7LHWB09PU1MTMi1oRGqE8QM1nYDbItf5W6tedEQDMIB\\nd\/sQlo0NorUTAqCazwXmc8mqPSBQr5hVmFCAbKkc0eCd9GSW3fzIP2xOInm5uc+Skhpclkk\/O4kw\\nzF77iHFga4tj\/2KwSCSSixcuTI2aPPg\/A9PT0houurm5kWuVGllMhvbhLkej0cg2gVAqKipOHj8R\\nc\/RoUWHL+K5OLs7Z2WSmL0AY6rJtYUnwz3jeJtYGM8bCG4lE8v3WrTFHjkqlrQ9l7OxIPkRZK8Fo\\nHYv0tQYAAJfLJdsE3MnLy1uz6stH\/7R0Znd3d1+\/cUPTaguX2\/ZUH1cQ6qFtYRlCNEhDWWvAAZVK\\ndfP6jZijR+\/dvdv8OgzDYUOGRERF9g8JaX7dhOxgAgj10D7GWKRPhfCgurr67OnTMUdjXua8dTSX\\nx+ONHjt2yrSprY7T28tX0T6EhTq085d\/Z1\/F9JDtwj6Os4P1DW2anZW1e9euy5f+Fovf8pj19PKa\\nO2\/ekPChWlpoDPNL4kr7EJZIhNINN7daiu0OeqkAfQw0pVJ58fyFYzFH45\/EN9cHlUodNnz4lGlT\\nu3fvDrUV5FIkJNojGR1tC8sEVWxTbOHzsc+GTSTV1dVHDh0+deJEQUFB8+s8Hi8iKnJSZOS7Lu3v\\ng89HE18PQxDqoW1hmTLJb9XKyvQNRjKzpz266L8NJBTWxeajPAi+etWqvy9eqqt763Hfrl0jo6KG\\njxxhZqZbttzSUoLisrwPHhuRHsgXDRJk71nUQc6m4R72emQS2HwrD7WwYo4cbfoZgqCh4eFz58\/3\\n80eZXutVPsm51syRNTTtQ1jV1SScSMEWM3Pz2XPmTJ4y2YLH06ecFlNI4oEpiLztEQnLnAnzSc1Z\\nlfwsmcTa9aRnUM\/IqKiRo0frv1Igk8kUCpLPH7QWtKsVEAnL3ZJFbsrn4iKUuTc6mDO62HIaUuvo\\nY4AVh9ZQjhVH513Lo8eP61N1c1JTUrAqCjUOyEYUiITlYckmV1g5OTkymQxFyIbvRnl+N6plilQU\\nzAl2nKP38pX+vMjMJNsE4GGJ6CQ6ImEhnAjgh0wmi330KHTAAMxLlkqlL3NyGg6C0mg0Ty8vAtKl\\nFBYW1tY0HgB2cHTkIR51paam4mkXItwxFBabRv5SVkZ6OrbCevjgwYF9+588fiwQvFlBtbGxCRkQ\\nOmPWrKZc9hhSXV198MCBy39fzs7KaroIQZB\/QMC48eMmToqg0dvoZ69eJiFIZAu8bThIbkP0dvo7\\nkr8HfO\/uPayKqigvX7p4yYyp027dvCkQCKhUqourq6ubG5VKLS8vP3n8xISx47Z8++37HFfQcfHC\\nhWFhQ37asbNBVRYWFp5enjweT6PRPE1MXLt6zbgxY5KfPWv12ZI6WWM7V0vy6igEAJeNaJSJqMXy\\nsUUkUlx5lpRUV1en63Liu7zMyZkxdVpJSQmDwZgwaeL0mTPNzMzOnjmjUqpGjRktkUgOHvjr+LGY\\n3X\/sSkxI\/H3XH3quDjTw7Tff\/Ll7DwDAz98\/Iipy7LhxTXk0FArF6VOnYg4fSUlJmTBu\/A87to8c\\nNar5s2dSyiMPpu6N8FanthHwlwA6WiEN9YOoxTIjb\/F9dqTgt01VENBIpdLrV6\/pWVpeXl7kpIiS\\nkpKQ0NCbd++s37DBxcUlcuLELZu+3fbddyPCh1lZWa3f8PWtu3eDe\/dKiI+fEhkll+ubIOnrdev+\\n3L2HzeHs+PmnU2fPTIqIaJ6dhUajRURGnrlwftPmzVQqddnHS4\/HxDR9uvZKzvj9KUq1Rq7S3Lh2\\nXU9L9KeHE1KnHUTC8rThcFkkaGvx9LoVc4QhQfIfv6qBIM2li9rCvCCBTqezmMyZ0bP2HthvZ2fX\\nMNLKz2tcyxYKBNevXgUA2Nvb\/3Xo0JixYyEKRf8O0dLS0tzc\/PS5syNGajvIOiky4ujxY6ampqrX\\nmWvUAET8lbLhep4ZA742P2CkKzU+Pl5PS\/THgoV0tQWRXCiv8+WfTiE06dfi6XWLpjfu5Hu5KV0c\\nlU8eP66qrLTUI3Wqg4PDqbNnrJrFgHBxdaXT6U3NkrOLS8MPMAxv+\/EHkUikv4\/h4o8\/njJ1KtfC\\nos07\/fz9H8Q+4nA4ZQL58N1JiUUCPweTmGm+nW04e\/7YJZORn5y8rytS\/1WkU2snLqFhP0eHiRdO\\na1RVVS20aLVFXiFNIpFc1LvRsno7soirq+vylSs4HA6DwZg1Ozq4V6+mjyAIwspzFYmqGuBw6oez\\n4\/clJxYJLNnUMzO7dX49Czt96hQmluhJZ8SjbaTCCvVA+tXoj7uzYu0n\/IatA6kMTF9umVfY2AIf\\n2Lcf8z2NufPnP05MiE96+uWaNdiWjJqTM7t6WLKqxMqPDiQX82WJCYkvXhAdyvZdGFTIG3NheVoR\\nFOcEhjVbV9Wy\/j9l3+qt5nkFb\/r1V\/n5N65jP4ZlMBgGFdrU3oyRsCJopLfl0yJhjx8ff\/bjfrIt\\nqmeAhwUL8YomUmF525o4mhGRaXJ0mKRzx8ZzILcfMS7faSnovXv2NI+Y+KFizqQem951RahTiUB+\\n2zJc0AFNYmZs8bXTYdUJqbBgCvDRpVx0MBia6EmNm5JyOdj6eyuT26eJT69euYq3JYYAmw5\/P9or\\nnJaloVCVLOKGIu9jaCdL5DfrsC\/2UVfcT42G9hC6Ozf658RcYOcXtT65\/XnnTrwtMRD+efgwK2aL\\n85UvLLL0XcPTEwgCvvY6TGV0EFZvxFNN1Ezo9ibfyZkr7x30ZGZk7NlFTq5RIlEoFN9u\/AYAQCMj\\n8nYLBna00MkFVwdhdXMwdeW1zIONITCkGuka1\/BzYirtRa62Id3O7dtLiovxM8YQ2L93X3p6Gwlg\\nCKOfm26H0XVbT\/+Ph8W+6hIdTUJKkE0GldI4Kk\/JaGOFVywWf7pi5eGYozgZQwxqeYZaeF6jyNYo\\nXwF1HQTbAKoDhdkLZg8qKFbt+PFHsg18w0gf3daldRPW1O52+57gJaxQxzf+x0+etT0DjYuNPX3q\\n1PiPPsLJHlxRS5+oqjepxZebX2w4aqiu26uE6JkJ7mymSCol32Hp9fIH3d9Rt+1\/3ZzaermYmzPx\\n+lU7mLzJOlRWiaiWLz\/\/orlvUztBoaz8QlE4sIWq3kIj7x+YcWlfxZAQ8gOh17\/z7lyqju6Put3O\\npsNhXhi4kbQO9N7\/vA+FQrFk0eKKCkI3MfVCLZUXR6lqfwSg7f0DM1PN1i9royeRHwt9fm+d3bJ1\\ndsNFmEqFMLKzslYuW65Ukh9rCQmKypUasQ7bnVQYLJstDA8ls91yMKP3cdU5jJTOwprgZ2tnSsQS\\nPHL+efhw7ZerybaibVSCE+q6P3V9CobBuhV8SwvSjt+N6WJN17UjRCEsKgUa44tLuhil+o0xpia6\\nfY\/Hjx37et06HIzCDrVIWbUW3aOmHM2SGaR1iONR9VFoTqRMCbRD8VSbpFa9CQfVK0Bnv82\/9h\/Y\\ntuU7rI3CDJXwIlDmon58fLjEzpqE7r6LLWcwqlE1GmH1d7fwssbeF+Dqq+5NP3u6ofkSf\/\/tt7Wr\\n16hV5AdNfReV6Lw+j1OpYEAvEhz95gSjTBCJ8gzd8hBndA9qoUBoWyZuHCSGBMnsrNHo48ihQ4sX\\nLRIKyTxe2yptJEpBgI8X0YfrYQhM64Eyli5KYc3sac\/UfUDXJmdeNoZwhWEQPgDlVOj61WsfjR2n\\nf+QjjFHrm6LWxZHornB2sIOl7iEFGkApDiYNnhOMfVzo\/Sn\/afp5yliRqQlKv6uc7OzhQ4ZeuqCX\\nH7NYrhLK6v\/pU0gDapVQqGAKFUypEn3AeksLor3QPu6HNBzcu6BvdT4f5IZ59ti0XM6dR41b6A62\\n6qjR6MMi8vn85Z98surzL1B3iyG\/JJiuumO66o5K7z9oeoXGas8pqz2nIq+uQl2IWEJott5hnXk6\\n+cm0AL2wHM0Zk\/wxXixV0Tnb95oq\/7+NmDdZ6OyAvv1Xq9XHY2LGjBx55\/Ztfayqk+o7uGnK5kCB\\n0Is0v5DQE3irBuuVW0WvcdK3Izrq8\/i7qBimWbm0\/ScaXVVZTLBjXTUV1itOcH5e\/pxZ0XOjZyPY\\nVVQCIH99pA+83r9q\/HKuvdDXHepKRlXDD\/Yc9EUVlRG3Id3L2UxXP5kW6CUsNx4rKgDT9ElUhgpm\\n7NxnmpLR+HZ6uat+2VjdPGy9h4fH77t37T1woE\/fvsgLvn3rVnjYkGUfLy0pafDOkKtEV5UVKxUl\\nkbK8TrJs5ut\/JrJsM1k2u\/7nHPN+vEMNzy46lXEtswr173QsqWzzrcYzsSH26ANc3biPozNcCzbr\\n3WRAesYNzygT+X0fJ1dhFnzc6fIXdHGFvY1y95ZqN6fGHuTvW8zV27gyef0g4+DhQ71fS0omk4X2\\n7VdZWYm8cEsLVXiodOFsDwtWUps5Fh6Vdh589juVprGdgCBgb0qnNAtoZ8aEfe1MhnlbTgm0o8GU\\nrArxTw8KnhYJCmplqtfJ19QaTUmdvKkaDlXyfMocOzaawB5PntFmrnxrw6POLaQicDqKotpkYEeL\\nmwv1TYyob7fd2ZYzr5fjzw9bJqlCjYrNBeKKknLq0rUWf2yudrCt75gCfOUOtsrc1+fAmP9\/TovB\\nYAwcNOj4MW0Zmpvo6KqYPEY8Llz8OlLQUySP9LbLmO1zedfzxnPxGg0ornt7P4AP0srEx5+Vv6yS\\nTPSz7fNTvPYp5Ajz8+hUpdaAXw8Sl+nkqyEYZK7DYC1q1WBXDGPBK9iN7+XLAtr8z3kl5ZQaPrRg\\nFS\/3\/08X7ty+XSJpXOKi0dveDre3UW78tPbUH5URo8RtxZ9qyQ\/9\/ljc9RyH2saK2jc38uafSNei\\nKopMwEs9lXn4ak4+mjf5xEXW4ySCTqJH+NuEYHE4GYOJhr0Z438DXdZceal\/UfXAb\/74LwtokxZa\\nmXA0r4rf2Hn\/3v2Tx49PmzGjzTDdNJpmyljR4ulCNgtlT02lqL\/vt+t\/gcfSa5wzapyqpGYaTWNX\\nqAGgSmp2vaB7Nt9RrQGPXgfrhpQyVkUGvbYA0rwWmUYDywT0uiIGv4CilAkBZeGXFod3VFlb6jA3\\njHtK3\/IbQRm\/WDTKhnAPTIrCZga7ItR5\/5MShGmotaOivjVErebD1e9kpTDnWjR4+V1\/\/6loF0fl\\n1ytre3TDYBvEhs23YaeEOrYy7lao4YmXV195FQRey8jhzhYm\/5WWoopKqVM+sfxpfU0nD0TLKBdv\\nMr\/eYd4wuCSA\/\/7HxdMamyPv2AiLTYe3juo4fj8GMX0VHOv3fdS7T28nJ+d+If2HjxhRP3PZtIn\/\\nngh3vQJl276ssTDHPZ8RjaL6LPCEs2lFQgrtZZpQu6oaKCqlzlhpOWuicE6kSEt87vJKyva9pueu\\nsRA60+qPE5fx6QDMtoD1nRU2Z\/Kh1KNP9d2hY1a+cLzbuvfL2Qvnfbt2BQBUVlRu2rjx\/Llzrd42\\nOkz87f+Izr0jkYLpyy3TsnRwgTThqKMnCXsFyrt1VjTNNWVyEJvIuBvLOH6J3dTttgrms8KbCwIG\\nemLmd46lsAprpQE\/PK4U6dX70GvynW5taPWjhYsXWfB4D+7de3D\/wfvCN0SMEq39BGVuEj1RqcC0\\nZZbP0tG417JZag5bU1tHUSiQtk\/YCmtyoO3hKb5YlYaxsAAAB+NLph9N06cESCF1O78EXes\/anB9\\nW4UwdQIeCITQvC94yai0pSsYCsvRjJG4MsjGBEuzMXZ9mdbDXk\/HZQ2NqTBB46Havats\/QoyVfXa\\no1rz84ZqF0eSs5Loyh8TO2OrKuyFBQDYPdHbxgS9c8jrHUOdN9XtrFXbv6phGMAhD0uuZuuqWiaj\\n3QRaig6yH6HjKWckYC8saxO6nr211FK3jSoqrNn6ZQ2Payg5bbt0Uq6cS\/5hQCR4WDJ\/Ht8Jj5Jx\\nSe8x2Iu3JswV9eMS68463T9ppDjQ17B6n4jR4uAALPMP4AGLRjkzyw95kD6dwCtvzBeDXAd7otwZ\\nUHJ0aJmteaolM9E3D2K913SFoubDusY\/EkwB\/50vYNB1a0RRZKHShz2TvLvq4cqnHbyExaLB+6N8\\nEGaKaoHCxFbBQrqgMm+y0NwUZSf4LI02bIbNzYfo\/5z7jnPGz7fKL6rXE9X2L6rN701faeeOytFh\\nYuRF+XTpcvn6tb79dPAF0ofFfR0n43OMrwEcM105mjPPzOrGoeteBQQpTBC5eXHNVJGjdfjjNaeq\\nBprzP15lNbz0K4vLt3V2ddJowE\/7TbbtMisqpc5cYQm438Cmk2CzaVT7kwBqbAbmRgnbdM5pILhX\\nr5gTx52dnXfv3dvFF8v1pFbp78b9YYwXrlXgm0Ktq73J4Sm+KFYAxPbdkNw2f4oQdRI4SwvNgqkN\\n7vDQp99YfL7ZHHmA\/tIKSvSnvN8PNbqyzJwoBMI\/gaq6vhPkDKc5xQF6vf2OdupxQ9vua1d+9tnh\\nmKNsNhsAEPvoURbOkbfdecwzs7rSYXz\/9Ljn5hvja71lpM7uiFKee5v3UGHN+GF6DZFmR4g+ia6D\\nKfWNyoUb7CFTbY6cY\/PrtL0IxWWUnftMhs+wefyM8bpt1Xy+iD9jghgoX8oLBwNlaf13SvdgOMfC\\n1jsAzWPCiPc2qAwGY9z48ddu3li4eFHDlevXri9esFD\/7D1asDGh3VoUaMnBfWEG45X39\/H5xawt\\nt9veoH2DRuN8ZRVNrC0+0eC+kh3rMUizdvwia\/OvbzwITDjqIf2lQX4ydxcVk6GhUTVCMSSRQk+e\\n0VMy6HfjGE1beEyGZv3y2pGDm83+qB40+yMURlOGerVKeOnbHxLjnyQIBHXVVdVMJtPaxsbe3r5P\\nv77Dhg+3sXlzGuXk8RNfrVmDPK8JipV3Dh2+Pt+\/t+6hY1BAkLAAAFGHUmN02aK2jt9vlv9Ayw2b\\n\/lszZgg2U\/rMHOoXW8wzX+rwHnu5KTZ8Wuvb6R3vF8iEarkR5s5B7jnC5\/N\/3Pb9oYMHdbBYd2Gx\\naZQjU33H+L7XeQRbiBOWSg0iDyafTEYaJI1TmGAX99v7P9c8vVyqq0eoFtRqcOEm6\/eDJs2dClvF\\n3kY5f4pwzBCJltoheleq5UYKZ5B2eUml0nNnzn6\/bVt1lc6HNXQSFgRAzDTfSf6YnnzRCnFH1WAK\\nODzFV6ZMuZCG6PiDyMFPyeRSpa13dl07KzBUVf3AiALGhElGDpQkZ9Cu32dm5VKT0uhiSeMYlGeu\\n8vFSuDsrB\/aRBXaVtznw1chTFCVjANUVNp0EMfwlmkEmpm+8QIsKC+Pi4uJiY2\/duFlTo+\/R+zaB\\nADg+3XeCH3GqIlRYAAA6lXJiRtfIgylnUxFoi0IV2fuZ595t9cPOHrgstcMwCOiiCOiiaGjDauvq\\nR1cmHA3KpTJlnqrmu\/pZwnLLogpnCx5PrVaXFBfX1RHn2ANB4ECkD8GqImJW2AIGlXJierepyJbm\\nhI7d3\/cRujhHOkGhAB5X42inRr0A24S7s7K0tDQ9LS0zI4NIVVEp0MnpXVFHjNEHooX1epkAOjCl\\ny+ygtn9bqa2Pktn6OYIunoa1Oagdax4JIbtM6PDfc\/zQxePTHxKE1VDrngifTcPbXqyq9Rza6nU3\\np\/YRzbYB4q3lsakPlnQP0yWtEraQI6wGvhjktjfCm03TZkOdW381pZWBoLmZoTjJIMEWVRA51Pg7\\nmCStDPZzJO6M67uQKSwAwKwgh2vzA7Q4BmpoLIFTL2KNwh5TDnGvwfDOltfnBzhxiQv00CokCwsA\\n0NeNm\/xpr27v99+o6TJWQ9QRKJwgzGF69WDXC3P8rbD2M0YB+cKq7ylM6XGf9JzXq\/U4qioWV+Dc\\nvhstKf5hablM6rlZ3TYM86AYxjtoEMJ6HXuS8sdE74OTfXjsVkZUtZ2Ga6C3TMVzoxZ7qmqw99JU\\nN\/vbBTmbJa4IGk3Udg0SDEVYDUztbv9gSY8+72TcVJjZ891Cm18pLDWItFgIKSzBQVg0VkMnu3qw\\n662FgW6ofCrxw7CE9TqrOefhxz02hLvT4bfa9NrOw1W0N2EFMnIw3dDBmZcF2O9wqJjm7pbM+4u7\\nbxjmwcEu2g9WGJywGlgd5pa0Mrhvs6ZLxbKo7jK26b\/J6e1JWDV8zL9naNmIwLT\/9u6rX0BH\/DBQ\\nYTU0XQ8+7vHLeK+mUON1riEy08YBfjGBATn1J+4pltM0H7+A0xcurJ8\/kYFDqH2sMFzLGljU1+n5\\nZ8GzguxhCgRgakXgdA1UL6l\/4gk90KIPFVUUvgCb18CCx1v99cbz505369oFkwLxw9CF9XoxgrE3\\nwufhku4DO1rIrDrWufYDAEhklLQsQl0zUHMvDoN3gMnmTJkx89qt2zOnT8HCKNxpH38bAECwi\/nN\\nhYE3s6qXnYD5RzLpwtIzV9g+nuQEltGJK\/f0WgSnUKnhI0Z99tlKpw46pzklEeI8SLFCrQaXHzzZ\\ntW1TWUHC3RPlZJvTBlU1lJCJNuiCp8FU2pjx42fPndvJE5vwjUTS\/oTVgFqtvnX7jrPJZhfLe2Tb\\noo29xzjf79Yt\/3t9P0JnTIyMmhU9y90V+yxrxNBehdWEVJSqqNpKkZykwgaXplClAn3H2wpEOgxk\\nbRw6RERGzps\/l2UIoXP0oN0LqwGVUiSu+AkSHaSBHLJteUPMedaGncjWmSAoZOCgydOmDx7QH3ez\\nCOEDEVYTgpoEWH5Jzf+FRiE6DGkLpDIQPs2morqNhQbvbv6TJ0cNGxbONde5xzRkPjRhNVFXeRWS\\n3wOSK1TVc9TH8PVhy2+mf51q3RfIxNSsq5\/f4LCwoeHhdrYGtHOMIR+ssJoQ8p8D6TW1+AakTKND\\nJcRU+iKXGrnYqnl8dogCe3h6+gd2Dw7uGRYWZsLBJpy6wfLhC6s5UmGyVBgPSf6mQ3lKSTqdhst4\\nXyyBJi2yzC2gmfOsnJw6dPMPCAsb7Onp+aE2Tq3y7xJWc6RSPlWTIxZmaqSJGlkCiy4W8DNNWSij\\njKhUQKp2YHNsJQrH\/MretfJe9ra2HTu6w6R0wwbAv1dYrVInKGFSSqmwhi8oA6pKJk0sEpZSNLVQ\\ns8yoSjWDzrCm0y3FcjbLxJFJ54hldCrTncn4wHs3nTAKywgu\/EsbaiN4YxSWEVwwCssILhiFZQQX\\njMIyggtGYRnBBaOwjOCCUVhGcOH\/AgAA\/\/+S+QX6OV9s5wAAAABJRU5ErkJggpQu\\n\",\"__pickled_extra_fields__\":[\"thumbnail\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_document(42, <>, caption=\"Here's your document with tumbnail! Run /start command again to restart.\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=<>, filename='deeppavlov_article.pdf')" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 39, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='/start'), update_id=9)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 57, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=13, supergroup_chat_created=False, text='some text'), update_id=13)", + "received_message": "{\"text\":\"some text\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Bot has entered unrecoverable state :\/\\nRun \/start command again to restart.\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_message(42, 'Bot has entered unrecoverable state :/\\nRun /start command again to restart.', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 59, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=14, supergroup_chat_created=False, text='/start'), update_id=14)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='restart', from_user=User(first_name='AlexaTestnder', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='14', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 59, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=15, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=15)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"restart\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='quit', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='15', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 10, 1, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=16, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=16)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"quit\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Bot has entered unrecoverable state :\/\\nRun \/start command again to restart.\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_message(42, 'Bot has entered unrecoverable state :/\\nRun /start command again to restart.', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + } + ] } diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index d497e25f0..7e55ee49d 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -1,21 +1,42 @@ from importlib import import_module +from json import loads from pathlib import Path +from typing import Dict, List import pytest -from tests.messengers.telegram.utils import MockApplication +from dff.script.core.message import Message +from tests.messengers.telegram.utils import MockApplication, PathStep from tests.test_utils import get_path_from_tests_to_current_dir dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") happy_paths_file = Path(__file__).parent / "test_happy_paths.json" +def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: + imports = globals().copy() + imports.update(import_module("telegram").__dict__) + imports.update(import_module("telegram.ext").__dict__) + imports.update(import_module("telegram.constants").__dict__) + + path_steps = list() + for step in dict: + update = eval(step["update"], imports) + received = Message.model_validate_json(step["received_message"]) + received.original_message = update + response = Message.model_validate_json(step["response_message"]) + path_steps += [(update, received, response, step["response_functions"])] + return path_steps + + @pytest.mark.asyncio @pytest.mark.parametrize( - ["tutorial_module_name"], - [("1_basic",), ("2_attachments",), ("3_advanced",)], + "tutorial_module_name", + ["1_basic", "2_attachments", "3_advanced"], ) async def test_tutorials_memory(tutorial_module_name: str): + happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] + happy_path_steps = _cast_dict_to_happy_step(happy_path_data) module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") - module.interface.application = MockApplication.create(module.interface, list()) + module.interface.application = MockApplication.create(module.interface, happy_path_steps) module.pipeline.run() diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index a95f5414c..8294d8e30 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,27 +1,49 @@ from asyncio import get_event_loop -from typing import Any, Dict, Hashable, List, Optional, Tuple, TypeAlias +from typing import Any, Hashable, List, Optional, Tuple, TypeAlias from pydantic import BaseModel +from re import sub from telegram import File, Update from telegram.ext import ExtBot from dff.messengers.telegram.abstract import _AbstractTelegramInterface +from dff.pipeline.types import PipelineRunnerFunction from dff.script import Message from dff.script.core.context import Context -PathStep: TypeAlias = Tuple[Dict, Message, Message, Tuple[str, Tuple, Dict]] +PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] -class MockBot(BaseModel): - _original_bot: ExtBot - _latest_trace: Optional[Tuple[str, Tuple, Dict]] = None +def _compare_messages(mess1: Message, mess2: Message) -> bool: + if mess1.text == None or mess2.text == None: + return True + m1 = mess1.model_copy(deep=True) + m2 = mess2.model_copy(deep=True) + m1.text = sub(r"`\d+`", "<>", m1.text) + m2.text = sub(r"`\d+`", "<>", m2.text) + return m1 == m2 + + +class MockBot(BaseModel, arbitrary_types_allowed=True): + original_bot: ExtBot + latest_trace: List[str] = list() async def get_file(self, file_id: str) -> File: - return await self._original_bot.get_file(file_id) + return await self.original_bot.get_file(file_id) + + @staticmethod + def representation(any: Any) -> str: + if isinstance(any, bytes): + return "<>" + else: + return any.__repr__() def __getattribute__(self, name: str) -> Any: - def set_trace(*args, **kwargs): - self._latest_trace = (name, args, kwargs) + async def set_trace(*args, **kwargs): + joined_args = ", ".join([self.representation(a) for a in args]) + joined_kwargs = ", ".join([f"{k}={self.representation(v)}" for k, v in kwargs.items()]) + arguments = ", ".join([joined_args, joined_kwargs]) + self.latest_trace += [f"{name}({arguments})"] try: return object.__getattribute__(self, name) @@ -29,40 +51,46 @@ def set_trace(*args, **kwargs): return set_trace -class MockApplication(BaseModel): +class MockApplication(BaseModel, arbitrary_types_allowed=True): bot: MockBot happy_path: List[PathStep] - _interface: _AbstractTelegramInterface - _latest_ctx: Optional[Context] = None + interface: _AbstractTelegramInterface + latest_ctx: Optional[Context] = None @classmethod def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep]) -> "MockApplication": - mock_bot = MockBot(_original_bot=interface.application.bot) - instance = cls(bot=mock_bot, happy_path=happy_path, _interface=interface) - interface.pipeline_runner = instance._wrapped_pipeline_runner + mock_bot = MockBot(original_bot=interface.application.bot) + instance = cls(bot=mock_bot, happy_path=happy_path, interface=interface) return instance - async def _wrapped_pipeline_runner( - self, message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None - ) -> Context: - self._latest_ctx = await self._interface.pipeline_runner(message, ctx_id, update_ctx_misc) - return self._latest_ctx + def _wrap_pipeline_runner(self, runner: PipelineRunnerFunction): + async def wrapped_pipeline_runner( + message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None + ) -> Context: + self.latest_ctx = await runner(message, ctx_id, update_ctx_misc) + return self.latest_ctx + + wrapped_pipeline_runner.is_wrapped = True + return wrapped_pipeline_runner def _run_bot(self) -> None: + if not getattr(self.interface.pipeline_runner, "is_wrapped", False): + self.interface.pipeline_runner = self._wrap_pipeline_runner(self.interface.pipeline_runner) + loop = get_event_loop() for update, received, response, trace in self.happy_path: - if update["is_message"]: - update = Update() - loop.run_until_complete(self._interface.on_message(update, None)) # type: ignore + if update.message is not None: + loop.run_until_complete(self.interface.on_message(update, None)) # type: ignore + elif update.callback_query is not None: + loop.run_until_complete(self.interface.on_callback(update, None)) # type: ignore else: - update = Update() - loop.run_until_complete(self._interface.on_callback(update, None)) # type: ignore - assert self._latest_ctx is not None, "During pipeline runner execution, no context was produced!" - assert self._latest_ctx.last_request == received, "Expected request message is not equal to expected!" - assert self._latest_ctx.last_response == response, "Expected response message is not equal to expected!" - assert self.bot._latest_trace == trace, "Expected trace is not equal to expected!" - self.bot._latest_trace = None - self._latest_ctx = None + raise RuntimeError(f"Update {update} type unknown!") + assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" + assert _compare_messages(self.latest_ctx.last_request, received), "Expected request message is not equal to expected!" + assert _compare_messages(self.latest_ctx.last_response, response), "Expected response message is not equal to expected!" + assert self.bot.latest_trace == trace, "Expected trace is not equal to expected!" + self.bot.latest_trace = list() + self.latest_ctx = None def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: return self._run_bot() diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index b8604b3f9..5b821a393 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -80,10 +80,10 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) animation_data = { # For some reason, if we don't define filename explicitly, animation is sent as file. "source": HttpUrl( - f"{EXAMPLE_ATTACHMENT_SOURCE}/hong-kong-simplyart4794.mp4" + f"{EXAMPLE_ATTACHMENT_SOURCE}/hong-kong-simplyart4794.gif" ), "title": "Hong Kong skyscraper views by Simplyart4794", - "filename": "hk.mp4", + "filename": "hk.gif", } image_data = { diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 9d7cdc362..f3a52d5e1 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -14,6 +14,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %pip install dff[telegram] # %% +from asyncio import get_event_loop import os from urllib.request import urlopen @@ -47,7 +48,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) 3. Multiple attachments of different kind handling. 4. Image with a spoiler. 5. Document with a thumbnail. -6. Raw representation of different data user can send to the bot. +6. Attachment bytes hash. Last option ("Raw attachments!") button might be especially interesting, because it shows how bot precepts different telegram attachments sent by user @@ -88,31 +89,15 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) } -# %% -formatted_request = r""" -Here's your previous request\! -```json -{} -``` -Run /start command again to restart\. -""" - - -def stringify_previous_request(ctx: Context, _: Pipeline) -> Message: - dump = ctx.last_request.model_dump_json(indent=4) - return Message( - formatted_request.format(dump), parse_mode=ParseMode.MARKDOWN_V2 - ) - - # %% def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: + loop = get_event_loop() atch = [ a for a in ctx.last_request.attachments if isinstance(a, DataAttachment) ] if len(atch) > 0: - atch_hash = hash(atch[0].get_bytes(pipe.messenger_interface)) - resp_format = r"Here's your previous request hash: `{}`\!\nRun /start command again to restart\." + atch_hash = hash(loop.run_until_complete(atch[0].get_bytes(pipe.messenger_interface))) + resp_format = "Here's your previous request hash: `{}`!\nRun /start command again to restart." return Message( resp_format.format(atch_hash, parse_mode=ParseMode.MARKDOWN_V2) ) @@ -162,11 +147,6 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: callback_data="thumbnail", ), ], - [ - InlineKeyboardButton( - "Raw attachments!", callback_data="raw" - ), - ], [ InlineKeyboardButton( "Attachment bytes hash!", @@ -191,7 +171,6 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: "attachments_node": cnd.has_callback_query("attachments"), "secret_node": cnd.has_callback_query("secret"), "thumbnail_node": cnd.has_callback_query("thumbnail"), - "raw_init_node": cnd.has_callback_query("raw"), "hash_init_node": cnd.has_callback_query("hash"), "hmmm_node": cnd.has_callback_query("restart"), "fallback_node": cnd.has_callback_query("quit"), @@ -221,15 +200,6 @@ def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: attachments=[Document(**document_data)], ), }, - "raw_init_node": { - RESPONSE: Message( - "Alright! Now send me any message and I'll send you it's raw data!" - ), - TRANSITIONS: {"raw_request_node": cnd.true()}, - }, - "raw_request_node": { - RESPONSE: stringify_previous_request, - }, "hash_init_node": { RESPONSE: Message( "Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!" From eb07fae9a7a3ae946f3adc92dfa95e689d1c694e Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 24 May 2024 11:53:44 +0200 Subject: [PATCH 098/140] last test step added --- dff/script/core/message.py | 2 + .../messengers/telegram/test_happy_paths.json | 26 +++++++++++- tests/messengers/telegram/test_tutorials.py | 2 +- tests/messengers/telegram/utils.py | 40 +++++++++---------- tutorials/messengers/telegram/3_advanced.py | 5 +-- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/dff/script/core/message.py b/dff/script/core/message.py index d982f9d0b..1abdd2964 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -162,6 +162,8 @@ def __eq__(self, other): if isinstance(other, DataAttachment): if self.id != other.id: return False + if self.source != other.source: + return False if self.title != other.title: return False return True diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index 0208daf7a..ba83ef773 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -179,7 +179,31 @@ ] }, { - "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 39, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='/start'), update_id=9)", + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 22, 19, 53, 42, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='/start'), update_id=9)", + "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_location(42, 58.43161, 27.792887, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))))" + ] + }, + { + "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='hash', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='9', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 22, 19, 53, 42, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=6601664672, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=10, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=10)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"hash\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_message(42, 'Alright! Now send me a message with data attachment (audio, video, animation, image, sticker or document)!', parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 22, 20, 12, 23, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=12, sticker=Sticker(api_kwargs={'thumb': {'file_id': 'AAMCAgADGQEAAgS0Zk5Rpz6PkZu6Ef3Ef7GwnxAZYocAAiwCAAJHBkMF0YsKl8FLgq8BAAdtAAM1BA', 'file_unique_id': 'AQADLAIAAkcGQwVy', 'file_size': 5416, 'width': 128, 'height': 128}}, emoji='👨', file_id='CAACAgIAAxkBAAIEtGZOUac-j5GbuhH9xH-xsJ8QGWKHAAIsAgACRwZDBdGLCpfBS4KvNQQ', file_size=29492, file_unique_id='AgADLAIAAkcGQwU', height=512, is_animated=False, is_video=False, set_name='citati_prosto', thumbnail=PhotoSize(file_id='AAMCAgADGQEAAgS0Zk5Rpz6PkZu6Ef3Ef7GwnxAZYocAAiwCAAJHBkMF0YsKl8FLgq8BAAdtAAM1BA', file_size=5416, file_unique_id='AQADLAIAAkcGQwVy', height=128, width=128), type=StickerType.REGULAR, width=512), supergroup_chat_created=False), update_id=11)", + "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"source\":null,\"cached_filename\":null,\"id\":\"CAACAgIAAxkBAAIEtGZOUac-j5GbuhH9xH-xsJ8QGWKHAAIsAgACRwZDBdGLCpfBS4KvNQQ\",\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"sticker\",\"is_animated\":false,\"is_video\":false,\"type\":\"regular\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your previous request hash: `0`!\\nRun \/start command again to restart.\",\"commands\":null,\"attachments\":null,\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_functions": [ + "send_message(42, \"Here's your previous request hash: `0`!\\nRun /start command again to restart.\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" + ] + }, + { + "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 39, tzinfo=UTC), delete_chat_photo=False, entities=(MessageEntity(length=6, offset=0, type=MessageEntityType.BOT_COMMAND),), from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=12, supergroup_chat_created=False, text='/start'), update_id=12)", "received_message": "{\"text\":\"\/start\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "response_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"longitude\":27.792887,\"latitude\":58.43161,\"dff_attachment_type\":\"location\",\"reply_markup\":\"gASV3AMAAAAAAACMJXRlbGVncmFtLl9pbmxpbmUuaW5saW5la2V5Ym9hcmRtYXJrdXCUjBRJbmxp\\nbmVLZXlib2FyZE1hcmt1cJSTlCmBlH2UKIwPaW5saW5lX2tleWJvYXJklCiMJXRlbGVncmFtLl9p\\nbmxpbmUuaW5saW5la2V5Ym9hcmRidXR0b26UjBRJbmxpbmVLZXlib2FyZEJ1dHRvbpSTlCmBlH2U\\nKIwNY2FsbGJhY2tfZGF0YZSMCWZvcm1hdHRlZJSMDWNhbGxiYWNrX2dhbWWUTowJbG9naW5fdXJs\\nlE6MA3BheZROjBNzd2l0Y2hfaW5saW5lX3F1ZXJ5lE6MH3N3aXRjaF9pbmxpbmVfcXVlcnlfY2hv\\nc2VuX2NoYXSUTowgc3dpdGNoX2lubGluZV9xdWVyeV9jdXJyZW50X2NoYXSUTowEdGV4dJSMFEN1\\ndGUgZm9ybWF0dGVkIHRleHQhlIwDdXJslE6MB3dlYl9hcHCUTowHX2Zyb3plbpSIjAlfaWRfYXR0\\ncnOUKGgUTk5oDE5OTk5OdJSMCmFwaV9rd2FyZ3OUfZR1YoWUaAgpgZR9lChoC4wLYXR0YWNobWVu\\ndHOUaA1OaA5OaA9OaBBOaBFOaBJOaBOMFU11bHRpcGxlIGF0dGFjaG1lbnRzIZRoFU5oFk5oF4ho\\nGChoIE5OaB9OTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAZzZWNyZXSUaA1OaA5OaA9OaBBOaBFO\\naBJOaBOMDVNlY3JldCBpbWFnZSGUaBVOaBZOaBeIaBgoaCdOTmgmTk5OTk50lGgafZR1YoWUaAgp\\ngZR9lChoC4wJdGh1bWJuYWlslGgNTmgOTmgPTmgQTmgRTmgSTmgTjBhEb2N1bWVudCB3aXRoIHRo\\ndW1ibmFpbCGUaBVOaBZOaBeIaBgoaC5OTmgtTk5OTk50lGgafZR1YoWUaAgpgZR9lChoC4wEaGFz\\naJRoDU5oDk5oD05oEE5oEU5oEk5oE4wWQXR0YWNobWVudCBieXRlcyBoYXNoIZRoFU5oFk5oF4ho\\nGChoNU5OaDROTk5OTnSUaBp9lHVihZRoCCmBlH2UKGgLjAdyZXN0YXJ0lGgNTmgOTmgPTmgQTmgR\\nTmgSTmgTjAhSZXN0YXJ0IZRoFU5oFk5oF4hoGChoPE5OaDtOTk5OTnSUaBp9lHViaAgpgZR9lCho\\nC4wEcXVpdJRoDU5oDk5oD05oEE5oEU5oEk5oE4wFUXVpdCGUaBVOaBZOaBeIaBgoaEJOTmhBTk5O\\nTk50lGgafZR1YoaUdJRoF4hoGGhGhZRoGn2UdWIu\\n\",\"__pickled_extra_fields__\":[\"reply_markup\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "response_functions": [ diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index 7e55ee49d..dd55cd783 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -34,7 +34,7 @@ def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: "tutorial_module_name", ["1_basic", "2_attachments", "3_advanced"], ) -async def test_tutorials_memory(tutorial_module_name: str): +def test_tutorials_memory(tutorial_module_name: str): happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] happy_path_steps = _cast_dict_to_happy_step(happy_path_data) module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index 8294d8e30..06f603142 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -2,35 +2,20 @@ from typing import Any, Hashable, List, Optional, Tuple, TypeAlias from pydantic import BaseModel -from re import sub -from telegram import File, Update -from telegram.ext import ExtBot +from telegram import Update from dff.messengers.telegram.abstract import _AbstractTelegramInterface from dff.pipeline.types import PipelineRunnerFunction from dff.script import Message from dff.script.core.context import Context +from dff.script.core.message import DataAttachment PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] -def _compare_messages(mess1: Message, mess2: Message) -> bool: - if mess1.text == None or mess2.text == None: - return True - m1 = mess1.model_copy(deep=True) - m2 = mess2.model_copy(deep=True) - m1.text = sub(r"`\d+`", "<>", m1.text) - m2.text = sub(r"`\d+`", "<>", m2.text) - return m1 == m2 - - class MockBot(BaseModel, arbitrary_types_allowed=True): - original_bot: ExtBot latest_trace: List[str] = list() - async def get_file(self, file_id: str) -> File: - return await self.original_bot.get_file(file_id) - @staticmethod def representation(any: Any) -> str: if isinstance(any, bytes): @@ -59,8 +44,7 @@ class MockApplication(BaseModel, arbitrary_types_allowed=True): @classmethod def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep]) -> "MockApplication": - mock_bot = MockBot(original_bot=interface.application.bot) - instance = cls(bot=mock_bot, happy_path=happy_path, interface=interface) + instance = cls(bot=MockBot(), happy_path=happy_path, interface=interface) return instance def _wrap_pipeline_runner(self, runner: PipelineRunnerFunction): @@ -71,11 +55,22 @@ async def wrapped_pipeline_runner( return self.latest_ctx wrapped_pipeline_runner.is_wrapped = True + wrapped_pipeline_runner.original = runner return wrapped_pipeline_runner + def _wrap_populate_attachment(self, interface: _AbstractTelegramInterface): + async def wrapped_populate_attachment(_: DataAttachment) -> bytes: + return bytes() + + wrapped_populate_attachment.is_wrapped = True + wrapped_populate_attachment.original = interface.populate_attachment + return wrapped_populate_attachment + def _run_bot(self) -> None: if not getattr(self.interface.pipeline_runner, "is_wrapped", False): self.interface.pipeline_runner = self._wrap_pipeline_runner(self.interface.pipeline_runner) + if not getattr(self.interface.populate_attachment, "is_wrapped", False): + self.interface.populate_attachment = self._wrap_populate_attachment(self.interface) loop = get_event_loop() for update, received, response, trace in self.happy_path: @@ -86,12 +81,15 @@ def _run_bot(self) -> None: else: raise RuntimeError(f"Update {update} type unknown!") assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" - assert _compare_messages(self.latest_ctx.last_request, received), "Expected request message is not equal to expected!" - assert _compare_messages(self.latest_ctx.last_response, response), "Expected response message is not equal to expected!" + assert self.latest_ctx.last_request == received, "Expected request message is not equal to expected!" + assert self.latest_ctx.last_response == response, "Expected response message is not equal to expected!" assert self.bot.latest_trace == trace, "Expected trace is not equal to expected!" self.bot.latest_trace = list() self.latest_ctx = None + self.interface.pipeline_runner = self.interface.pipeline_runner.original + self.interface.populate_attachment = self.interface.populate_attachment.original + def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: return self._run_bot() diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index f3a52d5e1..a608c879c 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -90,13 +90,12 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %% -def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: - loop = get_event_loop() +async def hash_data_attachment_request(ctx: Context, pipe: Pipeline) -> Message: atch = [ a for a in ctx.last_request.attachments if isinstance(a, DataAttachment) ] if len(atch) > 0: - atch_hash = hash(loop.run_until_complete(atch[0].get_bytes(pipe.messenger_interface))) + atch_hash = hash(await atch[0].get_bytes(pipe.messenger_interface)) resp_format = "Here's your previous request hash: `{}`!\nRun /start command again to restart." return Message( resp_format.format(atch_hash, parse_mode=ParseMode.MARKDOWN_V2) From 97be6b9bce3bebdc2013af09914dd10774a02289 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 24 May 2024 11:58:45 +0200 Subject: [PATCH 099/140] attachments migrated to wiki --- tests/messengers/telegram/test_happy_paths.json | 10 +++++----- tests/script/core/test_message.py | 2 +- tutorials/messengers/telegram/2_attachments.py | 2 +- tutorials/messengers/telegram/3_advanced.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index ba83ef773..9f88c12da 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -65,7 +65,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 46, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=6, supergroup_chat_created=False, text='audio'), update_id=6)", "received_message": "{\"text\":\"audio\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_audio(42, audio=<>, performer=None, title=None, caption=\"Here's your audio!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" ] @@ -73,7 +73,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 4, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=7, supergroup_chat_created=False, text='video'), update_id=7)", "received_message": "{\"text\":\"video\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your video!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/crownfall-lags-nkognit0.mp4\",\"cached_filename\":null,\"id\":null,\"title\":\"Epic Dota2 gameplay by Nkognit0\",\"use_cache\":true,\"dff_attachment_type\":\"video\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your video!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/crownfall-lags-nkognit0.mp4\",\"cached_filename\":null,\"id\":null,\"title\":\"Epic Dota2 gameplay by Nkognit0\",\"use_cache\":true,\"dff_attachment_type\":\"video\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_video(42, <>, caption=\"Here's your video!\", disable_notification=None, reply_markup=None, parse_mode=None, supports_streaming=None, has_spoiler=None, thumbnail=None, filename=None)" ] @@ -81,7 +81,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 22, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=8, supergroup_chat_created=False, text='animation'), update_id=8)", "received_message": "{\"text\":\"animation\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your animation!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/hong-kong-simplyart4794.gif\",\"cached_filename\":null,\"id\":null,\"title\":\"Hong Kong skyscraper views by Simplyart4794\",\"use_cache\":true,\"dff_attachment_type\":\"animation\",\"filename\":\"hk.gif\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your animation!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/hong-kong-simplyart4794.gif\",\"cached_filename\":null,\"id\":null,\"title\":\"Hong Kong skyscraper views by Simplyart4794\",\"use_cache\":true,\"dff_attachment_type\":\"animation\",\"filename\":\"hk.gif\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_animation(42, <>, caption=\"Here's your animation!\", parse_mode=None, disable_notification=None, reply_markup=None, has_spoiler=None, thumbnail=None, filename='hk.gif')" ] @@ -89,7 +89,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 35, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='image'), update_id=9)", "received_message": "{\"text\":\"image\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your image!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your image!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_photo(42, <>, caption=\"Here's your image!\", disable_notification=None, reply_markup=None, parse_mode=None, has_spoiler=None, filename=None)" ] @@ -97,7 +97,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 2, 19, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=10, supergroup_chat_created=False, text='document'), update_id=10)", "received_message": "{\"text\":\"document\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your document!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your document!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_document(42, <>, caption=\"Here's your document!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None, filename=None)" ] diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 1922b5bbf..ccd4216ab 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -27,7 +27,7 @@ Video, ) -EXAMPLE_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" +EXAMPLE_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" class DFFCLIMessengerInterface(CLIMessengerInterface): diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index 5b821a393..d46ddfc87 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -48,7 +48,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %% -EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" +EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" location_data = {"latitude": 50.65, "longitude": 3.916667} diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index a608c879c..3ac2a61e9 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -57,7 +57,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %% -EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@example-attachments" +EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" image_url = HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov.png") From 33a5c73df0f6f76f9e0441023c1e6ee87b9eafcd Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 27 May 2024 21:21:14 +0200 Subject: [PATCH 100/140] pragma removed, inheritance added --- dff/messengers/telegram/abstract.py | 10 ++++------ dff/messengers/telegram/interface.py | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 6c7e7be83..07d2738c5 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -45,7 +45,7 @@ telegram_available = False -class _AbstractTelegramInterface(MessengerInterface): # pragma: no cover +class _AbstractTelegramInterface(MessengerInterface): supported_request_attachment_types = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document, Invoice} supported_response_attachment_types = {Location, Contact, Poll, Sticker, Audio, Video, Animation, Image, Document} @@ -58,7 +58,7 @@ def __init__(self, token: str, attachments_directory: Optional[Path] = None) -> self.application.add_handler(MessageHandler(ALL, self.on_message)) self.application.add_handler(CallbackQueryHandler(self.on_callback)) - async def populate_attachment(self, attachment: DataAttachment) -> bytes: # pragma: no cover + async def populate_attachment(self, attachment: DataAttachment) -> bytes: if attachment.id is not None: file = await self.application.bot.get_file(attachment.id) data = await file.download_as_bytearray() @@ -66,7 +66,7 @@ async def populate_attachment(self, attachment: DataAttachment) -> bytes: # pra else: raise ValueError(f"For attachment {attachment} id is not defined!") - def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # pragma: no cover + def extract_message_from_telegram(self, update: TelegramMessage) -> Message: message = Message() message.attachments = list() @@ -196,9 +196,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: # return message - async def cast_message_to_telegram_and_send( - self, bot: ExtBot, chat_id: int, message: Message - ) -> None: # pragma: no cover + async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, message: Message) -> None: if message.attachments is not None: files = list() for attachment in message.attachments: diff --git a/dff/messengers/telegram/interface.py b/dff/messengers/telegram/interface.py index af294a62c..76106acb1 100644 --- a/dff/messengers/telegram/interface.py +++ b/dff/messengers/telegram/interface.py @@ -1,20 +1,28 @@ from pathlib import Path -from typing import Optional +from typing import Hashable, List, Optional, Tuple from telegram import Update +from dff.messengers.common.interface import PollingMessengerInterface, CallbackMessengerInterface from dff.pipeline.types import PipelineRunnerFunction +from dff.script import Context, Message from .abstract import _AbstractTelegramInterface -class PollingTelegramInterface(_AbstractTelegramInterface): # pragma: no cover +class PollingTelegramInterface(_AbstractTelegramInterface, PollingMessengerInterface): def __init__( self, token: str, attachments_directory: Optional[Path] = None, interval: int = 2, timeout: int = 20 ) -> None: - super().__init__(token, attachments_directory) + _AbstractTelegramInterface.__init__(self, token, attachments_directory) self.interval = interval self.timeout = timeout + def _request(self) -> List[Tuple[Message, Hashable]]: + raise RuntimeError("_request method for PollingTelegramInterface is not specified") + + def _respond(self, _: List[Context]): + raise RuntimeError("_respond method for PollingTelegramInterface is not specified") + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): await super().connect(pipeline_runner, *args, **kwargs) self.application.run_polling( @@ -22,14 +30,20 @@ async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs ) -class CallbackTelegramInterface(_AbstractTelegramInterface): # pragma: no cover +class CallbackTelegramInterface(_AbstractTelegramInterface, CallbackMessengerInterface): def __init__( self, token: str, attachments_directory: Optional[Path] = None, host: str = "localhost", port: int = 844 ): - super().__init__(token, attachments_directory) + _AbstractTelegramInterface.__init__(self, token, attachments_directory) self.listen = host self.port = port + def _request(self) -> List[Tuple[Message, Hashable]]: + raise RuntimeError("_request method for CallbackTelegramInterface is not specified") + + def _respond(self, _: List[Context]): + raise RuntimeError("_respond method for CallbackTelegramInterface is not specified") + async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): await super().connect(pipeline_runner, *args, **kwargs) self.application.run_webhook(listen=self.listen, port=self.port, allowed_updates=Update.ALL_TYPES) From 140f014dabc5908908d0bb6659697417f4f29fa7 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 27 May 2024 22:11:52 +0200 Subject: [PATCH 101/140] some review parts fixed --- dff/messengers/common/interface.py | 14 ++++++++------ dff/messengers/telegram/abstract.py | 15 ++++++++------- tests/script/core/test_message.py | 4 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index c1646ec39..9615d1b8e 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -11,13 +11,13 @@ import logging from pathlib import Path from tempfile import gettempdir -from typing import Optional, Any, List, Tuple, Hashable, TYPE_CHECKING +from typing import Optional, Any, List, Tuple, Hashable, TYPE_CHECKING, Type if TYPE_CHECKING: from dff.script import Context, Message from dff.pipeline.types import PipelineRunnerFunction from dff.messengers.common.types import PollingInterfaceLoopFunction - from dff.script.core.message import DataAttachment + from dff.script.core.message import Attachment, DataAttachment logger = logging.getLogger(__name__) @@ -28,8 +28,8 @@ class MessengerInterface(abc.ABC): It is responsible for connection between user and pipeline, as well as for request-response transactions. """ - supported_request_attachment_types = set() - supported_response_attachment_types = set() + supported_request_attachment_types: set[Type[Attachment]] = set() + supported_response_attachment_types: set[type[Attachment]] = set() def __init__(self, attachments_directory: Optional[Path] = None) -> None: tempdir = gettempdir() @@ -37,13 +37,14 @@ def __init__(self, attachments_directory: Optional[Path] = None) -> None: self.attachments_directory = attachments_directory else: warning_start = f"Attachments directory for {type(self).__name__} messenger interface" - warning_end = "attachment data won't be preserved locally!" + warning_end = "attachment data won't be cached locally!" if attachments_directory is None: self.attachments_directory = Path(tempdir) logger.warning(f"{warning_start} is None, so will be set to tempdir and {warning_end}") else: self.attachments_directory = attachments_directory logger.warning(f"{warning_start} is in tempdir, so {warning_end}") + self.attachments_directory.mkdir(parents=True, exist_ok=True) @abc.abstractmethod async def connect(self, pipeline_runner: PipelineRunnerFunction): @@ -140,7 +141,8 @@ class CallbackMessengerInterface(MessengerInterface): Callback message interface is waiting for user input and answers once it gets one. """ - def __init__(self): + def __init__(self, attachments_directory: Optional[Path] = None) -> None: + super().__init__(attachments_directory) self._pipeline_runner: Optional[PipelineRunnerFunction] = None async def connect(self, pipeline_runner: PipelineRunnerFunction): diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 07d2738c5..5ed53d45e 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -199,6 +199,7 @@ def extract_message_from_telegram(self, update: TelegramMessage) -> Message: async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, message: Message) -> None: if message.attachments is not None: files = list() + media_group_attachments_num = len([att for att in message.attachments if isinstance(att, DataAttachment)]) for attachment in message.attachments: if isinstance(attachment, Location): await bot.send_location( @@ -250,7 +251,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if len(message.attachments) > 1: + if media_group_attachments_num == 1: files += [ InputMediaAudio( attachment_bytes, @@ -278,7 +279,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Video): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if len(message.attachments) > 1: + if media_group_attachments_num == 1: files += [ InputMediaVideo( attachment_bytes, @@ -307,7 +308,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Animation): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if len(message.attachments) > 1: + if media_group_attachments_num == 1: files += [ InputMediaAnimation( attachment_bytes, @@ -334,7 +335,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Image): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if len(message.attachments) > 1: + if media_group_attachments_num == 1: files += [ InputMediaPhoto( attachment_bytes, @@ -359,7 +360,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Document): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if len(message.attachments) > 1: + if media_group_attachments_num == 1: files += [ InputMediaDocument( attachment_bytes, @@ -410,7 +411,7 @@ async def _on_event( if update.effective_chat is not None and data_available: message = create_message(update) message.original_message = update - resp = await self.pipeline_runner(message, update.effective_chat.id) + resp = await self._pipeline_runner(message, update.effective_chat.id) if resp.last_response is not None: await self.cast_message_to_telegram_and_send( self.application.bot, update.effective_chat.id, resp.last_response @@ -423,4 +424,4 @@ async def on_callback(self, update: Update, _: ContextTypes.DEFAULT_TYPE) -> Non await self._on_event(update, _, lambda s: Message(attachments=[CallbackQuery(query_string=s.callback_query.data)])) async def connect(self, pipeline_runner: PipelineRunnerFunction, *args, **kwargs): - self.pipeline_runner = pipeline_runner + self._pipeline_runner = pipeline_runner diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index ccd4216ab..15eff7510 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -147,10 +147,10 @@ async def test_getting_attachment_bytes(self): for document in (remote_document_att, local_document_att, iface_document_att): read_bytes = await document.get_bytes(cli_iface) - assert document_bytes, read_bytes + assert document_bytes == read_bytes if not isinstance(document.source, Path): cached_bytes = document.cached_filename.read_bytes() - assert document_bytes, cached_bytes + assert document_bytes == cached_bytes def test_missing_error(self): with pytest.raises(ValidationError) as e: From 47610a338b3df1558aedb2f575196a1890433286 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 27 May 2024 22:12:50 +0200 Subject: [PATCH 102/140] venv ignore added back --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bed9d05fb..bdba7af28 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.DS_Store* *.egg-info/ dist/ +venv/ build/ docs/source/apiref docs/source/_misc From 54358899f0abab874f6265d7cb70a10e7d34247d Mon Sep 17 00:00:00 2001 From: askatasuna Date: Wed, 29 May 2024 14:04:59 +0300 Subject: [PATCH 103/140] Fixed attachment parsing and tutorial attachments --- dff/messengers/vk.py | 28 ++++++++++++++++------- tutorials/messengers/vk/2_attachments.py | 6 +++-- tutorials/messengers/vk/cat.jpg | Bin 93255 -> 0 bytes 3 files changed, 24 insertions(+), 10 deletions(-) delete mode 100644 tutorials/messengers/vk/cat.jpg diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 481ed3fcd..ce237a80b 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -30,9 +30,25 @@ async def vk_api_call(method): def extract_vk_update(updates): upds = [] - for i in updates["updates"]: - text, id = i["object"]["message"]["text"], i["object"]["message"]["from_id"] - message = Message(text=text) + for update in updates["updates"]: + text, id = update["object"]["message"]["text"], update["object"]["message"]["from_id"] + attachments = [] + attachments_list = update["object"]["message"]["attachments"] + + if attachments_list != []: + for attachment in attachments_list: + att_object = attachment[attachment["type"]] + if attachment["type"] == "audio" or attachment["type"] == "doc": + attachments.append(DataAttachment(source=att_object["url"], id=str(att_object["id"]))) + elif attachment["type"] == "photo": + attachments.append( + DataAttachment( + source=att_object["sizes"][-1]["url"], # last one is the highest resolution + id=str(att_object["id"]) + ) + ) + + message = Message(text=text, attachments=attachments) upds.append(message, int(id)) return upds @@ -107,9 +123,6 @@ def connect(self): async def get_longpoll_server(self): return await vk_api_call(f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}") - # return requests.post( - # f"https://api.vk.com/method/groups.getLongPollServer?group_id={self.group_id}&v=5.81&access_token={self.token}" - # ).json() async def get_upload_server(self, data_type, peer_id): upload_url = await vk_api_call( @@ -221,6 +234,7 @@ async def _respond(self, response: ctx): if response.attachments is not None: attachment_list = [] for attachment in response.attachments: + # add id to each attachment that is being generated in upload_attachment method if isinstance(attachment, Image): attachment_list.append( {"type": "photo", "source": attachment.source} @@ -246,8 +260,6 @@ async def _respond(self, response: ctx): async def populate_attachment(self, attachment: DataAttachment) -> bytes: # pragma: no cover if attachment.id is not None: - # attachment.id is not present??? - # add file_link = await vk_api_call(f"https://api.vk.com/method/photos.getById?photos={attachment.id}&v=5.81&access_token={self.token}")[0]["sizes"][-1]["url"] data = FilesOpener(file_link, key_format="file").open_files(just_bytes=True) return bytes(data) diff --git a/tutorials/messengers/vk/2_attachments.py b/tutorials/messengers/vk/2_attachments.py index 2d80d9f70..3197d22ff 100644 --- a/tutorials/messengers/vk/2_attachments.py +++ b/tutorials/messengers/vk/2_attachments.py @@ -45,6 +45,8 @@ # %% +EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" + script = { "greeting_flow": { "start_node": { @@ -60,13 +62,13 @@ }, }, "cat_image_node": { - RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source="https://media.tenor.com/ff2BZlCK0SwAAAAM/gatin.gif"), Image(source="https://d2ph5fj80uercy.cloudfront.net/04/cat2634.jpg")]), + RESPONSE: Message(text="Two cool cats sent.", attachments=[Image(source=f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov.png"), Image(source=f"{EXAMPLE_ATTACHMENT_SOURCE}/hong-kong-simplyart4794.gif")]), TRANSITIONS: { "greeting_node": cnd.true() } }, "book_file_node": { - RESPONSE: Message(text="Here is your book!", attachments=[Document(source="book.pdf")]), + RESPONSE: Message(text="Here is your book!", attachments=[Document(source=f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov-article.pdf")]), TRANSITIONS: { "greeting_node": cnd.true() } diff --git a/tutorials/messengers/vk/cat.jpg b/tutorials/messengers/vk/cat.jpg deleted file mode 100644 index 5d6a4d2eb72eb7561957bf46e0f468cdf9dfb961..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93255 zcmbrlcR*9w7B75Khyj8o0W>rXA%HX`p-G(p0Rn_xq=}S(bfu|)dV>@b1PoOOMWi?B z#Xg9Dbd@RsHo90Tqu_Yw9UPr|@Auw+--4X8%h|uR+u3{VwbuFT*=SEkd!zMCoUyN zz!T(1ii#vXZ9N;CV95VpfWJBc3=)0>egp==08k7BhJpOm1*ic46bjp^>OTa5!r(lJ zT}WOq^#}cv13)1=S${nTP%sDpMZ?fw)}~9gFdlf;Gqp#Z*bb#4;7kNwjA&Hp1z{oZ z5Eg}IKvYHpiBISpBpgP-0}vzyipF9vEI1S$F3DfnMTJxG1W6=|$wm|43{zwZ#~-60 z%|#G|vycoa+hgx&;n4Q*%mmv$AP?`ocTSp%hqa~g-mf>U6aOjnWgKeW^Ujy%;s%)=NOaL=nVz5j!jIl89- z_dwAb%|_-xpD9zGr9+rZgd`R~159rKKqrz=6e!dHgEc_+veGaRNeqz!$BSUnL@=n@ zSZ8Q4Pdxo1 zd%;%6nSPuXF#<{T*dwp%pe#N{g`f5^bQIq)8DvEAf0J0f=5pX z;GcDs6KEFHcr_ps07xhU912dB!U0GG)fE;gANnUKYcc3MWt`QE5&9(}3Wa z^M1XzUTF3+EFY}n>Ym%%;j5S7k^qJv2`@Eh!j}rvA(J~-Ynky>=EH*+`{ZsTCyaL5 z9{=9>8on;l6*+Z0a>pS4}Y3 zt9=8W!>{y)s_s)RXk3W%e`?@W1t&2Vb9g$35RzaQLXaGk0a20#4r~l(KSUL5GmuDz zvse@Y1E3=8@|aP2CkHC>hA1Fgf$Q7Cqt|Td6iFn7$^^=1(mh=ky~o8R(HIN_0xglD zNQ)A*oIV6F_zb0i!w8a*mX30I5nbMi>7f_F!yl(62)@dA2+*YrVDRV;Pi{iF5ffkn zV9%k6)=p%+qbIk7llPf^?n_=dxU^6y0$bbsqt}e-a6AD{rN9MCIgXw4T~sQAmPQ~D z!;;BFhD}z$!4GS*h3NVDcQvRH1g=N9xI`54Uh>rgZh{@Qlh~o+9yn%VgjYcI0C+J7 zDwskVD)KOXoi+pjEGC>R?X8@Ak)y@IBc3)og(77Oz9+Vys^+lsx(UIe2` z6)!x&4AbS$pGlBnKpLUMGp35qm`NWY;k^N>AAJk5A$@&G4MWmO%20hHQw~w{8LIX& z3{n2(4KX=gvw0{7X$x(1gvUdPrOLchm`a%H{s0IMonnB8;yOxe$3%;Z$Ne6oxSw?V zl$ij4;OPc{)0dVFRg`?Y5O|F6#X%;@IwiBjQ<)&y2FEcC29o)D(^__Eq4fLz;m0)7c~mh~tV}cfQCsFmsbcBUbmpsh{{(`tV!o}! zfb?)qfXr^4nXN2$b%#5S*EREl8<)raSd8`@Up$dPG^c#V0RCn!2Unq*O_EJr%3NvZ zV+vK>3aW_4=-rkVrewWsIQI7iGX`tU5nO_Us!ZeX;4tkI@$iXsJgyjShm2i$^g>sb zEXZqO2G)=K#>8WHBtL|e#+PXvAX)h;-k+b7#E~JA3l&88a$;wP%;-F4ABke|G(%iR zgr|&h8R|1{eL`L`*ks!3o*1j&B|_6J*B&h1#j&vlN=;J?ueg1ss{_6_6o%?t_WD^U z9ceDqc{eh=GI}g{Nnfo=IaP5)h&7#qI066z{Ecb!ydYF+@9b_I^CIX>J@k| z@pn8E*3I_(#{4|OblOnS-S}hz*+434??t>WB`7&4l;6-2apyrFDyFCz*8`B4C~x#5 zvsImw3hUddV9fy7h4aX0=f;_LY9k?x+#{u(*_sWlV}%yRijEBnZRdKIgxg8335P_R zQons`9d_T0f2g|Y-agbuy2(QN~$;rxZNsQX?|isIX zBoh!Dr2+tazg(bvsu&mC3JY)MT1R-kv6&W5n;8H_mLr~MKJ9()F!vC?K8 ziCHLP8c>Yp9nJYs9RPs%=T#``QiruN z+N-MFx~&ugkER|O6T6|IZWK@H!jPc^@WGIjg8(2{R^F3mSEjD|phZ(r;i}Z3Qw`rG ztX%Nucu5FW%RUulFwX;5<5k4MjW63gIEbY3+>Yy(f`+6R4~WOEFdto_ zgsG*TJ6C^|^0Nxy4MC$aS(g#yr&t9AB|L!$2h&cbAOT?C#I)&ZM1J1b36JdiIBe-y zfz7sx-G#XVgN!FsDpiu-EUlj!V1wRAMzd@%Pb)jgE<8!g%tTJ=HXZPwQTWd8vc+~N zqqJz!61M05sAui)OxuyEb_kL#g7wCmvD)-015`%}m<}Bc@&_~e?%tm*wRDLnIEg3J zXCG3`ZdkfHaUq+VPffJ_ri`AyyRh9CIG!0|g=cL=wSgV%y2P`F|Bt%qumV;-Zq7_=};j*rC~ znjwY%$n*fJh*14YMx~aNE)uhM907maX~G5vPlig_Vf%x$TpZ!8(C6qn8xgIecra-O zmxu-+Dj|i#bKF_;sl~3x*(4a&<(~HeXV>MNT)*^@;_JIuX#_Zh3OA|p(!8vOk#fq@ z^Gm}(r6kRk*ve;r`M#4 z6DZ2@Py#g;!@=ts3^H%sd72W0?x8lowO|B#7)4DR=aspe_~$%{H!D^O1;YO%-T-1t zf{YN49Hs~hChg8yqyW6D;TAdy0Myqx*&d*6nq6y6O|nII5dh;Px&eW}$EqWY@}c*q zLBL%UD&o}ZrJ9m+>&_F=oDnussBf$b;DyIl0e=?E|B_CG5EG2>8~hK4A0b%dkyk1rQ}&-!JbvcvUpwy@ zAFH2 z){g~ECgk$)S>{i;zi*Id;%E1>ZMwNzzq%AvvSPQaQVi|0kX8VXJ5YIePApmhjh4J* z5-*7s!JtPt(W`MijLGEp+w1AzCC4Is%~dPnulNF6^=2Q?O14?v;wZx%nU0~#i( z!Iu3c!;YoDQpFyw3Qi`^$=jKi5a_IUBWq$Nj~A5aTdX9nn<+=3NMatAhB`@18=-c3 z4aHyryeLK@3@vm(^BOJ({{x2Sl661|rGxS#^5cSdHJNGmyNRGi5}o-gb${x4-!nWt z9%hWU9t6B3M$nqeD+wi}rmYUqc=4skWGd|~R&7?T(u2grqI=-+G=?dPgT=9twV%UZ z#UX#7(T?T|U zeWo-Ts%B=PETx)Yi$OE%sn_d1Q^1A+I4qQcC(;lk762&_a`?k>}X-RO)UOr z6uj{ZyuPji_q>V)M+5yM8TH{x_3lqEa^=#5X_u7F`;aiiqY@CeE<*x%peDBIV{GBY zFoKao`lIl27yu3!4&@CHN$Kbg59%krbISiPgIy=@KG)FsA6_soPY8CTGrj0nl1%j0 zX4=@rV40#|!M)VEB*>=;6%%P3``*>t4>6KJ4?r`78j4`4Y!m{Z zv4;)_7UF*4ApSJITl5bqxSQdF%#!tg_Ep;)0{3w@-+%GF?cco zf)vEq3ewoKSV*iSfa0LMh?21cFDL~bA7I7Vllu>Z06Wv(L+GCaq2b zG<@|#37vQ-fp}dF6GWlXSQI=4QZ8w>SiCC&28e*CScoLE!yDY3v6$4*6Aw;YWBvot zbAtQ%p9lm`_$Lf5t(#JBOB&S)hqyepy=mgv#Y(ZK3LHoQ1Skdyo_ne4_SyD4mdkKD z0z40+5XwYl5faKvB>vo+bADbR2T)n^gFwB`|C1n34_Fp9g`}_+*}6H;(4{R2*X2Wm zJqfKC2pWw6I;5p@wKwIK{p(*^o$zmBh#^Us2Y>X?B1J zJNw!{lG885|GGm>u3vMMn93d)aOq_}E3NT@Du_76lN(tq4EiFo4AAyBHNp{bSV*#S z^WInBdW_6rW#TSn9l+*S{(=$2{|f!QtDF#VpSb_&$A+_$6nv%Pinm6hKLJ#3z~31; zW2wkAu>Y|HVvdhoSvUqMJp+wRQH(%HrVDgLRWcGuX}I1jZbtXxl;LwfF?lgR1ApIO z_{xZuW~asV#7#YySGtYtqF>p)df9q$8axTFsD|hqOc0go;~@!wO2Kb9sBW;5lkY?q z(;1aegPr9V0GBXt1qFH4T?3bfWR3t`@E@-__P^&30J%}GG-VX@y)YzWT+e21BU1P7 zx7pBh(UC7To(@EZ8$SQ1nQrH?=S3sRE&}NO4i*4*AdAUjvA`q!uA401F9AgR_)Mt& z5DfR$Mlu;eV)pk6<@0_HU3l|%%^}%YX}{XAbB6|RT*-QIf9Cd;`Zufhn%6ak{|M0z zT^Tk^IeGs~iP-(H*;gGupXaH#dB9jAitEA?556`8BEpeOq%o0fOd6Wy8#nVohEwe< zS8iNx=$9UxT871S1~@1JR6e>?uT`?8+fNWiuEdkQz zueg$Z{-i3-t3PNpTk)vL+{d`-Yue8|em({0if_MrpWFoQ5a@U%O^Td2l|le0NEQpp z>XjIKq6|siozES4!dn-ktf}1@CRG`udp1?;T%sv}<&RZwIw<#taf>D40pSL}&7C zRBOTYjDi>ID;CD-^FPs`bIJ{?d&;gjt5E6QP$`0<0Z)NKClnyysT4i2&gkX`;cg8&H$#;xNgUu~W|_oeKG+ok5hidx_4W20(nGC!*%66KkQ z7~Ho1V#x5xg@LNugv!3O(o^x0;9NmNI3iG>@Iy3!+jT+)2FTh15OALI7|G;s-P~eK z{)7MmpWHnkW5pA7b>emL@iG60W9Y(g5AU?RtvqMT8ojCiD(wCrpu0*Vn{ zM9m_30|aZUcgt_|7slXV%z^%oCGYjTH#BX5(|US^SJu9tzf^zi(swIaiRzzACkJ_6EZFv_v*NnW;398jza4LZSYS@_=j)^?6&dc#k20aSzXCC1J?)_af z4>%KA&J*qu-dTOYQnTn6jMjcD>ZiyBUFW`N!oA_VzRC8jd*>DEqAvY@wJ^HGviEO6 z;MdbT_aB0nz=KWw_v_AcRh%wK2!;jf^r=(|+o=l=o*!yI%9M&4KBSd{TM#Evi(reu z%af|g^e$NS_Z0m?g61Jl-u&?VutN66%E}!0}7+PoBs>;f5rYji7h{_dwf&{0a3$@O@OjAl>k5qj${HFRQ!`m z?s5@iQ0mj8p z5iI^t1Z%k}6`X_MTtvnS-sXBk$}Yx&8fy-FgzSaG5-70=sX|-6g;LEl@V!9pfczlv zxcEN=^_frh0#o40Yjcx(%631w3%E6@8NDHZ`WDIIi&_o})@Tf#gn<%i1s|1#>EZZ| zU{Dw4L8cnRaEbO(*Q&NMw@N2K+lf!UK}4#&&r`afEa{vKr?m7E0S^Ea zeoPm?C0owMhH+R)Pm3R7OQf67Bj{dmw#7Q3K?};qTg)4tM>@Q2r^#jbL71SHyn|Kk zC#U&v5w=tUX97L{OkS@auSu4$P%;E$4fwtq&(7o0Cve`ru3<}LR5n7_heySst=gVa zTTL0R+>XK!ixF`GnNvPSF^94;h?*qq{_H2^aS?k#8xtEm z1u8eryZ&}y^b!CN-5u?B82%*D_UdUHWH_Kn#{ZoH2M=H4-dGx^!;1uG@n!Yk)a?MxQ@U1i2nYh2{*49d$qr5=Y3by3VT0z+AHLVjW+j$ z{iH?2giaOo6AWF;D+X)VE&W5Kh-}UyTJGb@k5_;;rUCQzDWHIcI_j`^Jt&^WK}-Av zsGxhm#sbI4HV5@9TDr*2hi!_eCGs}|s?RBIUCciPu1B8vK?C%#wKoPb-nmqZ&~g$J zWbIS1Px#IC5%Ha{$XI;i(8~Raa|=1)skh4)WRixXM9wv+*C_-y4~g9}p!v{d8t= zZD7oIbvVFD8qqtfvb*x`D-`VcV}>@2;aqNxgySW-{673@h+;(wtFjRQ&H1VLwDk)PRHCy{j_Wm9%1 z@s~iI=Lai7MQ5J-CnPE9@c6zd z(DM~ODuOFpxykP2D*s(25e}`g6hOs|YaIy)ltjkde_ZGgePO9ys^X-hQC6-`S)#v9 zrRE&{)U9iJkKMy@#zh87y6|n{#_}vTXu5z1?PIoa${F&MD_V+eUZ5ex&I#PQFt8_@ zr7%$RKxNpv>VxKAgya(CPawA88CI}@EC~4T{CsDEK1R5`r!$u-t z;F-QVq8r->nse3T9yeb&|Mv52KFl=P+rQRuk7I%7s?dvfUsT_(-Ck$rewI6%SD~PC zQTQb(U zcyJ{DTa-6fEJn_W73|EFy zG{N!2qEWmU9BOCrRTh*Zk-u8jYu)->@|Z0?<@~hZ!TYuitq9%~NnOuelS1>QzDoL6 z+lJ(3{G+yV>z>|Dd4QZXSy+0%rNqg9P9$|HrPZKWK;*f~scXTtgIc35!wI=Ea-N*3 zRC}{+;=TaXm5Jz~p*ojNZR<9zp!lHxucVF9v8;$~fsNWTFJ3JVRb6#94ff&9Uu+f$xI4{QaE)XM zU&T!P(KPk^6FXHX=k~+e>gHG-{|nJ|C&J0cc!x9B$hE)sGYT-;`S-E zZq`C|7il+hrOfxH9DH!`K+>6oEd-ClG-HeJQm&O@Z8S|Hgp7o%`@AiSPY z1#miKaymGfiI=0C z;!)s_pH9ALDyxtw<{ZU!uJOMtFYVhv_j;&UJB5)Az1q|soaiAe)1>C)Tjkc*vsSO9 zIqgiEzx)K}YjIoN%g{jc%=Y%7V>7@wXa|T1)42c}=mKa|CY;JPXiU~E)O&Hf_HqRMt%(0;oK>oA8y3qW6Y-2Kq1U<4>J;yS1-W`DAet;hUZ|3zUp9+eLo?8h$( zFNZ!C6ZC#ue6Vt=Sn%pzbsp(BjDEVJck_Xe;@!Fa`Hc%UHrUUZnYgtSGXG$ld`F0n zri0{2h{qw*TRDquHA0n>;+9L<7U#b2>&Y%mw2taab_>x`iL3<=W!JCRYAEGQkjEfUVGhPOU)9l$KT z?R&(v^LAdf-%Ki;pXo#xoD`}j+E3c4IcVDWM-hvCVn)R1bxvy&NH&K?MU@cwGlCC| zB{k>wRt5yeg&PL-i|MCWXf9P;uJ1i@HYyO6(WsSiQMFuGU2A64`|$Bgb$N^Lio>d0 zO3)8R@HxC}vo>X|K{%m}ec4?Si#Zx`E8ZDFgO)|)!n24R1Ze%Oq$z_23c~f|NuThs z&#R9~M>9j_jw=m+tQ%Oi%$OBJ`DWASa&7PC!!S+kp;|B$HTXWD1p_jA}zNZwp)yKHJiVVjBF9yeXa z%i%@p{Hmla133$2Q=NsCx;tawk=yEU^hhq!cSz+`-YhUvz1nBN9oWEu;S>qVtV&`10A133fzz%>n zBvht#D&+EJ?f#(R;9JagBtN(+oP4Lw$r5i7*zHHHwNY_UCD`5x@ZSuV9;8IvLHOSYv{aevb>hc%T?9r+4kwTF*hO*&xZC7 zEgHu@0Lu8}bP0HKTXreq*g+{ZeH+4>k+Erp8Q-WBE)7a?geTdS@!WPvQMy?&aP{@w z_I?5Ve99vQsEI*vv}SYN)zPpIniJ>iExN+W;$-xz=Ud@jhptx~q<00dh2hreS7%HZ zd(#eigW3oa-=hjB2gPfLdh#!-M)nq&G6&505H5(!xvW=@9!tmq&-SnRwV&%OSl7$1 zdaw3O%o~44X6+lj5K71p%8otc*+A_;YB?JF9V89TiC5-wy>@4aG9(3w6dyrik@rYa zpwd#)>!v?L&I~6F`%PpJ9UUn%8xdve1232A%NBwpuTF$P1C)~tqQg>aECSA0PlY8H z69~5Wo}3q7_Ph6L6-e`jA1c@LKxlW{hN$VOVgaDa>%L|6l+&v5x_^W5&8PW}lg!m_ z`BSNXu2_jYpPu{BUi1*lTQ>9Et)@d@sJ(oG0SaSM8F7aHQ25 z#gQo~bc97_N>i7NWS;32hszeh7Uemwy}lw}s#N4D7<&`dI$Yd@2DRG{I2PWoo}Fnr z<22_BC8Q}bYXYo~aKGp)6I!?2LT9}G`VG3kh3N6DstX{Nmw=p~(&f0u^{;BA# zh)W@-iOMN9RXX2~YfTTUpEjv3bo5%Ss@j;Dk&bR%Dwl1Z=zTsXzxIcdC6x(4QpQR1 zwTnHDtGuNhMYTmaY_tLyxLt~okyNiW_84NjRF%t`PUOGPDLLG?bnf3=xqv}0MDIh; zw_&5@@rk>`G4i*0Pxvmpu{cIeb2BrCYBt!*$>oGd9>RC!a4^%KH{kJl9cqXCJMlCX zvy9LoWnATa&!NT(9XCI%h~`DF@rl(%_NeZ5cXeIAVZ|4HeUKX`^apV(anjuC_{m25 z&2M?57fz_CH{&(SDHJ?T(4{xqOk|gSQb-eM{h}J+$q)8sjm1A1x37^p!kg*fx$z=m z&PrA1k~re1q+-~d>Qo*U&Nme0JafRv`(~o2e_*h{Sk5at71V2EY!MULy=j29rCvPg zvh8T|JVIHZJ6vugfFh?wrUw7ZR7$cxNjp!T=yAu3yAd98!S3k#5IrS!krHvDsN%7D zo8yM~%VPPMklYaod-ddj+6G(BM5otvV45gmOd}}8)e`&TDMhG@R0M)V8XH7s?GHEI zJ7U}>99>;_s#~oh-@8ZV)}H}GQFW@mN5FIKa>bKpA0_Y6yQX*L!ShT>wpfNE#Q;&J z55yZCyK;cqMK*vpQRCt5!t~+?$qZxib6Pb$?S#AIyE%pZT5m?38;AF6hQ4lD4qY(D z@2~alchu58^735O`x{evGlL^5>Dhwfqb7i#1E?@a|0|G!I#7qlt7RXwgyG6Fv0Da>2T~F(ngCdrC94pz!z`1W}Pm z#rsBU*H1ILNUR*7gYkf!?q#2YC8JKs(3{?jVj4;9%JQlv+`vXz?+U+dnNmklf z702n-*UpE%m;a7l6>cE&=SD0%g!04@U90H#WSv^1_!b0gtRF&u-<;^0-wcM<{(5kivu+&Qdnk3!`GjSBrFgSrBo#AG7x|# zHeFZ5YTef>hk^EX1P$&azxYTiONM^4h*wbN*e!kcU|#{>@)Azf=eUc@3j#d#6SwzY zwKNg29hNI!E95RrJ8n1EZ55E(e9eOMTXLb^MCI`e@{0zK%Jlg6N7Z06rP;wzocq6wKCrN)Z2d?D>ve#Svjpy03x?_rdtAk~dB$$EGY^bw(~jDK9)$SvdylOZI0 z5x_B8Hh+NPiiAoRg&*l((MygcAW9zvM zK8z}D)*iTlN0#O5=~o|5xx>k$=&8({G7l=-nF48<{Sp$s^7*`l<+CA0I!hjk zmX-%qHF9iF7rpz^wI+{jb9sZQG`t9&V_NA!YpC^ba=Dze4+2_>#M9+Wl@9#T!iJ6PW9C0qHbK)Tm zn9=>K7cMDk`B*DfRo*z#ZG7W?sPOAEg_izwLEK6TgmZ$sZcPPv(=gdFrtfuTCAlZ| zqHfl*ded-8ql5+p00Yw)*c2}t;mQz#899A}rRI?t0b^}J078bGVqm()_!Y^YUP_SM;A6ZZLr$Tza*+G@;(^)_78aU8tsr(;R#U%V8OKS- zT4Ps==d)t~52#qKMK|CJ+tW5Of z)oqc~4SKswcP_ypBeTX?$@B`tXd`|)DE*5|$g|r`EBTu3&eTdHp~;ZY$;bU4AJ2bZ z(l6rOe=+K_zo%ofe;yxdJ76I-SYSvu@Hl1qmU{DJB}TpNV1ILWPP?vcjT&fw9uPemr z+@+eqkFD8GHPq5vR4n-Eil7G`-<9UJ)b*WO?LMGbO^`6NXb%@8_Sp7KI7Jj_5 zoTZBhVZ^sz-tDBoa26&N9wcUHgi}Z7_x55sUVIO6SMpXrEm*vIT4K>Fdef;RE zDEW;{$K9?&YF&K&i3BPI5Qu#jb-#N!`g;(ssv<6t&S%hd^7vczkt;xTSr>q zVDYrf)fh~4Km1XrbctQlXXzGe19Norfh2+YVNhM29kc)Bjqt+uz%chN zIvaH5K*A-FRBYyBjXx*fGgx&`-!(-x?d|H5G0GFb*5&dX;Z%{|4_=bKljruSz*N_Q zR5|fd&$WHeq0O&HUYhK-5C%~1cI!|8fIgL**+FnSqx$7-^!3r9p#1e?Di74&hV@OD zMoGz>O$bhJD6gR3?w52kBe}wek0hmAU9KNGsghc=XxI8)i}$6t4r7Ur*>E$>L-dm( zxQPM)*@|(gY3O8Yvx-eX(bJ;*`Dd{Z0Q9IU$Ja~$dF^9qt}Q)#KxRTG+p?HiPpmQ3 zd?@c-LXKWYHFoz2pS%qo#;R+23o<7NiFsF6iabpV_H(3lhzRs%J_E zTv@c1i<>gzYyoCjaPcIz{4vCnaNh4Fw zxKR1_vTj}ny=diSUW)&D?fuN=WuC#H=;YET>5S%6t-W<*r;x_6?e4AQTjUPmtL%S@_-SV1ClGYC&(+x6dSpjB<_D zoK>lE{Ai;Y`jrXk}m6R)&iP2WDC!Tj>)(Bb2UMxA^?mq;lW;0H0p>>}%W zW>;QHV8bmw-&PsQJLE$ZOY{(GR}(FX(kSg&74t&eoXW}+#>pz5`wP(3>B)DANQ9(Y zQ$g$6FTW;%f1hmowEA-K!|7(HzScdV>B$DO9EO4ziC9K>N<8&j{&({rIicOv{+QeZ zJE)+7`W)u;kdnSR;ko4*(UY>}f=-S4?mc@hh<|B*(0zVS-lJ`uBLz|KKC`@;kQ`4Y zXuVE;1i*X|r`1|k-}}F)7~TD3IW^%<3qs_vmY-Nzh*;s+qUED3ztl@78np;Alw@o( zFgLt6I;vHtRmb01UqyV!3+wL|!+bQ}>u7z6iMj8P=S&`_at&OQQ$5TU1ruutlY|VZ z8wYy6^M|><;B{5DUDCHB8b3|Srb+|^#)k^uaXM&UW1DPx6PGn$K7C2@-PWHPPd@v_ zoP8SVj0VVj;J}Fy;?Up<>CE!YgH=o{PP+{!Zz!GK<$Gha5Hoz3J$cPM12ZIcG2bOR z{$sst@l1c#_9GbtWQbe)a{p0gh#%_I513zGOYkdJ>(S=}b+z4(k=4U^mF?FBvo4nA z@Qs*3Ef^YkrJ)U5*PPpM7aaoJOa}9yLNYIWf>Lc;qKe8%>gCU~XEe+#bVHY7PR*a+ zZ>78WHS+vTuoHN?%sPN)xC9CSBM-%rW%iR+Qc^BoxVZeqyZUh0{B);Q)aetMhNd^J zCs;JjdZRXsW2&{@)ht}8PJWHMq#pk5KCvD%IFiLm%l7=cPj{|jFV5>;xl(^)Vda_c zbJHq5vSC$%%oNf;Cl{;lHtw0aG_Wd!##2*yTbqTuVYR+Cd*j0rA2dn}yBMnoo;e=8 ze@S!l3T%08>tn@3_PGww(Sni0L~(Wui+x1U2oK4QR=b~85t{$uh}rw4_22Zu{W|)U z2dqNW4BDTl={?Z2e}AN(3=i}#JCa+!U&n1crvu>(j>s=^iQbntwJfe1Q}zDpaOTW{ zd~Tx*BWT2JfWcsdun}5UjxROY=JVyrOxl<49iiNW7Rl5aA_ENUv3W3P^DzM>%@_GP ze*x{+2EOYBX)o>=UT7>-ABplegPXYxy0>3^yt{6p&>lbdmC-m@L`qp1&+mJBzGj*&@>7?|&)rA&&!dm^39uC^Ox0}! zc&x_nzsv@TLT+R}i?gQ(I>uI`Bt`iR1P!VTmS76PqC;U0deS30*G3mB82>?5k_W?3 zlQYg6M#CSq*4dwtQQ2s$I>fT!kICO?Q_~VIZEuV2P6i%p?yu;HI{it7`k%632y)|P z-uU!ay|%eaHL}_L!Aq{_0LV=lp~7jIoGMMtsz%p$*Gje~)qKY&@JyIg5k;iZ;xb=X zlRlQ~{XQ^7+)8BP9Dl`O@<&i$`d{MT<6hBp+A&I2Bh&CWb9Zshca6Kbo0oobP!C=a zXc>oQ-(Tleqz*g?`#QDb9`aul=s8dy{AN3^UbbE8@$;=!t+DyFH%bYF8xtmK_yHSp z&8rUX-yd%L1t@7&eKdxCv?iqEj(obz?dEK&e8a_k?$MP0DT=6H z8g2UgeRoOUM$?hm=CJ_TJg9bRr0`hUjmVF3Mm51_IwI^5NmnP)o$lB1zeR6HpT2OiWbEs`Jl++CbDqdec$XM9ztMKK(ix3@ zwtatf`?oyr8BRMxk)(|11^f|39#j`2nRZd0(DD7Ac5@QmS5`>>A4~vHt$an zDvemuwS4npNM(9buRpM4LciR%q4DnPg^bZopF!sTR%P#F%hjRx@BjSw-TTLabMiM5 zrgF+x^LrF{L~k_qRa(T_URd2eUYI_wj7#sL1sGz9W27oJ%s>WGbyPLfevNyD_65*?pwI}-N(g<|6K?SyQ(d_ z|LgdfrS~nVU*u0Mq-ZiCZ}_th+eiDfp*zO zpA|4Zl+UA+SkiwdY|Q4rKv4_|7)$fKSy5^C+kV3oczL8p(4LT$VgHSF@yn6B3Io%V zK5xFJ{a2Blpo+{r{>Lw$e2ttr>DD?B`9>vc$blwvYsJOjNSvQT3`RtbL>dC!0E5B6t4=5zhb`JhL*IRYbCf|?G^^UTLds(ts z^Z}EYzQx!Q^_4!F7?}4;}nbn4A}=Y;KNPKThBIGHi!Jwl@B_ zpfUFN*x>uRHuA!_yxA885x220kLq0bI8Em6>Za9k7={q!(Z&m*jC3H%@fcA4j`z#z zwCh*6mhq*~&X@TE2ppi?6Q`rMo@WWCYfwBzNwyHpcd}}EuTBQsss$-P~7 za{qZN+57u#CL+Ey{;Fc0;OL&(JuY1JpmIx+aBOY?{ZH=T>F39@$oXNH3TFNsIoqmB zoGr9bawkS=O;3+GuY8Ewy8Wz<`lnD-8Dy z)Z|>1w)(AVsr(k(Pc0Q>N8h-hd;W64W+J@_l|*kAwmrhO=j8EBQtD-{FT|AO>#JkM zY79m7)l!(qoLG92pW0$!&6P)2Cl8CoQlNtLEgi1*N`(BtX~aDczB@Yd6n z6F0`T&D2Ln3>TV6tLicjhWU~L^2$c@E-3^LS+;xP{8c%hE@qs>h|{%`;r6Gh|E4%kt*oI7Eh2izTq~j^Ub?2@M`*W!7^BShujGd zEA?`!x6@rqS8usr3yfaKZB33E+ddNY((R>&!zl6D{A7}V{dl>6u}G2Lxm9 zHQe3hm3O+oEPtdpq7HoAm z=zsx1vg=fn7UY)19`zo+mb+PNhWoqbh@j-r7klc3@1>$-3K3KtC4FvdQm6RE8I-@(F=1W%6}z^&3#V2q3f6Af@^rUs%dfAL zewk{|#e}#_tdVEMB%FfSNlErxB|potdQqLT@9t}?>fB@kz*Nt-OMIIq$8I%b+XO2K z5-2Pg;xW9?MWGsz<^6j~^cr<82S|^~nB5x8h0|mo^_YBsQq~0 z@YTc9r+x`Q{8udW8s;~-E4ADyi-Q3x+z5x^jqy8!VXM6#wqe-=wH7LFmM8Q00{A8* z4ul+8d98K)@y4gc@UBeuH z@&|>(vCBg#i}&*1oscPL-o z9pCIZu{gW>x;00U4z%7M-S=KcENObQncEnYMkWxrJ=8SNnNdFa@#BA2cae~_am8kE za%*)Ws@XiEvT%(XxQaXGZFg%}_VVm}plZRKbwGV#@vS#*Z!`zH??)(?f|gSeDOAA5ZI^;69yx7S8~DIq~}_g5cz zc(vzQ4QRN_I$udyd0|&_^*7fgJC{;Nz$fs1-uZn3v2GKXiv>0*+U()ATTjO$!_&&$ z6QfU!t~{u_P~aXCJAfX~kv8sH*u#~GG}c{GvPnpJ{@p4&`rHZX9qBv159|n}%rqjE znZ(-b+f(Ki{F}x%1wqxOHR?(L(Ji;wJQZ)K-Xx;tkmn_p%QN6mF4od{CkYjt&$n>N zwN~Qu*h@X{T0j5TNzE^!N{7;B=zpv{dG~hv(OAl|bpJv?SFK$}>epu7`1Yiic^U%H zyT;#jD$G9Q>+Ui27I9FdkpH8*An)7;7mhH~~)|eAnCT&e8 zoXdV{k2S0F4vd6)Unum*>$6rovyPz|O0=-mh|L0$AV9pUHPqK}*Zz0)NQPZ0j@nry zMU0a&21;njkt9mft(qsyto2YbDym3(upy+hm?pBanqi{4nl@W<3{IT2U1O!beJ@TL zs&kRoS<^Mw9HdtjSJBTdnrqPYyl~)Zyf>!mI%eSXEa%@jZnA2Y7S0uJ9_H@nZek

&r7HogB|A4A7aHH^O3bxTQ!Gm$q*Iqf(I}CzLTV{{lYvPBCaYS>%mv*r zOq&$ML6sEJs49CADruJ%42EQDG1-fAsom7nYAQ>Owx*vuzCKgx<*n(K8Cg9Wds&RB zQ+cqyT=p%h=@V)+JDkNS&88g|uG-tPJXq43N}0=7TYBY;%#8i0nY)_`U`}fxC2J{( zTgWShwvto0?o-tArk>w-5W$fxVc3^422Dm8qnpDwVqJG6wfMz1Ea?q@R=z8s>6@l= z6PKq}%vE#S(>)m|&TY9pcjrH2bSH6gvUPl|-OEnSrq&|DMRJybk_5$QtcD`m_60_5 z5Gv(Xb*Phbl7=#QC8s-TCvxQU5S@Ed$gwJwsivWAR##JlIj7jsb&Ymx6+N3JwAi@8 zDC^H#t$j`XB81{nx}B#^6|!A3RnD}{s;2wgo#)mk6!Z5=+0pFZ5jwL~D;UL&eJ!?a z<;^wLg*>U7+Ir0Au*=f%u87?;l`!XMHq`8lh{+k7IHwX}D=&8#%+%9tW<{EESDH+V zSyoQEvYJ+B&Ssf-z%wb)erxsef?>1-tlP=i$)$i;HBJ|nme%B#)LNOB7H&<-SZW3| z#X{*CX;eY6D}*%#$54~pksZ~_vN}smgpk_FZXyX&)~%Q>oq;(UN>^%R!OAt2)m1SR z)u`OnbIf(%u58-WMrv+#_J=**^ydz|v<*nwS2^6@vqfSnD{gHun;~vmohMw_O2vFES}{X>Lu$j&^LCY?|9`L>S06 zAVo_t5zP}Fuo^T~L?t<@?o}y3+cJe4B+L^Kt&3YmGQl$$HjIN{nDplgna47b+I7ko z3$F<3&b+PZ1#+&Mx!7*YR8(1UU1SP(CSN&4X}LUOHyFDjS#g#*4G5z)^yS@8Hs;rP zOfgDzaSd2hOr*vxEHVfevkb+o+J0a50xg-6WZ0@ztR)poXd56rMaau)d$7V3joG@S zz?!ThIVM=!TRNKyvu#dI?TM9hw8&(MCiP1?$XUwN&h|yDLjo8kl2rsnQLSr;=2~JV zp*0Dh%N!D->ML6>&;2COwD#?z`eM}BQ^!bA)eG$&2g6A+w#A( zic<#4rsYYNO2$buRg`H7s3M6GR3=?olcOOS6-#WyXOmP%G`j4Q39A_z$tf|GHq^?l zQ6n#!ns4h_1&p><%OiHm=47`^DnSF9REagEwkeYnBC*aj)ex15u_%g>7?||Om^r%b z2ROE&Pe`V%>t&-Gikm7ZraNnvJaw&3v5~$sPdK)U=cb;Rq^f96JW$eSfTS{ zjC*n8k7?j?dB!Uq2aHw+nEwF4MvtC8vHii~R1{T^eFxEwF<7j5 z5B&0|Q9GAin&r{UyE2<`G(9KJ1bo=%9?|_l;g190D5*}%xk>7oonZd}P=BJEjfV9R z#E)R(9?W?jG5z!C6^}e~kY0Ly=IhonuDS5DJ#X~mhB+P>^3RFq zHJ>r!J*7ceQnyN$LcyWy$IFmMIdHiD0PPna^rc^>^|Z^EzQEflA7(r;#&hb=BhaAZ z(yo8>zw|5W1a(*X@#i7(q%Mc69wXRmV(ELhh3=(yq{zB;1HD4U>UHJWo{e=k zj+Ca6#y)*~PuS&LrQJG($vyJDo0!GoFIii7?XFieToR18ZcMHZ#w=eYMURQf= z^BUx-&)j6*?p;XyoW-Zln53mB2nZ=d3uvA?O@`|qemNWunMvwpxW6$_Z#JH_k9R|x zg;DS)$2n5_;z4`9sSCI{d2;ygQ9snuZ_2$cjnDa+-)6hj;3R%TDu3*tf;Nz$nFJgvfOfHo1}~K`j`Hh zT~O~-Na`0ZrgEO!ITe#x&U_+;d1ol1km3~0DX!keQEg3h3?MnriSo~<9OuCDcpoma z;>~Z^ms2T=#7?k<)q?#es3i3_{XAZzg?0Uln=0u#`6BSSUC!ZiZL%vBnjWS-0Ud^l z9bt!EQr4v(-yuf2IiI5*81l!4K1VC7V0;NuWvX9uWJ!y9YpOr!-n_0sCxOYViXhSB z9|$Rw+_>y6K$YG!>{qx-Y|%V%$??a*gW`O#@hE@vNS{W0MPN~+m3U!3r@X}kQxRQp zvXJCY%uuJ5RyfV49|`k5SoI%~Ro8L-82OC~BvPn~6gVf%H80Fok)cR!x6>g?OM-eQ zy-P#!rO@Abvi^*Ft{8IkG7zaA&R z@I5&A4LqK-f%c9^D)z%m{#lOa?0KX}ZKO(7#8RT_q^$IVfcmk zFCPJ2Ga?a4_UFv`pFDjS;YjOieFEFX!x>2aO8l5@=RKBpElM7|d7mTvjK-`cdR|Xj#quYXUjf+v0DNJ?Elgj-(>EA$vzpHb-bEi- ztRJ9wxm{@AuPsY*As=j^#kH5+_*-3y{T2QP(VlTw``sN{93IA=6!RZjD7iUNBi*0) z;L5XK5aLyw^N)UfjbQR?KU%A*;<%q^ElHCX>W5A)t@P`akBY@A1OEV_2>5a6$JdeM zYpIg|0KpPuxO9>8rF9L7vS}?VfSm$#BiR+(UBVdKBZ2Ur4Er(Vj{)uKmAUZ4mo6Gq zQ}d*EXj0s*Yi+joS|>rev{OU-hPthX6Y#^CHWO-fA2LpIC?<-&AbNg8HH8IyxbVmD zXT<7@KgAAghETPm<M@(|jVkC`EFe95k! zb(ckKpQ9ekd{{J1&PD!D&7Ye;MTJn7*8xMvJZIE-Kf`qOEcch_$M<1Kw9aZmTL5}7 z{Gs8JXFJsw59;ILYOM=`dxM-&_T$lyVE718y-T^f{{V*-W`5srLz^bE<|{rY(0IiU ztkTta7gYRN{sLHXKgSVvhnS=R_MS2GnsDEqp6~NggIH}HfS4}0)5-Xo79_F4Pp=-c z&VI6~O6n<2E6YE{j>D+6*~1x$FYze_*@*a&RwPAGPJRK#KZa`RyW8IeKCl^PRa<(B z@pT|PnJy`co_-`M%OVr$0T}dPdW|2uI~6S6ow+&jWqe-M<}SVl9{wey8xHBV&*Sux-R6U z{Lsago1inD>lA(rayZYhdksi8+LV44T}zW=E5g{r0br})&)F1M*kzF3pm}4!{{SB) zPpzBn^CmlbTKwqP>UNVnURmr_sjVpWn$P6Yv9VmE7@#rdkK`UTc-_%*N6Z#n{*}G!Otxtw)sIFv!5$g<4LMgR_n0UD z02OaVp)Gn3z<%O&D4IHfYySYnS>fAaw?O#kjAPZ05n1{$LWJ~Q+F1VB2}Kj={OLA! z;k25^z$o*Maq*8_v|r)LNA!}=Wli9U2}=Qul;@BEt-nc18MCGxB>NA%Rz9q}tIJbu z{{ZHHoETs8P}pH_m4G8AI4gX+U$8*2o2{xE4BOf9D77BZFBj1Crll<=bl-pq{ zn7Jf|(-ZvBX#W5c{7>=?u-pFtC*~}6%6Wh+>Sl#w!1^)j%^#l>JV}*T=(1Yz0R4FO zW0r#yi;w*X>Vws3>L)L%zYd}o&-TCE7twnE07yu}qACJyw)ikuZ8+B&;}|21W5+an zO=H|X5{CueJ>8EXML$3WkB&X!kUM&*K_#&E`8=W2N{cGiV+7WA&U0C!c+VK)6n%L5 ziBY&UeuzhsX-FvJ9G`$u2f$JEgrd>@F|`|Uh53;fJh_T^IA|X3I|Oltgj%*LI)^#* zpEKc)EPSJkQKFvP>|L#wIDTPCb+qVX2m;&wXZgS9{y`ALTxFxum3MZm`dMLYf{T+E zxT|v9>O07JVR02728{~W2zXF~{&(SR=rZ9+ZNPaPXWn?nCyafH6Jy@sI*&BcoS?1y zhma8o*q=ZxzKQO{QfL^rs28=sf2JJi=<$WI`$@LDXI-UmKPzy}p{sLiefbT?k!-ld zl-q#kKEd#hlO7l}>vwqfCQ0NaFqY8=fRsmK%+E@H%V@5mlhjLJ&4M|PAxU~VL4^uD zQy%EbQ)_b0t7`4eTMfVbm#wOZ+%?CJNK=7U&YH0mit68RVAjPey_M5^c@LY&R=) z#C9T>EOy?E<8MDch~@;_boL}9=RT})k26Q$9$53u8Z_j4lv|{)^~Lx8kNy7u_EmWO zYLS}#0rqLAQY}ku4MXW?-;qDwnhNo4aSQOvEx8=MYO`BdfgSXy#YzHoO$QXiuvXH= z%B9Qw3-C&l#UsB)KcSF;6{vyX{|yUa8YMm5wLYmOJ?ku2R+4jGUc9RSCU0z;2vk*J(%#q z#l{`R+Wa2NjwK~3ezb!Dn>22oX3q}U+POa`rDu>Fg;)SITRw*4n|k4P6fh_$#?U0j zvo2k}*==IW5xrK@KuAJDT)}NhaZbAA`7>8^b&0k$AQgC8Ux4FuJ(%|6cf=<<^$BH=SJ3y~G8k8(w+NTF6| zA*l)n;yyV35vM8EpN#BzO~;JPJAJLRm8HD!5NXDLF}D8zi*~Tivntg#*KM}DXkx&N zD>laM>V({Muo?~MmV+U(%2`Wc3kyvU-6;u5Xi-KhQWo0dC{1Sb9H1o+w=r$F%xj+V zEoC-`E#(v_5NkZ=jAF6iYd^(2D899+bc<^+qQFwp6GZTo(E%kotO$~zF3UF29?Yw1 zA&AM3*$pKoQA@+^kX=;v%(vDylumwG!WM zQV8T80Q8^aXN46iORh*}Y&MdukdEg9k_`&QV9^@rS~1qgVJ!xOS`_xcC<9cAP}^mz zRE4D>15gEE0l`iUC@oGVW3!e^exs@ggI}!KykWF4l%}kct6K9X;m(y zFqOxc#mS|2g#rKtR0RP>fUGQNP*bf6N^~hoZ~z#klS!jk2}%M|6rDw4hZrG6*Huf0 zDKpHu3|$(NGSo#OZM>kiQ&w3~WTfODkojYbeI|`4ITqnJR!O+EdWSW)Qd3G^TN_ZU z&^ZMaj434r03;ebXMMAhMJBWf2uLZ^)-Wp=91y1aeYYxF=NpR~Hzp<4WOo~&8d)l8 z0k=5C3Ju_UkBI&mtyCqOg5pHFUQ(tXgDyOV4{;RITv|#=D*lj#jxreOPM2_d}HOunV^L% ziB3sk?R-P8NrvT^TiK)}Akapb)S)OTDbP2rn(K^Ug;G$a!(p!8iA^Y_I`e}-V-=1C z8gWiO>XgKo_o!>|i#;+V#x<)hFuQw^=^!LfBzO;qcn_o@O2f*NSDTxzXEDW~L@gx( zv91y^t~A$NV;bwOn&?~9rx>gyAQBRI)D1usd`VlvLekp3 zJsRU486z5ml!{V&K;>0{opr?n;&|>nsfJVY;C=TL z!J|f&r;Wu^#j+*JUl!JHvs$LA-qol!>lE4&kU7V!@DrL9lBAJXJ^FCeIFp*G~ zY^DPxBr9;N=Q+=(0*bLmj0B1_s>nE?4QDw#V5L-2s&U7hnJ#){txkGvj@z9`ZF%QD zjB}dLfc1|I@&c8}p-MDKrI~KsA7K|K=_!qBc^kbUD1_y@Q&OY6l>#dugU)lGEE+Tp zNJ?uMUl`O@XpvbpobXgs^r?4cU#=H<6Hg%}9!$Atl^N8fG(B14HIF>_=h6)dD&%pR zG@_+ExwNl+qUV~yP0{m+d?0=N`$6eZN#du2N}rZcxNQhNEl6IaA{OH#yKOL z8YS1Ako3!(d3MJmiduO})V(yvHmNWkZD}C;an5T$An_C_ToR(o?4sZqqVuy&}nlzLU6Ifj(7^1BBV9_dDsx+n@M4@#NgY=h` zK?;mp&0}ow0-!CI8&*e-dC#jpoac zd=*|l=^$NVOhS^OS&xQjVlJWj%YI=!~ghr%2`cIOx18w>yDDk9?JD-_&#)i9xiI~w(FmlZoEf%DhC;&q|iGG3Kf6?HLX&L%9KoN?E#4_sMGYHZOln3nGw7pOR)w%c(LR_7ThtfcuK4}kL6C@d&1 zZGyJnJ8ibvD&K9k3JOVD_9`j_(&}YQT%+KlT87ZxrDj7;I@fthk5+dhI?L!)U;qFE zz#Q?M@7&c~xBvpSDpK2C`#yrJoQe0xrz(O{ke}F0sNPitA?slg52{t@hh} z!nV%a?iaXT={xPV!CP#V6$NKIDQ>$mOqU%#4y$2Z<0EZ?yRD^cAhl6s!I=@nzJ(-$ z3QpUD##2P)G~$s#IX(&DMO3O+xoatshb^}l55=Uof|8of zz@=e9djd%(gjP_ct13`C8Wd=8EytejrE{6N#&{k@2D>Q^uaZ3t)u=ELNh5nP*&(uiwoOrl&4oU<*t@I7IU8iaAz2iW!c7V)K?_l!O*p3b92a;Z`rQjuS&Z_rjr;8MInBgj>;*os9Cb6NFf zhn8zO2aNEuoaTjOsj}+A_Rh;&?@V_fx$q_Ot~-$`!x@=LoYa)Km87PVLX<**E*0*D zEo*fS(#l9VRcxg?<=*D?N`SQ*TJxF;*sPI9-33q{ZNR!5XF1Mx$UA4tO);jr>#YjM z2(0muLb7SPbHPe=$K8EYl(;+-?n=bRoN4nyR24L&s4snjw%cvC+ic`3InHz2(@iwcBV9DtU3Jr4 zbqLgqHWmj2t!}PEi&Y?#;NPJrQ1ES!(A<@}!HmpSV#H>feWO`Y-gZp1OQ(7w&3Wv)bcJ(x*I2WCQvK5@|kgc`~3fpY$+tW=udItM_ zy*qjY6lhVVfguGNAuCR$CY>*-_c+_d1o;Nm=Yv7T(ooD$!X=KOjeCnsC6ZQMl__&1 z-GA3z&P=G6X%`D+A;@&vln~;S2_(u>jNR$UB|IXJ$_=tZE&`Lj+ikvg-*BwwV!gND zAtf4i`+8~H?e_HT_Vn%c^eu+;(?qtUcGQ;xiIY#CLMdJ-3RjXFO3c+yG7FT-?UzW( zX~ix1U!v`K{Z6|Da^yt{g&o++j`C6#z7j|XkimBD?3Cx1erRt)kd^EX!CP&<+ikwv z>=n3H+v%pgy)@HJbnS!`cKdz4-kNAprn>5|w7ey$-$AOm?Y7!> z`(?c}?djXoO*HN4rk%Ys(@jfiLeSzJZfh?4iT449U9jH}?{VtBAc{e8%8L!z&b@7F z-ApZNP)Xl)D7i6G?lL4SpQ<{Tbqfng3fM1w!uQw^puP6nZMDX_>!C)vY1`9HG}B!* z(_K4yIEAH6yql7oKX5T+TV^(=jmep@xCALuQjlOZZ)!7u;WSdJQr}&|r?vJZ#c{O- zg>AO`@4ov5Z@6CD6$7ri>#n-%uDa`{nro)IXc4BR3Tw2qN~@S(&PS%xHYC+li1$d` zgBiCK0z6ub5F1W_DGDlFmE7dZ`=cq9Az7evoPtypw)<`uzWY`&jAIzay5kz_uDI7- zb=0JV)1qZu-#@_y&2nYg4$r9w<||34EU=bPgd%}8mrI81WjNyg)@h1J9AbrMJ~^y| zSn|h?D;UNxj9`M5B0{bX&!hY(>bJ>Ud$V&mO(iafF)fWHxXMFl1cj)n*-5!MIe&60 zH6+mS9Or{u8r##3G2@PL!i%ersb+uh!Ld&-UKZ)3E;>TeZS5kVr72ZzRPkGqW!!F3 zN8Fl<5(0J8Tx+Jj1Rh5tjCwKUj8UbRDnh22s{R}^0aMX6o*p2~R7If0QeINsSLp7@ zcH-=bzj|sJNB|?ZrkZF`u9zt(DA!GWc;_BQjV(_ZCTiv%;iYgX^<5ZHpyW20FlVyl z8GXdQTzx`J>C>lw0W|=$5(0E6(_M7!>8Ec(jY@lUk8tuORJ6XCbvF!9xTEnTLb5{W-}v#ae5 zlxe59d74!^xerc$Ys)_iX@b{J*%@WZN|D3jQ;_AfsvwLS*+D{ey7AM|QKi8=LR?yg zh{m0(qpz#MDQUQNh}|`A>GmOnU@DCvB8_8GnKT)0+bY?3w#j47BGpmQnn2eYYl5A1 z*Fv3i*HWKWI38K06{+=0a%!b3-V>@55*>=k7Ck#awsN|j%LWsm@@YgDD>EV7?CMnJ zxI&WTT4`@mrrzCq#sq6cjvcAE>2F$j=9R)c4JlGwh`|n<(k^d#$E$lRve-&>3Dk{i z8taTV(^bZfP- zbn*oe96&h_-6T07N#O|%^wp}{ZcAVRPbp!9{=#WO;a zK|-_S1!KTJ-R}1{+d1|qth~8S&2~)|)II2{Yc@!w(&}p}EG;U@5}QRZ?)zky=>_u2 zlTHcIZV@G-l!(;8Q;sg?>Kt{>Afg4j(*d+&g%#Gh1vRl&{nfnV(Z=gr&OX)Z&ifuB zt*u0ifR!axjAImd9AbzSiqja#Sa-YM{Q^LLz8&uEw#8c&D7fS5mboTP5J$8mqO4VI zB}ge!oLh}J+lgMz2h!BENK1ibPf;sUX|*bxMdBQ`R2o}C8r*JFsWQAGxzo)=Mkt+> zqP>CGD`MiFc2m=#1gTCq>XlA0e6>2)f@;#tbZC;5dXEN&AkYT2(@xiKx2Cm_zVCa# z-|m+b9AVfJEYEcM`h4{JmP2b?BFE-ZIL9eWc#p?{Z?f5gCC$UDamU+`%!Ile-cXYC zYlAY-?{RB!TLRMZYGN;}It3!3I)`pC*9fPU$4kX%WRj&gUR$NP^$0WNlOz7*1 z=W%YS!r)q0bz)ReX?D`<7-6^}m&Am+g^vuA&U4}`ZTo@V?{qpG*d7XW(6!s`cFHxu zPMwm+X7t?rLip%+ITrB z`R_L-9l?o+eM?fd*|(DJ?kfJnoHbCEwZmy}t~S-P#gZkxOv*9~%X!%=l!p}RUM`{M z9+fTW{{W&h@trQI<;eX3#5pNRf|&2exI|lQw*d_SN>dJ@c^oa&JDsaElSRa-M^4vd zv)j{6cn5I4=X1H-3*UU2!A`xt-*30u(_J+v?3m^VfT$^mSX@-WW`nO%(o#gq3uaR@ zBFR*XgvoPLA&D_=EKU-YB)+G_w&nhpAG)pfU1fyDhGRxRr`VNmRh>4wTt?(KH5U;* z>w}V*NpZ;tl4OZeCCiw(KdKzIWG;D-3IURUv7Z)P${WI`b5o z-*=x>q|Gx-re7|HgT27Lxd|yP_KRJv*+#qrox=N}&hK-$9p8Pp#x>NWBemM?ly>#g zv{*4*x0_O}DYrJljP~7+r)>_gaAIPmrg!RkOB0be%z48U+mUQ(8Ew$&oZSg6Da5{+ z0nqlyKdEwZLY;C{i-WS1>q&_mzQr=r?xJF+q2}n&QBsiUX=$yCyQzCJp&`i`Vb#3k zl)hbcNv(B4l<$A^316s762zp)OWp4GbA9&DI%(VOcDr4@H6x6Lh3*{ghXbL`=X1DK zka)(rY1{4gl^Mtjw11EONBE-1n^CnJNwqG`{y+JG+`D>V2&JIQjg^T3^cKV6@ZB_? z;+#XPaZZQht=Be?mtngRi*s<4l~h`CQ>zIfg*N8E_Y~x(T2iD3ci9v`Sa2266sO5s zyXBV61d7hMz^qVLbUpe%NR#@6p(slILP(MN1c2~!xEu-xjdUpO_WNDF-)~Jw&U2l& z-+t$Jx!mrTdz%$*6cv!Z?)}ZOMxDOGnRS#$F&ww9+HK+sZ7sJUrU;IhijDb1M3F6_>&02Fp&u{jDOCUzm-uF z5Jc<-I|4e{$Cfcz#xcf0-?`or6C_IgB3J1WM1cPQf4|-C_czXX#=7a-?RL98uGed~ z+bwpxeWKrMv>WZ|rZJ3a1~HD%Z(TbjpU?S!FXa4xlk@&_88M3rWl{S9lAS;_2~r$d z#R9eN6bYlkh+a~l=D|yR$nW<=gCIJo0$F`B1HJC|c*^hh0@A$ajAH>ftX46|PM~6q zB;+f8>R+aiaM z3J5e@b@1|EZbGI0l}J>fArGoSnwfv4$I|Lnr+-piO5Ai5lU?xVaJUs%p+tpmxL*4O zg=ait6^u|A#whWORxz$9ageU(bHCpY{(&G#{Q^LcBzOD$((iCDZL^%#bH;ec@Xs0B zZMNSz$Wc5Ku~utc3w@r#qbe8T{A!8$KR4!FPs`bHzTOc;ftOCf*4@ZED5{d+RRN#> z!~jJQ009F60|f;H2L=QN0|5X40RRFK10fI+F$5qYK~WPhGC*MkLUDlZ-olhT=!!eVil3VVtIX0H-M&YQ7;`z|}%Zu>_7s!o zgIgt1*_#E|D`ui{_K3_OQNDb8@F`?)tP%#}Ag(1!i7IP$}m7Fur= z8@BFr{{XRXzY0oiHZ7lIZc_W5R~A|q3vAk*ne|FLt);ip&*3VOrqa&-+wq4j`zZ2y zcXPRKv*)?G0IGEJl2tHWPL0aic9Km;%=ZydpA;RkQX}rBjWHeY-nVlY+X41a?xVjQ z_*_Y>E+puv?9^)2bG-uEc9xoS&Q_F3lic>(RT^^{o)D)(n`c4YSYdABH%d5L{?!)Oe zMj39cBbo~MN7&HWKs8eW>XCFR6L&3|i%HL5qdRF_t*2~$YL7kKH`MO-zSh}Wl%76H zpllu#1|z$T{+->Bz<1-iELl<6oi~ND82ZsGW2irAb+c0rdule`Cas>GW}eVwD`Tlh zR25oSRR@z#v>jSgb6p6Kgn7Y$K?DIoO1c?Pl-5&{n@y#yRSK^9-X&Z=h048Y%>8?l zfohAD&#oD9cmDv`rIe6;6^3F;15WBUVGY>c81wVQizBkI_JYbYQ=3S~HgGD7?j8s>K=ApHhg8(SHB{Nn zQ=bx~)8YxawM`}q(;PKTk;Ir8s;5Tsg+@87DfJvrR9Dt1s_y1WaMJ#X`e;>1yjd{V zw64*)2gS0TKyfurH7omKmQ5N7a^V?NZ`;U@;?}?o`)@~kA#HRvSC+M|WL{CI^5fh> z+cqL$PMTE+^h2=}_Pag0Ic(=J&uv24$?>h8p^V9nZm1L#CZ^0Gs+>S6tmc@(XC}4Y zHI?Box5k-1G}zTW+7(&OoaI#_GZgcwMB5v#ozIA=CwwMpZ<;M1vQ04=ermA0Skv%N zsA2S;)G3(F2k=`XyjxEnM*jf1tikmeDtt~?EwE42Wj$LCMy#I8=aN4!?4ZVG{$uq} z+V#oQ#gJ&Xl#c2#y6L&kba@~}*K4!XXnw8fC{fz$(;n-{?`k(k6@XKxkE3hR#lQr4paX5{kAXG9ym* zD7g0p+A9A5bgJyN(_O8;Nr#9T2l-WPo5D!&=*jpD5V1SLq*y)D_kJLM6{ zIi49zJ|T6pzv~RGikOEqeivH_;mUveFJ&?ORE_@td-@gZw-5zvpBBQT&}vcIp#JM* zAmN#{#Yoks`e0t*(Wx-LhwS~Hmqs@L5b}}U#syE9VdSW>^eZujbSIaYI9q!7M&@M* z&vllAM)>BZOQ3v1i8=S|bXDl^vp7|rB|ni({?b8=~^b3}~5Y9i~hZ`B8YtHdya@oKLAE}wK5L~#R~_X|I| z+I68r;@30uTT5msvIn|>oXsQCJh$*$HDke%ht^>^hT(SJ)$I#>4L~XKgC2Xak2P)E zZbz18(XrNHWXnoBJ$jUgjIQ(6T{j6rK3kUVezmLXZPR)ageO%TRtfDH826wHbvda@wi!Q)M=Khc9eX1ZQk@0Don*w=Qgt_^^LO%DyTT*zQi`o*~U;FOyYc z;JoqivthT6bpKw(e%4`q%Hcxu7<~Rj>x- za5UZNaI(!xbwip@B;24>FK_P!TBjDzv@za|c2oEjwCwdiYS8Xr*#~Our||`BRS5d_ z1JHvXil*P$)S~0}NrV3YkXwB#eI36hgZe6=)AVeo;NYtJ%s({Wqp)a%TfdI_%GgE+ zbaL|`gv$E^s`Fwabh}PoTyss0Z-$t$3AcOWDoNfhFcWAp2Z<6>={i_bDqWlp`@ZXy zGI)V$>OZormd|B&bUOb4bl08+5!7ph2&mlcQD(b`p+NP*4oO@y-3{)2#BSeqJo~n- zlA}6={hMj4Nc*lp>YDu%f+qR_sZuhw&HFDV%J=UQU@pOubtt&W-Gp7^;{AUW({ky| z+A@N((rSUccRAx5r9wNsJDz)y+{Wa0vLSsJ+C8Xj2jE7FDdG~DTE@uxsm;`Vm6u>2 zE#SuIa_t{HyWY=hVN*%IN1ps)8~t}J=UKOVJ@7c%puy$1_NrAZ>mY8#=4rEH)FcDkiH@} zBg#hL+-BLby`)Nh#k4+?xpyvRij`|V0Z(s-i|iyBh)RQYZ~QxsY_it{eju+6>4)hy0t*T z%?*}-pv`&tDtjw3xz|FoBw^Fa$8*(22hZ@P)Mfj~E8VGa)ivWi6F!O!{P$z9(r4bp zQQ6(Jydzeloz(d!Q+ROXm|E5obasK5XrNrKiZG8XP{KDk<8A#suL>Dlq22508EI5@ z(f4X9lpPN9nd-H^t2Jh`lST(=uG)W!Z4k|xpS!P=`Ym?78trJ%pmi%Zheef6@WkRb zM|B@zS{8aPDhcn1G7~GevaUW3PN43s>*nF^cijlodz^XTHaZn6yTqMUtFHm0i&|5b`)rm`gf;*c#eK!D+mKz zJ8HMlw^`zod?WS1M4V+9luCsi=%rbtuG1qzmgXuJe}|Mf3?p=|N<4?BejBqrO-KBE zk79DZ^vVoxZASFZaW?~m!d3tnspvau;70cGpIp>wxN1Q@>xoQBTp_Vwt1|_66DsR ze3@yoe`wi2v#J3Tna--g9!=XZ%0_BuR;IdY(fyz3z0!*hnL3mO zhn71l&xIG#O84uaxZSf)FfhD_I0Pv4r=)DDrW< zF=)9>6w2)@AG4(ivLPCdfT~PH$3#j2{hRbC0J790$;;ZQWo*>>E)iuI4qd^*JHd&< z{%Q~i2HkdffGabJ-#=q^rg;UDjH>%^by479O>^opyCsy^d0JFHTV-2jFR9ssorRb6 z=9x=nY+c7x8c=;IZt9{P*U9k&<~5{+EfBh(H|@F0xr{k)$C__7mYbm$RWf{yyyTcc zv=|3O8?(CCX$5TbHbFt{$a;+m_HNbeN_6Q}Zgb)TSx~>_iw{`~HpJed%6%8r(g;Ii z$(A}oCnT!D0f4~w@zlhOm?Agr&Xlvyuyr3 zLd#79qHqmoq5Gy(%ilLbqQtb%UreB^fVbxTi{IvuXO1tT^K2qZZmGnKS>}$ir9T|p>O@F8< z`#Z0vBjk-Y2Q2iZtD@|y7Y_@!b3Xb6+HLJRBT?n&pOkA|mn5oC(1V4M$Cq|D?YVu+ zd4q@)+#yX<R+Gai(Yu#xUZdh9 zrd6j`@3cr%_N|fhoHXW$WOHeR+O#seqBP!Gd3hZ4np?>Oz*j|`rLNIbqHZmTIv{=s zAFF4Cc_%x<2}FL;?Pted$!x6mT~p)25YGhUZ${Z{qyiTWmR(L0_D`pD1{PGyT`9ez zviBpo29uHOo<~ke&DB+)?9|>`eHPzFg<3o=59W1Q%$-qTvU3aLn)rnqraRF0IDQX-o}6P{(pPnV`^H!|4T z*25D>uu*{Pfk&B8x?mOjfbRV~mkMtYg~n~aQ?)d{i=}PHvL3eVj}6g_VPi%0=Gf-f6uMZk_e}yD0K}x592!OCysr zyDyXaGojuBn^B;&%BJ(1Hdp$pl>ALket`zJJItPm^)7fqWiZ#&`88A8c8Ecma-E|Zig%ap8o)z;NH50ruqInBS^8DHdcS+-bXfM{#x23wg^R_PI5L zkgxv$Wd~Lgni$(FPCo=Yp}TBH*ab=nfr^+VaecoX+iN&XuF0Yba2{+Z^8;|F9-Zcc5W>CkXSI+YpHk zm6D`=ruQzXfj1W&0whePfhmm(rujAr!}g71e~RCd*qib9ny%6_mCds$~k@&AZ!fi1XYwRVoL<+D%y$%G*BTsyt6%{$;YX{bhf_Y{S8r z{C>@KLk&!%Gd!WALUHDtbX8BHYcA`pm7+las$;?>Jn3ap*|$mPo6f5T;#STzbI-s+ zq&zgg)MxuDu>sjf?(qJbwI1*@KurOSG0f2 z{MOz6TH8nXC2eE;7cHP`N&f(Xt;wpe)|NhHfgO9Q#+TisGc2=yZJ};Ud(TUVn34Eo2JH@?(C8COsF_m z!SP#Pxk8cn6}PlW+1RQ$@l$9{Cf%3KR{sDYhv4J|%@55`_o+E-FYyPDlJ;(wUdnyH zs`gpaD%l<_mOcw*Izpw%2DvaY&4mNY^}rp$ubl`&%-11Kqm1v!QTCN{;00}M{{S=d zM4m93?HwN#QJheIDdVB|-4D7xN{oBTk0R`9Q}DVIi+FYDk2|Kg1;b^}x(Ih%zQ&cA zh_&ht`wztfrI8q&#zmz00-QN+$8=qy+FsCjZnmziTS(}(o{MN6>aX_-aQ&qa=q!+X1nZg5t zbSrrfhUneqxuNF?z!t98GWt8rcLXMlP_NPlifp!FYJ5lUe`M2sB*X6%)9;kezEwVT zR?p72=(a|lD&Lr1&Hn)8{%hI1wxzQByFfvv&JOO2P6NDsZwjeT#MDNMY^ESoRdlNd zKSN_S_7qsYp%C=y(>U99xC>ZJ$8qBt; zyG@#$HD~0W?Hbj#17KRq6VCQ|WM;jUI}ISbK6$ zFr7K6@sC96PmK{UB}h|$2O_C3S~N{be#mPpouKXJ#48n z{7d>K0enleRi9?ER^3y>Ma6qYua6}^iCYfNCv5hM8}Nny010ebz4glWX3isG_G<^L zm$bHllsr=(xFJ5FmpGH=BXH8Ux~SI{DAUs6W-zvlxx;fe(FfIn;?lO=k+Vx^F8$Y{ z`&QY6^=jCwe(6-)IAO?pqbeX?=oOd3m~2{`t6h}(Evb{0!Nb@6l}7S-`Jp^nkHte} zl_SwqrBf|N{MA_d&FF|S*CX$7d{##e&C%#njf!)C^4(WW?tXkKZ(yOT;B!jb z$K3w_QmoGtTz`daAnwubDgCb00`?Bh=&!bB zJu`o0{{ReZmZeLyBh&k>nw_?7g`?uVsQXiE8T>6?*4hshN|);7{{VgRekgt$gsq{? z&6WqM%45ioCkRa=0!#%`myAT>cBf>f=&Aau)ShY8ZdaqIRp`_LCA}8Kwl$=*HQhoq z#J7+2Olh33R#f(A=v5nIbw&D!RG;A~?R3PcMW{zaO@a(r6+Nc>(P2_;i>bH-2p2)Y z4)!~Qd$#_(Bf)G9+Nm|Jsot3M^Qx9*?iTX4~={1>!crcd;*X^m>NzseW1o&Nw( z?~>ZzdfQD{>6uojU^t-B8k9xfV4gfSRk=A=s6#WyRBH`>}o1nsv%XcB_wts0*>}q(&R47#}eU;!U zyFF0$7;{#|{{RwfxhimNY#ObzWUrCz{>4*xmoTuE*ok5Os=Xa_RBP(kD7Nj~Eztww zR4QLWovSXg_=0aFG7^ZD+Wc2-Z+w1egNbR7p3(t!h&`=SyfBPyy$hx{#tt#P9qyg% zCsk=g$tcr&HtGKN55-b%?-f+GPYY8I2$R(pxj3Ay5>xYK8mNFS zqr_w2sg_x??^~+7bzJW`8P$6a{v4;1W@l?$f9|Vq_LI2Z4EuvmCCIC;NVMG!Xpe?3 zp;5IMV1+~4+aRe<)f@R0Qk6`V1QhZ>%XL-tTK2fHp>J3zjS>#+@RjS*_6 zQ{%f9QK3wD<4uXC>#d`+u#leDkmUx;pETO7k>VSUrtm`W$_@&A+;>CE2wkW~o@{{- z>)i?iF>EJ1qVoYVi+xkbfnn)`igj0dtc=RW-1AZ5vZY8_vQal%F3R2^B~{v6*|R_J zvcVoI`%A?tTKbhjokGo(kiqX1NwTRzkbQ0$(Y*1L;$c&yIE=fwd-*D$*eZ>D5Q|5u zGP_1Bj=BxEBwKz;T-5EFrdM;gRT;Eo9{TOY*%bwoYtn5h?BX60o3j~fekz-WLu!LU zvy6|`c5AAP3X2riC_rkuBHO1^yR=iqP3gdKw=(vBv>Olum0Bk?E+(SG2E{=_ZMl@S z0tb=gqXXPWf2J1i`K-bat0l-Za5LtzNjE9v_*E^RPZBRAxj364U>h%0st{_}Dl{9B zjrpJi2BPjtoiQ&`A+`uS&RJAw_**4?D#f{#YLz2GbYLH<_Fw!nL$%s|w`x8Xs@rvQ zR;S2xPOki+G#9r{_`E~IlOf(ew;BC{YdITDPyX>053`ONJx~aB-0D$n^uELw$@1AO=-CfnHx%^*=PNj3g z6!__o)9i@Boom|MY(61aZYtC>a+5|PjPIuHheZsXlaBR zG`bBCge#zVAbDL4a-lX%X%YsnX|p+wv^MrR#TJkSxkkTXKEn|f)1z1MQ7Sj<=|udgIo z0>%<9n95;+sg&5+YMbbUSxAn7MS?EXOFcrIAgIO=7YJ&jMV*t(DZ0vGa|$kl$EqU7 zdQdKzO<;$aOxhV{g|{%6%=UB|Dz5h-IM^{eXZ?}CGP`R(#Dl_pGi6?doy0#ivTftn z^Hmroox&|JY>2B0Sk*WV@^BlL-Hc=G5TIFRdSh6HXXbLzl-j9K;(rscE=;HKS(I*b zS$;SL)l;iew0mYWRO&dKyhq+t-&#W;1jlBPIfMmIW~A1J#pI!%tf43aIaX&~Xaa$C zmC%4c6f;Leb4WrID%v}Aga|l>pS}dDjbyVdZtrmXKJ(IIE@sQlw%vd?^Feb z0AZA2Y3^Z4%7zl8VFp#u8<3?FiR7xeQ+?hG%Be|_NMs(GuW3F*Ob(6!{;ItL^{r*T zSjU@O(=_n22o^jEX_dQxjW-GY#WmDP4XCLNOw!sYHq_%Hn0Zq54jaZj1(m0SdLk@}-R>@h+ z;Q@0yfo5@b{g*5RU;^lbVIf%;BhPXQIE~0siB9H

AvH|6=l12$Os-9I~@QBoe{ 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

Kxr868&o`81l=zn26`gBms zHMIQ3o{7o3?`JO6NG*oHd6R5oTYn`goju(~{C*FzU?;&N)5LsNx_eGO+FLPS$cV^p zsil<{sAO9|#&L&Iv5cIYc+Unk>dp7#P@7MdA_a$FBqi=fz8G8;KFxnbiQ=_q?G%~miA=lz^V5e3r)3!ZFVMUx6O=&;^hKR4 z1+{s1RM)$v!k}?@$2>6lG9w0Z9Uxf1t-h?Ji5}tw2E~`sc8Gi!^q{i0r5BIZz0I{2 z!Gv}7q4Z*OVR~=Gj%PlX#W&f{#nQO1+d!=S-{d({yP|LSN{K+hqh{PSLgC?C4+il8 zti&?peSiw#Uz9Cb5#0cPyGh;2mj$=LTNg_kZitkL)7_S35pd;>LcL)*Q2>~HrqV9m zTDk2MLsh)NGO}G0uCRYmP;1ZM)#D_aS|^jz-ai@#w%L~vE(d0kbHZ8?UpU~213Yx3 zdts21jEu%cK~3w1V|ZN@K<)*P7S-M6UwCaT__0G+h`U~(lD^h;2E2-}m}OHajw@_; zr}tYwj<~H)2bGRS*K2%C=PkUO*fJs$rlA#s2Nh17@)(VCQQ!{>JF{B<(ppY7(UiS4VW9btKqiMO=02=wa&%Vmk-wHWK2SN zVA)a*0>sk(H%dYRL&Ko2P-g14S+uT%`xNS^^Xv*OjyOgMP;j}tZ=5Pvig{mW?(E7i>jF&#g`lsuvhgBV%gLPghlHGf%$_Dmh}!{n^&tQv^?|; z`Gjp%-l_AC=qmHo2y5sv!hM4ON6-=9tcM0N2V;XQew2ae+mr;NQU!{c>U8#<>XFk~ zIoLxsr@PNSjf}2K%P7$B)bq5z+5B*ZAV+MHR@1fG2uQDjJl>;Yc{!fU$eNSye``v; zL62g{ThYEXQT6>ZjZ0ndq)>Ar2%*Ei>9Ddpz<2DkcxM{|Yz zO8EXFosiga<<$HaNzSw{#HX4%FTE$^n8?*|UtF!22d^4KU_=Vm`e%Q`V?E>AqNhD> zSJ2(iZ^KK|fM{s)mJS-EmER}Ot*?ajH$2gg zp8x)|*FJ49m@+(=KSrnnqUxc?>V%Ky(D{1#tXY`sh05z{;TpDTsVrf4Md3xF(#6

sdQ&^he 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

=d+7Df@_yToxl67}YqUKAtKoa| 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

=v51v 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[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

YBYaZ4g7MXaEbER| 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

-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 Date: Wed, 29 May 2024 14:32:22 +0300 Subject: [PATCH 104/140] Added title extra field to doc type attachments --- dff/messengers/vk.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index ce237a80b..e739a6468 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -22,13 +22,13 @@ logging.basicConfig(level=logging.INFO) -async def vk_api_call(method): +async def vk_api_call(method: str): async with aiohttp.ClientSession() as session: async with session.post(method) as response: return response.json() -def extract_vk_update(updates): +def extract_vk_update(updates: dict): upds = [] for update in updates["updates"]: text, id = update["object"]["message"]["text"], update["object"]["message"]["from_id"] @@ -54,7 +54,7 @@ def extract_vk_update(updates): class FilesOpener: - def __init__(self, paths, key_format="file{}"): + def __init__(self, paths: list, key_format="file{}") -> list[tuple[str, tuple[str, io.BytesIO]]]: if not isinstance(paths, list): paths = [paths] @@ -135,14 +135,14 @@ async def get_upload_server(self, data_type, peer_id): return upload_url["response"]["upload_url"] - async def save_attachment(self, uploaded_data, data_type): + async def save_attachment(self, uploaded_data, data_type, title: str=None): if data_type == "photos": saved_data = await vk_api_call( f"https://api.vk.com/method/{data_type}.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_data['photo']}&server={uploaded_data['server']}&hash={uploaded_data['hash']}" ) else: saved_data = await vk_api_call( - f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&group_id={self.group_id}&v=5.81&access_token={self.token}" + f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&title={title}&group_id={self.group_id}&v=5.81&access_token={self.token}" ) if "response" not in saved_data: @@ -177,7 +177,7 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = await vk_api_call(upload_url, files=files).json() - saved_doc_data = self.save_attachment(uploaded_photo_data, "docs") + saved_doc_data = self.save_attachment(uploaded_photo_data, "docs", title=attachment.title) return saved_doc_data["response"] From 0362fc8129501a5b23e25c17d0f302866746969f Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 3 Jun 2024 21:18:36 +0200 Subject: [PATCH 105/140] some review comments updated --- dff/messengers/common/interface.py | 2 +- dff/script/core/message.py | 11 ++++++----- dff/utils/pydantic/__init__.py | 10 +++++----- tests/messengers/telegram/test_tutorials.py | 1 + tests/script/core/test_message.py | 1 + 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/dff/messengers/common/interface.py b/dff/messengers/common/interface.py index 9615d1b8e..e1d10c2c0 100644 --- a/dff/messengers/common/interface.py +++ b/dff/messengers/common/interface.py @@ -39,7 +39,7 @@ def __init__(self, attachments_directory: Optional[Path] = None) -> None: warning_start = f"Attachments directory for {type(self).__name__} messenger interface" warning_end = "attachment data won't be cached locally!" if attachments_directory is None: - self.attachments_directory = Path(tempdir) + self.attachments_directory = Path(tempdir) / f"dff-cache-{type(self).__name__}" logger.warning(f"{warning_start} is None, so will be set to tempdir and {warning_end}") else: self.attachments_directory = attachments_directory diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 1abdd2964..691d5dd60 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -11,7 +11,7 @@ from urllib.request import urlopen from uuid import uuid4 -from pydantic import Field, field_validator, FilePath, HttpUrl, BaseModel, model_serializer, model_validator +from pydantic import Field, JsonValue, field_validator, FilePath, HttpUrl, BaseModel, model_serializer, model_validator from pydantic_core import Url from dff.messengers.common.interface import MessengerInterface @@ -23,11 +23,12 @@ class DataModel(BaseModel, extra="allow", arbitrary_types_allowed=True): This class is a Pydantic BaseModel that serves as a base class for all DFF models. """ - pass + def __init__(self, **kwargs): + super().__init__(**kwargs) # TODO: inline once annotated __pydantic_extra__ will be available in pydantic -def _json_extra_serializer(model: DataModel, original_serializer: Callable[[DataModel], Dict[str, Any]]) -> Dict[str, Any]: +def _json_extra_serializer(model: DataModel, original_serializer: Callable[[DataModel], JsonValue]) -> JsonValue: model_copy = model.model_copy(deep=True) for extra_name in model.model_extra.keys(): delattr(model_copy, extra_name) @@ -146,7 +147,7 @@ async def get_bytes(self, from_interface: MessengerInterface) -> Optional[bytes] if isinstance(self.source, Path): with open(self.source, "rb") as file: return file.read() - elif self.cached_filename is not None: + elif self.use_cache and self.cached_filename is not None: with open(self.cached_filename, "rb") as file: return file.read() elif isinstance(self.source, Url): @@ -243,7 +244,7 @@ def __init__( self, text: Optional[str] = None, commands: Optional[List[Command]] = None, - attachments: Optional[Attachment] = None, + attachments: Optional[List[Union[CallbackQuery, Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Sticker, Document]]] = None, annotations: Optional[dict] = None, misc: Optional[dict] = None, **kwargs, diff --git a/dff/utils/pydantic/__init__.py b/dff/utils/pydantic/__init__.py index a4d2b09c1..b96d0c2e7 100644 --- a/dff/utils/pydantic/__init__.py +++ b/dff/utils/pydantic/__init__.py @@ -1,13 +1,13 @@ from base64 import decodebytes, encodebytes from copy import deepcopy from pickle import dumps, loads -from typing import Annotated, Any, Callable, Dict -from pydantic import PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator +from typing import Annotated, Callable +from pydantic import JsonValue, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator _JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" -def json_pickle_serializer(model: Dict[str, Any], original_serializer: Callable[[Dict[str, Any]], Dict[str, Any]]) -> Dict[str, Any]: +def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[JsonValue], JsonValue]) -> JsonValue: extra_fields = list() model_copy = deepcopy(model) @@ -26,7 +26,7 @@ def json_pickle_serializer(model: Dict[str, Any], original_serializer: Callable[ return original_dump -def json_pickle_validator(model: Dict[str, Any]) -> Dict[str, Any]: +def json_pickle_validator(model: JsonValue) -> JsonValue: model_copy = deepcopy(model) if _JSON_EXTRA_FIELDS_KEYS in model.keys(): @@ -40,4 +40,4 @@ def json_pickle_validator(model: Dict[str, Any]) -> Dict[str, Any]: JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") JSONPickleValidator = WrapValidator(json_pickle_validator) -JSONSerializableDict = Annotated[Dict[str, Any], JSONPickleSerializer, JSONPickleValidator] +JSONSerializableDict = Annotated[JsonValue, JSONPickleSerializer, JSONPickleValidator] diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index dd55cd783..bac4bc038 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -29,6 +29,7 @@ def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: return path_steps +@pytest.mark.telegram @pytest.mark.asyncio @pytest.mark.parametrize( "tutorial_module_name", diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 15eff7510..9cd2f0e4a 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -149,6 +149,7 @@ async def test_getting_attachment_bytes(self): read_bytes = await document.get_bytes(cli_iface) assert document_bytes == read_bytes if not isinstance(document.source, Path): + assert document.cached_filename is not None cached_bytes = document.cached_filename.read_bytes() assert document_bytes == cached_bytes From ea033b46a4ae4ebe4cd390e066acd3f9cbaf3801 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Wed, 5 Jun 2024 13:53:51 +0300 Subject: [PATCH 106/140] Created MockVK, splitted saving functions, added extra fields handling --- dff/messengers/vk.py | 32 ++++++---- tests/messengers/vk/mock_bot.py | 86 +++++++++++++++++++++++++++ tests/messengers/vk/test_incoming.py | 1 - tests/messengers/vk/test_tutorials.py | 39 ++++++++++++ 4 files changed, 144 insertions(+), 14 deletions(-) create mode 100644 tests/messengers/vk/mock_bot.py create mode 100644 tests/messengers/vk/test_tutorials.py diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index e739a6468..29eedbd84 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -112,7 +112,7 @@ def connect(self): server_request = self.get_longpoll_server() if "response" not in server_request: - raise Exception(f"Errror getting longpoll server\n{server_request}") + raise Exception(f"Error getting longpoll server\n{server_request}") self.server = server_request["response"]["server"] self.ts_base = int(server_request["response"]["ts"]) @@ -135,18 +135,24 @@ async def get_upload_server(self, data_type, peer_id): return upload_url["response"]["upload_url"] - async def save_attachment(self, uploaded_data, data_type, title: str=None): - if data_type == "photos": - saved_data = await vk_api_call( - f"https://api.vk.com/method/{data_type}.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_data['photo']}&server={uploaded_data['server']}&hash={uploaded_data['hash']}" - ) - else: - saved_data = await vk_api_call( - f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&title={title}&group_id={self.group_id}&v=5.81&access_token={self.token}" - ) + async def save_document(self, uploaded_data, title: str=""): + saved_data = await vk_api_call( + f"https://api.vk.com/method/docs.save?file={uploaded_data['file']}&title={title}&group_id={self.group_id}&v=5.81&access_token={self.token}" + ) + + if "response" not in saved_data: + logger.error(f"Error saving document\n{saved_data}") + raise Exception() + + return saved_data["response"] + + async def save_photo(self, uploaded_data, caption: str=""): + saved_data = await vk_api_call( + f"https://api.vk.com/method/photos.saveMessagesPhoto?&group_id={self.group_id}&v=5.81&access_token={self.token}&photo={uploaded_data['photo']}&caption={caption}&server={uploaded_data['server']}&hash={uploaded_data['hash']}" + ) if "response" not in saved_data: - logger.error(f"Error saving attachment\n{saved_data}") + logger.error(f"Error saving photo\n{saved_data}") raise Exception() return saved_data["response"] @@ -165,7 +171,7 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> upload_url, files=photo_files ).json() - saved_photo_data = self.save_attachment(uploaded_photo_data, "photos") + saved_photo_data = self.save_photo(uploaded_photo_data, caption=attachment.title) return saved_photo_data @@ -177,7 +183,7 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = await vk_api_call(upload_url, files=files).json() - saved_doc_data = self.save_attachment(uploaded_photo_data, "docs", title=attachment.title) + saved_doc_data = self.save_document(uploaded_photo_data, title=attachment.title) return saved_doc_data["response"] diff --git a/tests/messengers/vk/mock_bot.py b/tests/messengers/vk/mock_bot.py new file mode 100644 index 000000000..ad17569ec --- /dev/null +++ b/tests/messengers/vk/mock_bot.py @@ -0,0 +1,86 @@ +from asyncio import get_event_loop +from typing import Any, Dict, List, Optional, Tuple, TypeAlias, Hashable + +from pydantic import BaseModel + +from dff.messengers.vk import PollingVKInterface +from dff.pipeline.types import PipelineRunnerFunction +from dff.script import Message +from dff.script.core.context import Context +from dff.script.core.message import DataAttachment + +PathStep: TypeAlias = Tuple[Dict[str, Any], Message, Message, List[str]] + +class MockVK(BaseModel, arbitrary_types_allowed=True): + latest_trace: List[str] = list() + + @staticmethod + def representation(any: Any) -> str: + if isinstance(any, bytes): + return "<>" + else: + return any.__repr__() + + def __getattribute__(self, name: str) -> Any: + async def set_trace(*args, **kwargs): + joined_args = ", ".join([self.representation(a) for a in args]) + joined_kwargs = ", ".join([f"{k}={self.representation(v)}" for k, v in kwargs.items()]) + arguments = ", ".join([joined_args, joined_kwargs]) + self.latest_trace += [f"{name}({arguments})"] + + try: + return object.__getattribute__(self, name) + except AttributeError: + return set_trace + +class MockApplication(BaseModel, arbitrary_types_allowed=True): + bot: MockVK + happy_path: List[PathStep] + interface: PollingVKInterface + latest_ctx: Optional[Context] = None + + @classmethod + def create(cls, interface: PollingVKInterface, happy_path: List[PathStep]) -> "MockApplication": + instance = cls(bot=MockVK(), happy_path=happy_path, interface=interface) + return instance + + def _wrap_pipeline_runner(self, runner: PipelineRunnerFunction): + async def wrapped_pipeline_runner( + message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None + ) -> Context: + self.latest_ctx = await runner(message, ctx_id, update_ctx_misc) + return self.latest_ctx + + wrapped_pipeline_runner.is_wrapped = True + wrapped_pipeline_runner.original = runner + return wrapped_pipeline_runner + + def _wrap_populate_attachment(self, interface: PollingVKInterface): + async def wrapped_populate_attachment(_: DataAttachment) -> bytes: + return bytes() + + wrapped_populate_attachment.is_wrapped = True + wrapped_populate_attachment.original = interface.populate_attachment + return wrapped_populate_attachment + + def _run_bot(self) -> None: + if not getattr(self.interface.pipeline_runner, "is_wrapped", False): + self.interface.pipeline_runner = self._wrap_pipeline_runner(self.interface.pipeline_runner) + if not getattr(self.interface.populate_attachment, "is_wrapped", False): + self.interface.populate_attachment = self._wrap_populate_attachment(self.interface) + + loop = get_event_loop() + for update, received, response, trace in self.happy_path: + loop.run_until_complete(self.interface.on_message(update)) + assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" + assert self.latest_ctx.last_request == received, "Expected request message is not equal to expected!" + assert self.latest_ctx.last_response == response, "Expected response message is not equal to expected!" + assert self.bot.latest_trace == trace, "Expected trace is not equal to expected!" + self.bot.latest_trace = list() + self.latest_ctx = None + + self.interface.pipeline_runner = self.interface.pipeline_runner.original + self.interface.populate_attachment = self.interface.populate_attachment.original + + def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: + return self._run_bot() diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_incoming.py index 3a5ed2351..a6fb42111 100644 --- a/tests/messengers/vk/test_incoming.py +++ b/tests/messengers/vk/test_incoming.py @@ -2,7 +2,6 @@ import requests import json from dff.script import Message -# from vk_dummy import VKDummy from dff.messengers.vk import PollingVKInterface @pytest.fixture diff --git a/tests/messengers/vk/test_tutorials.py b/tests/messengers/vk/test_tutorials.py new file mode 100644 index 000000000..8cc76552a --- /dev/null +++ b/tests/messengers/vk/test_tutorials.py @@ -0,0 +1,39 @@ +from importlib import import_module +from json import loads +from pathlib import Path +from typing import Dict, List + +import pytest + +from dff.script.core.message import Message +from tests.messengers.vk.mock_bot import MockApplication, PathStep +from tests.test_utils import get_path_from_tests_to_current_dir + +dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") +happy_paths_file = Path(__file__).parent / "incoming_data.json" + +def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: + imports = globals().copy() + imports.update(import_module("vk_api").__dict__) + + path_steps = list() + for step in dict: + update = eval(step["update"], imports) + received = Message.model_validate_json(step["received_message"]) + received.original_message = update + response = Message.model_validate_json(step["response_message"]) + path_steps += [(update, received, response, step["response_functions"])] + return path_steps + +@pytest.mark.vk +@pytest.mark.asyncio +@pytest.mark.parametrize( + "tutorial_module_name", + ["1_basic", "2_attachments"], +) +def test_tutorials_vk_memory(tutorial_module_name: str): + happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] + happy_path_steps = _cast_dict_to_happy_step(happy_path_data) + module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") + module.interface.application = MockApplication.create(module.interface, happy_path_steps) + module.pipeline.run() From 07d887e8caa11e31842a9487da4dddffafd58a1a Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 6 Jun 2024 00:20:52 +0200 Subject: [PATCH 107/140] erview notes taken into account --- dff/messengers/telegram/abstract.py | 10 +-- dff/script/core/message.py | 12 ++-- dff/utils/pydantic/__init__.py | 22 ++++-- .../messengers/telegram/test_happy_paths.json | 14 ++-- tests/messengers/telegram/utils.py | 69 ++++++++++--------- tests/script/core/test_message.py | 11 +-- 6 files changed, 77 insertions(+), 61 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 5ed53d45e..50c4742b6 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -251,7 +251,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if media_group_attachments_num == 1: + if media_group_attachments_num != 1: files += [ InputMediaAudio( attachment_bytes, @@ -279,7 +279,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Video): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if media_group_attachments_num == 1: + if media_group_attachments_num != 1: files += [ InputMediaVideo( attachment_bytes, @@ -308,7 +308,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Animation): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if media_group_attachments_num == 1: + if media_group_attachments_num != 1: files += [ InputMediaAnimation( attachment_bytes, @@ -335,7 +335,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Image): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if media_group_attachments_num == 1: + if media_group_attachments_num != 1: files += [ InputMediaPhoto( attachment_bytes, @@ -360,7 +360,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes if isinstance(attachment, Document): attachment_bytes = await attachment.get_bytes(self) if attachment_bytes is not None: - if media_group_attachments_num == 1: + if media_group_attachments_num != 1: files += [ InputMediaDocument( attachment_bytes, diff --git a/dff/script/core/message.py b/dff/script/core/message.py index 691d5dd60..ca8d1226a 100644 --- a/dff/script/core/message.py +++ b/dff/script/core/message.py @@ -15,7 +15,7 @@ from pydantic_core import Url from dff.messengers.common.interface import MessengerInterface -from dff.utils.pydantic import json_pickle_serializer, json_pickle_validator +from dff.utils.pydantic import JSONSerializableDict, SerializableVaue, json_pickle_serializer, json_pickle_validator class DataModel(BaseModel, extra="allow", arbitrary_types_allowed=True): @@ -232,9 +232,9 @@ class level variables to store message information. text: Optional[str] = None commands: Optional[List[Command]] = None attachments: Optional[List[Union[CallbackQuery, Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Sticker, Document]]] = None - annotations: Optional[dict] = None - misc: Optional[dict] = None - original_message: Optional[Any] = None + annotations: Optional[JSONSerializableDict] = None + misc: Optional[JSONSerializableDict] = None + original_message: Optional[SerializableVaue] = None # commands and state options are required for integration with services # that use an intermediate backend server, like Yandex's Alice # state: Optional[Session] = Session.ACTIVE @@ -245,8 +245,8 @@ def __init__( text: Optional[str] = None, commands: Optional[List[Command]] = None, attachments: Optional[List[Union[CallbackQuery, Location, Contact, Invoice, Poll, Audio, Video, Animation, Image, Sticker, Document]]] = None, - annotations: Optional[dict] = None, - misc: Optional[dict] = None, + annotations: Optional[JSONSerializableDict] = None, + misc: Optional[JSONSerializableDict] = None, **kwargs, ): super().__init__( diff --git a/dff/utils/pydantic/__init__.py b/dff/utils/pydantic/__init__.py index b96d0c2e7..31bb68879 100644 --- a/dff/utils/pydantic/__init__.py +++ b/dff/utils/pydantic/__init__.py @@ -1,12 +1,20 @@ from base64 import decodebytes, encodebytes from copy import deepcopy from pickle import dumps, loads -from typing import Annotated, Callable -from pydantic import JsonValue, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator +from typing import Annotated, Any, Callable +from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator _JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" +def pickle_serializer(value: Any) -> JsonValue: + return encodebytes(dumps(value)).decode() + + +def pickle_validator(value: JsonValue) -> Any: + return loads(decodebytes(value.encode())) + + def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[JsonValue], JsonValue]) -> JsonValue: extra_fields = list() model_copy = deepcopy(model) @@ -18,7 +26,7 @@ def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[Json else: TypeAdapter(type(field_value)) except PydanticSchemaGenerationError: - model_copy[field_name] = encodebytes(dumps(field_value)).decode() + model_copy[field_name] = pickle_serializer(field_value) extra_fields += [field_name] original_dump = original_serializer(model_copy) @@ -32,12 +40,16 @@ def json_pickle_validator(model: JsonValue) -> JsonValue: if _JSON_EXTRA_FIELDS_KEYS in model.keys(): for extra_key in model[_JSON_EXTRA_FIELDS_KEYS]: extra_value = model[extra_key] - model_copy[extra_key] = loads(decodebytes(extra_value.encode())) + model_copy[extra_key] = pickle_validator(extra_value) del model_copy[_JSON_EXTRA_FIELDS_KEYS] return model_copy +PickleSerializer = PlainSerializer(pickle_serializer, when_used="json") +PickleValidator = PlainValidator(pickle_validator) +SerializableVaue = Annotated[Any, PickleSerializer, PickleValidator] + JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") -JSONPickleValidator = WrapValidator(json_pickle_validator) +JSONPickleValidator = AfterValidator(json_pickle_validator) JSONSerializableDict = Annotated[JsonValue, JSONPickleSerializer, JSONPickleValidator] diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index 9f88c12da..fb71a225d 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -65,7 +65,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 46, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=6, supergroup_chat_created=False, text='audio'), update_id=6)", "received_message": "{\"text\":\"audio\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_audio(42, audio=<>, performer=None, title=None, caption=\"Here's your audio!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" ] @@ -73,7 +73,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 4, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=7, supergroup_chat_created=False, text='video'), update_id=7)", "received_message": "{\"text\":\"video\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your video!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/crownfall-lags-nkognit0.mp4\",\"cached_filename\":null,\"id\":null,\"title\":\"Epic Dota2 gameplay by Nkognit0\",\"use_cache\":true,\"dff_attachment_type\":\"video\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your video!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/crownfall-lags-nkognit0.mp4\",\"cached_filename\":null,\"id\":null,\"title\":\"Epic Dota2 gameplay by Nkognit0\",\"use_cache\":true,\"dff_attachment_type\":\"video\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_video(42, <>, caption=\"Here's your video!\", disable_notification=None, reply_markup=None, parse_mode=None, supports_streaming=None, has_spoiler=None, thumbnail=None, filename=None)" ] @@ -81,7 +81,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 22, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=8, supergroup_chat_created=False, text='animation'), update_id=8)", "received_message": "{\"text\":\"animation\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your animation!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/hong-kong-simplyart4794.gif\",\"cached_filename\":null,\"id\":null,\"title\":\"Hong Kong skyscraper views by Simplyart4794\",\"use_cache\":true,\"dff_attachment_type\":\"animation\",\"filename\":\"hk.gif\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your animation!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/hong-kong-simplyart4794.gif\",\"cached_filename\":null,\"id\":null,\"title\":\"Hong Kong skyscraper views by Simplyart4794\",\"use_cache\":true,\"dff_attachment_type\":\"animation\",\"filename\":\"hk.gif\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_animation(42, <>, caption=\"Here's your animation!\", parse_mode=None, disable_notification=None, reply_markup=None, has_spoiler=None, thumbnail=None, filename='hk.gif')" ] @@ -89,7 +89,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 1, 35, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=9, supergroup_chat_created=False, text='image'), update_id=9)", "received_message": "{\"text\":\"image\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your image!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your image!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_photo(42, <>, caption=\"Here's your image!\", disable_notification=None, reply_markup=None, parse_mode=None, has_spoiler=None, filename=None)" ] @@ -97,7 +97,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 2, 19, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=10, supergroup_chat_created=False, text='document'), update_id=10)", "received_message": "{\"text\":\"document\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your document!\",\"commands\":null,\"attachments\":[{\"source\":\"https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your document!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_document(42, <>, caption=\"Here's your document!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None, filename=None)" ] @@ -157,7 +157,7 @@ { "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='secret', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='5', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 28, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=6, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=6)", "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"secret\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", - "response_message": "{\"text\":\"Here's your secret image! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/cdn.jsdelivr.net\/gh\/deeppavlov\/dialog_flow_framework@example-attachments\/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\",\"has_spoiler\":true,\"filename\":\"deeppavlov_logo.png\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your secret image! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/github.com\/deeppavlov\/dialog_flow_framework\/wiki\/example_attachments\/deeppavlov.png\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov logo\",\"use_cache\":true,\"dff_attachment_type\":\"image\",\"has_spoiler\":true,\"filename\":\"deeppavlov_logo.png\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "response_functions": [ "send_photo(42, <>, caption=\"Here's your secret image! Run /start command again to restart.\", disable_notification=None, reply_markup=None, parse_mode=None, has_spoiler=True, filename='deeppavlov_logo.png')" ] @@ -173,7 +173,7 @@ { "update": "Update(callback_query=CallbackQuery(chat_instance='-1', data='thumbnail', from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), id='7', message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 21, 19, 9, 34, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Bot', id=16, is_bot=True, username='dff_bot'), group_chat_created=False, location=Location(latitude=58.43162, longitude=27.792879), message_id=8, reply_markup=InlineKeyboardMarkup(inline_keyboard=((InlineKeyboardButton(callback_data='formatted', text='Cute formatted text!'),), (InlineKeyboardButton(callback_data='attachments', text='Multiple attachments!'),), (InlineKeyboardButton(callback_data='secret', text='Secret image!'),), (InlineKeyboardButton(callback_data='thumbnail', text='Document with thumbnail!'),), (InlineKeyboardButton(callback_data='hash', text='Attachment bytes hash!'),), (InlineKeyboardButton(callback_data='restart', text='Restart!'), InlineKeyboardButton(callback_data='quit', text='Quit!')))), supergroup_chat_created=False)), update_id=8)", "received_message": "{\"text\":null,\"commands\":null,\"attachments\":[{\"query_string\":\"thumbnail\",\"dff_attachment_type\":\"callback_query\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", - "response_message": "{\"text\":\"Here's your document with tumbnail! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/cdn.jsdelivr.net\/gh\/deeppavlov\/dialog_flow_framework@example-attachments\/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\",\"filename\":\"deeppavlov_article.pdf\",\"thumbnail\":\"gASVySsAAAAAAABCwisAAIlQTkcNChoKAAAADUlIRFIAAADIAAAAyAgCAAAAIjo5yQAAK4lJREFU\\neJzsnXdcFFfXx+\/sbF\/KsnSQLiiIUlSwgo+KYi9RAbvYS4wleZ7EqNFojEaTqOlqLLFh77F3jaCA\\nCEgREJDeWbb394PwIiIus7NTFrPfj3\/g7My9h+U3t557DlWj0QAjRrCGQrYBRj5MjMIyggtGYRnB\\nBaOwjOCCUVhGcMEoLCO4YBSWEVwwCssILhiFZQQXqGQbgBIlf6+qYhHZVuAMbEOzP0NhdifbDjS0\\n1xZLVbmSbBPwR1WuEsSQbQRK2quwgEZCtgWEoBGTbQFK2q2wjBg2RmEZwQWjsIzgglFYRnDBKCw0\\n8GXsEhGPL2PrU4hcRX1a4Y6dUYZFe13H0s7DEu9tTycxYflgp8Ro76sQhOipx2Ve3yZEMWH5KNfY\\nyZ1ua7nzUn7Q7ucjulrm7gz5FbWRNwv9l91fkDl1DuoSDJkPU1ilYh6DIt8QvD\/65qdcunCoS8LG\\nJ5OFCtZnAcddzCrOvex9raB7oHXWbJ+rmxPq9ZfF77Cgy8VyiYVGAzb13jvk3OYulnnPq10flnSh\\nQqqvgw8czw515FQOd31yLCuExxBM9rrDl5mk1zg3VLcrddizKo\/edmmhDsm704Z9HXywWMj74\/mI\\n9cEHm1t1JPM\/D0u7MGH5V0EHM2s6XMzrNanjPZK+Idz5YLtCGqzqyC0Jc46\/Vej\/6YO5tqyavvap\\n824vyxdYr4md8XHXs\/vShqZVO5\/L7ZNe4+zFLVjxYD4AQAMgCqQGQEOnKDtxC77scVitATFZoQo1\\nvDF+MgDgh6cfmdFFzSs6md3vyIuBEzzurX88tUzC\/Tsv6G6R76X8IImS3sKkblYvV\/c4nFdnczwr\\n1MO8JNz5ybGsAcR+K8TxYbZYTYgVTAum8GZhQHKVuylNYsuqiSvtXCs3+eT+Ig5NSgFqAMB837\/N\\naKIfnk4AAMSWek++umplwClvXsHauGl3Cv3rFGwf3qto76urHkUnlHfkyznBdi+aV5FV6xhkm\/Gf\\nDsn97FOTq9wjve5cyO39qNRnR8gvDTeoNRAF0mg0YF\/6kCflncrEFiGOqTym0Ncyj6RvhQg+WGEV\\nCS1\/SxlxIifk0sjVpSIelyGY3OkOC5axqPX\/1vQ8DEEaJ9MKAEB6tVNiRcchzvEAgP4OqSeHbWgo\\n4VhW6Ibgv\/akhQMAmFTFoq7nh1345que9b3bS75dvsCmTMzN4dt15BZtSYi8VeB37VWPdUH1n\/Y5\\nucOGXdPdOhsAcDqnz+K7S4tnRQoVzN3Ph18Yufa\/D+sHVeVi82eV7jIV7XFZpyDbTLK\/LeyB161b\\nR7YNOpNUJLBWbtVyA5WigiDIhCZdH3zQw7w0xDGlQGjzoMS3g0mln3Wuv1XO+dzeVVKzYNuMvzLD\\nxEpmgHXOZ4EnmLDcgV3dyaKwoZBO3MLYMu+JHvd9eK\/sODU+vPwqqfmSbufYNHlcWSeJitnBpJIC\\naUa7xVox6+4U+23svd+HV8BliJmwfIRrnA+vAADAospMaeJ+DmkMWOlrmXe\/2HdOlyte3CKJkpFY\\n4dXLLqNAaNPbLv19v0iB2FvNGsamwzh8i\/gCta9zhQkFdRuu515IqxQvGIFJgb1Pbv8l9OfA162L\\nAbInLXz14+VL+nb4dICLOas9dS\/txtbcasmmG3kH4ksUKizfhEsjV5vSDXo\/u1ai3Hgjb09c8ReD\\nXJf2dyLbHKS0g1mhUqVefTnHc9M\/e+KKsVUVAIDHFNIoKmzLxINSgfyTsy\/cNj688aKabFsQYegt\\n1vnUioWnMorr5GQbYhDk1UjD\/ng6pBNvX4SPgzmDbHO0YbgtVoVQPn5f8ph9yUZVteBaZnWnzY9+\\neVBAtiHaMFBh7Xtc7L0l9kxqBdmGGChCuWrJmRcDfk14Xiok25bWMThhVYrkkw+mRh9LrxIrtNym\\n1iDb\/2vnKFTaFhru5tQG73iy61GRSk2gTcgwLGHdf1nTdWvc0aSyNu88n9uLEIvIRKGCrxcEar9H\\nJFfPP5kxdt+zaq3vIfEY0DrWqr+zt95+pVQjsodNlYY5JVix6vC3ixw0GpBY4ZlU2RHh\/Xam9PPR\\n3Xo6m+NsF1IMQlg1YsWMo2kX0irJNqR9w6RSNg33WB7qTLYhwCCElVkuGrsvOaO8vR5HMTSW9u+w\\nbZQnDSZ5kEOysO69rBn95zO+tB0sUbYj+rtzL0T7kbsFRKaw9sYVLziZoUA2qDKiE64WzDuLAl14\\nLLIMIEdYagDWXc7ZcONDdkgiHWcu88QM3yCShvMkCEupUn95Oee7268IrvdfiCWbejbar58bl\/iq\\nSRDWsrOZO+4XElzpvxZTBnw+2m9ARwuC6yVaWPNPpO+KLSayRiMsGuXvOf4Ea4vQSemS0xlGVRGP\\nRKEevifpQW4NkZUSJ6z\/Xcz65WERYdUZaY5EoR79Z3JCAXEbFQQJ69ubucbROrnUSJRDdydllImI\\nqY4IYR14Urzq75cEVGREO1UixcDfEssEMgLqwl1Yj1\/xF5z8AI83tVNKBPLwXUkiOe5bHfgKK7Nc\\nNHx3klRpeO5C\/2KSioXzTqTLcfbhwlFYApky8mBqlViJXxVG0HEksWzLLXy3PfASlkoN5p\/ISCo2\\nUMdZI19dyb2agaOfEl7C+vFe\/tGnbTuCGiELDQBRh57nVuF1phIXYT15Vbf6cg4eJRvBkBqJctJf\\nKTg5l2AvLIlCFXUoVaY0OsO0A+ILBeuv4tIEYC+sZWdf5ODWwBrBnK+v5z1+xce8WIyFdTWjyrgb\\n2O6IPJgqUWC8soWlsKpE8jnH3xuRx4jBklstXXEuC9sysXSbWXAi\/Y\/22FypVeySZJqwTOQYqDSx\\naf4JpJSZ5j9kVuXAMoGKaS4zcxS49FEzzcizFS9gCDxe1jOwA2a\/GmbCupdTM+j3pwhPBRoU1k\/2\\nmL2KrZ+BQ3DRgM9lPLfGD9Qqu39+4pSlNr9ZRWOV95gtdvAnx1Y88XcwebS0B5OGTZA3bLpChUq9\\n7NyL9qgqWFRl+lpVr18ylVnOraaPOMWJLVRVf79CYvfoF0algQZq04ekYuEvDzHz7MXmhNAfj4qe\\nFrXLRXYNBQYQBWgaN86cLU1H9LTvwGX06GBWEF+5Pe7Nnc4uLr6+vjeuX5fL5X1Lz2\/9JkahUqeW\\nCp8VCwv5sttZNbXSdr95tf5a7pRAOzszDAIkYdAVVork3ltiK0WGFTsAOc4pR2gv6hsqFpt1\/NQp\\nb2\/vhusymWxu9Ox\/Hj4EAMyZO3fFZ5\/S6fSE+PiICRMBAIdjjgb3ehM\/Qq5SpxQLb2fX3M+tvZxR\\nhXmAOMJY3Nfx5\/Gd9S8HA2GtbZ8HubhMamSA7YI+jn4OpokJiTk52UOHDjUzb3lYKutFFpfLtbax\\nbroya\/qM+\/furV67ZmZ0dKslK1TqI4mlx5LKr2RUtUd9PV0R5O9oqmch+naFxXzZd3fy9SyEYAId\\nTRf1dZzZ07HpGHpg98DA7q3HdfH08mxxxdHREQCQnfXeYRYNpszo6TCjp0OZQLb19qtdsUUCWXs6\\n6r3+2sszs\/z0LETfFuvj05k\/Yzfiw5t+buabhnv0d9frvMqd27dTklM6enYcNnw4kvsVKvWeuOLV\\nl3Oq248HUeKKoAD9Gi29hFUqkDl9\/bBdTAaDnM2+Dncf2smSLANEctX2e6++u51f1x4CVQzsaHFz\\nYRuhubSjl7AWn8r49R9DP3hjxoQ3hnss6ONIegAWAMCrGunnl7JjnpYZ\/rv4bGVQNwf0jRZ6YfGl\\nSpu19+SGPf0Z2om3P9IHk\/kzhlxKq1xwMqOQT8ShBtREBdgemeqL+nH0L\/E313MNWVVUCrRrYucr\\n8wIMTVUAgBE+Vokrg0Z3sSLbEG0cfVqWVYE+aBlKYSnVmt1xBrMtqFZRheX0mnxGTV7DP0+W9OHH\\n3ef2ciTbsvdizaGfi\/bbPMKDUfuKKqoAakMceP3+CP04B2VXeCSxdMrh56hr1R8av4hdlsoue04V\\nV9FElZDmzR+mi2+XP\/fvt7Iy6PagiatXrny2YqVIKpOb2Co51mIbH7G9n5JjEMYzqJSqDSEcVCmi\\nUAor8Ic4cvZw1ErT\/Fjuiyt0YWmrn\/fr33\/vgf0UCvnjdOQ8S3q2cN688vLypisSS8+aTsMk9t1I\\ntaue3z7qtKBPBxQPohHW00JB4I+PUVSmJ5xXsVYpJ6jS97o7jhk7dsu2rVSqoedxeZfCgoIJ48ZX\\nVr51bEbKdan0j5JZIg2cjAe9XMweLe2J4kE0b\/aBeKJHV1Rhuf397+2e7NGiqtFjxnz3\/bb2qCoA\\nQAcnp1Nnzzg4ODS\/yKzNd7yzhffsGKQkLelLbH7do7xaFA\/qLCylWnOW2EwkjKoch3tb2eXafFND\\nBwzYvPU7GG5\/CSObcOzQ4fc9u1tsVkJAY5F93fbRzxQ5ac4jp5LR\/Ll1Ftbl9Mr8GuIWYFhlaQ73\\nttIk2mI7+fr6bv9pJ53eMrl3u8PHx+fnX39lMpktrnPK0+zv\/0iRCUix6nRKOYrj+DoL62Ryuc6V\\noIVZnmH\/z06KWtsWm42NzW+7d5ma6rsbbyD06dtn9Vdr373OrM23f7gDaP0qcCK3WhpfoPMxHt2E\\nJVOqL6dX6VoHOmiCUtvHu6C2vsodP\/9kb29PjEnEEBkVNSli0rvXmTV5No93k2ER2BWr84KWbsJK\\nKKirIMahT6O2jt9HlbURge6T5ct7BgURYQ+xrFm3zt3D493rpkUJJv\/vSE0kt7J1DjOpm7CQ5OXC\\nBIv0i6zqNk7oevv4fPzJUmLsIRgWi7Xz558gqJXUedaJByGllGB78qqlz4p0G+HpJqzrmUQkJKbI\\nBOY5N9u4h0LZvnMHAcaQRWdv70VLlrx7naKScTOvEG\/PZR1D0+ggrIwyUaYeu5LI4WZegeVthMpc\\nsGihR0cyVw4JYM68ue7u7u9et3hxBaiIPmHwIFe38bsOwnpCSMxdSCExzX+o\/R4nZ+ely5YRYAy5\\nmJqafva\/\/757HVIrTfP\/IdiY6y+qq0Q6rNPqICxiFhpYFZnUthYD5y9c0E5X2HUlbOjQ3n36vHud\\nU5RIsCVyleZ5qQ4Rl3UQVjIh4fk4JUnab+js7T1u\/HgCLDEQlq9c8e5FZlU28b3h5QwdVpqQCiu9\\nVJRXg\/9kRKNhad26AQDMmh3NYBic7x5+BHbv7u\/f8kQ\/rJKxKl8QbEkaHi3Wy2oiQl5RheU0sbbX\\nwsbGZviIEQRYYlAsXd7KgJImIjrT8a2cGhniANhIhXU3h4hMLLCijVlnRFQki0Vackey6NO3r5OT\\nU4uLlLYmzpgjlKmQJ7ZAKqzCWiIW5WCtm80wDE+KiCDADEODSqV+NHFCi4uwhIg1xRZkI47ViHRu\\ndVP3RX0UwFrngz2Dguzf9lgiHpXghFp0UcsNsNl0CnsQ5vWOHT9+5\/YdavWbngjSkJCW4V5OzUfd\\nbJDciUhYLyvF5UIi5iCQVnfWEaNGEmCDdjTyFLXwmJYbKKw+AGAvrA4dOvQMCoqLfbNR2Mp2D\/5U\\nId4pRiSsKjH5kWRodNrgsDCyrQAAdoAYAVpvwOscxKDBg5oLixSQZ4RAJCxDiILs69vV2tqabCsA\\nlbsAcBeQUnW\/kBAAviGl6iYyKjAdvCcUkuO72JzQ0FCyTSAZLy8vNptNrg0qNRAgiy+HqMWqM4BY\\ndZ28MYgGpj+qugMqgbYxFsxdBHPwGguGDR1y7sxZnApHSEa5qKdzyyhi74JIWHyyhUWj0VrdMiMe\\njSJHI7ml7Q6TMfjVHhgYSLqwXlZJMBPWS7LHWB09PU1MTMi1oRGqE8QM1nYDbItf5W6tedEQDMIB\\nd\/sQlo0NorUTAqCazwXmc8mqPSBQr5hVmFCAbKkc0eCd9GSW3fzIP2xOInm5uc+Skhpclkk\/O4kw\\nzF77iHFga4tj\/2KwSCSSixcuTI2aPPg\/A9PT0houurm5kWuVGllMhvbhLkej0cg2gVAqKipOHj8R\\nc\/RoUWHL+K5OLs7Z2WSmL0AY6rJtYUnwz3jeJtYGM8bCG4lE8v3WrTFHjkqlrQ9l7OxIPkRZK8Fo\\nHYv0tQYAAJfLJdsE3MnLy1uz6stH\/7R0Znd3d1+\/cUPTaguX2\/ZUH1cQ6qFtYRlCNEhDWWvAAZVK\\ndfP6jZijR+\/dvdv8OgzDYUOGRERF9g8JaX7dhOxgAgj10D7GWKRPhfCgurr67OnTMUdjXua8dTSX\\nx+ONHjt2yrSprY7T28tX0T6EhTq085d\/Z1\/F9JDtwj6Os4P1DW2anZW1e9euy5f+Fovf8pj19PKa\\nO2\/ekPChWlpoDPNL4kr7EJZIhNINN7daiu0OeqkAfQw0pVJ58fyFYzFH45\/EN9cHlUodNnz4lGlT\\nu3fvDrUV5FIkJNojGR1tC8sEVWxTbOHzsc+GTSTV1dVHDh0+deJEQUFB8+s8Hi8iKnJSZOS7Lu3v\\ng89HE18PQxDqoW1hmTLJb9XKyvQNRjKzpz266L8NJBTWxeajPAi+etWqvy9eqqt763Hfrl0jo6KG\\njxxhZqZbttzSUoLisrwPHhuRHsgXDRJk71nUQc6m4R72emQS2HwrD7WwYo4cbfoZgqCh4eFz58\/3\\n80eZXutVPsm51syRNTTtQ1jV1SScSMEWM3Pz2XPmTJ4y2YLH06ecFlNI4oEpiLztEQnLnAnzSc1Z\\nlfwsmcTa9aRnUM\/IqKiRo0frv1Igk8kUCpLPH7QWtKsVEAnL3ZJFbsrn4iKUuTc6mDO62HIaUuvo\\nY4AVh9ZQjhVH513Lo8eP61N1c1JTUrAqCjUOyEYUiITlYckmV1g5OTkymQxFyIbvRnl+N6plilQU\\nzAl2nKP38pX+vMjMJNsE4GGJ6CQ6ImEhnAjgh0wmi330KHTAAMxLlkqlL3NyGg6C0mg0Ty8vAtKl\\nFBYW1tY0HgB2cHTkIR51paam4mkXItwxFBabRv5SVkZ6OrbCevjgwYF9+588fiwQvFlBtbGxCRkQ\\nOmPWrKZc9hhSXV198MCBy39fzs7KaroIQZB\/QMC48eMmToqg0dvoZ69eJiFIZAu8bThIbkP0dvo7\\nkr8HfO\/uPayKqigvX7p4yYyp027dvCkQCKhUqourq6ubG5VKLS8vP3n8xISx47Z8++37HFfQcfHC\\nhWFhQ37asbNBVRYWFp5enjweT6PRPE1MXLt6zbgxY5KfPWv12ZI6WWM7V0vy6igEAJeNaJSJqMXy\\nsUUkUlx5lpRUV1en63Liu7zMyZkxdVpJSQmDwZgwaeL0mTPNzMzOnjmjUqpGjRktkUgOHvjr+LGY\\n3X\/sSkxI\/H3XH3quDjTw7Tff\/Ll7DwDAz98\/Iipy7LhxTXk0FArF6VOnYg4fSUlJmTBu\/A87to8c\\nNar5s2dSyiMPpu6N8FanthHwlwA6WiEN9YOoxTIjb\/F9dqTgt01VENBIpdLrV6\/pWVpeXl7kpIiS\\nkpKQ0NCbd++s37DBxcUlcuLELZu+3fbddyPCh1lZWa3f8PWtu3eDe\/dKiI+fEhkll+ubIOnrdev+\\n3L2HzeHs+PmnU2fPTIqIaJ6dhUajRURGnrlwftPmzVQqddnHS4\/HxDR9uvZKzvj9KUq1Rq7S3Lh2\\nXU9L9KeHE1KnHUTC8rThcFkkaGvx9LoVc4QhQfIfv6qBIM2li9rCvCCBTqezmMyZ0bP2HthvZ2fX\\nMNLKz2tcyxYKBNevXgUA2Nvb\/3Xo0JixYyEKRf8O0dLS0tzc\/PS5syNGajvIOiky4ujxY6ampqrX\\nmWvUAET8lbLhep4ZA742P2CkKzU+Pl5PS\/THgoV0tQWRXCiv8+WfTiE06dfi6XWLpjfu5Hu5KV0c\\nlU8eP66qrLTUI3Wqg4PDqbNnrJrFgHBxdaXT6U3NkrOLS8MPMAxv+\/EHkUikv4\/h4o8\/njJ1KtfC\\nos07\/fz9H8Q+4nA4ZQL58N1JiUUCPweTmGm+nW04e\/7YJZORn5y8rytS\/1WkU2snLqFhP0eHiRdO\\na1RVVS20aLVFXiFNIpFc1LvRsno7soirq+vylSs4HA6DwZg1Ozq4V6+mjyAIwspzFYmqGuBw6oez\\n4\/clJxYJLNnUMzO7dX49Czt96hQmluhJZ8SjbaTCCvVA+tXoj7uzYu0n\/IatA6kMTF9umVfY2AIf\\n2Lcf8z2NufPnP05MiE96+uWaNdiWjJqTM7t6WLKqxMqPDiQX82WJCYkvXhAdyvZdGFTIG3NheVoR\\nFOcEhjVbV9Wy\/j9l3+qt5nkFb\/r1V\/n5N65jP4ZlMBgGFdrU3oyRsCJopLfl0yJhjx8ff\/bjfrIt\\nqmeAhwUL8YomUmF525o4mhGRaXJ0mKRzx8ZzILcfMS7faSnovXv2NI+Y+KFizqQem951RahTiUB+\\n2zJc0AFNYmZs8bXTYdUJqbBgCvDRpVx0MBia6EmNm5JyOdj6eyuT26eJT69euYq3JYYAmw5\/P9or\\nnJaloVCVLOKGIu9jaCdL5DfrsC\/2UVfcT42G9hC6Ozf658RcYOcXtT65\/XnnTrwtMRD+efgwK2aL\\n85UvLLL0XcPTEwgCvvY6TGV0EFZvxFNN1Ezo9ibfyZkr7x30ZGZk7NlFTq5RIlEoFN9u\/AYAQCMj\\n8nYLBna00MkFVwdhdXMwdeW1zIONITCkGuka1\/BzYirtRa62Id3O7dtLiovxM8YQ2L93X3p6Gwlg\\nCKOfm26H0XVbT\/+Ph8W+6hIdTUJKkE0GldI4Kk\/JaGOFVywWf7pi5eGYozgZQwxqeYZaeF6jyNYo\\nXwF1HQTbAKoDhdkLZg8qKFbt+PFHsg18w0gf3daldRPW1O52+57gJaxQxzf+x0+etT0DjYuNPX3q\\n1PiPPsLJHlxRS5+oqjepxZebX2w4aqiu26uE6JkJ7mymSCol32Hp9fIH3d9Rt+1\/3ZzaermYmzPx\\n+lU7mLzJOlRWiaiWLz\/\/orlvUztBoaz8QlE4sIWq3kIj7x+YcWlfxZAQ8gOh17\/z7lyqju6Put3O\\npsNhXhi4kbQO9N7\/vA+FQrFk0eKKCkI3MfVCLZUXR6lqfwSg7f0DM1PN1i9royeRHwt9fm+d3bJ1\\ndsNFmEqFMLKzslYuW65Ukh9rCQmKypUasQ7bnVQYLJstDA8ls91yMKP3cdU5jJTOwprgZ2tnSsQS\\nPHL+efhw7ZerybaibVSCE+q6P3V9CobBuhV8SwvSjt+N6WJN17UjRCEsKgUa44tLuhil+o0xpia6\\nfY\/Hjx37et06HIzCDrVIWbUW3aOmHM2SGaR1iONR9VFoTqRMCbRD8VSbpFa9CQfVK0Bnv82\/9h\/Y\\ntuU7rI3CDJXwIlDmon58fLjEzpqE7r6LLWcwqlE1GmH1d7fwssbeF+Dqq+5NP3u6ofkSf\/\/tt7Wr\\n16hV5AdNfReV6Lw+j1OpYEAvEhz95gSjTBCJ8gzd8hBndA9qoUBoWyZuHCSGBMnsrNHo48ihQ4sX\\nLRIKyTxe2yptJEpBgI8X0YfrYQhM64Eyli5KYc3sac\/UfUDXJmdeNoZwhWEQPgDlVOj61WsfjR2n\\nf+QjjFHrm6LWxZHornB2sIOl7iEFGkApDiYNnhOMfVzo\/Sn\/afp5yliRqQlKv6uc7OzhQ4ZeuqCX\\nH7NYrhLK6v\/pU0gDapVQqGAKFUypEn3AeksLor3QPu6HNBzcu6BvdT4f5IZ59ti0XM6dR41b6A62\\n6qjR6MMi8vn85Z98surzL1B3iyG\/JJiuumO66o5K7z9oeoXGas8pqz2nIq+uQl2IWEJott5hnXk6\\n+cm0AL2wHM0Zk\/wxXixV0Tnb95oq\/7+NmDdZ6OyAvv1Xq9XHY2LGjBx55\/Ztfayqk+o7uGnK5kCB\\n0Is0v5DQE3irBuuVW0WvcdK3Izrq8\/i7qBimWbm0\/ScaXVVZTLBjXTUV1itOcH5e\/pxZ0XOjZyPY\\nVVQCIH99pA+83r9q\/HKuvdDXHepKRlXDD\/Yc9EUVlRG3Id3L2UxXP5kW6CUsNx4rKgDT9ElUhgpm\\n7NxnmpLR+HZ6uat+2VjdPGy9h4fH77t37T1woE\/fvsgLvn3rVnjYkGUfLy0pafDOkKtEV5UVKxUl\\nkbK8TrJs5ut\/JrJsM1k2u\/7nHPN+vEMNzy46lXEtswr173QsqWzzrcYzsSH26ANc3biPozNcCzbr\\n3WRAesYNzygT+X0fJ1dhFnzc6fIXdHGFvY1y95ZqN6fGHuTvW8zV27gyef0g4+DhQ71fS0omk4X2\\n7VdZWYm8cEsLVXiodOFsDwtWUps5Fh6Vdh589juVprGdgCBgb0qnNAtoZ8aEfe1MhnlbTgm0o8GU\\nrArxTw8KnhYJCmplqtfJ19QaTUmdvKkaDlXyfMocOzaawB5PntFmrnxrw6POLaQicDqKotpkYEeL\\nmwv1TYyob7fd2ZYzr5fjzw9bJqlCjYrNBeKKknLq0rUWf2yudrCt75gCfOUOtsrc1+fAmP9\/TovB\\nYAwcNOj4MW0Zmpvo6KqYPEY8Llz8OlLQUySP9LbLmO1zedfzxnPxGg0ornt7P4AP0srEx5+Vv6yS\\nTPSz7fNTvPYp5Ajz8+hUpdaAXw8Sl+nkqyEYZK7DYC1q1WBXDGPBK9iN7+XLAtr8z3kl5ZQaPrRg\\nFS\/3\/08X7ty+XSJpXOKi0dveDre3UW78tPbUH5URo8RtxZ9qyQ\/9\/ljc9RyH2saK2jc38uafSNei\\nKopMwEs9lXn4ak4+mjf5xEXW4ySCTqJH+NuEYHE4GYOJhr0Z438DXdZceal\/UfXAb\/74LwtokxZa\\nmXA0r4rf2Hn\/3v2Tx49PmzGjzTDdNJpmyljR4ulCNgtlT02lqL\/vt+t\/gcfSa5wzapyqpGYaTWNX\\nqAGgSmp2vaB7Nt9RrQGPXgfrhpQyVkUGvbYA0rwWmUYDywT0uiIGv4CilAkBZeGXFod3VFlb6jA3\\njHtK3\/IbQRm\/WDTKhnAPTIrCZga7ItR5\/5MShGmotaOivjVErebD1e9kpTDnWjR4+V1\/\/6loF0fl\\n1ytre3TDYBvEhs23YaeEOrYy7lao4YmXV195FQRey8jhzhYm\/5WWoopKqVM+sfxpfU0nD0TLKBdv\\nMr\/eYd4wuCSA\/\/7HxdMamyPv2AiLTYe3juo4fj8GMX0VHOv3fdS7T28nJ+d+If2HjxhRP3PZtIn\/\\nngh3vQJl276ssTDHPZ8RjaL6LPCEs2lFQgrtZZpQu6oaKCqlzlhpOWuicE6kSEt87vJKyva9pueu\\nsRA60+qPE5fx6QDMtoD1nRU2Z\/Kh1KNP9d2hY1a+cLzbuvfL2Qvnfbt2BQBUVlRu2rjx\/Llzrd42\\nOkz87f+Izr0jkYLpyy3TsnRwgTThqKMnCXsFyrt1VjTNNWVyEJvIuBvLOH6J3dTttgrms8KbCwIG\\nemLmd46lsAprpQE\/PK4U6dX70GvynW5taPWjhYsXWfB4D+7de3D\/wfvCN0SMEq39BGVuEj1RqcC0\\nZZbP0tG417JZag5bU1tHUSiQtk\/YCmtyoO3hKb5YlYaxsAAAB+NLph9N06cESCF1O78EXes\/anB9\\nW4UwdQIeCITQvC94yai0pSsYCsvRjJG4MsjGBEuzMXZ9mdbDXk\/HZQ2NqTBB46Havats\/QoyVfXa\\no1rz84ZqF0eSs5Loyh8TO2OrKuyFBQDYPdHbxgS9c8jrHUOdN9XtrFXbv6phGMAhD0uuZuuqWiaj\\n3QRaig6yH6HjKWckYC8saxO6nr211FK3jSoqrNn6ZQ2Payg5bbt0Uq6cS\/5hQCR4WDJ\/Ht8Jj5Jx\\nSe8x2Iu3JswV9eMS68463T9ppDjQ17B6n4jR4uAALPMP4AGLRjkzyw95kD6dwCtvzBeDXAd7otwZ\\nUHJ0aJmteaolM9E3D2K913SFoubDusY\/EkwB\/50vYNB1a0RRZKHShz2TvLvq4cqnHbyExaLB+6N8\\nEGaKaoHCxFbBQrqgMm+y0NwUZSf4LI02bIbNzYfo\/5z7jnPGz7fKL6rXE9X2L6rN701faeeOytFh\\nYuRF+XTpcvn6tb79dPAF0ofFfR0n43OMrwEcM105mjPPzOrGoeteBQQpTBC5eXHNVJGjdfjjNaeq\\nBprzP15lNbz0K4vLt3V2ddJowE\/7TbbtMisqpc5cYQm438Cmk2CzaVT7kwBqbAbmRgnbdM5pILhX\\nr5gTx52dnXfv3dvFF8v1pFbp78b9YYwXrlXgm0Ktq73J4Sm+KFYAxPbdkNw2f4oQdRI4SwvNgqkN\\n7vDQp99YfL7ZHHmA\/tIKSvSnvN8PNbqyzJwoBMI\/gaq6vhPkDKc5xQF6vf2OdupxQ9vua1d+9tnh\\nmKNsNhsAEPvoURbOkbfdecwzs7rSYXz\/9Ljn5hvja71lpM7uiFKee5v3UGHN+GF6DZFmR4g+ia6D\\nKfWNyoUb7CFTbY6cY\/PrtL0IxWWUnftMhs+wefyM8bpt1Xy+iD9jghgoX8oLBwNlaf13SvdgOMfC\\n1jsAzWPCiPc2qAwGY9z48ddu3li4eFHDlevXri9esFD\/7D1asDGh3VoUaMnBfWEG45X39\/H5xawt\\nt9veoH2DRuN8ZRVNrC0+0eC+kh3rMUizdvwia\/OvbzwITDjqIf2lQX4ydxcVk6GhUTVCMSSRQk+e\\n0VMy6HfjGE1beEyGZv3y2pGDm83+qB40+yMURlOGerVKeOnbHxLjnyQIBHXVVdVMJtPaxsbe3r5P\\nv77Dhg+3sXlzGuXk8RNfrVmDPK8JipV3Dh2+Pt+\/t+6hY1BAkLAAAFGHUmN02aK2jt9vlv9Ayw2b\\n\/lszZgg2U\/rMHOoXW8wzX+rwHnu5KTZ8Wuvb6R3vF8iEarkR5s5B7jnC5\/N\/3Pb9oYMHdbBYd2Gx\\naZQjU33H+L7XeQRbiBOWSg0iDyafTEYaJI1TmGAX99v7P9c8vVyqq0eoFtRqcOEm6\/eDJs2dClvF\\n3kY5f4pwzBCJltoheleq5UYKZ5B2eUml0nNnzn6\/bVt1lc6HNXQSFgRAzDTfSf6YnnzRCnFH1WAK\\nODzFV6ZMuZCG6PiDyMFPyeRSpa13dl07KzBUVf3AiALGhElGDpQkZ9Cu32dm5VKT0uhiSeMYlGeu\\n8vFSuDsrB\/aRBXaVtznw1chTFCVjANUVNp0EMfwlmkEmpm+8QIsKC+Pi4uJiY2\/duFlTo+\/R+zaB\\nADg+3XeCH3GqIlRYAAA6lXJiRtfIgylnUxFoi0IV2fuZ595t9cPOHrgstcMwCOiiCOiiaGjDauvq\\nR1cmHA3KpTJlnqrmu\/pZwnLLogpnCx5PrVaXFBfX1RHn2ANB4ECkD8GqImJW2AIGlXJierepyJbm\\nhI7d3\/cRujhHOkGhAB5X42inRr0A24S7s7K0tDQ9LS0zI4NIVVEp0MnpXVFHjNEHooX1epkAOjCl\\ny+ygtn9bqa2Pktn6OYIunoa1Oagdax4JIbtM6PDfc\/zQxePTHxKE1VDrngifTcPbXqyq9Rza6nU3\\np\/YRzbYB4q3lsakPlnQP0yWtEraQI6wGvhjktjfCm03TZkOdW381pZWBoLmZoTjJIMEWVRA51Pg7\\nmCStDPZzJO6M67uQKSwAwKwgh2vzA7Q4BmpoLIFTL2KNwh5TDnGvwfDOltfnBzhxiQv00CokCwsA\\n0NeNm\/xpr27v99+o6TJWQ9QRKJwgzGF69WDXC3P8rbD2M0YB+cKq7ylM6XGf9JzXq\/U4qioWV+Dc\\nvhstKf5hablM6rlZ3TYM86AYxjtoEMJ6HXuS8sdE74OTfXjsVkZUtZ2Ga6C3TMVzoxZ7qmqw99JU\\nN\/vbBTmbJa4IGk3Udg0SDEVYDUztbv9gSY8+72TcVJjZ891Cm18pLDWItFgIKSzBQVg0VkMnu3qw\\n662FgW6ofCrxw7CE9TqrOefhxz02hLvT4bfa9NrOw1W0N2EFMnIw3dDBmZcF2O9wqJjm7pbM+4u7\\nbxjmwcEu2g9WGJywGlgd5pa0Mrhvs6ZLxbKo7jK26b\/J6e1JWDV8zL9naNmIwLT\/9u6rX0BH\/DBQ\\nYTU0XQ8+7vHLeK+mUON1riEy08YBfjGBATn1J+4pltM0H7+A0xcurJ8\/kYFDqH2sMFzLGljU1+n5\\nZ8GzguxhCgRgakXgdA1UL6l\/4gk90KIPFVUUvgCb18CCx1v99cbz505369oFkwLxw9CF9XoxgrE3\\nwufhku4DO1rIrDrWufYDAEhklLQsQl0zUHMvDoN3gMnmTJkx89qt2zOnT8HCKNxpH38bAECwi\/nN\\nhYE3s6qXnYD5RzLpwtIzV9g+nuQEltGJK\/f0WgSnUKnhI0Z99tlKpw46pzklEeI8SLFCrQaXHzzZ\\ntW1TWUHC3RPlZJvTBlU1lJCJNuiCp8FU2pjx42fPndvJE5vwjUTS\/oTVgFqtvnX7jrPJZhfLe2Tb\\noo29xzjf79Yt\/3t9P0JnTIyMmhU9y90V+yxrxNBehdWEVJSqqNpKkZykwgaXplClAn3H2wpEOgxk\\nbRw6RERGzps\/l2UIoXP0oN0LqwGVUiSu+AkSHaSBHLJteUPMedaGncjWmSAoZOCgydOmDx7QH3ez\\nCOEDEVYTgpoEWH5Jzf+FRiE6DGkLpDIQPs2morqNhQbvbv6TJ0cNGxbONde5xzRkPjRhNVFXeRWS\\n3wOSK1TVc9TH8PVhy2+mf51q3RfIxNSsq5\/f4LCwoeHhdrYGtHOMIR+ssJoQ8p8D6TW1+AakTKND\\nJcRU+iKXGrnYqnl8dogCe3h6+gd2Dw7uGRYWZsLBJpy6wfLhC6s5UmGyVBgPSf6mQ3lKSTqdhst4\\nXyyBJi2yzC2gmfOsnJw6dPMPCAsb7Onp+aE2Tq3y7xJWc6RSPlWTIxZmaqSJGlkCiy4W8DNNWSij\\njKhUQKp2YHNsJQrH\/MretfJe9ra2HTu6w6R0wwbAv1dYrVInKGFSSqmwhi8oA6pKJk0sEpZSNLVQ\\ns8yoSjWDzrCm0y3FcjbLxJFJ54hldCrTncn4wHs3nTAKywgu\/EsbaiN4YxSWEVwwCssILhiFZQQX\\njMIyggtGYRnBBaOwjOCCUVhGcOH\/AgAA\/\/+S+QX6OV9s5wAAAABJRU5ErkJggpQu\\n\",\"__pickled_extra_fields__\":[\"thumbnail\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "response_message": "{\"text\":\"Here's your document with tumbnail! Run \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"source\":\"https:\/\/github.com\/deeppavlov\/dialog_flow_framework\/wiki\/example_attachments\/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":\"DeepPavlov article\",\"use_cache\":true,\"dff_attachment_type\":\"document\",\"filename\":\"deeppavlov_article.pdf\",\"thumbnail\":\"gASVySsAAAAAAABCwisAAIlQTkcNChoKAAAADUlIRFIAAADIAAAAyAgCAAAAIjo5yQAAK4lJREFU\\neJzsnXdcFFfXx+\/sbF\/KsnSQLiiIUlSwgo+KYi9RAbvYS4wleZ7EqNFojEaTqOlqLLFh77F3jaCA\\nCEgREJDeWbb394PwIiIus7NTFrPfj3\/g7My9h+U3t557DlWj0QAjRrCGQrYBRj5MjMIyggtGYRnB\\nBaOwjOCCUVhGcMEoLCO4YBSWEVwwCssILhiFZQQXqGQbgBIlf6+qYhHZVuAMbEOzP0NhdifbDjS0\\n1xZLVbmSbBPwR1WuEsSQbQRK2quwgEZCtgWEoBGTbQFK2q2wjBg2RmEZwQWjsIzgglFYRnDBKCw0\\n8GXsEhGPL2PrU4hcRX1a4Y6dUYZFe13H0s7DEu9tTycxYflgp8Ro76sQhOipx2Ve3yZEMWH5KNfY\\nyZ1ua7nzUn7Q7ucjulrm7gz5FbWRNwv9l91fkDl1DuoSDJkPU1ilYh6DIt8QvD\/65qdcunCoS8LG\\nJ5OFCtZnAcddzCrOvex9raB7oHXWbJ+rmxPq9ZfF77Cgy8VyiYVGAzb13jvk3OYulnnPq10flnSh\\nQqqvgw8czw515FQOd31yLCuExxBM9rrDl5mk1zg3VLcrddizKo\/edmmhDsm704Z9HXywWMj74\/mI\\n9cEHm1t1JPM\/D0u7MGH5V0EHM2s6XMzrNanjPZK+Idz5YLtCGqzqyC0Jc46\/Vej\/6YO5tqyavvap\\n824vyxdYr4md8XHXs\/vShqZVO5\/L7ZNe4+zFLVjxYD4AQAMgCqQGQEOnKDtxC77scVitATFZoQo1\\nvDF+MgDgh6cfmdFFzSs6md3vyIuBEzzurX88tUzC\/Tsv6G6R76X8IImS3sKkblYvV\/c4nFdnczwr\\n1MO8JNz5ybGsAcR+K8TxYbZYTYgVTAum8GZhQHKVuylNYsuqiSvtXCs3+eT+Ig5NSgFqAMB837\/N\\naKIfnk4AAMSWek++umplwClvXsHauGl3Cv3rFGwf3qto76urHkUnlHfkyznBdi+aV5FV6xhkm\/Gf\\nDsn97FOTq9wjve5cyO39qNRnR8gvDTeoNRAF0mg0YF\/6kCflncrEFiGOqTym0Ncyj6RvhQg+WGEV\\nCS1\/SxlxIifk0sjVpSIelyGY3OkOC5axqPX\/1vQ8DEEaJ9MKAEB6tVNiRcchzvEAgP4OqSeHbWgo\\n4VhW6Ibgv\/akhQMAmFTFoq7nh1345que9b3bS75dvsCmTMzN4dt15BZtSYi8VeB37VWPdUH1n\/Y5\\nucOGXdPdOhsAcDqnz+K7S4tnRQoVzN3Ph18Yufa\/D+sHVeVi82eV7jIV7XFZpyDbTLK\/LeyB161b\\nR7YNOpNUJLBWbtVyA5WigiDIhCZdH3zQw7w0xDGlQGjzoMS3g0mln3Wuv1XO+dzeVVKzYNuMvzLD\\nxEpmgHXOZ4EnmLDcgV3dyaKwoZBO3MLYMu+JHvd9eK\/sODU+vPwqqfmSbufYNHlcWSeJitnBpJIC\\naUa7xVox6+4U+23svd+HV8BliJmwfIRrnA+vAADAospMaeJ+DmkMWOlrmXe\/2HdOlyte3CKJkpFY\\n4dXLLqNAaNPbLv19v0iB2FvNGsamwzh8i\/gCta9zhQkFdRuu515IqxQvGIFJgb1Pbv8l9OfA162L\\nAbInLXz14+VL+nb4dICLOas9dS\/txtbcasmmG3kH4ksUKizfhEsjV5vSDXo\/u1ai3Hgjb09c8ReD\\nXJf2dyLbHKS0g1mhUqVefTnHc9M\/e+KKsVUVAIDHFNIoKmzLxINSgfyTsy\/cNj688aKabFsQYegt\\n1vnUioWnMorr5GQbYhDk1UjD\/ng6pBNvX4SPgzmDbHO0YbgtVoVQPn5f8ph9yUZVteBaZnWnzY9+\\neVBAtiHaMFBh7Xtc7L0l9kxqBdmGGChCuWrJmRcDfk14Xiok25bWMThhVYrkkw+mRh9LrxIrtNym\\n1iDb\/2vnKFTaFhru5tQG73iy61GRSk2gTcgwLGHdf1nTdWvc0aSyNu88n9uLEIvIRKGCrxcEar9H\\nJFfPP5kxdt+zaq3vIfEY0DrWqr+zt95+pVQjsodNlYY5JVix6vC3ixw0GpBY4ZlU2RHh\/Xam9PPR\\n3Xo6m+NsF1IMQlg1YsWMo2kX0irJNqR9w6RSNg33WB7qTLYhwCCElVkuGrsvOaO8vR5HMTSW9u+w\\nbZQnDSZ5kEOysO69rBn95zO+tB0sUbYj+rtzL0T7kbsFRKaw9sYVLziZoUA2qDKiE64WzDuLAl14\\nLLIMIEdYagDWXc7ZcONDdkgiHWcu88QM3yCShvMkCEupUn95Oee7268IrvdfiCWbejbar58bl\/iq\\nSRDWsrOZO+4XElzpvxZTBnw+2m9ARwuC6yVaWPNPpO+KLSayRiMsGuXvOf4Ea4vQSemS0xlGVRGP\\nRKEevifpQW4NkZUSJ6z\/Xcz65WERYdUZaY5EoR79Z3JCAXEbFQQJ69ubucbROrnUSJRDdydllImI\\nqY4IYR14Urzq75cEVGREO1UixcDfEssEMgLqwl1Yj1\/xF5z8AI83tVNKBPLwXUkiOe5bHfgKK7Nc\\nNHx3klRpeO5C\/2KSioXzTqTLcfbhwlFYApky8mBqlViJXxVG0HEksWzLLXy3PfASlkoN5p\/ISCo2\\nUMdZI19dyb2agaOfEl7C+vFe\/tGnbTuCGiELDQBRh57nVuF1phIXYT15Vbf6cg4eJRvBkBqJctJf\\nKTg5l2AvLIlCFXUoVaY0OsO0A+ILBeuv4tIEYC+sZWdf5ODWwBrBnK+v5z1+xce8WIyFdTWjyrgb\\n2O6IPJgqUWC8soWlsKpE8jnH3xuRx4jBklstXXEuC9sysXSbWXAi\/Y\/22FypVeySZJqwTOQYqDSx\\naf4JpJSZ5j9kVuXAMoGKaS4zcxS49FEzzcizFS9gCDxe1jOwA2a\/GmbCupdTM+j3pwhPBRoU1k\/2\\nmL2KrZ+BQ3DRgM9lPLfGD9Qqu39+4pSlNr9ZRWOV95gtdvAnx1Y88XcwebS0B5OGTZA3bLpChUq9\\n7NyL9qgqWFRl+lpVr18ylVnOraaPOMWJLVRVf79CYvfoF0algQZq04ekYuEvDzHz7MXmhNAfj4qe\\nFrXLRXYNBQYQBWgaN86cLU1H9LTvwGX06GBWEF+5Pe7Nnc4uLr6+vjeuX5fL5X1Lz2\/9JkahUqeW\\nCp8VCwv5sttZNbXSdr95tf5a7pRAOzszDAIkYdAVVork3ltiK0WGFTsAOc4pR2gv6hsqFpt1\/NQp\\nb2\/vhusymWxu9Ox\/Hj4EAMyZO3fFZ5\/S6fSE+PiICRMBAIdjjgb3ehM\/Qq5SpxQLb2fX3M+tvZxR\\nhXmAOMJY3Nfx5\/Gd9S8HA2GtbZ8HubhMamSA7YI+jn4OpokJiTk52UOHDjUzb3lYKutFFpfLtbax\\nbroya\/qM+\/furV67ZmZ0dKslK1TqI4mlx5LKr2RUtUd9PV0R5O9oqmch+naFxXzZd3fy9SyEYAId\\nTRf1dZzZ07HpGHpg98DA7q3HdfH08mxxxdHREQCQnfXeYRYNpszo6TCjp0OZQLb19qtdsUUCWXs6\\n6r3+2sszs\/z0LETfFuvj05k\/Yzfiw5t+buabhnv0d9frvMqd27dTklM6enYcNnw4kvsVKvWeuOLV\\nl3Oq248HUeKKoAD9Gi29hFUqkDl9\/bBdTAaDnM2+Dncf2smSLANEctX2e6++u51f1x4CVQzsaHFz\\nYRuhubSjl7AWn8r49R9DP3hjxoQ3hnss6ONIegAWAMCrGunnl7JjnpYZ\/rv4bGVQNwf0jRZ6YfGl\\nSpu19+SGPf0Z2om3P9IHk\/kzhlxKq1xwMqOQT8ShBtREBdgemeqL+nH0L\/E313MNWVVUCrRrYucr\\n8wIMTVUAgBE+Vokrg0Z3sSLbEG0cfVqWVYE+aBlKYSnVmt1xBrMtqFZRheX0mnxGTV7DP0+W9OHH\\n3ef2ciTbsvdizaGfi\/bbPMKDUfuKKqoAakMceP3+CP04B2VXeCSxdMrh56hr1R8av4hdlsoue04V\\nV9FElZDmzR+mi2+XP\/fvt7Iy6PagiatXrny2YqVIKpOb2Co51mIbH7G9n5JjEMYzqJSqDSEcVCmi\\nUAor8Ic4cvZw1ErT\/Fjuiyt0YWmrn\/fr33\/vgf0UCvnjdOQ8S3q2cN688vLypisSS8+aTsMk9t1I\\ntaue3z7qtKBPBxQPohHW00JB4I+PUVSmJ5xXsVYpJ6jS97o7jhk7dsu2rVSqoedxeZfCgoIJ48ZX\\nVr51bEbKdan0j5JZIg2cjAe9XMweLe2J4kE0b\/aBeKJHV1Rhuf397+2e7NGiqtFjxnz3\/bb2qCoA\\nQAcnp1Nnzzg4ODS\/yKzNd7yzhffsGKQkLelLbH7do7xaFA\/qLCylWnOW2EwkjKoch3tb2eXafFND\\nBwzYvPU7GG5\/CSObcOzQ4fc9u1tsVkJAY5F93fbRzxQ5ac4jp5LR\/Ll1Ftbl9Mr8GuIWYFhlaQ73\\nttIk2mI7+fr6bv9pJ53eMrl3u8PHx+fnX39lMpktrnPK0+zv\/0iRCUix6nRKOYrj+DoL62Ryuc6V\\noIVZnmH\/z06KWtsWm42NzW+7d5ma6rsbbyD06dtn9Vdr373OrM23f7gDaP0qcCK3WhpfoPMxHt2E\\nJVOqL6dX6VoHOmiCUtvHu6C2vsodP\/9kb29PjEnEEBkVNSli0rvXmTV5No93k2ER2BWr84KWbsJK\\nKKirIMahT6O2jt9HlbURge6T5ct7BgURYQ+xrFm3zt3D493rpkUJJv\/vSE0kt7J1DjOpm7CQ5OXC\\nBIv0i6zqNk7oevv4fPzJUmLsIRgWi7Xz558gqJXUedaJByGllGB78qqlz4p0G+HpJqzrmUQkJKbI\\nBOY5N9u4h0LZvnMHAcaQRWdv70VLlrx7naKScTOvEG\/PZR1D0+ggrIwyUaYeu5LI4WZegeVthMpc\\nsGihR0cyVw4JYM68ue7u7u9et3hxBaiIPmHwIFe38bsOwnpCSMxdSCExzX+o\/R4nZ+ely5YRYAy5\\nmJqafva\/\/757HVIrTfP\/IdiY6y+qq0Q6rNPqICxiFhpYFZnUthYD5y9c0E5X2HUlbOjQ3n36vHud\\nU5RIsCVyleZ5qQ4Rl3UQVjIh4fk4JUnab+js7T1u\/HgCLDEQlq9c8e5FZlU28b3h5QwdVpqQCiu9\\nVJRXg\/9kRKNhad26AQDMmh3NYBic7x5+BHbv7u\/f8kQ\/rJKxKl8QbEkaHi3Wy2oiQl5RheU0sbbX\\nwsbGZviIEQRYYlAsXd7KgJImIjrT8a2cGhniANhIhXU3h4hMLLCijVlnRFQki0Vackey6NO3r5OT\\nU4uLlLYmzpgjlKmQJ7ZAKqzCWiIW5WCtm80wDE+KiCDADEODSqV+NHFCi4uwhIg1xRZkI47ViHRu\\ndVP3RX0UwFrngz2Dguzf9lgiHpXghFp0UcsNsNl0CnsQ5vWOHT9+5\/YdavWbngjSkJCW4V5OzUfd\\nbJDciUhYLyvF5UIi5iCQVnfWEaNGEmCDdjTyFLXwmJYbKKw+AGAvrA4dOvQMCoqLfbNR2Mp2D\/5U\\nId4pRiSsKjH5kWRodNrgsDCyrQAAdoAYAVpvwOscxKDBg5oLixSQZ4RAJCxDiILs69vV2tqabCsA\\nlbsAcBeQUnW\/kBAAviGl6iYyKjAdvCcUkuO72JzQ0FCyTSAZLy8vNptNrg0qNRAgiy+HqMWqM4BY\\ndZ28MYgGpj+qugMqgbYxFsxdBHPwGguGDR1y7sxZnApHSEa5qKdzyyhi74JIWHyyhUWj0VrdMiMe\\njSJHI7ml7Q6TMfjVHhgYSLqwXlZJMBPWS7LHWB09PU1MTMi1oRGqE8QM1nYDbItf5W6tedEQDMIB\\nd\/sQlo0NorUTAqCazwXmc8mqPSBQr5hVmFCAbKkc0eCd9GSW3fzIP2xOInm5uc+Skhpclkk\/O4kw\\nzF77iHFga4tj\/2KwSCSSixcuTI2aPPg\/A9PT0houurm5kWuVGllMhvbhLkej0cg2gVAqKipOHj8R\\nc\/RoUWHL+K5OLs7Z2WSmL0AY6rJtYUnwz3jeJtYGM8bCG4lE8v3WrTFHjkqlrQ9l7OxIPkRZK8Fo\\nHYv0tQYAAJfLJdsE3MnLy1uz6stH\/7R0Znd3d1+\/cUPTaguX2\/ZUH1cQ6qFtYRlCNEhDWWvAAZVK\\ndfP6jZijR+\/dvdv8OgzDYUOGRERF9g8JaX7dhOxgAgj10D7GWKRPhfCgurr67OnTMUdjXua8dTSX\\nx+ONHjt2yrSprY7T28tX0T6EhTq085d\/Z1\/F9JDtwj6Os4P1DW2anZW1e9euy5f+Fovf8pj19PKa\\nO2\/ekPChWlpoDPNL4kr7EJZIhNINN7daiu0OeqkAfQw0pVJ58fyFYzFH45\/EN9cHlUodNnz4lGlT\\nu3fvDrUV5FIkJNojGR1tC8sEVWxTbOHzsc+GTSTV1dVHDh0+deJEQUFB8+s8Hi8iKnJSZOS7Lu3v\\ng89HE18PQxDqoW1hmTLJb9XKyvQNRjKzpz266L8NJBTWxeajPAi+etWqvy9eqqt763Hfrl0jo6KG\\njxxhZqZbttzSUoLisrwPHhuRHsgXDRJk71nUQc6m4R72emQS2HwrD7WwYo4cbfoZgqCh4eFz58\/3\\n80eZXutVPsm51syRNTTtQ1jV1SScSMEWM3Pz2XPmTJ4y2YLH06ecFlNI4oEpiLztEQnLnAnzSc1Z\\nlfwsmcTa9aRnUM\/IqKiRo0frv1Igk8kUCpLPH7QWtKsVEAnL3ZJFbsrn4iKUuTc6mDO62HIaUuvo\\nY4AVh9ZQjhVH513Lo8eP61N1c1JTUrAqCjUOyEYUiITlYckmV1g5OTkymQxFyIbvRnl+N6plilQU\\nzAl2nKP38pX+vMjMJNsE4GGJ6CQ6ImEhnAjgh0wmi330KHTAAMxLlkqlL3NyGg6C0mg0Ty8vAtKl\\nFBYW1tY0HgB2cHTkIR51paam4mkXItwxFBabRv5SVkZ6OrbCevjgwYF9+588fiwQvFlBtbGxCRkQ\\nOmPWrKZc9hhSXV198MCBy39fzs7KaroIQZB\/QMC48eMmToqg0dvoZ69eJiFIZAu8bThIbkP0dvo7\\nkr8HfO\/uPayKqigvX7p4yYyp027dvCkQCKhUqourq6ubG5VKLS8vP3n8xISx47Z8++37HFfQcfHC\\nhWFhQ37asbNBVRYWFp5enjweT6PRPE1MXLt6zbgxY5KfPWv12ZI6WWM7V0vy6igEAJeNaJSJqMXy\\nsUUkUlx5lpRUV1en63Liu7zMyZkxdVpJSQmDwZgwaeL0mTPNzMzOnjmjUqpGjRktkUgOHvjr+LGY\\n3X\/sSkxI\/H3XH3quDjTw7Tff\/Ll7DwDAz98\/Iipy7LhxTXk0FArF6VOnYg4fSUlJmTBu\/A87to8c\\nNar5s2dSyiMPpu6N8FanthHwlwA6WiEN9YOoxTIjb\/F9dqTgt01VENBIpdLrV6\/pWVpeXl7kpIiS\\nkpKQ0NCbd++s37DBxcUlcuLELZu+3fbddyPCh1lZWa3f8PWtu3eDe\/dKiI+fEhkll+ubIOnrdev+\\n3L2HzeHs+PmnU2fPTIqIaJ6dhUajRURGnrlwftPmzVQqddnHS4\/HxDR9uvZKzvj9KUq1Rq7S3Lh2\\nXU9L9KeHE1KnHUTC8rThcFkkaGvx9LoVc4QhQfIfv6qBIM2li9rCvCCBTqezmMyZ0bP2HthvZ2fX\\nMNLKz2tcyxYKBNevXgUA2Nvb\/3Xo0JixYyEKRf8O0dLS0tzc\/PS5syNGajvIOiky4ujxY6ampqrX\\nmWvUAET8lbLhep4ZA742P2CkKzU+Pl5PS\/THgoV0tQWRXCiv8+WfTiE06dfi6XWLpjfu5Hu5KV0c\\nlU8eP66qrLTUI3Wqg4PDqbNnrJrFgHBxdaXT6U3NkrOLS8MPMAxv+\/EHkUikv4\/h4o8\/njJ1KtfC\\nos07\/fz9H8Q+4nA4ZQL58N1JiUUCPweTmGm+nW04e\/7YJZORn5y8rytS\/1WkU2snLqFhP0eHiRdO\\na1RVVS20aLVFXiFNIpFc1LvRsno7soirq+vylSs4HA6DwZg1Ozq4V6+mjyAIwspzFYmqGuBw6oez\\n4\/clJxYJLNnUMzO7dX49Czt96hQmluhJZ8SjbaTCCvVA+tXoj7uzYu0n\/IatA6kMTF9umVfY2AIf\\n2Lcf8z2NufPnP05MiE96+uWaNdiWjJqTM7t6WLKqxMqPDiQX82WJCYkvXhAdyvZdGFTIG3NheVoR\\nFOcEhjVbV9Wy\/j9l3+qt5nkFb\/r1V\/n5N65jP4ZlMBgGFdrU3oyRsCJopLfl0yJhjx8ff\/bjfrIt\\nqmeAhwUL8YomUmF525o4mhGRaXJ0mKRzx8ZzILcfMS7faSnovXv2NI+Y+KFizqQem951RahTiUB+\\n2zJc0AFNYmZs8bXTYdUJqbBgCvDRpVx0MBia6EmNm5JyOdj6eyuT26eJT69euYq3JYYAmw5\/P9or\\nnJaloVCVLOKGIu9jaCdL5DfrsC\/2UVfcT42G9hC6Ozf658RcYOcXtT65\/XnnTrwtMRD+efgwK2aL\\n85UvLLL0XcPTEwgCvvY6TGV0EFZvxFNN1Ezo9ibfyZkr7x30ZGZk7NlFTq5RIlEoFN9u\/AYAQCMj\\n8nYLBna00MkFVwdhdXMwdeW1zIONITCkGuka1\/BzYirtRa62Id3O7dtLiovxM8YQ2L93X3p6Gwlg\\nCKOfm26H0XVbT\/+Ph8W+6hIdTUJKkE0GldI4Kk\/JaGOFVywWf7pi5eGYozgZQwxqeYZaeF6jyNYo\\nXwF1HQTbAKoDhdkLZg8qKFbt+PFHsg18w0gf3daldRPW1O52+57gJaxQxzf+x0+etT0DjYuNPX3q\\n1PiPPsLJHlxRS5+oqjepxZebX2w4aqiu26uE6JkJ7mymSCol32Hp9fIH3d9Rt+1\/3ZzaermYmzPx\\n+lU7mLzJOlRWiaiWLz\/\/orlvUztBoaz8QlE4sIWq3kIj7x+YcWlfxZAQ8gOh17\/z7lyqju6Put3O\\npsNhXhi4kbQO9N7\/vA+FQrFk0eKKCkI3MfVCLZUXR6lqfwSg7f0DM1PN1i9royeRHwt9fm+d3bJ1\\ndsNFmEqFMLKzslYuW65Ukh9rCQmKypUasQ7bnVQYLJstDA8ls91yMKP3cdU5jJTOwprgZ2tnSsQS\\nPHL+efhw7ZerybaibVSCE+q6P3V9CobBuhV8SwvSjt+N6WJN17UjRCEsKgUa44tLuhil+o0xpia6\\nfY\/Hjx37et06HIzCDrVIWbUW3aOmHM2SGaR1iONR9VFoTqRMCbRD8VSbpFa9CQfVK0Bnv82\/9h\/Y\\ntuU7rI3CDJXwIlDmon58fLjEzpqE7r6LLWcwqlE1GmH1d7fwssbeF+Dqq+5NP3u6ofkSf\/\/tt7Wr\\n16hV5AdNfReV6Lw+j1OpYEAvEhz95gSjTBCJ8gzd8hBndA9qoUBoWyZuHCSGBMnsrNHo48ihQ4sX\\nLRIKyTxe2yptJEpBgI8X0YfrYQhM64Eyli5KYc3sac\/UfUDXJmdeNoZwhWEQPgDlVOj61WsfjR2n\\nf+QjjFHrm6LWxZHornB2sIOl7iEFGkApDiYNnhOMfVzo\/Sn\/afp5yliRqQlKv6uc7OzhQ4ZeuqCX\\nH7NYrhLK6v\/pU0gDapVQqGAKFUypEn3AeksLor3QPu6HNBzcu6BvdT4f5IZ59ti0XM6dR41b6A62\\n6qjR6MMi8vn85Z98surzL1B3iyG\/JJiuumO66o5K7z9oeoXGas8pqz2nIq+uQl2IWEJott5hnXk6\\n+cm0AL2wHM0Zk\/wxXixV0Tnb95oq\/7+NmDdZ6OyAvv1Xq9XHY2LGjBx55\/Ztfayqk+o7uGnK5kCB\\n0Is0v5DQE3irBuuVW0WvcdK3Izrq8\/i7qBimWbm0\/ScaXVVZTLBjXTUV1itOcH5e\/pxZ0XOjZyPY\\nVVQCIH99pA+83r9q\/HKuvdDXHepKRlXDD\/Yc9EUVlRG3Id3L2UxXP5kW6CUsNx4rKgDT9ElUhgpm\\n7NxnmpLR+HZ6uat+2VjdPGy9h4fH77t37T1woE\/fvsgLvn3rVnjYkGUfLy0pafDOkKtEV5UVKxUl\\nkbK8TrJs5ut\/JrJsM1k2u\/7nHPN+vEMNzy46lXEtswr173QsqWzzrcYzsSH26ANc3biPozNcCzbr\\n3WRAesYNzygT+X0fJ1dhFnzc6fIXdHGFvY1y95ZqN6fGHuTvW8zV27gyef0g4+DhQ71fS0omk4X2\\n7VdZWYm8cEsLVXiodOFsDwtWUps5Fh6Vdh589juVprGdgCBgb0qnNAtoZ8aEfe1MhnlbTgm0o8GU\\nrArxTw8KnhYJCmplqtfJ19QaTUmdvKkaDlXyfMocOzaawB5PntFmrnxrw6POLaQicDqKotpkYEeL\\nmwv1TYyob7fd2ZYzr5fjzw9bJqlCjYrNBeKKknLq0rUWf2yudrCt75gCfOUOtsrc1+fAmP9\/TovB\\nYAwcNOj4MW0Zmpvo6KqYPEY8Llz8OlLQUySP9LbLmO1zedfzxnPxGg0ornt7P4AP0srEx5+Vv6yS\\nTPSz7fNTvPYp5Ajz8+hUpdaAXw8Sl+nkqyEYZK7DYC1q1WBXDGPBK9iN7+XLAtr8z3kl5ZQaPrRg\\nFS\/3\/08X7ty+XSJpXOKi0dveDre3UW78tPbUH5URo8RtxZ9qyQ\/9\/ljc9RyH2saK2jc38uafSNei\\nKopMwEs9lXn4ak4+mjf5xEXW4ySCTqJH+NuEYHE4GYOJhr0Z438DXdZceal\/UfXAb\/74LwtokxZa\\nmXA0r4rf2Hn\/3v2Tx49PmzGjzTDdNJpmyljR4ulCNgtlT02lqL\/vt+t\/gcfSa5wzapyqpGYaTWNX\\nqAGgSmp2vaB7Nt9RrQGPXgfrhpQyVkUGvbYA0rwWmUYDywT0uiIGv4CilAkBZeGXFod3VFlb6jA3\\njHtK3\/IbQRm\/WDTKhnAPTIrCZga7ItR5\/5MShGmotaOivjVErebD1e9kpTDnWjR4+V1\/\/6loF0fl\\n1ytre3TDYBvEhs23YaeEOrYy7lao4YmXV195FQRey8jhzhYm\/5WWoopKqVM+sfxpfU0nD0TLKBdv\\nMr\/eYd4wuCSA\/\/7HxdMamyPv2AiLTYe3juo4fj8GMX0VHOv3fdS7T28nJ+d+If2HjxhRP3PZtIn\/\\nngh3vQJl276ssTDHPZ8RjaL6LPCEs2lFQgrtZZpQu6oaKCqlzlhpOWuicE6kSEt87vJKyva9pueu\\nsRA60+qPE5fx6QDMtoD1nRU2Z\/Kh1KNP9d2hY1a+cLzbuvfL2Qvnfbt2BQBUVlRu2rjx\/Llzrd42\\nOkz87f+Izr0jkYLpyy3TsnRwgTThqKMnCXsFyrt1VjTNNWVyEJvIuBvLOH6J3dTttgrms8KbCwIG\\nemLmd46lsAprpQE\/PK4U6dX70GvynW5taPWjhYsXWfB4D+7de3D\/wfvCN0SMEq39BGVuEj1RqcC0\\nZZbP0tG417JZag5bU1tHUSiQtk\/YCmtyoO3hKb5YlYaxsAAAB+NLph9N06cESCF1O78EXes\/anB9\\nW4UwdQIeCITQvC94yai0pSsYCsvRjJG4MsjGBEuzMXZ9mdbDXk\/HZQ2NqTBB46Havats\/QoyVfXa\\no1rz84ZqF0eSs5Loyh8TO2OrKuyFBQDYPdHbxgS9c8jrHUOdN9XtrFXbv6phGMAhD0uuZuuqWiaj\\n3QRaig6yH6HjKWckYC8saxO6nr211FK3jSoqrNn6ZQ2Payg5bbt0Uq6cS\/5hQCR4WDJ\/Ht8Jj5Jx\\nSe8x2Iu3JswV9eMS68463T9ppDjQ17B6n4jR4uAALPMP4AGLRjkzyw95kD6dwCtvzBeDXAd7otwZ\\nUHJ0aJmteaolM9E3D2K913SFoubDusY\/EkwB\/50vYNB1a0RRZKHShz2TvLvq4cqnHbyExaLB+6N8\\nEGaKaoHCxFbBQrqgMm+y0NwUZSf4LI02bIbNzYfo\/5z7jnPGz7fKL6rXE9X2L6rN701faeeOytFh\\nYuRF+XTpcvn6tb79dPAF0ofFfR0n43OMrwEcM105mjPPzOrGoeteBQQpTBC5eXHNVJGjdfjjNaeq\\nBprzP15lNbz0K4vLt3V2ddJowE\/7TbbtMisqpc5cYQm438Cmk2CzaVT7kwBqbAbmRgnbdM5pILhX\\nr5gTx52dnXfv3dvFF8v1pFbp78b9YYwXrlXgm0Ktq73J4Sm+KFYAxPbdkNw2f4oQdRI4SwvNgqkN\\n7vDQp99YfL7ZHHmA\/tIKSvSnvN8PNbqyzJwoBMI\/gaq6vhPkDKc5xQF6vf2OdupxQ9vua1d+9tnh\\nmKNsNhsAEPvoURbOkbfdecwzs7rSYXz\/9Ljn5hvja71lpM7uiFKee5v3UGHN+GF6DZFmR4g+ia6D\\nKfWNyoUb7CFTbY6cY\/PrtL0IxWWUnftMhs+wefyM8bpt1Xy+iD9jghgoX8oLBwNlaf13SvdgOMfC\\n1jsAzWPCiPc2qAwGY9z48ddu3li4eFHDlevXri9esFD\/7D1asDGh3VoUaMnBfWEG45X39\/H5xawt\\nt9veoH2DRuN8ZRVNrC0+0eC+kh3rMUizdvwia\/OvbzwITDjqIf2lQX4ydxcVk6GhUTVCMSSRQk+e\\n0VMy6HfjGE1beEyGZv3y2pGDm83+qB40+yMURlOGerVKeOnbHxLjnyQIBHXVVdVMJtPaxsbe3r5P\\nv77Dhg+3sXlzGuXk8RNfrVmDPK8JipV3Dh2+Pt+\/t+6hY1BAkLAAAFGHUmN02aK2jt9vlv9Ayw2b\\n\/lszZgg2U\/rMHOoXW8wzX+rwHnu5KTZ8Wuvb6R3vF8iEarkR5s5B7jnC5\/N\/3Pb9oYMHdbBYd2Gx\\naZQjU33H+L7XeQRbiBOWSg0iDyafTEYaJI1TmGAX99v7P9c8vVyqq0eoFtRqcOEm6\/eDJs2dClvF\\n3kY5f4pwzBCJltoheleq5UYKZ5B2eUml0nNnzn6\/bVt1lc6HNXQSFgRAzDTfSf6YnnzRCnFH1WAK\\nODzFV6ZMuZCG6PiDyMFPyeRSpa13dl07KzBUVf3AiALGhElGDpQkZ9Cu32dm5VKT0uhiSeMYlGeu\\n8vFSuDsrB\/aRBXaVtznw1chTFCVjANUVNp0EMfwlmkEmpm+8QIsKC+Pi4uJiY2\/duFlTo+\/R+zaB\\nADg+3XeCH3GqIlRYAAA6lXJiRtfIgylnUxFoi0IV2fuZ595t9cPOHrgstcMwCOiiCOiiaGjDauvq\\nR1cmHA3KpTJlnqrmu\/pZwnLLogpnCx5PrVaXFBfX1RHn2ANB4ECkD8GqImJW2AIGlXJierepyJbm\\nhI7d3\/cRujhHOkGhAB5X42inRr0A24S7s7K0tDQ9LS0zI4NIVVEp0MnpXVFHjNEHooX1epkAOjCl\\ny+ygtn9bqa2Pktn6OYIunoa1Oagdax4JIbtM6PDfc\/zQxePTHxKE1VDrngifTcPbXqyq9Rza6nU3\\np\/YRzbYB4q3lsakPlnQP0yWtEraQI6wGvhjktjfCm03TZkOdW381pZWBoLmZoTjJIMEWVRA51Pg7\\nmCStDPZzJO6M67uQKSwAwKwgh2vzA7Q4BmpoLIFTL2KNwh5TDnGvwfDOltfnBzhxiQv00CokCwsA\\n0NeNm\/xpr27v99+o6TJWQ9QRKJwgzGF69WDXC3P8rbD2M0YB+cKq7ylM6XGf9JzXq\/U4qioWV+Dc\\nvhstKf5hablM6rlZ3TYM86AYxjtoEMJ6HXuS8sdE74OTfXjsVkZUtZ2Ga6C3TMVzoxZ7qmqw99JU\\nN\/vbBTmbJa4IGk3Udg0SDEVYDUztbv9gSY8+72TcVJjZ891Cm18pLDWItFgIKSzBQVg0VkMnu3qw\\n662FgW6ofCrxw7CE9TqrOefhxz02hLvT4bfa9NrOw1W0N2EFMnIw3dDBmZcF2O9wqJjm7pbM+4u7\\nbxjmwcEu2g9WGJywGlgd5pa0Mrhvs6ZLxbKo7jK26b\/J6e1JWDV8zL9naNmIwLT\/9u6rX0BH\/DBQ\\nYTU0XQ8+7vHLeK+mUON1riEy08YBfjGBATn1J+4pltM0H7+A0xcurJ8\/kYFDqH2sMFzLGljU1+n5\\nZ8GzguxhCgRgakXgdA1UL6l\/4gk90KIPFVUUvgCb18CCx1v99cbz505369oFkwLxw9CF9XoxgrE3\\nwufhku4DO1rIrDrWufYDAEhklLQsQl0zUHMvDoN3gMnmTJkx89qt2zOnT8HCKNxpH38bAECwi\/nN\\nhYE3s6qXnYD5RzLpwtIzV9g+nuQEltGJK\/f0WgSnUKnhI0Z99tlKpw46pzklEeI8SLFCrQaXHzzZ\\ntW1TWUHC3RPlZJvTBlU1lJCJNuiCp8FU2pjx42fPndvJE5vwjUTS\/oTVgFqtvnX7jrPJZhfLe2Tb\\noo29xzjf79Yt\/3t9P0JnTIyMmhU9y90V+yxrxNBehdWEVJSqqNpKkZykwgaXplClAn3H2wpEOgxk\\nbRw6RERGzps\/l2UIoXP0oN0LqwGVUiSu+AkSHaSBHLJteUPMedaGncjWmSAoZOCgydOmDx7QH3ez\\nCOEDEVYTgpoEWH5Jzf+FRiE6DGkLpDIQPs2morqNhQbvbv6TJ0cNGxbONde5xzRkPjRhNVFXeRWS\\n3wOSK1TVc9TH8PVhy2+mf51q3RfIxNSsq5\/f4LCwoeHhdrYGtHOMIR+ssJoQ8p8D6TW1+AakTKND\\nJcRU+iKXGrnYqnl8dogCe3h6+gd2Dw7uGRYWZsLBJpy6wfLhC6s5UmGyVBgPSf6mQ3lKSTqdhst4\\nXyyBJi2yzC2gmfOsnJw6dPMPCAsb7Onp+aE2Tq3y7xJWc6RSPlWTIxZmaqSJGlkCiy4W8DNNWSij\\njKhUQKp2YHNsJQrH\/MretfJe9ra2HTu6w6R0wwbAv1dYrVInKGFSSqmwhi8oA6pKJk0sEpZSNLVQ\\ns8yoSjWDzrCm0y3FcjbLxJFJ54hldCrTncn4wHs3nTAKywgu\/EsbaiN4YxSWEVwwCssILhiFZQQX\\njMIyggtGYRnBBaOwjOCCUVhGcOH\/AgAA\/\/+S+QX6OV9s5wAAAABJRU5ErkJggpQu\\n\",\"__pickled_extra_fields__\":[\"thumbnail\"]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "response_functions": [ "send_document(42, <>, caption=\"Here's your document with tumbnail! Run /start command again to restart.\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=<>, filename='deeppavlov_article.pdf')" ] diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index 06f603142..a3860c051 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,11 +1,11 @@ from asyncio import get_event_loop -from typing import Any, Hashable, List, Optional, Tuple, TypeAlias +from contextlib import contextmanager +from typing import Any, Hashable, Iterator, List, Optional, Tuple, TypeAlias from pydantic import BaseModel from telegram import Update from dff.messengers.telegram.abstract import _AbstractTelegramInterface -from dff.pipeline.types import PipelineRunnerFunction from dff.script import Message from dff.script.core.context import Context from dff.script.core.message import DataAttachment @@ -47,48 +47,51 @@ def create(cls, interface: _AbstractTelegramInterface, happy_path: List[PathStep instance = cls(bot=MockBot(), happy_path=happy_path, interface=interface) return instance - def _wrap_pipeline_runner(self, runner: PipelineRunnerFunction): + @contextmanager + def _check_context_and_trace(self, last_request: Message, last_response: Message, last_trace: List[str]) -> Iterator[None]: + self.bot.latest_trace = list() + self.latest_ctx = None + yield + assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" + assert self.latest_ctx.last_request == last_request, "Expected request message is not equal to expected!" + assert self.latest_ctx.last_response == last_response, "Expected response message is not equal to expected!" + assert self.bot.latest_trace == last_trace, "Expected trace is not equal to expected!" + + @contextmanager + def _wrap_pipeline_runner(self) -> Iterator[None]: + original_pipeline_runner = self.interface._pipeline_runner + async def wrapped_pipeline_runner( message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None ) -> Context: - self.latest_ctx = await runner(message, ctx_id, update_ctx_misc) + self.latest_ctx = await original_pipeline_runner(message, ctx_id, update_ctx_misc) return self.latest_ctx - wrapped_pipeline_runner.is_wrapped = True - wrapped_pipeline_runner.original = runner - return wrapped_pipeline_runner + self.interface._pipeline_runner = wrapped_pipeline_runner + yield + self.interface._pipeline_runner = original_pipeline_runner - def _wrap_populate_attachment(self, interface: _AbstractTelegramInterface): + @contextmanager + def _wrap_populate_attachment(self) -> Iterator[None]: async def wrapped_populate_attachment(_: DataAttachment) -> bytes: return bytes() - - wrapped_populate_attachment.is_wrapped = True - wrapped_populate_attachment.original = interface.populate_attachment - return wrapped_populate_attachment - def _run_bot(self) -> None: - if not getattr(self.interface.pipeline_runner, "is_wrapped", False): - self.interface.pipeline_runner = self._wrap_pipeline_runner(self.interface.pipeline_runner) - if not getattr(self.interface.populate_attachment, "is_wrapped", False): - self.interface.populate_attachment = self._wrap_populate_attachment(self.interface) + original_populate_attachment = self.interface.populate_attachment + self.interface.populate_attachment = wrapped_populate_attachment + yield + self.interface.populate_attachment = original_populate_attachment + def _run_bot(self) -> None: loop = get_event_loop() - for update, received, response, trace in self.happy_path: - if update.message is not None: - loop.run_until_complete(self.interface.on_message(update, None)) # type: ignore - elif update.callback_query is not None: - loop.run_until_complete(self.interface.on_callback(update, None)) # type: ignore - else: - raise RuntimeError(f"Update {update} type unknown!") - assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" - assert self.latest_ctx.last_request == received, "Expected request message is not equal to expected!" - assert self.latest_ctx.last_response == response, "Expected response message is not equal to expected!" - assert self.bot.latest_trace == trace, "Expected trace is not equal to expected!" - self.bot.latest_trace = list() - self.latest_ctx = None - - self.interface.pipeline_runner = self.interface.pipeline_runner.original - self.interface.populate_attachment = self.interface.populate_attachment.original + with self._wrap_pipeline_runner(), self._wrap_populate_attachment(): + for update, received, response, trace in self.happy_path: + with self._check_context_and_trace(received, response, trace): + if update.message is not None: + loop.run_until_complete(self.interface.on_message(update, None)) # type: ignore + elif update.callback_query is not None: + loop.run_until_complete(self.interface.on_callback(update, None)) # type: ignore + else: + raise RuntimeError(f"Update {update} type unknown!") def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: return self._run_bot() diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 9cd2f0e4a..3d0b74293 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -1,5 +1,6 @@ from pathlib import Path from shutil import rmtree +from tempfile import gettempdir from typing import Hashable, Optional, TextIO from urllib.request import urlopen @@ -27,7 +28,8 @@ Video, ) -EXAMPLE_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" +TEMP_PATH = Path(gettempdir()) / "dff_script_test" +EXAMPLE_SOURCE = "https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments" class DFFCLIMessengerInterface(CLIMessengerInterface): @@ -50,7 +52,7 @@ async def populate_attachment(self, attachment: DataAttachment) -> bytes: class TestMessage: @pytest.fixture def json_context_storage(self) -> DBContextStorage: - return JSONContextStorage(f"file://{Path(__file__).parent / 'serialization_database.json'}") + return JSONContextStorage(f"file://{TEMP_PATH / 'serialization_database.json'}") def clear_and_create_dir(self, dir: Path) -> Path: rmtree(dir, ignore_errors=True) @@ -129,11 +131,10 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta @pytest.mark.asyncio async def test_getting_attachment_bytes(self): - root_dir = Path(__file__).parent - local_path = self.clear_and_create_dir(root_dir / "local") + local_path = self.clear_and_create_dir(TEMP_PATH / "local") local_document = local_path / "pre-saved-document.pdf" - cli_iface = DFFCLIMessengerInterface(self.clear_and_create_dir(root_dir / "cache")) + cli_iface = DFFCLIMessengerInterface(self.clear_and_create_dir(TEMP_PATH / "cache")) document_name = "deeppavlov-article.pdf" remote_document_url = f"{EXAMPLE_SOURCE}/{document_name}" From 121b0925b1886b028368867a70a721cddb1d24d6 Mon Sep 17 00:00:00 2001 From: pseusys Date: Thu, 6 Jun 2024 00:52:11 +0200 Subject: [PATCH 108/140] additional `Message` serialization test introduced --- .gitignore | 3 --- tests/script/core/test_message.py | 39 +++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index bdba7af28..a6828357b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,3 @@ dbs benchmarks benchmark_results_files.json uploaded_benchmarks -tests/script/core/serialization_database.json -tests/script/core/cache/ -tests/script/core/local/ diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 3d0b74293..5a8179120 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -1,6 +1,6 @@ from pathlib import Path +from random import randint, randbytes from shutil import rmtree -from tempfile import gettempdir from typing import Hashable, Optional, TextIO from urllib.request import urlopen @@ -28,10 +28,21 @@ Video, ) -TEMP_PATH = Path(gettempdir()) / "dff_script_test" EXAMPLE_SOURCE = "https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments" +class UnserializableObject: + def __init__(self, number: int, string: bytes) -> None: + self.number = number + self.bytes = string + + def __eq__(self, value: object) -> bool: + if isinstance(value, UnserializableObject): + return self.number == value.number and self.bytes == value.bytes + else: + return False + + class DFFCLIMessengerInterface(CLIMessengerInterface): def __init__(self, attachments_directory: Optional[Path] = None): MessengerInterface.__init__(self, attachments_directory) @@ -51,8 +62,12 @@ async def populate_attachment(self, attachment: DataAttachment) -> bytes: class TestMessage: @pytest.fixture - def json_context_storage(self) -> DBContextStorage: - return JSONContextStorage(f"file://{TEMP_PATH / 'serialization_database.json'}") + def json_context_storage(self, tmp_path) -> DBContextStorage: + return JSONContextStorage(f"file://{tmp_path / 'serialization_database.json'}") + + @pytest.fixture + def random_original_message(self) -> UnserializableObject: + return UnserializableObject(randint(0, 256), randbytes(32)) def clear_and_create_dir(self, dir: Path) -> Path: rmtree(dir, ignore_errors=True) @@ -129,12 +144,22 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta retrieved = json_context_storage[name].requests[0].attachments[0] assert attachment == retrieved + def test_field_serializable(self, json_context_storage: DBContextStorage, random_original_message: UnserializableObject): + name = "serializable_test" + message = Message(text="sample message") + message.misc = {"answer": 42} + message.original_message = random_original_message + message.some_extra_field = {"unserializable": random_original_message} + json_context_storage[name] = Context(requests={0: message}) + retrieved = json_context_storage[name].requests[0] + assert message == retrieved + @pytest.mark.asyncio - async def test_getting_attachment_bytes(self): - local_path = self.clear_and_create_dir(TEMP_PATH / "local") + async def test_getting_attachment_bytes(self, tmp_path): + local_path = self.clear_and_create_dir(tmp_path / "local") local_document = local_path / "pre-saved-document.pdf" - cli_iface = DFFCLIMessengerInterface(self.clear_and_create_dir(TEMP_PATH / "cache")) + cli_iface = DFFCLIMessengerInterface(self.clear_and_create_dir(tmp_path / "cache")) document_name = "deeppavlov-article.pdf" remote_document_url = f"{EXAMPLE_SOURCE}/{document_name}" From 5172f0c4b8f6ae7fb977a95b52981df917b42f67 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 19:10:10 +0200 Subject: [PATCH 109/140] extra field verification added --- dff/messengers/telegram/abstract.py | 103 +++++--------------------- dff/utils/messengers/__init__.py | 1 + dff/utils/messengers/verify_params.py | 7 ++ dff/utils/pydantic/__init__.py | 56 +------------- dff/utils/pydantic/serializing.py | 55 ++++++++++++++ 5 files changed, 82 insertions(+), 140 deletions(-) create mode 100644 dff/utils/messengers/__init__.py create mode 100644 dff/utils/messengers/verify_params.py create mode 100644 dff/utils/pydantic/serializing.py diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 50c4742b6..a8ec3a898 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -8,6 +8,8 @@ from pathlib import Path from typing import Callable, Optional +from dff.utils.messengers.verify_params import generate_extra_fields + try: from telegram import ( InputMediaAnimation, @@ -206,10 +208,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, attachment.latitude, attachment.longitude, - horizontal_accuracy=attachment.__pydantic_extra__.get("horizontal_accuracy", None), - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + **generate_extra_fields(attachment, ["horizontal_accuracy", "disable_notification", "protect_content", "reply_markup"]), ) if isinstance(attachment, Contact): await bot.send_contact( @@ -217,36 +216,21 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes attachment.phone_number, attachment.first_name, attachment.last_name, - vcard=attachment.__pydantic_extra__.get("vcard", None), - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + **generate_extra_fields(attachment, ["vcard", "disable_notification", "protect_content", "reply_markup"]), ) if isinstance(attachment, Poll): await bot.send_poll( chat_id, attachment.question, [option.text for option in attachment.options], - is_anonymous=attachment.__pydantic_extra__.get("is_anonymous", None), - type=attachment.__pydantic_extra__.get("type", None), - allows_multiple_answers=attachment.__pydantic_extra__.get("allows_multiple_answers", None), - correct_option_id=attachment.__pydantic_extra__.get("correct_option_id", None), - explanation=attachment.__pydantic_extra__.get("explanation", None), - explanation_parse_mode=attachment.__pydantic_extra__.get("explanation_parse_mode", None), - open_period=attachment.__pydantic_extra__.get("open_period", None), - is_closed=attachment.__pydantic_extra__.get("is_closed", None), - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - protect_content=attachment.__pydantic_extra__.get("protect_content", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), + **generate_extra_fields(attachment, ["is_anonymous", "type", "allows_multiple_answers", "correct_option_id", "explanation", "explanation_parse_mode", "open_period", "is_closed", "disable_notification", "protect_content", "reply_markup"]), ) if isinstance(attachment, Sticker): sticker = await attachment.get_bytes(self) if attachment.id is None else attachment.id await bot.send_sticker( chat_id, sticker, - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - emoji=attachment.__pydantic_extra__.get("emoji", None), + **generate_extra_fields(attachment, ["disable_notification", "protect_content", "reply_markup"]), ) if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) @@ -255,25 +239,15 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes files += [ InputMediaAudio( attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - performer=attachment.__pydantic_extra__.get("performer", None), - title=attachment.__pydantic_extra__.get("title", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + **generate_extra_fields(attachment, ["filename", "caption", "parse_mode", "performer", "title", "thumbnail"]), ), ] else: await bot.send_audio( chat_id, audio=attachment_bytes, - performer=attachment.__pydantic_extra__.get("performer", None), - title=attachment.__pydantic_extra__.get("title", None), caption=message.text, - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + **generate_extra_fields(attachment, ["performer", "title", "disable_notification", "reply_markup", "parse_mode", "thumbnail"]), ) return if isinstance(attachment, Video): @@ -283,12 +257,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes files += [ InputMediaVideo( attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - supports_streaming=attachment.__pydantic_extra__.get("supports_streaming", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + **generate_extra_fields(attachment, ["filename", "caption", "parse_mode", "supports_streaming", "has_spoiler", "thumbnail"]), ), ] else: @@ -296,13 +265,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, attachment_bytes, caption=message.text, - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - supports_streaming=attachment.__pydantic_extra__.get("supports_streaming", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - filename=attachment.__pydantic_extra__.get("filename", None), + **generate_extra_fields(attachment, ["disable_notification", "reply_markup", "parse_mode", "supports_streaming", "has_spoiler", "thumbnail", "filename"]), ) return if isinstance(attachment, Animation): @@ -312,11 +275,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes files += [ InputMediaAnimation( attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + **generate_extra_fields(attachment, ["filename", "caption", "parse_mode", "has_spoiler", "thumbnail"]), ), ] else: @@ -324,12 +283,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, attachment_bytes, caption=message.text, - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - filename=attachment.__pydantic_extra__.get("filename", None), + **generate_extra_fields(attachment, ["parse_mode", "disable_notification", "reply_markup", "has_spoiler", "thumbnail", "filename"]), ) return if isinstance(attachment, Image): @@ -339,10 +293,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes files += [ InputMediaPhoto( attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), + **generate_extra_fields(attachment, ["filename", "caption", "parse_mode", "has_spoiler"]), ), ] else: @@ -350,11 +301,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, attachment_bytes, caption=message.text, - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - has_spoiler=attachment.__pydantic_extra__.get("has_spoiler", None), - filename=attachment.__pydantic_extra__.get("filename", None), + **generate_extra_fields(attachment, ["disable_notification", "reply_markup", "parse_mode", "has_spoiler", "filename"]), ) return if isinstance(attachment, Document): @@ -364,13 +311,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes files += [ InputMediaDocument( attachment_bytes, - filename=attachment.__pydantic_extra__.get("filename", None), - caption=attachment.__pydantic_extra__.get("caption", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - disable_content_type_detection=attachment.__pydantic_extra__.get( - "disable_content_type_detection", None - ), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), + **generate_extra_fields(attachment, ["filename", "caption", "parse_mode", "disable_content_type_detection", "thumbnail"]), ), ] else: @@ -378,30 +319,22 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, attachment_bytes, caption=message.text, - disable_notification=attachment.__pydantic_extra__.get("disable_notification", None), - reply_markup=attachment.__pydantic_extra__.get("reply_markup", None), - parse_mode=attachment.__pydantic_extra__.get("parse_mode", None), - thumbnail=attachment.__pydantic_extra__.get("thumbnail", None), - filename=attachment.__pydantic_extra__.get("filename", None), + **generate_extra_fields(attachment, ["disable_notification", "reply_markup", "parse_mode", "thumbnail", "filename"]), ) return if len(files) > 0: await bot.send_media_group( chat_id, files, - disable_notification=message.__pydantic_extra__.get("disable_notification", None), - protect_content=message.__pydantic_extra__.get("protect_content", None), caption=message.text, + **generate_extra_fields(attachment, ["disable_notification", "protect_content"]), ) return if message.text is not None: await bot.send_message( chat_id, message.text, - parse_mode=message.__pydantic_extra__.get("parse_mode", None), - disable_notification=message.__pydantic_extra__.get("disable_notification", None), - protect_content=message.__pydantic_extra__.get("protect_content", None), - reply_markup=message.__pydantic_extra__.get("reply_markup", None), + **generate_extra_fields(attachment, ["parse_mode", "disable_notification", "protect_content", "reply_markup"]), ) async def _on_event( diff --git a/dff/utils/messengers/__init__.py b/dff/utils/messengers/__init__.py new file mode 100644 index 000000000..09e683272 --- /dev/null +++ b/dff/utils/messengers/__init__.py @@ -0,0 +1 @@ +from .verify_params import generate_extra_fields diff --git a/dff/utils/messengers/verify_params.py b/dff/utils/messengers/verify_params.py new file mode 100644 index 000000000..34e8ad12c --- /dev/null +++ b/dff/utils/messengers/verify_params.py @@ -0,0 +1,7 @@ +from typing import List + +from pydantic import BaseModel + + +def generate_extra_fields(attachment: BaseModel, extra_fields: List[str]): + return {extra_field: attachment.__pydantic_extra__.get(extra_field, None) for extra_field in extra_fields} diff --git a/dff/utils/pydantic/__init__.py b/dff/utils/pydantic/__init__.py index 31bb68879..656538e90 100644 --- a/dff/utils/pydantic/__init__.py +++ b/dff/utils/pydantic/__init__.py @@ -1,55 +1 @@ -from base64 import decodebytes, encodebytes -from copy import deepcopy -from pickle import dumps, loads -from typing import Annotated, Any, Callable -from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer, WrapValidator - -_JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" - - -def pickle_serializer(value: Any) -> JsonValue: - return encodebytes(dumps(value)).decode() - - -def pickle_validator(value: JsonValue) -> Any: - return loads(decodebytes(value.encode())) - - -def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[JsonValue], JsonValue]) -> JsonValue: - extra_fields = list() - model_copy = deepcopy(model) - - for field_name, field_value in model_copy.items(): - try: - if isinstance(field_value, bytes): - raise PydanticSchemaGenerationError("") - else: - TypeAdapter(type(field_value)) - except PydanticSchemaGenerationError: - model_copy[field_name] = pickle_serializer(field_value) - extra_fields += [field_name] - - original_dump = original_serializer(model_copy) - original_dump[_JSON_EXTRA_FIELDS_KEYS] = extra_fields - return original_dump - - -def json_pickle_validator(model: JsonValue) -> JsonValue: - model_copy = deepcopy(model) - - if _JSON_EXTRA_FIELDS_KEYS in model.keys(): - for extra_key in model[_JSON_EXTRA_FIELDS_KEYS]: - extra_value = model[extra_key] - model_copy[extra_key] = pickle_validator(extra_value) - del model_copy[_JSON_EXTRA_FIELDS_KEYS] - - return model_copy - - -PickleSerializer = PlainSerializer(pickle_serializer, when_used="json") -PickleValidator = PlainValidator(pickle_validator) -SerializableVaue = Annotated[Any, PickleSerializer, PickleValidator] - -JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") -JSONPickleValidator = AfterValidator(json_pickle_validator) -JSONSerializableDict = Annotated[JsonValue, JSONPickleSerializer, JSONPickleValidator] +from .serializing import JSONSerializableDict, SerializableVaue, json_pickle_serializer, json_pickle_validator, pickle_serializer, pickle_validator diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py new file mode 100644 index 000000000..3d59a6718 --- /dev/null +++ b/dff/utils/pydantic/serializing.py @@ -0,0 +1,55 @@ +from base64 import decodebytes, encodebytes +from copy import deepcopy +from pickle import dumps, loads +from typing import Annotated, Any, Callable +from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer + +_JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" + + +def pickle_serializer(value: Any) -> JsonValue: + return encodebytes(dumps(value)).decode() + + +def pickle_validator(value: JsonValue) -> Any: + return loads(decodebytes(value.encode())) + + +def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[JsonValue], JsonValue]) -> JsonValue: + extra_fields = list() + model_copy = deepcopy(model) + + for field_name, field_value in model_copy.items(): + try: + if isinstance(field_value, bytes): + raise PydanticSchemaGenerationError("") + else: + TypeAdapter(type(field_value)) + except PydanticSchemaGenerationError: + model_copy[field_name] = pickle_serializer(field_value) + extra_fields += [field_name] + + original_dump = original_serializer(model_copy) + original_dump[_JSON_EXTRA_FIELDS_KEYS] = extra_fields + return original_dump + + +def json_pickle_validator(model: JsonValue) -> JsonValue: + model_copy = deepcopy(model) + + if _JSON_EXTRA_FIELDS_KEYS in model.keys(): + for extra_key in model[_JSON_EXTRA_FIELDS_KEYS]: + extra_value = model[extra_key] + model_copy[extra_key] = pickle_validator(extra_value) + del model_copy[_JSON_EXTRA_FIELDS_KEYS] + + return model_copy + + +PickleSerializer = PlainSerializer(pickle_serializer, when_used="json") +PickleValidator = PlainValidator(pickle_validator) +SerializableVaue = Annotated[Any, PickleSerializer, PickleValidator] + +JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") +JSONPickleValidator = AfterValidator(json_pickle_validator) +JSONSerializableDict = Annotated[JsonValue, JSONPickleSerializer, JSONPickleValidator] From 27205bb50fa08cb738638f6d4b5c45b0ea6610ad Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 19:21:36 +0200 Subject: [PATCH 110/140] github action fixes #1 --- dff/messengers/telegram/abstract.py | 4 ++-- tests/messengers/telegram/utils.py | 3 ++- tutorials/messengers/telegram/2_attachments.py | 2 +- tutorials/messengers/telegram/3_advanced.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index a8ec3a898..127c20816 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -327,14 +327,14 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes chat_id, files, caption=message.text, - **generate_extra_fields(attachment, ["disable_notification", "protect_content"]), + **generate_extra_fields(message, ["disable_notification", "protect_content"]), ) return if message.text is not None: await bot.send_message( chat_id, message.text, - **generate_extra_fields(attachment, ["parse_mode", "disable_notification", "protect_content", "reply_markup"]), + **generate_extra_fields(message, ["parse_mode", "disable_notification", "protect_content", "reply_markup"]), ) async def _on_event( diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index a3860c051..e7fb7ce71 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,9 +1,10 @@ from asyncio import get_event_loop from contextlib import contextmanager -from typing import Any, Hashable, Iterator, List, Optional, Tuple, TypeAlias +from typing import Any, Hashable, Iterator, List, Optional, Tuple from pydantic import BaseModel from telegram import Update +from typing_extensions import TypeAlias from dff.messengers.telegram.abstract import _AbstractTelegramInterface from dff.script import Message diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index d46ddfc87..f6a563ce0 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -48,7 +48,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %% -EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" +EXAMPLE_ATTACHMENT_SOURCE = "https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments" location_data = {"latitude": 50.65, "longitude": 3.916667} diff --git a/tutorials/messengers/telegram/3_advanced.py b/tutorials/messengers/telegram/3_advanced.py index 3ac2a61e9..9e121bba5 100644 --- a/tutorials/messengers/telegram/3_advanced.py +++ b/tutorials/messengers/telegram/3_advanced.py @@ -57,7 +57,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) # %% -EXAMPLE_ATTACHMENT_SOURCE = "https://cdn.jsdelivr.net/gh/deeppavlov/dialog_flow_framework@wiki/example-attachments" +EXAMPLE_ATTACHMENT_SOURCE = "https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments" image_url = HttpUrl(f"{EXAMPLE_ATTACHMENT_SOURCE}/deeppavlov.png") From 0de3e2b4cd6587ee337a8ab052a97b688d501771 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 20:37:14 +0200 Subject: [PATCH 111/140] github action fixes N2 --- dff/messengers/telegram/abstract.py | 2 +- tests/messengers/telegram/test_happy_paths.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dff/messengers/telegram/abstract.py b/dff/messengers/telegram/abstract.py index 127c20816..67714544a 100644 --- a/dff/messengers/telegram/abstract.py +++ b/dff/messengers/telegram/abstract.py @@ -230,7 +230,7 @@ async def cast_message_to_telegram_and_send(self, bot: ExtBot, chat_id: int, mes await bot.send_sticker( chat_id, sticker, - **generate_extra_fields(attachment, ["disable_notification", "protect_content", "reply_markup"]), + **generate_extra_fields(attachment, ["disable_notification", "protect_content", "reply_markup", "emoji"]), ) if isinstance(attachment, Audio): attachment_bytes = await attachment.get_bytes(self) diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index fb71a225d..30398bc9d 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -58,7 +58,7 @@ "received_message": "{\"text\":\"sticker\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_message": "{\"text\":\"Here's your sticker!\",\"commands\":null,\"attachments\":[{\"source\":null,\"cached_filename\":null,\"id\":\"CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE\",\"title\":\"A sticker I've just found\",\"use_cache\":true,\"dff_attachment_type\":\"sticker\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ - "send_sticker(42, 'CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE', disable_notification=None, reply_markup=None, emoji=None)", + "send_sticker(42, 'CAACAgIAAxkBAAErAAFXZibO5ksphCKSXSe1CYiw5588yqsAAkEAAzyKVxogmx2BPCogYDQE', disable_notification=None, protect_content=None, reply_markup=None, emoji=None)", "send_message(42, \"Here's your sticker!\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" ] }, @@ -67,7 +67,7 @@ "received_message": "{\"text\":\"audio\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ - "send_audio(42, audio=<>, performer=None, title=None, caption=\"Here's your audio!\", disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" + "send_audio(42, audio=<>, caption=\"Here's your audio!\", performer=None, title=None, disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" ] }, { @@ -142,7 +142,7 @@ "response_message": "{\"text\":\"Here's your message with multiple attachments (a location and a sticker)!\\nRun \/start command again to restart.\",\"commands\":null,\"attachments\":[{\"longitude\":30.3141,\"latitude\":59.9386,\"dff_attachment_type\":\"location\",\"__pickled_extra_fields__\":[]},{\"source\":null,\"cached_filename\":null,\"id\":\"CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE\",\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"sticker\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "response_functions": [ "send_location(42, 59.9386, 30.3141, horizontal_accuracy=None, disable_notification=None, protect_content=None, reply_markup=None)", - "send_sticker(42, 'CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE', disable_notification=None, reply_markup=None, emoji=None)", + "send_sticker(42, 'CAACAgIAAxkBAAErBZ1mKAbZvEOmhscojaIL5q0u8vgp1wACRygAAiSjCUtLa7RHZy76ezQE', disable_notification=None, protect_content=None, reply_markup=None, emoji=None)", "send_message(42, \"Here's your message with multiple attachments (a location and a sticker)!\\nRun /start command again to restart.\", parse_mode=None, disable_notification=None, protect_content=None, reply_markup=None)" ] }, From 83cb8a0b3fc8b93ddfb8af33394a8aef88b0a4cb Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 21:34:18 +0200 Subject: [PATCH 112/140] github action fixes N3 --- dff/utils/pydantic/serializing.py | 4 +++- tests/script/core/test_message.py | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py index 3d59a6718..c8701acbb 100644 --- a/dff/utils/pydantic/serializing.py +++ b/dff/utils/pydantic/serializing.py @@ -3,6 +3,7 @@ from pickle import dumps, loads from typing import Annotated, Any, Callable from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer +from pydantic_core import PydanticSerializationError _JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" @@ -25,7 +26,8 @@ def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[Json raise PydanticSchemaGenerationError("") else: TypeAdapter(type(field_value)) - except PydanticSchemaGenerationError: + model_copy[field_name] = original_serializer(field_value) + except (PydanticSchemaGenerationError, PydanticSerializationError): model_copy[field_name] = pickle_serializer(field_value) extra_fields += [field_name] diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 5a8179120..6f8192f04 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -88,18 +88,21 @@ def test_location(self): @pytest.mark.parametrize( "attachment1,attachment2,equal", [ + ( + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="Title"), + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="Title"), + True, + ), ( DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="File"), DataAttachment( source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="File" ), - True, + False, ), ( DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="1"), - DataAttachment( - source="https://raw.githubusercontent.com/mathiasbynens/small/master/pdf.pdf", title="2" - ), + DataAttachment(source="https://github.com/mathiasbynens/small/raw/master/pdf.pdf", title="2"), False, ), ( @@ -147,9 +150,10 @@ def test_attachment_serialize(self, json_context_storage: DBContextStorage, atta def test_field_serializable(self, json_context_storage: DBContextStorage, random_original_message: UnserializableObject): name = "serializable_test" message = Message(text="sample message") - message.misc = {"answer": 42} + message.misc = {"answer": 42, "unserializable": random_original_message} message.original_message = random_original_message - message.some_extra_field = {"unserializable": random_original_message} + message.some_extra_field = random_original_message + message.other_extra_field = {"unserializable": random_original_message} json_context_storage[name] = Context(requests={0: message}) retrieved = json_context_storage[name].requests[0] assert message == retrieved From 27678f56817b02dc99bb857adc6ea9c720c73afc Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 22:09:44 +0200 Subject: [PATCH 113/140] misc typing fixed --- tests/script/conditions/test_conditions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/script/conditions/test_conditions.py b/tests/script/conditions/test_conditions.py index ab85df16a..de69edb6e 100644 --- a/tests/script/conditions/test_conditions.py +++ b/tests/script/conditions/test_conditions.py @@ -16,7 +16,7 @@ def test_conditions(): assert cnd.exact_match(Message("text"))(ctx, pipeline) assert cnd.exact_match(Message("text", misc={}))(ctx, pipeline) - assert not cnd.exact_match(Message("text", misc={1: 1}))(ctx, pipeline) + assert not cnd.exact_match(Message("text", misc={"one": 1}))(ctx, pipeline) assert not cnd.exact_match(Message("text1"))(ctx, pipeline) assert cnd.exact_match(Message())(ctx, pipeline) assert not cnd.exact_match(Message(), skip_none=False)(ctx, pipeline) From f88e4541d395ce82ee3739ecc31fb125969bf51e Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 22:48:49 +0200 Subject: [PATCH 114/140] Attachment name changed (for windows) --- tutorials/messengers/telegram/2_attachments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/messengers/telegram/2_attachments.py b/tutorials/messengers/telegram/2_attachments.py index f6a563ce0..05383b9b3 100644 --- a/tutorials/messengers/telegram/2_attachments.py +++ b/tutorials/messengers/telegram/2_attachments.py @@ -67,7 +67,7 @@ class and [python-telegram-bot](https://docs.python-telegram-bot.org/) "source": HttpUrl( f"{EXAMPLE_ATTACHMENT_SOURCE}/separation-william-king.mp3" ), - "title": '"Separation" melody by William King', + "title": "Separation melody by William King", } video_data = { From 85487c3671255ef956150ae572aec0da27743f3e Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 22:49:56 +0200 Subject: [PATCH 115/140] typing.Annotated fixed --- dff/utils/pydantic/serializing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py index c8701acbb..31ec1a434 100644 --- a/dff/utils/pydantic/serializing.py +++ b/dff/utils/pydantic/serializing.py @@ -1,7 +1,8 @@ from base64 import decodebytes, encodebytes from copy import deepcopy from pickle import dumps, loads -from typing import Annotated, Any, Callable +from typing import Any, Callable +from typing_extensions import Annotated from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer from pydantic_core import PydanticSerializationError From e634436d25f660a6a057eb1d72cc0dc24822fa09 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 22:56:40 +0200 Subject: [PATCH 116/140] Naming fixed once again --- tests/messengers/telegram/test_happy_paths.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/telegram/test_happy_paths.json b/tests/messengers/telegram/test_happy_paths.json index 30398bc9d..bf493d163 100644 --- a/tests/messengers/telegram/test_happy_paths.json +++ b/tests/messengers/telegram/test_happy_paths.json @@ -65,7 +65,7 @@ { "update": "Update(message=Message(channel_chat_created=False, chat=Chat(first_name='Test', id=42, last_name='User', type=ChatType.PRIVATE, username='test_user'), date=datetime.datetime(2024, 5, 15, 19, 0, 46, tzinfo=UTC), delete_chat_photo=False, from_user=User(first_name='Test', id=42, is_bot=False, language_code='en', last_name='User', username='test_user'), group_chat_created=False, message_id=6, supergroup_chat_created=False, text='audio'), update_id=6)", "received_message": "{\"text\":\"audio\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"\\\"Separation\\\" melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_message": "{\"text\":\"Here's your audio!\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/separation-william-king.mp3\",\"cached_filename\":null,\"id\":null,\"title\":\"Separation melody by William King\",\"use_cache\":true,\"dff_attachment_type\":\"audio\"}],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_functions": [ "send_audio(42, audio=<>, caption=\"Here's your audio!\", performer=None, title=None, disable_notification=None, reply_markup=None, parse_mode=None, thumbnail=None)" ] From 5ca6e20385726aecc2b0fe17980ee498a6f08e2c Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 23:09:49 +0200 Subject: [PATCH 117/140] telegram import in tests fixed --- tests/messengers/telegram/utils.py | 8 +++++--- tests/script/core/test_message.py | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index e7fb7ce71..1ae22404d 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,9 +1,8 @@ from asyncio import get_event_loop from contextlib import contextmanager -from typing import Any, Hashable, Iterator, List, Optional, Tuple +from typing import TYPE_CHECKING, Any, Hashable, Iterator, List, Optional, Tuple from pydantic import BaseModel -from telegram import Update from typing_extensions import TypeAlias from dff.messengers.telegram.abstract import _AbstractTelegramInterface @@ -11,7 +10,10 @@ from dff.script.core.context import Context from dff.script.core.message import DataAttachment -PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] +if TYPE_CHECKING: + from telegram import Update + + PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] class MockBot(BaseModel, arbitrary_types_allowed=True): diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 6f8192f04..379b1b35b 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -1,5 +1,6 @@ +from os import urandom from pathlib import Path -from random import randint, randbytes +from random import randint from shutil import rmtree from typing import Hashable, Optional, TextIO from urllib.request import urlopen @@ -67,7 +68,7 @@ def json_context_storage(self, tmp_path) -> DBContextStorage: @pytest.fixture def random_original_message(self) -> UnserializableObject: - return UnserializableObject(randint(0, 256), randbytes(32)) + return UnserializableObject(randint(0, 256), urandom(32)) def clear_and_create_dir(self, dir: Path) -> Path: rmtree(dir, ignore_errors=True) From 209d9751227d62cf892b59a459b5651ade13cca8 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 23:24:22 +0200 Subject: [PATCH 118/140] telegram import fix (again) --- tests/messengers/telegram/test_tutorials.py | 8 ++++++-- tests/messengers/telegram/utils.py | 8 +++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index bac4bc038..6820f6d42 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -1,14 +1,16 @@ from importlib import import_module from json import loads from pathlib import Path -from typing import Dict, List +from typing import TYPE_CHECKING, Dict, List import pytest from dff.script.core.message import Message -from tests.messengers.telegram.utils import MockApplication, PathStep from tests.test_utils import get_path_from_tests_to_current_dir +if TYPE_CHECKING: + from tests.messengers.telegram.utils import PathStep + dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") happy_paths_file = Path(__file__).parent / "test_happy_paths.json" @@ -36,6 +38,8 @@ def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: ["1_basic", "2_attachments", "3_advanced"], ) def test_tutorials_memory(tutorial_module_name: str): + from tests.messengers.telegram.utils import MockApplication + happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] happy_path_steps = _cast_dict_to_happy_step(happy_path_data) module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index 1ae22404d..e7fb7ce71 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,8 +1,9 @@ from asyncio import get_event_loop from contextlib import contextmanager -from typing import TYPE_CHECKING, Any, Hashable, Iterator, List, Optional, Tuple +from typing import Any, Hashable, Iterator, List, Optional, Tuple from pydantic import BaseModel +from telegram import Update from typing_extensions import TypeAlias from dff.messengers.telegram.abstract import _AbstractTelegramInterface @@ -10,10 +11,7 @@ from dff.script.core.context import Context from dff.script.core.message import DataAttachment -if TYPE_CHECKING: - from telegram import Update - - PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] +PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] class MockBot(BaseModel, arbitrary_types_allowed=True): From 2f6781638d6f99337223c5decc1e6d8d4e291bd5 Mon Sep 17 00:00:00 2001 From: pseusys Date: Fri, 7 Jun 2024 23:27:23 +0200 Subject: [PATCH 119/140] PathStep quotes added --- tests/messengers/telegram/test_tutorials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index 6820f6d42..f815907f9 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -15,7 +15,7 @@ happy_paths_file = Path(__file__).parent / "test_happy_paths.json" -def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: +def _cast_dict_to_happy_step(dict: Dict) -> List["PathStep"]: imports = globals().copy() imports.update(import_module("telegram").__dict__) imports.update(import_module("telegram.ext").__dict__) From b61c42d00fad1bbb003feeb51fa6102cb5882447 Mon Sep 17 00:00:00 2001 From: pseusys Date: Sat, 8 Jun 2024 03:05:38 +0200 Subject: [PATCH 120/140] aiofiles dependency fixed --- tests/script/core/test_message.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/tests/script/core/test_message.py b/tests/script/core/test_message.py index 379b1b35b..2b4c66601 100644 --- a/tests/script/core/test_message.py +++ b/tests/script/core/test_message.py @@ -8,10 +8,8 @@ import pytest from pydantic import ValidationError, HttpUrl, FilePath -from dff.context_storages import DBContextStorage, JSONContextStorage from dff.messengers.common.interface import MessengerInterface from dff.messengers.console import CLIMessengerInterface -from dff.script.core.context import Context from dff.script.core.message import ( Animation, Audio, @@ -62,10 +60,6 @@ async def populate_attachment(self, attachment: DataAttachment) -> bytes: class TestMessage: - @pytest.fixture - def json_context_storage(self, tmp_path) -> DBContextStorage: - return JSONContextStorage(f"file://{tmp_path / 'serialization_database.json'}") - @pytest.fixture def random_original_message(self) -> UnserializableObject: return UnserializableObject(randint(0, 256), urandom(32)) @@ -142,22 +136,21 @@ def test_attachment_equal(self, attachment1: DataAttachment, attachment2: DataAt Document(source="https://example.com/some_document.pdf"), ], ) - def test_attachment_serialize(self, json_context_storage: DBContextStorage, attachment: DataAttachment): - name = type(attachment).__name__ - json_context_storage[name] = Context(requests={0: Message(attachments=[attachment])}) - retrieved = json_context_storage[name].requests[0].attachments[0] - assert attachment == retrieved - - def test_field_serializable(self, json_context_storage: DBContextStorage, random_original_message: UnserializableObject): - name = "serializable_test" + def test_attachment_serialize(self, attachment: DataAttachment): + message = Message(attachments=[attachment]) + serialized = message.model_dump_json() + validated = Message.model_validate_json(serialized) + assert message == validated + + def test_field_serializable(self, random_original_message: UnserializableObject): message = Message(text="sample message") message.misc = {"answer": 42, "unserializable": random_original_message} message.original_message = random_original_message message.some_extra_field = random_original_message message.other_extra_field = {"unserializable": random_original_message} - json_context_storage[name] = Context(requests={0: message}) - retrieved = json_context_storage[name].requests[0] - assert message == retrieved + serialized = message.model_dump_json() + validated = Message.model_validate_json(serialized) + assert message == validated @pytest.mark.asyncio async def test_getting_attachment_bytes(self, tmp_path): From cc5772ee4220378ed5f44bc101452b1feef478b8 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 10 Jun 2024 00:24:23 +0200 Subject: [PATCH 121/140] typing fixed --- dff/utils/pydantic/serializing.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py index 31ec1a434..17306e1bb 100644 --- a/dff/utils/pydantic/serializing.py +++ b/dff/utils/pydantic/serializing.py @@ -1,13 +1,15 @@ from base64 import decodebytes, encodebytes from copy import deepcopy from pickle import dumps, loads -from typing import Any, Callable -from typing_extensions import Annotated -from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer +from typing import Any, Callable, Dict, List, Union +from typing_extensions import Annotated, TypeAlias +from pydantic import AfterValidator, BaseModel, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer from pydantic_core import PydanticSerializationError _JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" +Serializable: TypeAlias = Dict[str, Union[JsonValue, BaseModel, List[BaseModel], Dict[str, BaseModel]]] + def pickle_serializer(value: Any) -> JsonValue: return encodebytes(dumps(value)).decode() @@ -17,7 +19,7 @@ def pickle_validator(value: JsonValue) -> Any: return loads(decodebytes(value.encode())) -def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[JsonValue], JsonValue]) -> JsonValue: +def json_pickle_serializer(model: Serializable, original_serializer: Callable[[Serializable], Serializable]) -> Serializable: extra_fields = list() model_copy = deepcopy(model) @@ -37,7 +39,7 @@ def json_pickle_serializer(model: JsonValue, original_serializer: Callable[[Json return original_dump -def json_pickle_validator(model: JsonValue) -> JsonValue: +def json_pickle_validator(model: SerialDict) -> SerialDict: model_copy = deepcopy(model) if _JSON_EXTRA_FIELDS_KEYS in model.keys(): @@ -55,4 +57,4 @@ def json_pickle_validator(model: JsonValue) -> JsonValue: JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") JSONPickleValidator = AfterValidator(json_pickle_validator) -JSONSerializableDict = Annotated[JsonValue, JSONPickleSerializer, JSONPickleValidator] +JSONSerializableDict = Annotated[SerialDict, JSONPickleSerializer, JSONPickleValidator] From ae35fb9601fea947fcc90de7ca395e99044fab74 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 10 Jun 2024 02:27:43 +0200 Subject: [PATCH 122/140] naming error fixed --- dff/utils/pydantic/serializing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py index 17306e1bb..507aef46b 100644 --- a/dff/utils/pydantic/serializing.py +++ b/dff/utils/pydantic/serializing.py @@ -39,7 +39,7 @@ def json_pickle_serializer(model: Serializable, original_serializer: Callable[[S return original_dump -def json_pickle_validator(model: SerialDict) -> SerialDict: +def json_pickle_validator(model: Serializable) -> Serializable: model_copy = deepcopy(model) if _JSON_EXTRA_FIELDS_KEYS in model.keys(): @@ -57,4 +57,4 @@ def json_pickle_validator(model: SerialDict) -> SerialDict: JSONPickleSerializer = WrapSerializer(json_pickle_serializer, when_used="json") JSONPickleValidator = AfterValidator(json_pickle_validator) -JSONSerializableDict = Annotated[SerialDict, JSONPickleSerializer, JSONPickleValidator] +JSONSerializableDict = Annotated[Serializable, JSONPickleSerializer, JSONPickleValidator] From a1df33f32e293aed41b99686eae75dc47db0f9c3 Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 10 Jun 2024 02:50:32 +0200 Subject: [PATCH 123/140] ok, we'll just use any I guess --- dff/utils/pydantic/serializing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dff/utils/pydantic/serializing.py b/dff/utils/pydantic/serializing.py index 507aef46b..cecc2bb41 100644 --- a/dff/utils/pydantic/serializing.py +++ b/dff/utils/pydantic/serializing.py @@ -3,12 +3,12 @@ from pickle import dumps, loads from typing import Any, Callable, Dict, List, Union from typing_extensions import Annotated, TypeAlias -from pydantic import AfterValidator, BaseModel, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer +from pydantic import AfterValidator, JsonValue, PlainSerializer, PlainValidator, PydanticSchemaGenerationError, TypeAdapter, WrapSerializer from pydantic_core import PydanticSerializationError _JSON_EXTRA_FIELDS_KEYS = "__pickled_extra_fields__" -Serializable: TypeAlias = Dict[str, Union[JsonValue, BaseModel, List[BaseModel], Dict[str, BaseModel]]] +Serializable: TypeAlias = Dict[str, Union[JsonValue, Any, List[Any], Dict[str, Any]]] def pickle_serializer(value: Any) -> JsonValue: From d6fbaafa230c534d46832b53a2b73f5c1c83e94d Mon Sep 17 00:00:00 2001 From: pseusys Date: Mon, 10 Jun 2024 03:09:25 +0200 Subject: [PATCH 124/140] telegram skip setup correctly --- dff/messengers/telegram/__init__.py | 1 + tests/messengers/telegram/test_tutorials.py | 28 ++++----------------- tests/messengers/telegram/utils.py | 19 +++++++++++++- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/dff/messengers/telegram/__init__.py b/dff/messengers/telegram/__init__.py index 68ea21beb..88c0bf3f9 100644 --- a/dff/messengers/telegram/__init__.py +++ b/dff/messengers/telegram/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- +from .abstract import telegram_available from .interface import PollingTelegramInterface, CallbackTelegramInterface diff --git a/tests/messengers/telegram/test_tutorials.py b/tests/messengers/telegram/test_tutorials.py index f815907f9..9d90a139d 100644 --- a/tests/messengers/telegram/test_tutorials.py +++ b/tests/messengers/telegram/test_tutorials.py @@ -1,36 +1,20 @@ from importlib import import_module from json import loads from pathlib import Path -from typing import TYPE_CHECKING, Dict, List import pytest -from dff.script.core.message import Message +from dff.messengers.telegram import telegram_available from tests.test_utils import get_path_from_tests_to_current_dir -if TYPE_CHECKING: - from tests.messengers.telegram.utils import PathStep +if telegram_available: + from tests.messengers.telegram.utils import cast_dict_to_happy_step, MockApplication dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") happy_paths_file = Path(__file__).parent / "test_happy_paths.json" -def _cast_dict_to_happy_step(dict: Dict) -> List["PathStep"]: - imports = globals().copy() - imports.update(import_module("telegram").__dict__) - imports.update(import_module("telegram.ext").__dict__) - imports.update(import_module("telegram.constants").__dict__) - - path_steps = list() - for step in dict: - update = eval(step["update"], imports) - received = Message.model_validate_json(step["received_message"]) - received.original_message = update - response = Message.model_validate_json(step["response_message"]) - path_steps += [(update, received, response, step["response_functions"])] - return path_steps - - +@pytest.mark.skipif(not telegram_available, reason="Telegram dependencies missing") @pytest.mark.telegram @pytest.mark.asyncio @pytest.mark.parametrize( @@ -38,10 +22,8 @@ def _cast_dict_to_happy_step(dict: Dict) -> List["PathStep"]: ["1_basic", "2_attachments", "3_advanced"], ) def test_tutorials_memory(tutorial_module_name: str): - from tests.messengers.telegram.utils import MockApplication - happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] - happy_path_steps = _cast_dict_to_happy_step(happy_path_data) + happy_path_steps = cast_dict_to_happy_step(happy_path_data) module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") module.interface.application = MockApplication.create(module.interface, happy_path_steps) module.pipeline.run() diff --git a/tests/messengers/telegram/utils.py b/tests/messengers/telegram/utils.py index e7fb7ce71..31fe24d37 100644 --- a/tests/messengers/telegram/utils.py +++ b/tests/messengers/telegram/utils.py @@ -1,6 +1,7 @@ from asyncio import get_event_loop from contextlib import contextmanager -from typing import Any, Hashable, Iterator, List, Optional, Tuple +from importlib import import_module +from typing import Any, Dict, Hashable, Iterator, List, Optional, Tuple from pydantic import BaseModel from telegram import Update @@ -14,6 +15,22 @@ PathStep: TypeAlias = Tuple[Update, Message, Message, List[str]] +def cast_dict_to_happy_step(dict: Dict) -> List["PathStep"]: + imports = globals().copy() + imports.update(import_module("telegram").__dict__) + imports.update(import_module("telegram.ext").__dict__) + imports.update(import_module("telegram.constants").__dict__) + + path_steps = list() + for step in dict: + update = eval(step["update"], imports) + received = Message.model_validate_json(step["received_message"]) + received.original_message = update + response = Message.model_validate_json(step["response_message"]) + path_steps += [(update, received, response, step["response_functions"])] + return path_steps + + class MockBot(BaseModel, arbitrary_types_allowed=True): latest_trace: List[str] = list() From eb74d0ae2d1f1725b77f62c8e3a42c47849c0508 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 <59259188+NotBioWaste905@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:51:32 +0300 Subject: [PATCH 125/140] Add files via upload --- tests/messengers/vk/test_tutorial.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/messengers/vk/test_tutorial.json diff --git a/tests/messengers/vk/test_tutorial.json b/tests/messengers/vk/test_tutorial.json new file mode 100644 index 000000000..d68a09486 --- /dev/null +++ b/tests/messengers/vk/test_tutorial.json @@ -0,0 +1,8 @@ +{ + "1_basic": { + "update": {"ts": "300", "updates": [{"group_id": 224377718, "type": "message_new", "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", "v": "5.199", "object": {"message": {"date": 1718015647, "from_id": 355442652, "id": 388, "out": 0, "version": 10000792, "attachments": [], "conversation_message_id": 388, "fwd_messages": [], "important": false, "is_hidden": false, "peer_id": 355442652, "random_id": 0, "text": "Hello"}, "client_info": {"button_actions": ["text", "vkpay", "open_app", "location", "open_link", "callback", "intent_subscribe", "intent_unsubscribe"], "keyboard": true, "inline_keyboard": true, "carousel": true, "lang_id": 0}}}]}, + "received_message": "{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_request": "https://api.vk.com/method/messages.send?user_id=355442652&random_id=0&message=Hi&v=5.81&access_token=token" + } +} \ No newline at end of file From c9231ff1771c4820605eb08973010187d0678331 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 17:20:36 +0300 Subject: [PATCH 126/140] Fixes in testing --- tests/messengers/vk/test_outgoing.py | 0 tests/messengers/vk/test_tutorial.json | 8 ++++ tests/messengers/vk/test_tutorials.py | 14 +++---- .../vk/{test_incoming.py => test_vk.py} | 40 +++++++++---------- 4 files changed, 35 insertions(+), 27 deletions(-) delete mode 100644 tests/messengers/vk/test_outgoing.py create mode 100644 tests/messengers/vk/test_tutorial.json rename tests/messengers/vk/{test_incoming.py => test_vk.py} (66%) diff --git a/tests/messengers/vk/test_outgoing.py b/tests/messengers/vk/test_outgoing.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/messengers/vk/test_tutorial.json b/tests/messengers/vk/test_tutorial.json new file mode 100644 index 000000000..d68a09486 --- /dev/null +++ b/tests/messengers/vk/test_tutorial.json @@ -0,0 +1,8 @@ +{ + "1_basic": { + "update": {"ts": "300", "updates": [{"group_id": 224377718, "type": "message_new", "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", "v": "5.199", "object": {"message": {"date": 1718015647, "from_id": 355442652, "id": 388, "out": 0, "version": 10000792, "attachments": [], "conversation_message_id": 388, "fwd_messages": [], "important": false, "is_hidden": false, "peer_id": 355442652, "random_id": 0, "text": "Hello"}, "client_info": {"button_actions": ["text", "vkpay", "open_app", "location", "open_link", "callback", "intent_subscribe", "intent_unsubscribe"], "keyboard": true, "inline_keyboard": true, "carousel": true, "lang_id": 0}}}]}, + "received_message": "{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "response_request": "https://api.vk.com/method/messages.send?user_id=355442652&random_id=0&message=Hi&v=5.81&access_token=token" + } +} \ No newline at end of file diff --git a/tests/messengers/vk/test_tutorials.py b/tests/messengers/vk/test_tutorials.py index 8cc76552a..84b4568ee 100644 --- a/tests/messengers/vk/test_tutorials.py +++ b/tests/messengers/vk/test_tutorials.py @@ -6,30 +6,30 @@ import pytest from dff.script.core.message import Message -from tests.messengers.vk.mock_bot import MockApplication, PathStep +from mock_bot import MockApplication, PathStep from tests.test_utils import get_path_from_tests_to_current_dir dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") -happy_paths_file = Path(__file__).parent / "incoming_data.json" +happy_paths_file = Path(__file__).parent / "test_tutorial.json" def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: imports = globals().copy() - imports.update(import_module("vk_api").__dict__) + # imports.update(import_module("vk_api").__dict__) path_steps = list() for step in dict: - update = eval(step["update"], imports) + update = step["update"] received = Message.model_validate_json(step["received_message"]) received.original_message = update - response = Message.model_validate_json(step["response_message"]) - path_steps += [(update, received, response, step["response_functions"])] + response = Message.model_validate_json(step["response"]) + path_steps += [(update, received, response, step["response_request"])] return path_steps @pytest.mark.vk @pytest.mark.asyncio @pytest.mark.parametrize( "tutorial_module_name", - ["1_basic", "2_attachments"], + ["1_basic"], ) def test_tutorials_vk_memory(tutorial_module_name: str): happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] diff --git a/tests/messengers/vk/test_incoming.py b/tests/messengers/vk/test_vk.py similarity index 66% rename from tests/messengers/vk/test_incoming.py rename to tests/messengers/vk/test_vk.py index a6fb42111..ef3405ad9 100644 --- a/tests/messengers/vk/test_incoming.py +++ b/tests/messengers/vk/test_vk.py @@ -12,24 +12,8 @@ def patch_interface(): # custom class to be the mock return value # will override the requests.Response returned from requests.get -class MockResponse: - # mock json() method always returns a specific testing dictionary - @staticmethod - def json(): - return {"mock_key": "mock_response"} - - def test_post(monkeypatch): - # Any arguments may be passed and mock_get() will always return our - # mocked object, which only has the .json() method. def dummy_post(request_method: str, *args, **kwargs): - """Function for logging POST requests that will override original `requests.post` method. - Will return dummy objects for requests that require response. - - Args: - request (_str_): method to request - data (_dict_): data to post - """ print((request_method, args, kwargs)) if "getMessagesUploadServer" in request_method: return {"response": {"upload_url": "https://dummy_url"}} @@ -40,14 +24,30 @@ def dummy_post(request_method: str, *args, **kwargs): monkeypatch.setattr(requests, "post", dummy_post) - # app.get_json, which contains requests.get, uses the monkeypatch - # result = app.get_json("https://fakeurl") - # assert result["mock_key"] == "mock_response" - iface = PollingVKInterface(token="", group_id="") iface._respond(Message(text="test")) +def test_data_parsing(patch_interface): + with open("test_tutorial.json") as f: + incoming_data = json.load(f) + + for test_case, data in incoming_data.items(): + update = data["update"] + received_message = json.loads(data["received_message"]) + expected_message = Message( + text=received_message["text"], + commands=received_message["commands"], + attachments=received_message["attachments"], + annotations=received_message["annotations"], + misc=received_message["misc"], + original_message=received_message["original_message"] + ) + + parsed_message = patch_interface._request(update) + + assert parsed_message == expected_message + # with open("incoming_data.json") as f: # incoming_data = json.load(f) From e12fbb43560bd058a0006ccfd907444396420dbc Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 17:27:19 +0300 Subject: [PATCH 127/140] Test old testing version --- tests/messengers/vk/test_tutorials.py | 66 +++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/messengers/vk/test_tutorials.py b/tests/messengers/vk/test_tutorials.py index 84b4568ee..41d34aeaa 100644 --- a/tests/messengers/vk/test_tutorials.py +++ b/tests/messengers/vk/test_tutorials.py @@ -1,39 +1,39 @@ -from importlib import import_module -from json import loads -from pathlib import Path -from typing import Dict, List +# from importlib import import_module +# from json import loads +# from pathlib import Path +# from typing import Dict, List -import pytest +# import pytest -from dff.script.core.message import Message -from mock_bot import MockApplication, PathStep -from tests.test_utils import get_path_from_tests_to_current_dir +# from dff.script.core.message import Message +# from mock_bot import MockApplication, PathStep +# from tests.test_utils import get_path_from_tests_to_current_dir -dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") -happy_paths_file = Path(__file__).parent / "test_tutorial.json" +# dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") +# happy_paths_file = Path(__file__).parent / "test_tutorial.json" -def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: - imports = globals().copy() - # imports.update(import_module("vk_api").__dict__) +# def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: +# imports = globals().copy() +# # imports.update(import_module("vk_api").__dict__) - path_steps = list() - for step in dict: - update = step["update"] - received = Message.model_validate_json(step["received_message"]) - received.original_message = update - response = Message.model_validate_json(step["response"]) - path_steps += [(update, received, response, step["response_request"])] - return path_steps +# path_steps = list() +# for step in dict: +# update = step["update"] +# received = Message.model_validate_json(step["received_message"]) +# received.original_message = update +# response = Message.model_validate_json(step["response"]) +# path_steps += [(update, received, response, step["response_request"])] +# return path_steps -@pytest.mark.vk -@pytest.mark.asyncio -@pytest.mark.parametrize( - "tutorial_module_name", - ["1_basic"], -) -def test_tutorials_vk_memory(tutorial_module_name: str): - happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] - happy_path_steps = _cast_dict_to_happy_step(happy_path_data) - module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") - module.interface.application = MockApplication.create(module.interface, happy_path_steps) - module.pipeline.run() +# @pytest.mark.vk +# @pytest.mark.asyncio +# @pytest.mark.parametrize( +# "tutorial_module_name", +# ["1_basic"], +# ) +# def test_tutorials_vk_memory(tutorial_module_name: str): +# happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] +# happy_path_steps = _cast_dict_to_happy_step(happy_path_data) +# module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") +# module.interface.application = MockApplication.create(module.interface, happy_path_steps) +# module.pipeline.run() From c091dd1228846e4f18c6e85428fde72592684742 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 17:50:54 +0300 Subject: [PATCH 128/140] Fixed path to test data --- tests/messengers/vk/test_vk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index ef3405ad9..086682336 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -29,7 +29,7 @@ def dummy_post(request_method: str, *args, **kwargs): def test_data_parsing(patch_interface): - with open("test_tutorial.json") as f: + with open("./test_tutorial.json") as f: incoming_data = json.load(f) for test_case, data in incoming_data.items(): From 7c1a9e49c078ccbbe70cef47605e9e9898c32933 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 18:37:15 +0300 Subject: [PATCH 129/140] Merged woth TG + fixed fixed path to test files --- tests/messengers/vk/test_vk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 086682336..606425a94 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -1,6 +1,7 @@ import pytest import requests import json +import pathlib from dff.script import Message from dff.messengers.vk import PollingVKInterface @@ -29,7 +30,7 @@ def dummy_post(request_method: str, *args, **kwargs): def test_data_parsing(patch_interface): - with open("./test_tutorial.json") as f: + with open( pathlib.Path(__file__).parent + "/test_tutorial.json") as f: incoming_data = json.load(f) for test_case, data in incoming_data.items(): From df6a99e8521da5e309f3bff1a3a6c0591f50a566 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 18:42:31 +0300 Subject: [PATCH 130/140] Quickfix --- tests/messengers/vk/test_vk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 606425a94..484662613 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -30,7 +30,7 @@ def dummy_post(request_method: str, *args, **kwargs): def test_data_parsing(patch_interface): - with open( pathlib.Path(__file__).parent + "/test_tutorial.json") as f: + with open( pathlib.Path(__file__).parent / "/test_tutorial.json") as f: incoming_data = json.load(f) for test_case, data in incoming_data.items(): From 964c9e92c34f70fb2f417c46067fb518133a2282 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 19:39:08 +0300 Subject: [PATCH 131/140] Fixed path --- pyproject.toml | 2 ++ tests/messengers/vk/test_vk.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3c4bde2ba..800799dd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ pandas = { version = "*", optional = true } altair = { version = "*", optional = true } asyncmy = { version = "*", optional = true } asyncpg = { version = "*", optional = true } +aiohttp = { version = "*", optional = true } pympler = { version = "*", optional = true } aiofiles = { version = "*", optional = true } humanize = { version = "*", optional = true } @@ -90,6 +91,7 @@ ydb = ["ydb", "six"] telegram = ["python-telegram-bot"] stats = ["opentelemetry-exporter-otlp", "opentelemetry-instrumentation", "requests", "tqdm", "omegaconf"] benchmark = ["pympler", "humanize", "pandas", "altair", "tqdm"] +vk = ["aiohttp"] [tool.poetry.group.lint] diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 484662613..b50a86d7c 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -30,7 +30,7 @@ def dummy_post(request_method: str, *args, **kwargs): def test_data_parsing(patch_interface): - with open( pathlib.Path(__file__).parent / "/test_tutorial.json") as f: + with open( pathlib.Path(__file__).parent / "test_tutorial.json") as f: incoming_data = json.load(f) for test_case, data in incoming_data.items(): @@ -46,7 +46,7 @@ def test_data_parsing(patch_interface): ) parsed_message = patch_interface._request(update) - + assert parsed_message == expected_message # with open("incoming_data.json") as f: From b74152d0328fa2e291d3e40da8336ca9c07d265f Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 19:44:34 +0300 Subject: [PATCH 132/140] Retracted pyproject edit --- tests/messengers/vk/aaa.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/messengers/vk/aaa.py diff --git a/tests/messengers/vk/aaa.py b/tests/messengers/vk/aaa.py new file mode 100644 index 000000000..d2c870846 --- /dev/null +++ b/tests/messengers/vk/aaa.py @@ -0,0 +1,2 @@ +import pathlib +print(pathlib.Path(__file__).parent / "test_tutorial.json") From a1af7192f793b486d46afa9f5966ee745d556eca Mon Sep 17 00:00:00 2001 From: askatasuna Date: Thu, 13 Jun 2024 19:49:03 +0300 Subject: [PATCH 133/140] Retracted pyproject to previous version (for real) --- pyproject.toml | 2 -- tests/messengers/vk/aaa.py | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 tests/messengers/vk/aaa.py diff --git a/pyproject.toml b/pyproject.toml index 800799dd2..3c4bde2ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,6 @@ pandas = { version = "*", optional = true } altair = { version = "*", optional = true } asyncmy = { version = "*", optional = true } asyncpg = { version = "*", optional = true } -aiohttp = { version = "*", optional = true } pympler = { version = "*", optional = true } aiofiles = { version = "*", optional = true } humanize = { version = "*", optional = true } @@ -91,7 +90,6 @@ ydb = ["ydb", "six"] telegram = ["python-telegram-bot"] stats = ["opentelemetry-exporter-otlp", "opentelemetry-instrumentation", "requests", "tqdm", "omegaconf"] benchmark = ["pympler", "humanize", "pandas", "altair", "tqdm"] -vk = ["aiohttp"] [tool.poetry.group.lint] diff --git a/tests/messengers/vk/aaa.py b/tests/messengers/vk/aaa.py deleted file mode 100644 index d2c870846..000000000 --- a/tests/messengers/vk/aaa.py +++ /dev/null @@ -1,2 +0,0 @@ -import pathlib -print(pathlib.Path(__file__).parent / "test_tutorial.json") From edd5e932d0698c1b4ab0bc0ef45740395bdf6fe8 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Fri, 14 Jun 2024 16:44:11 +0300 Subject: [PATCH 134/140] Fixed message extraction --- dff/messengers/vk.py | 14 +++-- tests/messengers/vk/test_tutorial.json | 46 +++++++++++++- tests/messengers/vk/test_vk.py | 87 ++++++++++++++------------ 3 files changed, 101 insertions(+), 46 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 29eedbd84..574fbd415 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -49,8 +49,9 @@ def extract_vk_update(updates: dict): ) message = Message(text=text, attachments=attachments) - upds.append(message, int(id)) - return upds + upds.append(message) + # why does it nest arrays? + return upds[0] class FilesOpener: @@ -190,10 +191,11 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> elif attachment_type == "video": raise NotImplementedError() - async def request(self): - updates = await vk_api_call( - f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50" - ) + async def request(self, updates=None): + if updates is None: + updates = await vk_api_call( + f"{self.server}?act=a_check&key={self.server_key}&ts={self.ts_current}&wait=50" + ) self.ts_current = updates["ts"] return updates["updates"] diff --git a/tests/messengers/vk/test_tutorial.json b/tests/messengers/vk/test_tutorial.json index d68a09486..471cbdb5d 100644 --- a/tests/messengers/vk/test_tutorial.json +++ b/tests/messengers/vk/test_tutorial.json @@ -1,6 +1,50 @@ { "1_basic": { - "update": {"ts": "300", "updates": [{"group_id": 224377718, "type": "message_new", "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", "v": "5.199", "object": {"message": {"date": 1718015647, "from_id": 355442652, "id": 388, "out": 0, "version": 10000792, "attachments": [], "conversation_message_id": 388, "fwd_messages": [], "important": false, "is_hidden": false, "peer_id": 355442652, "random_id": 0, "text": "Hello"}, "client_info": {"button_actions": ["text", "vkpay", "open_app", "location", "open_link", "callback", "intent_subscribe", "intent_unsubscribe"], "keyboard": true, "inline_keyboard": true, "carousel": true, "lang_id": 0}}}]}, + "update": { + "ts": "300", + "updates": [ + + { + "group_id": 224377718, + "type": "message_new", + "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", + "v": "5.199", + "object": { + "message": { + "date": 1718015647, + "from_id": 355442652, + "id": 388, + "out": 0, + "version": 10000792, + "attachments": [], + "conversation_message_id": 388, + "fwd_messages": [], + "important": false, + "is_hidden": false, + "peer_id": 355442652, + "random_id": 0, + "text": "Hello" + }, + "client_info": { + "button_actions": [ + "text", + "vkpay", + "open_app", + "location", + "open_link", + "callback", + "intent_subscribe", + "intent_unsubscribe" + ], + "keyboard": true, + "inline_keyboard": true, + "carousel": true, + "lang_id": 0 + } + } + } + ] + }, "received_message": "{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", "response_request": "https://api.vk.com/method/messages.send?user_id=355442652&random_id=0&message=Hi&v=5.81&access_token=token" diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index b50a86d7c..7eb498c6d 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -3,58 +3,67 @@ import json import pathlib from dff.script import Message -from dff.messengers.vk import PollingVKInterface +from dff.messengers.vk import PollingVKInterface, extract_vk_update +import logging + +logging.basicConfig(level=logging.DEBUG) @pytest.fixture -def patch_interface(): +def patch_interface(monkeypatch): iface = PollingVKInterface(token="", group_id="") - # iface.bot = VKDummy() + + @pytest.mark.asyncio + async def mock_request(): + with open(pathlib.Path(__file__).parent / "test_tutorial.json") as f: + incoming_data = json.load(f) + + update_list = [] + for test_case, data in incoming_data.items(): + update = data["update"] + update_list.append( + extract_vk_update( + (update) + ) + ) + return update_list + + monkeypatch.setattr(iface, "_request", mock_request) + return iface # custom class to be the mock return value # will override the requests.Response returned from requests.get -def test_post(monkeypatch): - def dummy_post(request_method: str, *args, **kwargs): - print((request_method, args, kwargs)) - if "getMessagesUploadServer" in request_method: - return {"response": {"upload_url": "https://dummy_url"}} - elif "save" in request_method: - return {"response": [{"owner": "dummy", "id": "123"}]} - elif "getLongPollServer" in request_method: - return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} - - monkeypatch.setattr(requests, "post", dummy_post) +# def test_post(monkeypatch): +# def dummy_post(request_method: str, *args, **kwargs): +# print((request_method, args, kwargs)) +# if "getMessagesUploadServer" in request_method: +# return {"response": {"upload_url": "https://dummy_url"}} +# elif "save" in request_method: +# return {"response": [{"owner": "dummy", "id": "123"}]} +# elif "getLongPollServer" in request_method: +# return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} - iface = PollingVKInterface(token="", group_id="") - iface._respond(Message(text="test")) +# monkeypatch.setattr(requests, "post", dummy_post) +# iface = PollingVKInterface(token="", group_id="") +# iface._respond(Message(text="test")) -def test_data_parsing(patch_interface): - with open( pathlib.Path(__file__).parent / "test_tutorial.json") as f: +@pytest.mark.asyncio +async def test_data_parsing(patch_interface): + with open(pathlib.Path(__file__).parent / "test_tutorial.json") as f: incoming_data = json.load(f) for test_case, data in incoming_data.items(): - update = data["update"] received_message = json.loads(data["received_message"]) - expected_message = Message( - text=received_message["text"], - commands=received_message["commands"], - attachments=received_message["attachments"], - annotations=received_message["annotations"], - misc=received_message["misc"], - original_message=received_message["original_message"] - ) - - parsed_message = patch_interface._request(update) - - assert parsed_message == expected_message -# with open("incoming_data.json") as f: -# incoming_data = json.load(f) - -# for i in incoming_data: -# incoming_data[i][1] = Message(text=incoming_data[i][1]["text"]) + parsed_messages = await patch_interface._request() + print("Parsed messages: " + str(parsed_messages)) -# @pytest.mark.parametrize("incoming_http_request,parsed_dff_request", list(map(tuple, incoming_data.values()))) -# def test_data_parsing(incoming_http_request, parsed_dff_request, patched_interface): -# assert parsed_dff_request == patched_interface._request(incoming_http_request) + for parsed_message in parsed_messages: + print("Received message: " + str(received_message)) + assert parsed_message.text == received_message["text"] + assert parsed_message.commands == received_message["commands"] + assert parsed_message.attachments == received_message["attachments"] + assert parsed_message.annotations == received_message["annotations"] + assert parsed_message.misc == received_message["misc"] + assert parsed_message.original_message == received_message["original_message"] From 9469846a785935934b133614ac47fe5d5714974e Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 17 Jun 2024 12:18:39 +0300 Subject: [PATCH 135/140] Added outgoing testing and fixed vk_api_call --- dff/messengers/vk.py | 6 +-- dff/messengers/vk_dummy_example.py | 84 ----------------------------- tests/messengers/vk/test_cases.json | 58 ++++++++++++++++++++ tests/messengers/vk/test_vk.py | 54 ++++++++++++------- 4 files changed, 95 insertions(+), 107 deletions(-) delete mode 100644 dff/messengers/vk_dummy_example.py create mode 100644 tests/messengers/vk/test_cases.json diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 574fbd415..dbb88bb60 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -25,7 +25,7 @@ async def vk_api_call(method: str): async with aiohttp.ClientSession() as session: async with session.post(method) as response: - return response.json() + return await response.json() def extract_vk_update(updates: dict): @@ -259,8 +259,8 @@ async def _respond(self, response: ctx): ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" - # self.bot.send_message(resp.last_response, resp.id, attachment_list) - self.bot.send_message("resp", "id", attachment_list) + self.bot.send_message(resp.text, resp.id, attachment_list) + # return await self.bot.send_message("resp", "id", attachment_list) logger.info("Responded.") diff --git a/dff/messengers/vk_dummy_example.py b/dff/messengers/vk_dummy_example.py deleted file mode 100644 index 536aaf9e0..000000000 --- a/dff/messengers/vk_dummy_example.py +++ /dev/null @@ -1,84 +0,0 @@ -from vk import PollingVKInterface -from dff.utils.testing import ( - check_happy_path, - is_interactive_mode, - run_interactive_mode, -) -from dff.script import Message -from dff.script.conditions import exact_match -from dff.script import RESPONSE, TRANSITIONS -from dff.pipeline import Pipeline - - -toy_script = { - "greeting_flow": { - "start_node": { - RESPONSE: Message(text=""), - TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, - }, - "node1": { - RESPONSE: Message(text="Hi, how are you?"), - TRANSITIONS: { - "node2": exact_match(Message(text="i'm fine, how are you?")) - }, - }, - "node2": { - RESPONSE: Message(text="Good. What do you want to talk about?"), - TRANSITIONS: { - "node3": exact_match(Message(text="Let's talk about music.")) - }, - }, - "node3": { - RESPONSE: Message(text="Sorry, I can not talk about music now."), - TRANSITIONS: {"node4": exact_match(Message(text="Ok, goodbye."))}, - }, - "node4": { - RESPONSE: Message(text="bye"), - TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, - }, - "fallback_node": { - RESPONSE: Message(text="Ooops"), - TRANSITIONS: {"node1": exact_match(Message(text="Hi"))}, - }, - } -} - -happy_path = ( - (Message(text="Hi"), Message(text="Hi, how are you?")), - ( - Message(text="i'm fine, how are you?"), - Message(text="Good. What do you want to talk about?"), - ), - ( - Message(text="Let's talk about music."), - Message(text="Sorry, I can not talk about music now."), - ), - (Message(text="Ok, goodbye."), Message(text="bye")), - (Message(text="Hi"), Message(text="Hi, how are you?")), - (Message(text="stop"), Message(text="Ooops")), - (Message(text="stop"), Message(text="Ooops")), - (Message(text="Hi"), Message(text="Hi, how are you?")), - ( - Message(text="i'm fine, how are you?"), - Message(text="Good. What do you want to talk about?"), - ), - ( - Message(text="Let's talk about music."), - Message(text="Sorry, I can not talk about music now."), - ), - (Message(text="Ok, goodbye."), Message(text="bye")), -) - -test_dialogue = [] - -test_interface = PollingVKInterface("token", "id", debug=True, test_path=happy_path) - -pipeline = Pipeline.from_script( - script=toy_script, - start_label=("greeting_flow", "start_node"), - fallback_label=("greeting_flow", "fallback_node"), - messenger_interface=test_interface -) - -def main(): - pipeline.run() diff --git a/tests/messengers/vk/test_cases.json b/tests/messengers/vk/test_cases.json new file mode 100644 index 000000000..9b3fa1338 --- /dev/null +++ b/tests/messengers/vk/test_cases.json @@ -0,0 +1,58 @@ +{ + "incoming": { + "simple_message": { + "update": { + "ts": "300", + "updates": [ + + { + "group_id": 224377718, + "type": "message_new", + "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", + "v": "5.199", + "object": { + "message": { + "date": 1718015647, + "from_id": 355442652, + "id": 388, + "out": 0, + "version": 10000792, + "attachments": [], + "conversation_message_id": 388, + "fwd_messages": [], + "important": false, + "is_hidden": false, + "peer_id": 355442652, + "random_id": 0, + "text": "Hello" + }, + "client_info": { + "button_actions": [ + "text", + "vkpay", + "open_app", + "location", + "open_link", + "callback", + "intent_subscribe", + "intent_unsubscribe" + ], + "keyboard": true, + "inline_keyboard": true, + "carousel": true, + "lang_id": 0 + } + } + } + ] + }, + "received_message": "{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}" + } + }, + "outgoing": { + "simple_message": { + "message": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "methods_called":[ "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Hi&v=5.81&access_token=token"] + } + } +} \ No newline at end of file diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 7eb498c6d..55e3a7d3f 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -4,13 +4,13 @@ import pathlib from dff.script import Message from dff.messengers.vk import PollingVKInterface, extract_vk_update +import dff.messengers.vk as dff_vk import logging logging.basicConfig(level=logging.DEBUG) @pytest.fixture def patch_interface(monkeypatch): - iface = PollingVKInterface(token="", group_id="") @pytest.mark.asyncio async def mock_request(): @@ -26,32 +26,35 @@ async def mock_request(): ) ) return update_list + + @pytest.mark.asyncio + async def patched_post(request_method: str, *args, **kwargs): + print((request_method, args, kwargs)) + if "getMessagesUploadServer" in request_method: + return {"response": {"upload_url": "https://dummy_url"}} + elif "save" in request_method: + return {"response": [{"owner": "dummy", "id": "123"}]} + elif "getLongPollServer" in request_method: + return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} + else: + return request_method + @pytest.mark.asyncio + async def mock_respond(message: Message, *args, **kwargs): + return await iface.bot.send_message(message.text, 42, message.attachments) + + monkeypatch.setattr(dff_vk, "vk_api_call", patched_post) + iface = PollingVKInterface(token="token", group_id="") monkeypatch.setattr(iface, "_request", mock_request) + monkeypatch.setattr(iface, "_respond", mock_respond) return iface -# custom class to be the mock return value -# will override the requests.Response returned from requests.get -# def test_post(monkeypatch): -# def dummy_post(request_method: str, *args, **kwargs): -# print((request_method, args, kwargs)) -# if "getMessagesUploadServer" in request_method: -# return {"response": {"upload_url": "https://dummy_url"}} -# elif "save" in request_method: -# return {"response": [{"owner": "dummy", "id": "123"}]} -# elif "getLongPollServer" in request_method: -# return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} - -# monkeypatch.setattr(requests, "post", dummy_post) - -# iface = PollingVKInterface(token="", group_id="") -# iface._respond(Message(text="test")) @pytest.mark.asyncio -async def test_data_parsing(patch_interface): - with open(pathlib.Path(__file__).parent / "test_tutorial.json") as f: - incoming_data = json.load(f) +async def test_incoming(patch_interface): + with open(pathlib.Path(__file__).parent / "test_cases.json") as f: + incoming_data = json.load(f)["incoming"] for test_case, data in incoming_data.items(): received_message = json.loads(data["received_message"]) @@ -67,3 +70,14 @@ async def test_data_parsing(patch_interface): assert parsed_message.annotations == received_message["annotations"] assert parsed_message.misc == received_message["misc"] assert parsed_message.original_message == received_message["original_message"] + +@pytest.mark.asyncio +async def test_outgoing(patch_interface): + with open(pathlib.Path(__file__).parent / "test_cases.json") as f: + incoming_data = json.load(f)["outgoing"] + + for test_case, data in incoming_data.items(): + msg_scheme = json.loads(data["message"]) + message_to_send = Message(text=msg_scheme["text"], commands=msg_scheme["commands"], attachments= msg_scheme["attachments"]) + trace = await patch_interface._respond(message_to_send) + assert trace == data["methods_called"][0] \ No newline at end of file From be7a75016bbf8348839d32c47330c421371a08ca Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 17 Jun 2024 13:33:05 +0300 Subject: [PATCH 136/140] Fixed missing awaits --- dff/messengers/vk.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index dbb88bb60..96cce643c 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -163,7 +163,7 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> Return json object with `owner_id` and `photo_id` needed to send it """ if attachment_type == "photo": - upload_url = self.get_upload_server("photos", peer_id) + upload_url = await self.get_upload_server("photos", peer_id) attachment_path = str(attachment.source) logger.info(f"Uploading {attachment_path}") @@ -172,19 +172,19 @@ async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> upload_url, files=photo_files ).json() - saved_photo_data = self.save_photo(uploaded_photo_data, caption=attachment.title) + saved_photo_data = await self.save_photo(uploaded_photo_data, caption=attachment.title) return saved_photo_data elif attachment_type == "doc" or attachment_type == "audio": - upload_url = self.get_upload_server("docs", peer_id) + upload_url = await self.get_upload_server("docs", peer_id) attachment_path = str(attachment.source) logger.info(f"Uploading {attachment_path}") with FilesOpener(attachment_path, key_format="file") as files: uploaded_photo_data = await vk_api_call(upload_url, files=files).json() - saved_doc_data = self.save_document(uploaded_photo_data, title=attachment.title) + saved_doc_data = await self.save_document(uploaded_photo_data, title=attachment.title) return saved_doc_data["response"] @@ -202,7 +202,7 @@ async def request(self, updates=None): async def send_message(self, response: str, id, attachment_list): if attachment_list != []: for attachment in attachment_list: - data_to_send = self.upload_attachment( + data_to_send = await self.upload_attachment( id, attachment["source"], attachment["type"] ) attachment_list.append( @@ -249,13 +249,13 @@ async def _respond(self, response: ctx): ) elif isinstance(attachment, Document): attachment_list.append( - {"doc": "photo", "source": attachment.source} + {"type": "doc", "source": attachment.source} ) elif isinstance(attachment, Video): raise NotImplementedError() elif isinstance(attachment, Audio): attachment_list.append( - {"audio": "photo", "source": attachment.source} + {"type": "audio", "source": attachment.source} ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" From c80117565c9214697a9cd3d51ad1f2f049837ff9 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 17 Jun 2024 14:27:57 +0300 Subject: [PATCH 137/140] testing outgoing attachments --- dff/messengers/vk.py | 16 +++++++-------- tests/messengers/vk/test_vk.py | 36 +++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 96cce643c..97d13fb63 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -158,33 +158,31 @@ async def save_photo(self, uploaded_data, caption: str=""): return saved_data["response"] - async def upload_attachment(self, peer_id, attachment, attachment_type: str) -> str: + async def upload_attachment(self, peer_id, attachment_source: str, attachment_type: str, title: str="") -> str: """ Return json object with `owner_id` and `photo_id` needed to send it """ if attachment_type == "photo": upload_url = await self.get_upload_server("photos", peer_id) - attachment_path = str(attachment.source) - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path) as photo_files: + logger.info(f"Uploading {attachment_source}") + with FilesOpener(attachment_source) as photo_files: uploaded_photo_data = requests.post( upload_url, files=photo_files ).json() - saved_photo_data = await self.save_photo(uploaded_photo_data, caption=attachment.title) + saved_photo_data = await self.save_photo(uploaded_photo_data, caption=title) return saved_photo_data elif attachment_type == "doc" or attachment_type == "audio": upload_url = await self.get_upload_server("docs", peer_id) - attachment_path = str(attachment.source) - logger.info(f"Uploading {attachment_path}") - with FilesOpener(attachment_path, key_format="file") as files: + logger.info(f"Uploading {attachment_source}") + with FilesOpener(attachment_source, key_format="file") as files: uploaded_photo_data = await vk_api_call(upload_url, files=files).json() - saved_doc_data = await self.save_document(uploaded_photo_data, title=attachment.title) + saved_doc_data = await self.save_document(uploaded_photo_data, title=title) return saved_doc_data["response"] diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 55e3a7d3f..7f7ee6d5e 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -3,6 +3,7 @@ import json import pathlib from dff.script import Message +from dff.script.core.message import Document, Image from dff.messengers.vk import PollingVKInterface, extract_vk_update import dff.messengers.vk as dff_vk import logging @@ -29,7 +30,6 @@ async def mock_request(): @pytest.mark.asyncio async def patched_post(request_method: str, *args, **kwargs): - print((request_method, args, kwargs)) if "getMessagesUploadServer" in request_method: return {"response": {"upload_url": "https://dummy_url"}} elif "save" in request_method: @@ -41,7 +41,22 @@ async def patched_post(request_method: str, *args, **kwargs): @pytest.mark.asyncio async def mock_respond(message: Message, *args, **kwargs): - return await iface.bot.send_message(message.text, 42, message.attachments) + attachment_list = [] + print("Attachment_list", message.attachments) + if message.attachments is not None: + attachment_list = [] + for attachment in message.attachments: + print("Attachment:", attachment) + # add id to each attachment that is being generated in upload_attachment method + if isinstance(attachment, Image): + attachment_list.append( + {"type": "photo", "source": attachment.source} + ) + elif isinstance(attachment, Document): + attachment_list.append( + {"type": "doc", "source": attachment.source} + ) + return await iface.bot.send_message(message.text, 42, attachment_list) monkeypatch.setattr(dff_vk, "vk_api_call", patched_post) iface = PollingVKInterface(token="token", group_id="") @@ -57,19 +72,12 @@ async def test_incoming(patch_interface): incoming_data = json.load(f)["incoming"] for test_case, data in incoming_data.items(): - received_message = json.loads(data["received_message"]) + received_message = Message.model_validate_json(data["received_message"]) parsed_messages = await patch_interface._request() - print("Parsed messages: " + str(parsed_messages)) for parsed_message in parsed_messages: - print("Received message: " + str(received_message)) - assert parsed_message.text == received_message["text"] - assert parsed_message.commands == received_message["commands"] - assert parsed_message.attachments == received_message["attachments"] - assert parsed_message.annotations == received_message["annotations"] - assert parsed_message.misc == received_message["misc"] - assert parsed_message.original_message == received_message["original_message"] + assert parsed_message == received_message @pytest.mark.asyncio async def test_outgoing(patch_interface): @@ -77,7 +85,7 @@ async def test_outgoing(patch_interface): incoming_data = json.load(f)["outgoing"] for test_case, data in incoming_data.items(): - msg_scheme = json.loads(data["message"]) - message_to_send = Message(text=msg_scheme["text"], commands=msg_scheme["commands"], attachments= msg_scheme["attachments"]) + message_to_send = Message.model_validate_json(data["message"]) trace = await patch_interface._respond(message_to_send) - assert trace == data["methods_called"][0] \ No newline at end of file + print("Trace:", trace) + assert trace == data["methods_called"][0] From b06fd83f77e052bc5731c1fef9112de2d5d48641 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Fri, 21 Jun 2024 16:52:23 +0300 Subject: [PATCH 138/140] Fixed attachment testing --- dff/messengers/vk.py | 43 +++++++++++++-------- tests/messengers/vk/incoming_data.json | 42 --------------------- tests/messengers/vk/outgoing_data.json | 10 ----- tests/messengers/vk/test_cases.json | 27 ++++++++++++- tests/messengers/vk/test_vk.py | 52 +++++++++++++++++++++----- 5 files changed, 96 insertions(+), 78 deletions(-) delete mode 100644 tests/messengers/vk/incoming_data.json delete mode 100644 tests/messengers/vk/outgoing_data.json diff --git a/dff/messengers/vk.py b/dff/messengers/vk.py index 97d13fb63..a8e957bf4 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk.py @@ -7,6 +7,7 @@ # import asyncio # import aiofiles import aiohttp +from aiohttp import FormData import logging import requests @@ -22,9 +23,15 @@ logging.basicConfig(level=logging.INFO) -async def vk_api_call(method: str): +async def vk_api_call(method: str, file: list = []) -> dict: async with aiohttp.ClientSession() as session: - async with session.post(method) as response: + if file != []: + name, file_bytes, filename = file[0][0], file[0][1][1], file[0][1][0] + data = FormData() + data.add_field(name, file_bytes, filename=filename) + else: + data = None + async with session.post(method, data=data) as response: return await response.json() @@ -80,7 +87,7 @@ def open_files(self, just_bytes=False): filename = file.name if hasattr(file, "name") else ".jpg" else: - filename = file + filename = str(file) if "http" in filename: f = io.BytesIO(requests.get(filename).content) else: @@ -167,11 +174,9 @@ async def upload_attachment(self, peer_id, attachment_source: str, attachment_ty logger.info(f"Uploading {attachment_source}") with FilesOpener(attachment_source) as photo_files: - uploaded_photo_data = requests.post( - upload_url, files=photo_files - ).json() + uploaded_data = await vk_api_call(upload_url, file=photo_files) - saved_photo_data = await self.save_photo(uploaded_photo_data, caption=title) + saved_photo_data = await self.save_photo(uploaded_data, caption=title) return saved_photo_data @@ -180,11 +185,11 @@ async def upload_attachment(self, peer_id, attachment_source: str, attachment_ty logger.info(f"Uploading {attachment_source}") with FilesOpener(attachment_source, key_format="file") as files: - uploaded_photo_data = await vk_api_call(upload_url, files=files).json() + uploaded_data = await vk_api_call(upload_url, file=files) - saved_doc_data = await self.save_document(uploaded_photo_data, title=title) + saved_doc_data = await self.save_document(uploaded_data, title=title) - return saved_doc_data["response"] + return saved_doc_data elif attachment_type == "video": raise NotImplementedError() @@ -198,17 +203,23 @@ async def request(self, updates=None): return updates["updates"] async def send_message(self, response: str, id, attachment_list): + attachments = [] if attachment_list != []: for attachment in attachment_list: data_to_send = await self.upload_attachment( id, attachment["source"], attachment["type"] ) - attachment_list.append( - f"photo{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}" + if attachment['type'] == "doc": + attachments.append( + f"{attachment['type']}{data_to_send['doc']['owner_id']}_{data_to_send['doc']['id']}" ) + else: + attachments.append( + f"{attachment['type']}{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}" + ) # elif isinstance(attachment, Link): # response.text += f"[{attachment.source}|{attachment.title}]" - attachment_string = ",".join(attachment_list).strip(",") + attachment_string = ",".join(attachments).strip(",") api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" else: @@ -242,10 +253,12 @@ async def _respond(self, response: ctx): for attachment in response.attachments: # add id to each attachment that is being generated in upload_attachment method if isinstance(attachment, Image): + print("Photo Attachment", attachment) attachment_list.append( {"type": "photo", "source": attachment.source} ) elif isinstance(attachment, Document): + print("Document Attachment", attachment) attachment_list.append( {"type": "doc", "source": attachment.source} ) @@ -255,10 +268,8 @@ async def _respond(self, response: ctx): attachment_list.append( {"type": "audio", "source": attachment.source} ) - # elif isinstance(attachment, Link): - # response.text += f"[{attachment.source}|{attachment.title}]" + print("Attachment list", attachment_list, len(attachment_list)) self.bot.send_message(resp.text, resp.id, attachment_list) - # return await self.bot.send_message("resp", "id", attachment_list) logger.info("Responded.") diff --git a/tests/messengers/vk/incoming_data.json b/tests/messengers/vk/incoming_data.json deleted file mode 100644 index 49270ceda..000000000 --- a/tests/messengers/vk/incoming_data.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "case_1": [ - { - "ts": "4", - "updates": [ - { - "type": "message_new", - "event_id": "c68dfb983247fea8ac98ea0ea59717df71d8064f", - "v": "5.131", - "object": { - "message": { - "text": "hello", - "from_id": 1234 - }, - "client_info": {} - } - } - ] - }, - {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null} - ], - "case_2": [ - { - "ts": "4", - "updates": [ - { - "type": "message_new", - "event_id": "c68dfb983247fea8ac98ea0ea59717df71d8064f", - "v": "5.131", - "object": { - "message": { - "text": "goodbye", - "from_id": 1234 - }, - "client_info": {} - } - } - ] - }, - {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null} - ] -} \ No newline at end of file diff --git a/tests/messengers/vk/outgoing_data.json b/tests/messengers/vk/outgoing_data.json deleted file mode 100644 index a97f25f06..000000000 --- a/tests/messengers/vk/outgoing_data.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "case_1": [ - {"text":"hello","commands":null,"attachments":null,"annotations":null,"misc":null}, - ["messages.send", ["hello"]] - ], - "case_2": [ - {"text":"goodbye","commands":null,"attachments":null,"annotations":null,"misc":null}, - ["messages.send", ["hello"]] - ] -} \ No newline at end of file diff --git a/tests/messengers/vk/test_cases.json b/tests/messengers/vk/test_cases.json index 9b3fa1338..d87458e46 100644 --- a/tests/messengers/vk/test_cases.json +++ b/tests/messengers/vk/test_cases.json @@ -52,7 +52,32 @@ "outgoing": { "simple_message": { "message": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "methods_called":[ "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Hi&v=5.81&access_token=token"] + "trace":[ + { + "request_method": "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Hi&v=5.81&access_token=token" + } + ] + }, + "file_attached": { + "message": "{\"text\":\"Here is your file\",\"commands\":null,\"attachments\":[{\"source\":\"/home/askatasuna/Documents/DeepPavlov/DFF/dialog_flow_framework/tests/messengers/vk/test_tutorial.json\",\"cached_filename\":null,\"id\":null,\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"document\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "trace": [ + { + "request_method": "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Hi&v=5.81&access_token=token" + }, + { + "request_method": "https://api.vk.com/method/docs.getMessagesUploadServer?peer_id=42&group_id=&v=5.81&access_token=token" + }, + { + "request_method": "https://dummy_upload_url", + "file": -348252432389113352 + }, + { + "request_method": "https://api.vk.com/method/docs.save?file=dummy_file&title=&group_id=&v=5.81&access_token=token" + }, + { + "request_method": "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Here is your file&attachment=doc4321_1234&group_id=&v=5.81&access_token=token" + } + ] } } } \ No newline at end of file diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index 7f7ee6d5e..c67bf7b5d 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -12,7 +12,7 @@ @pytest.fixture def patch_interface(monkeypatch): - + trace = [] @pytest.mark.asyncio async def mock_request(): with open(pathlib.Path(__file__).parent / "test_tutorial.json") as f: @@ -30,23 +30,39 @@ async def mock_request(): @pytest.mark.asyncio async def patched_post(request_method: str, *args, **kwargs): + req = {"request_method": request_method} if "getMessagesUploadServer" in request_method: - return {"response": {"upload_url": "https://dummy_url"}} - elif "save" in request_method: - return {"response": [{"owner": "dummy", "id": "123"}]} + req.update(kwargs) + trace.append(req) + return {"response": {"upload_url": "https://dummy_upload_url"}} + elif "upload_url" in request_method: + # hashing bytes of the file + req.update({"file": hash(kwargs['file'][0][1][0])}) + trace.append(req) + return {"file": "dummy_file"} + elif "saveMessagesPhoto" in request_method: + req.update(kwargs) + trace.append(req) + return {"response": [{"id": 1234, "owner_id": 4321, "sizes": []}]} + elif "docs.save" in request_method: + req.update(kwargs) + trace.append(req) + return {"response": {"type": "doc", "doc": {"id": 1234, "owner_id": 4321}}} elif "getLongPollServer" in request_method: + req.update(kwargs) + trace.append(req) return {"response": {"server": "dummy_url", "key": "dummy_key", "ts": "dummy_ts"}} else: + req.update(kwargs) + trace.append(req) return request_method @pytest.mark.asyncio async def mock_respond(message: Message, *args, **kwargs): attachment_list = [] - print("Attachment_list", message.attachments) if message.attachments is not None: attachment_list = [] for attachment in message.attachments: - print("Attachment:", attachment) # add id to each attachment that is being generated in upload_attachment method if isinstance(attachment, Image): attachment_list.append( @@ -60,6 +76,7 @@ async def mock_respond(message: Message, *args, **kwargs): monkeypatch.setattr(dff_vk, "vk_api_call", patched_post) iface = PollingVKInterface(token="token", group_id="") + iface.trace = trace monkeypatch.setattr(iface, "_request", mock_request) monkeypatch.setattr(iface, "_respond", mock_respond) @@ -86,6 +103,23 @@ async def test_outgoing(patch_interface): for test_case, data in incoming_data.items(): message_to_send = Message.model_validate_json(data["message"]) - trace = await patch_interface._respond(message_to_send) - print("Trace:", trace) - assert trace == data["methods_called"][0] + # message_to_send = Message(text="Here is your file", attachments=[Document(source="README.md")]) + await patch_interface._respond(message_to_send) + trace = patch_interface.trace + with open(f'{test_case}_trace.json', 'w') as f: + f.write(json.dumps(trace)) + assert trace == data["trace"] + + +@pytest.mark.asyncio +async def test_tutorials(patch_interface): + with open(pathlib.Path(__file__).parent / "test_tutorial.json") as f: + tutorial_data = json.loads(f) + + for tutorial, data in tutorial_data.items(): + message_to_send = Message.model_validate_json(data["message"]) + # message_to_send = Message(text="Here is your file", attachments=[Document(source="README.md")]) + await patch_interface._respond(message_to_send) + trace = patch_interface.trace + assert trace == data["trace"] + From fb59508de59a66631337780cdf57250f040e5af0 Mon Sep 17 00:00:00 2001 From: NotBioWaste905 Date: Mon, 24 Jun 2024 02:14:11 +0300 Subject: [PATCH 139/140] Switched to the url attachments --- dff/messengers/vk/__init__.py | 1 + dff/messengers/{vk.py => vk/interface.py} | 12 ++-- tests/messengers/vk/mock_bot.py | 86 ----------------------- tests/messengers/vk/test_cases.json | 2 +- tests/messengers/vk/test_tutorial.json | 56 ++------------- tests/messengers/vk/test_tutorials.py | 39 ---------- tests/messengers/vk/test_vk.py | 7 +- tutorials/messengers/vk/1_basic.py | 2 +- tutorials/messengers/vk/2_attachments.py | 2 +- 9 files changed, 19 insertions(+), 188 deletions(-) create mode 100644 dff/messengers/vk/__init__.py rename dff/messengers/{vk.py => vk/interface.py} (97%) delete mode 100644 tests/messengers/vk/mock_bot.py delete mode 100644 tests/messengers/vk/test_tutorials.py diff --git a/dff/messengers/vk/__init__.py b/dff/messengers/vk/__init__.py new file mode 100644 index 000000000..40a96afc6 --- /dev/null +++ b/dff/messengers/vk/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/dff/messengers/vk.py b/dff/messengers/vk/interface.py similarity index 97% rename from dff/messengers/vk.py rename to dff/messengers/vk/interface.py index a8e957bf4..9910d43a8 100644 --- a/dff/messengers/vk.py +++ b/dff/messengers/vk/interface.py @@ -1,13 +1,12 @@ """ Interface ------------ +This module implements Polling Interface +that can be used to interact with the VK API. """ from typing import Callable, Optional -# import asyncio -# import aiofiles import aiohttp -from aiohttp import FormData import logging import requests @@ -27,7 +26,7 @@ async def vk_api_call(method: str, file: list = []) -> dict: async with aiohttp.ClientSession() as session: if file != []: name, file_bytes, filename = file[0][0], file[0][1][1], file[0][1][0] - data = FormData() + data = aiohttp.FormData() data.add_field(name, file_bytes, filename=filename) else: data = None @@ -111,6 +110,9 @@ def close_files(self): class VKWrapper: + """ + Class that handles interaction with VK API. + """ def __init__(self, token: str, group_id: str) -> None: self.token = token self.group_id = group_id @@ -217,8 +219,6 @@ async def send_message(self, response: str, id, attachment_list): attachments.append( f"{attachment['type']}{data_to_send[0]['owner_id']}_{data_to_send[0]['id']}" ) - # elif isinstance(attachment, Link): - # response.text += f"[{attachment.source}|{attachment.title}]" attachment_string = ",".join(attachments).strip(",") api_request = f"https://api.vk.com/method/messages.send?user_id={id}&random_id=0&message={response}&attachment={attachment_string}&group_id={self.group_id}&v=5.81&access_token={self.token}" diff --git a/tests/messengers/vk/mock_bot.py b/tests/messengers/vk/mock_bot.py deleted file mode 100644 index ad17569ec..000000000 --- a/tests/messengers/vk/mock_bot.py +++ /dev/null @@ -1,86 +0,0 @@ -from asyncio import get_event_loop -from typing import Any, Dict, List, Optional, Tuple, TypeAlias, Hashable - -from pydantic import BaseModel - -from dff.messengers.vk import PollingVKInterface -from dff.pipeline.types import PipelineRunnerFunction -from dff.script import Message -from dff.script.core.context import Context -from dff.script.core.message import DataAttachment - -PathStep: TypeAlias = Tuple[Dict[str, Any], Message, Message, List[str]] - -class MockVK(BaseModel, arbitrary_types_allowed=True): - latest_trace: List[str] = list() - - @staticmethod - def representation(any: Any) -> str: - if isinstance(any, bytes): - return "<>" - else: - return any.__repr__() - - def __getattribute__(self, name: str) -> Any: - async def set_trace(*args, **kwargs): - joined_args = ", ".join([self.representation(a) for a in args]) - joined_kwargs = ", ".join([f"{k}={self.representation(v)}" for k, v in kwargs.items()]) - arguments = ", ".join([joined_args, joined_kwargs]) - self.latest_trace += [f"{name}({arguments})"] - - try: - return object.__getattribute__(self, name) - except AttributeError: - return set_trace - -class MockApplication(BaseModel, arbitrary_types_allowed=True): - bot: MockVK - happy_path: List[PathStep] - interface: PollingVKInterface - latest_ctx: Optional[Context] = None - - @classmethod - def create(cls, interface: PollingVKInterface, happy_path: List[PathStep]) -> "MockApplication": - instance = cls(bot=MockVK(), happy_path=happy_path, interface=interface) - return instance - - def _wrap_pipeline_runner(self, runner: PipelineRunnerFunction): - async def wrapped_pipeline_runner( - message: Message, ctx_id: Optional[Hashable] = None, update_ctx_misc: Optional[dict] = None - ) -> Context: - self.latest_ctx = await runner(message, ctx_id, update_ctx_misc) - return self.latest_ctx - - wrapped_pipeline_runner.is_wrapped = True - wrapped_pipeline_runner.original = runner - return wrapped_pipeline_runner - - def _wrap_populate_attachment(self, interface: PollingVKInterface): - async def wrapped_populate_attachment(_: DataAttachment) -> bytes: - return bytes() - - wrapped_populate_attachment.is_wrapped = True - wrapped_populate_attachment.original = interface.populate_attachment - return wrapped_populate_attachment - - def _run_bot(self) -> None: - if not getattr(self.interface.pipeline_runner, "is_wrapped", False): - self.interface.pipeline_runner = self._wrap_pipeline_runner(self.interface.pipeline_runner) - if not getattr(self.interface.populate_attachment, "is_wrapped", False): - self.interface.populate_attachment = self._wrap_populate_attachment(self.interface) - - loop = get_event_loop() - for update, received, response, trace in self.happy_path: - loop.run_until_complete(self.interface.on_message(update)) - assert self.latest_ctx is not None, "During pipeline runner execution, no context was produced!" - assert self.latest_ctx.last_request == received, "Expected request message is not equal to expected!" - assert self.latest_ctx.last_response == response, "Expected response message is not equal to expected!" - assert self.bot.latest_trace == trace, "Expected trace is not equal to expected!" - self.bot.latest_trace = list() - self.latest_ctx = None - - self.interface.pipeline_runner = self.interface.pipeline_runner.original - self.interface.populate_attachment = self.interface.populate_attachment.original - - def run_polling(self, poll_interval: float, timeout: int, allowed_updates: List[str]) -> None: - return self._run_bot() diff --git a/tests/messengers/vk/test_cases.json b/tests/messengers/vk/test_cases.json index d87458e46..87877bac2 100644 --- a/tests/messengers/vk/test_cases.json +++ b/tests/messengers/vk/test_cases.json @@ -59,7 +59,7 @@ ] }, "file_attached": { - "message": "{\"text\":\"Here is your file\",\"commands\":null,\"attachments\":[{\"source\":\"/home/askatasuna/Documents/DeepPavlov/DFF/dialog_flow_framework/tests/messengers/vk/test_tutorial.json\",\"cached_filename\":null,\"id\":null,\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"document\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", + "message": "{\"text\":\"Here is your file\",\"commands\":null,\"attachments\":[{\"source\":\"https://github.com/deeppavlov/dialog_flow_framework/wiki/example_attachments/deeppavlov-article.pdf\",\"cached_filename\":null,\"id\":null,\"title\":null,\"use_cache\":true,\"dff_attachment_type\":\"document\",\"__pickled_extra_fields__\":[]}],\"annotations\":null,\"misc\":null,\"original_message\":null,\"__pickled_extra_fields__\":[]}", "trace": [ { "request_method": "https://api.vk.com/method/messages.send?user_id=42&random_id=0&message=Hi&v=5.81&access_token=token" diff --git a/tests/messengers/vk/test_tutorial.json b/tests/messengers/vk/test_tutorial.json index 471cbdb5d..7d1265277 100644 --- a/tests/messengers/vk/test_tutorial.json +++ b/tests/messengers/vk/test_tutorial.json @@ -1,52 +1,8 @@ { - "1_basic": { - "update": { - "ts": "300", - "updates": [ - - { - "group_id": 224377718, - "type": "message_new", - "event_id": "ef2d8a225e5c10a4c88692a2a471c00eaacb451b", - "v": "5.199", - "object": { - "message": { - "date": 1718015647, - "from_id": 355442652, - "id": 388, - "out": 0, - "version": 10000792, - "attachments": [], - "conversation_message_id": 388, - "fwd_messages": [], - "important": false, - "is_hidden": false, - "peer_id": 355442652, - "random_id": 0, - "text": "Hello" - }, - "client_info": { - "button_actions": [ - "text", - "vkpay", - "open_app", - "location", - "open_link", - "callback", - "intent_subscribe", - "intent_unsubscribe" - ], - "keyboard": true, - "inline_keyboard": true, - "carousel": true, - "lang_id": 0 - } - } - } - ] - }, - "received_message": "{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response": "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", - "response_request": "https://api.vk.com/method/messages.send?user_id=355442652&random_id=0&message=Hi&v=5.81&access_token=token" - } + "1_basic": [ + ["{\"text\":\"Hello\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "{\"text\":\"Hi\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}"], + ["{\"text\":\"Goodbye\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}", + "{\"text\":\"Please, repeat the request\",\"commands\":null,\"attachments\":[],\"annotations\":null,\"misc\":null,\"original_message\":null}"] + ] } \ No newline at end of file diff --git a/tests/messengers/vk/test_tutorials.py b/tests/messengers/vk/test_tutorials.py deleted file mode 100644 index 41d34aeaa..000000000 --- a/tests/messengers/vk/test_tutorials.py +++ /dev/null @@ -1,39 +0,0 @@ -# from importlib import import_module -# from json import loads -# from pathlib import Path -# from typing import Dict, List - -# import pytest - -# from dff.script.core.message import Message -# from mock_bot import MockApplication, PathStep -# from tests.test_utils import get_path_from_tests_to_current_dir - -# dot_path_to_addon = get_path_from_tests_to_current_dir(__file__, separator=".") -# happy_paths_file = Path(__file__).parent / "test_tutorial.json" - -# def _cast_dict_to_happy_step(dict: Dict) -> List[PathStep]: -# imports = globals().copy() -# # imports.update(import_module("vk_api").__dict__) - -# path_steps = list() -# for step in dict: -# update = step["update"] -# received = Message.model_validate_json(step["received_message"]) -# received.original_message = update -# response = Message.model_validate_json(step["response"]) -# path_steps += [(update, received, response, step["response_request"])] -# return path_steps - -# @pytest.mark.vk -# @pytest.mark.asyncio -# @pytest.mark.parametrize( -# "tutorial_module_name", -# ["1_basic"], -# ) -# def test_tutorials_vk_memory(tutorial_module_name: str): -# happy_path_data = loads(happy_paths_file.read_text())[tutorial_module_name] -# happy_path_steps = _cast_dict_to_happy_step(happy_path_data) -# module = import_module(f"tutorials.{dot_path_to_addon}.{tutorial_module_name}") -# module.interface.application = MockApplication.create(module.interface, happy_path_steps) -# module.pipeline.run() diff --git a/tests/messengers/vk/test_vk.py b/tests/messengers/vk/test_vk.py index c67bf7b5d..bd33f1fbd 100644 --- a/tests/messengers/vk/test_vk.py +++ b/tests/messengers/vk/test_vk.py @@ -4,8 +4,8 @@ import pathlib from dff.script import Message from dff.script.core.message import Document, Image -from dff.messengers.vk import PollingVKInterface, extract_vk_update -import dff.messengers.vk as dff_vk +from dff.messengers.vk.interface import PollingVKInterface, extract_vk_update +import dff.messengers.vk.interface as dff_vk import logging logging.basicConfig(level=logging.DEBUG) @@ -37,7 +37,7 @@ async def patched_post(request_method: str, *args, **kwargs): return {"response": {"upload_url": "https://dummy_upload_url"}} elif "upload_url" in request_method: # hashing bytes of the file - req.update({"file": hash(kwargs['file'][0][1][0])}) + req.update({"file": kwargs['file'][0][1][0]}) trace.append(req) return {"file": "dummy_file"} elif "saveMessagesPhoto" in request_method: @@ -122,4 +122,3 @@ async def test_tutorials(patch_interface): await patch_interface._respond(message_to_send) trace = patch_interface.trace assert trace == data["trace"] - diff --git a/tutorials/messengers/vk/1_basic.py b/tutorials/messengers/vk/1_basic.py index 3f2feebee..c36268234 100644 --- a/tutorials/messengers/vk/1_basic.py +++ b/tutorials/messengers/vk/1_basic.py @@ -21,7 +21,7 @@ """ # %% -from dff.messengers.vk import PollingVKInterface +from dff.messengers.vk.interface import PollingVKInterface from dff.script import conditions as cnd from dff.script import labels as lbl from dff.script import RESPONSE, TRANSITIONS, Message diff --git a/tutorials/messengers/vk/2_attachments.py b/tutorials/messengers/vk/2_attachments.py index 3197d22ff..d62d6a6bd 100644 --- a/tutorials/messengers/vk/2_attachments.py +++ b/tutorials/messengers/vk/2_attachments.py @@ -29,7 +29,7 @@ """ # %% -from dff.messengers.vk import PollingVKInterface +from dff.messengers.vk.interface import PollingVKInterface from dff.script import conditions as cnd from dff.script import labels as lbl from dff.script import RESPONSE, TRANSITIONS, Message From 26e4eea9f69cb070a556dfb165b3df1282fc0302 Mon Sep 17 00:00:00 2001 From: askatasuna Date: Mon, 1 Jul 2024 10:50:16 +0300 Subject: [PATCH 140/140] Deleted old attachments --- JXK5IiyaUUc.jpg | Bin 598152 -> 0 bytes photo_2024-02-29_23-14-08.jpg | Bin 98258 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 JXK5IiyaUUc.jpg delete mode 100644 photo_2024-02-29_23-14-08.jpg diff --git a/JXK5IiyaUUc.jpg b/JXK5IiyaUUc.jpg deleted file mode 100644 index 5d85299eac88494f65853bd5916f35ecae7f5b20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598152 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