FAQ по переходу з версії 2.x на 3.0

Небезпека

Цей посібник все ще в розробці.

Ця версія містить численні суттєві зміни та архітектурні покращення. Вона допомагає зменшити кількість глобальних змінних у вашому коді, надає корисні механізми для модуляризації вашого коду та дозволяє створювати спільні модулі за допомогою пакетів на PyPI. Крім того, серед інших покращень, він робить проміжне програмне забезпечення (мідлварі) та фільтри більш контрольованими.

На цій сторінці ви можете прочитати про зміни, внесені в останню стабільну версію 2.x.

Примітка

Ця сторінка більше нагадує детальний список змін, ніж посібник з міграції, але вона буде оновлюватися в майбутньому.

Не соромтеся зробити свій внесок у цю сторінку, якщо ви знайшли щось, про що тут не згадано.

Залежності

  • Залежності, необхідні для i18n, більше не є частиною пакету за замовчуванням. Якщо ваш додаток використовує функціональність перекладу, обов’язково додайте необов’язкову залежність:

    pip install aiogram[i18n]

Диспетчер

  • Клас Dispatcher більше не приймає екземпляр Bot у своєму ініціалізаторі. Замість цього екземпляр Bot слід передавати диспетчеру тільки для запуску полінгу або обробки подій з вебхуків. Такий підхід також дозволяє використовувати декілька екземплярів бота одночасно («мультибот»).

  • Клас Dispatcher тепер можна розширити ще одним об’єктом на кшталт диспетчера з назвою Router (Детальніше »).

  • Видалено суфікс _handler з усіх декораторів обробників подій та методів реєстрації. (Детальніше »)

  • Executor було повністю вилучено; тепер ви можете використовувати Dispatcher безпосередньо для запуску полінгу або обробки вебхуків.

  • Метод дроселювання (Throttling) повністю вилучено; тепер ви можете використовувати проміжне програмне забезпечення (middleware) для керування контекстом виконання та реалізовувати будь-який механізм дроселювання за вашим бажанням.

  • Вилучено глобальні контекстні змінні з типів API, об’єктів Bot та Dispatcher, Відтепер, якщо ви хочете отримати доступ до поточного екземпляру бота в обробниках або фільтрах, ви повинні приймати аргумент bot: Bot і використовувати його замість Bot.get_current(). У проміжному програмному забезпеченні (middleware) доступ до нього можна отримати через data["bot"].

  • To skip pending updates, you should now call the DeleteWebhook method directly, rather than passing skip_updates=True to the start polling method.

  • To feed updates to the Dispatcher, instead of method process_update(), you should use method feed_update(). (Read more »)

Фільтрація подій

  • Фільтри за ключовими словами більше не можна використовувати; використовуйте фільтри явно. (Детальніше »)

  • У зв’язку з вилученням keyword фільтрів, всі раніше ввімкнені за замовчуванням фільтри (такі як state і content_type) тепер вимкнено. Якщо ви бажаєте їх використовувати, ви повинні вказати їх явно. Наприклад, замість @dp.message_handler(content_types=ContentType.PHOTO) слід використовувати @router.message(F.photo).

  • Most common filters have been replaced with the «magic filter.» (Read more »)

  • За замовчуванням обробник повідомлень тепер отримує будь-який тип вмісту. Якщо вам потрібен певний тип, просто додайте відповідні фільтри (Magic або будь-який інший).

  • Фільтр стану більше не вмикається за замовчуванням. Це означає, що якщо ви використовували state="*" у v2, вам не слід передавати фільтр стану у v3. І навпаки, якщо стан не було вказано у v2, вам потрібно буде вказати його у v3.

  • Додано можливість реєстрації глобальних фільтрів для кожного роутера, що допомагає зменшити повторення коду і полегшує контроль призначення кожного роутера.

Bot API

  • Всі методи API тепер є класами з валідацією, реалізованими через pydantic <https://docs.pydantic.dev/>. Ці виклики API також доступні як методи в класі Bot.

  • Додано більше попередньо визначених enums та переміщено їх до підпакету aiogram.enums. Наприклад, enum типу чату тепер має вигляд aiogram.enums.ChatType замість aiogram.types.chat.ChatType.

  • Клієнтська сесія HTTP була відокремлена в контейнер, який можна повторно використовувати для різних екземплярів бота в додатку.

  • Виключення API більше не класифікуються за конкретними повідомленнями, оскільки Telegram не має задокументованих кодів помилок. Проте всі помилки класифікуються за кодами статусу HTTP, і для кожного методу з певним кодом може бути пов’язаний лише один тип помилки. Тому в більшості випадків слід перевіряти лише тип помилки (за кодом статусу), не перевіряючи повідомлення про помилку.

Проміжне ПО (Middlewares)

  • Проміжне програмне забезпечення тепер може керувати контекстом виконання, наприклад, за допомогою менеджерів контексту. (Детальніше »)

  • Всі контекстні дані тепер наскрізно використовуються між проміжним програмним забезпеченням, фільтрами та обробниками. Наприклад, тепер ви можете легко передати деякі дані в контекст у проміжному програмному забезпеченні і отримати їх у шарі фільтрів так само, як і в обробниках через аргументи ключових слів.

  • Додано механізм з назвою flags, який допомагає налаштовувати поведінку обробника у поєднанні з проміжним програмним забезпеченням. (Детальніше про »)

