Welcome to pywood’s documentation!¶
Overview¶
Что такое pywood?¶
pywood позволяет создавать боты для Telegram на языке Python
Rationale¶
В настоящее время существует несколько утилит для создания ботов Telegram.
Например:
Однако эти утилиты неудобны в использовании, громоздки и сложны для изучения.
Для простых ботов они обладают избыточными возможностями.
pywood- попытка решить данную проблему.
Installation¶
$ pip install pywood
License¶
Licensed under the MIT License |
Begin license text.
Copyright (c) 2020 Dzmitry Maliuzhenets (https://github.com/pynista)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
End license text.
Introduction¶
Webhooks¶
Overview¶
Using handle_update()¶
Функция handle_update()- самая главная функция в библиотеке pywood. Ее задача- обработать переданный ей объект обновления.
Функция имеет следующий вид:
-
handle_update
(update, states, state_getter, state_attrs=None)¶
importing¶
Функция handle_update() находиться в модуле __init__ библиотеки pywood, поэтому вы должны импортировать ее так:
Arguments¶
update argument¶
states argument¶
state_getter argument¶
state_getter должен представлять собой функцию, принимающую update.
Данная функция обязана возвратить (один из трех вариантов):
- строку, являющуюся названием текущего состояния
- класс текущего состояния
- кортеж из двух элементов, первый из которых- строка, являющаяся названием текущего состояния, второй- данные, которые будут добавлены в виде аттрибута state_data к экземпляру объекта состояния
Рассмотрим эти три варианта.
Функция возвращает строку¶
Функция возвращает класс¶
Функция возвращает кортеж¶
Note
Обратите внимание, что в примере выше метод handle() имеет аргумент data. В него будут переданы данные переданные в функцию handle_update() виде аргумента data.
В методе handle() мы также обращаемся к аттрибуту self.state_data, который содержит второй элемент кортежа, который возвращает функция get_curr_state()
В дополнение к этому, объект класса State будет также иметь аттрибуты, определенные аргументом state_attrs функции handle_update()
state_attrs argument¶
картинка
Warning
Запрещено добавлять аттрибут с именем state_data, т.к. он будет заменен
Using Bot.handle_update() method¶
Using decorators¶
-
@
event
(event_cls)¶ Remove name of the decorated function.
-
@
events
(*event_classes)¶ Remove name of the decorated function.
-
@
no_events
¶ Remove name of the decorated function.
Decorator
|
Параметры
декорируемой
функции
|
Пример использования
|
|
update, data | |
|
update, event_cls, data | |
|
update, data |
Порядок обработки классов событий¶
Using states¶
Update reception¶
Для получения обновлений должны использовать
Logging¶
handle_update()¶
decorators.py¶
Note
Декораторы из данного модуля применяются к методам классов
унаследованных от pywood.states.BaseState
event¶
events¶
no_events¶
states.py¶
BaseState¶
Warning
Если класс содержит декоратор no_events, то тогда методы before_handling() и after_handling() выполнятся в любом случае: либо во время обработки событий методами декорируемыми декораторами event и events, либо во при работе метода продекорируемого декоратором no_events
devtools.py¶
pooling.py¶
commands¶
Example 1: Hello World¶
Note
В этом примере и в следующих примерах мы для простоты не используем виртуальные окружения. Однако, категорически рекомендуется их использование.
Цели примера¶
- Показать, как написать самого простого бота, используя pywood
Описание задачи¶
Напишем бота, который на любое входящее сообщение будет отвечать “Hello World’
Подготовительные мероприятия¶
Создание бота и получение токена¶
Установка необходимых пакетов¶
Устанавливаем пакет pywood:
$ pip install pywood
Для обращения к API Telegram устанавливаем пакет pyTelegramBotAPI
$ pip install pyTelegramBotAPI
Создание структуры файлов¶
Создадим 3 файла:
Файл | Назначение |
handler.py | Обработка получаемых обновлений |
states.py | Хранение классов состояний |
config.py | Хранение чувствительных данных, например токен бота |
Определение классов состояний¶
В данном примере невозможно выделить какие-то определенные состояния. Поэтому создадим один класс состояния, который будет обрабатывать все обновления.
Обратите внимание, что данный класс наследует от BaseState
:
class State(BaseState):
...
События¶
Воспользуемся событием IncomingUpdate
, которое происходит при каждом обновлении
Обработчики и декораторы¶
Воспользуемся декоратором event()
, который предназначен для регистрации
обработки одного события.
Имя декорируемого метода- не важно. Обратите внимание, что каждый декорируемый метод должен иметь позиционные аргуметны update и context.
class State(BaseState):
@event(IncomingUpdate)
def handle_all_update(self, update, context):
...
state_getter¶
Также добавим в модуль states
функцию state_getter()
.
Данная функция будет возвращать один класс состояния, вне зависимости от полученного update:
def state_getter(update):
return State
Полный код state.py¶
import telebot
from config import TOKEN
from pywood.decorators import event
from pywood.eventlib import IncomingUpdate
from pywood.states import BaseState
class State(BaseState):
@event(IncomingUpdate)
def handle_all_update(self, update, context):
chat_id = update.message.chat.id
bot = telebot.TeleBot(TOKEN)
bot.send_message(chat_id, "Hello World")
def state_getter(update):
"""Мы имеем одно состояние, поэтому всегда возвращаем его"""
return State
Получение и обработка входящих обновлений при помощи handle_update()¶
Для получения обновлений воспользуемся функцией pywood.pooling.listen()
.
Данная функция получает от Telegram обновления, связанные с ботом, и передает полученные обновления в функцию обработчик
Аргумент handler функции listen()
должен принимать только один аргумент (Update).
Но функция handle_update()
принимает три аргумента.
Поэтому напрямую передать функцию handle_update()
как аргумент функции
listen()
мы не можем.
Создадим для этого вспомогательную функцию, которая принимает один аргумент update и вызывает функцию handle_update()
,
обеспечив ее нужными аргументами:
def handler(update):
handle_update(
update, states=[State,],
state_getter=state_getter,
)
listen(TOKEN, handler=handler)
Немного оптимизируем код выше, воспользовавшись функцией partial из стандартной библиотеки Python:
handler = partial(handle_update,
states=[State],
state_getter=state_getter)
listen(TOKEN, handler=handler)
Код полностью¶
TOKEN = 'YOUR BOT TOKEN'
import telebot
from config import TOKEN # noqa
from pywood.decorators import event
from pywood.eventlib import IncomingUpdate
from pywood.states import BaseState
class State(BaseState):
@event(IncomingUpdate)
def handle_all_update(self, update, context):
chat_id = update.message.chat.id
bot = telebot.TeleBot(TOKEN)
bot.send_message(chat_id, "Hello World")
def state_getter(update):
"""Мы имеем одно состояние, поэтому всегда возвращаем его"""
return State
from functools import partial
from config import TOKEN # noqa
from states import State, state_getter # noqa
from pywood import handle_update
from pywood.pooling import listen
if __name__ == '__main__':
handler = partial(handle_update,
states=[State,],
state_getter=state_getter)
listen(TOKEN, handler=handler)
Запуск¶
$ python3 handler.py
Example 2: Moderator bot¶
Цели примера¶
- Показать как писать свой класс события
- Показать как производить логгирование
Описание задачи¶
Написать простого бота, который будет удалять из чата текстовые сообщения, содержащие фразу “fuck you”
Последовательность действий¶
# Составляем диаграмму состояний # Пишем класс события, определяющего приход сообщения, содержащего фразу “fuck you” # Пишем классы состояний
Составление диаграммы состояний¶
Система, определяющая чат может находиться в одном состоянии.
Реализация класса события¶
Реализация классы состояния¶
Описание задачи |
Последовательность действий |
Составление диаграммы состояний |
Реализация класса события |
Example 3: Keyboard Bot¶
Example 4: Pizza Shop bot¶
Frequently Asked Questions¶
Changelog¶
Note
This is a note box.
Warning
note the space between the directive and the text