✨ Магічні 🔮 фільтри ✨#

Примітка

Ця сторінка все ще в розробці. Має багато неправильно сформульованих речень.

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

За замовчуванням встановлюється разом з aiogram і, також, доступний в PyPi - magic-filter. Це означає, що Ви можете встановити його та використовувати з будь-якими іншими бібліотеками та у власних проектах, незалежно від того встановлено aiogram чи ні.

Використання#

Пакет magic_filter реалізує клас із короткою назвою magic_filter.F, тобто F можна імпортувати з aiogram або magic_filter. F є псевдонімом для MagicFilter.

Примітка

Зауважте, що aiogram має невелике розширення для magic-filter, і якщо Ви хочете використовувати це розширення, вам слід імпортувати магію з aiogram замість пакета magic_filter

Об’єкт классу MagicFilter можна викликати, підтримує деякі дії і запам’ятовує ланцюжок атрибутів і дію, яку слід перевіряти на вимогу.

Тож це означає, що ви можете ланцюжком отримати атрибути, описати прості перевірки даних, а потім викликати отриманий об’єкт, передаючи один об’єкт як аргумент, наприклад, створити ланцюжок атрибутів F.foo.bar.baz, а потім додати дію „F.foo.bar.baz == 'spam', після чого викликати отриманий об’єкт - (F.foo.bar.baz == 'spam').resolve(obj)

Можливі дії#

Об’єкт магічного фільтра підтримує деякі основні логічні операції над атрибутами об’єкта

Атрибут існує, або не «None»#

Дії за замовчуванням.

F.photo  # lambda message: message.photo

Перевірка на однаковість#

F.text == 'hello'  # lambda message: message.text == 'hello'
F.from_user.id == 42  # lambda message: message.from_user.id == 42
F.text != 'spam'  # lambda message: message.text != 'spam'

Перевірка на приналежність#

Може використовуватися як метод із назвою in_ або як оператор matmul @ з будь-яким ітерованим

F.from_user.id.in_({42, 1000, 123123})  # lambda query: query.from_user.id in {42, 1000, 123123}
F.data.in_({'foo', 'bar', 'baz'})  # lambda query: query.data in {'foo', 'bar', 'baz'}

Перевірка на наявність#

F.text.contains('foo')  # lambda message: 'foo' in message.text

Рядок починається/закінчується на#

Може застосовуватися лише для текстових атрибутів

F.text.startswith('foo')  # lambda message: message.text.startswith('foo')
F.text.endswith('bar')  # lambda message: message.text.startswith('bar')

Перевірка регулярними виразами#

F.text.regexp(r'Hello, .+')  # lambda message: re.match(r'Hello, .+', message.text)

Власні функції#

Приймає будь-яку функцію

F.chat.func(lambda chat: chat.id == -42)  # lambda message: (lambda chat: chat.id == -42)(message.chat)

Інвертування результату#

Будь-яка доступна операція може бути інвертована за допомогою побітової інверсії - ~

~F.text  # lambda message: not message.text
~F.text.startswith('spam')  # lambda message: not message.text.startswith('spam')

Комбінація#

Усі операції можна комбінувати за допомогою побітових і/або операторів - &/|

(F.from_user.id == 42) & (F.text == 'admin')
F.text.startswith('a') | F.text.endswith('b')
(F.from_user.id.in_({42, 777, 911})) & (F.text.startswith('!') | F.text.startswith('/')) & F.text.contains('ban')

Модифікатори атрибутів - маніпуляції з рядками#

Робить текст верхнім або нижнім регістром

Можна використовувати лише з рядковими атрибутами.

F.text.lower() == 'test'  # lambda message: message.text.lower() == 'test'
F.text.upper().in_({'FOO', 'BAR'})  # lambda message: message.text.upper() in {'FOO', 'BAR'}
F.text.len() == 5  # lambda message: len(message.text) == 5

Отримати результат фільтра як аргумент обробника#

Ця частина недоступна безпосередньо в magic-filter, але її можна використовувати з aiogram

from aiogram import F

...

@router.message(F.text.regexp(r"^(\d+)$").as_("digits"))
async def any_digits_handler(message: Message, digits: Match[str]):
    await message.answer(html.quote(str(digits)))

Використання в aiogram#

@router.message(F.text == 'hello')
@router.inline_query(F.data == 'button:1')
@router.message(F.text.startswith('foo'))
@router.message(F.content_type.in_({'text', 'sticker'}))
@router.message(F.text.regexp(r'\d+'))

...

# Many others cases when you will need to check any of available event attribute