Розмітка клавіатури

Дані зворотного виклику

  • Фабрику даних зворотного виклику тепер строго типізовано за допомогою моделей pydantic. (Детальніше »)

Скінченний автомат

  • Фільтри станів більше не будуть автоматично додаватися до всіх обробників; вам потрібно буде вказати стан, якщо ви хочете його використати.

  • Додано можливість змінювати стратегію FSM. Наприклад, якщо ви хочете контролювати стан для кожного користувача на основі топіків чату, а не користувача в чаті, ви можете вказати це в Диспетчері.

  • Now aiogram.fsm.state.State and aiogram.fsm.state.StateGroup don’t have helper methods like .set(), .next(), etc. Instead, you should set states by passing them directly to aiogram.fsm.context.FSMContext (Read more »)

  • Проксі стану є застарілим; вам слід оновити дані стану, викликавши state.set_data(...) та state.get_data() відповідно.

Надсилання файлів

  • Відтепер перед відправкою файлів слід обертати їх в об’єкт InputFile замість того, щоб передавати об’єкт вводу-виводу безпосередньо до методу API. (Детальніше »)

Вебхук

  • Спрощено налаштування веб-застосунку aiohttp.

  • За замовчуванням додана можливість завантаження файлів при відповідях на оновлення (доступно тільки для вебхука).

Сервер Telegram API

  • The server parameter has been moved from the Bot instance to api parameter of the BaseSession.

  • The constant aiogram.bot.api.TELEGRAM_PRODUCTION has been moved to aiogram.client.telegram.PRODUCTION.

Перетворення об’єктів Telegram (у словник, у json, з json)

  • Методи TelegramObject.to_object(), TelegramObject.to_json() та TelegramObject.to_python() були вилучені через використання моделей pydantic.

  • TelegramObject.to_object() слід замінити на TelegramObject.model_validate() (Детальніше)

  • TelegramObject.as_json() слід замінити на aiogram.utils.serialization.deserialize_telegram_object_to_python()

  • <TelegramObject>.to_python() слід замінити на json.dumps(deserialize_telegram_object_to_python(<TelegramObject>))

Ось деякі приклади використання:

  • Створення об’єкта з представлення об’єкта у вигляді словника

    # Version 2.x
    message_dict = {"id": 42, ...}
    message_obj = Message.to_object(message_dict)
    print(message_obj)
    # id=42 name='n' ...
    print(type(message_obj))
    # <class 'aiogram.types.message.Message'>
    
    # Version 3.x
    message_dict = {"id": 42, ...}
    message_obj = Message.model_validate(message_dict)
    print(message_obj)
    # id=42 name='n' ...
    print(type(message_obj))
    # <class 'aiogram.types.message.Message'>
    
  • Cтворення представлення об’єкта у вигляді json

    # Version 2.x
    async def handler(message: Message) -> None:
        message_json = message.as_json()
        print(message_json)
        # {"id": 42, ...}
        print(type(message_json))
        # <class 'str'>
    
    # Version 3.x
    async def handler(message: Message) -> None:
        message_json = json.dumps(deserialize_telegram_object_to_python(message))
        print(message_json)
        # {"id": 42, ...}
        print(type(message_json))
        # <class 'str'>
    
  • Створення представлення об’єкта у вигляді словника

    async def handler(message: Message) -> None:
        # Version 2.x
        message_dict = message.to_python()
        print(message_dict)
        # {"id": 42, ...}
        print(type(message_dict))
        # <class 'dict'>
    
    async def handler(message: Message) -> None:
        # Version 3.x
        message_dict = deserialize_telegram_object_to_python(message)
        print(message_dict)
        # {"id": 42, ...}
        print(type(message_dict))
        # <class 'dict'>
    

Інструменти ChatMember

  • Тепер aiogram.types.chat_member.ChatMember більше не містить інструментів для вирішення об’єкта з відповідним статусом.

    # Version 2.x
    from aiogram.types import ChatMember
    
    chat_member = ChatMember.resolve(**dict_data)
    
    # Version 3.x
    from aiogram.utils.chat_member import ChatMemberAdapter
    
    chat_member = ChatMemberAdapter.validate_python(dict_data)
    
  • Відтепер aiogram.types.chat_member.ChatMember та всі його дочірні класи більше не містять методів для перевірки належності до певних логічних груп. Замість цього ви можете використовувати попередньо визначені групи або створювати такі групи самостійно та перевіряти їх входження за допомогою функції isinstance()

    # Version 2.x
    
    if chat_member.is_chat_admin():
        print("ChatMember is chat admin")
    
    if chat_member.is_chat_member():
        print("ChatMember is in the chat")
    
    # Version 3.x
    
    from aiogram.utils.chat_member import ADMINS, MEMBERS
    
    if isinstance(chat_member, ADMINS):
        print("ChatMember is chat admin")
    
    if isinstance(chat_member, MEMBERS):
        print("ChatMember is in the chat")
    

    Примітка

    Також ви можете самостійно створити групу, подібну до ADMINS, яка відповідає логіці вашого застосунку.

    Наприклад, ви можете створити групу PUNISHED та включити туди заблокованих та обмежених учасників!