Создание api на основе django и telegram bota на flask
Flask Telegram Bot
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Flask Telegram Bot
Приложение реализовано с использованием Flask, библитеки pyTelegramBotAPI и базы данных RethinkDB. Выбор RethinkDB обусловлен тем, что RethinkDB распределённая документоориентированная СУБД с открытым исходным кодом, сохраняющая данные в бессхемном JSON-формате. Ориентирована на применение для веб-приложений, требующих интенсивных обновлений базы данных. В приложении используется метод Webhook, что позволяет получать одновления для бота с серверов Telegram.
Приложение позволяет выполнять регистрацию, аутентификацию, а также функции по изменению данных пользователя (смена пароля, смена данных введенных пользователем).
Для работы с базой данных используется диспетчер контекста.
Описание развертывания приложения опробовано на VDS c системой CentOS7.
Установка Python3 и базы данных RethinkDB
Загрузка проекта и создание виртуальной среды
Настройка базы данных RethinkDB
Для работы приложения используются самоподписанных сертификаты. Создаем самоподписанный сертификат.
Создать токен согласно документации Telegram
Добавить полученный токен в файл config.py
Если ошибок нет, настроить работу приложения через systemd.
Приложение имеет две команды start и setting .
Первая вводится при старте, вторая для настройки и входа в скрытое меню, где необходимо создать базу данных и пользователя администратора. Рекомендуется сразу после запуска приложения последовательно создать Базу данных, таблицы в базе и нового администратора.
По умолчанию логин и пароль администратора root root .
Если необходимо изменить логин и пароль по умолчанию:
После чего измените соответствующие поля в файле config.py
После создания администратора, дефолтная учетная запись будет отлючена. Если же база данных будет удалена, будет вновь активирована дефолтная учетная запись админитсратора, до тех пор пока не будет создана новая.
Используя меню приложения, можно создать новых пользователей и редактировать их учетные записи и просматривать их.
Всем привет, в этой статье я расскажу как сделать простейшего телеграмм бота на Python для отправки текущей погоды в Москве.
Статья расчитана на новичков в Python, которые бы хотели узнать больше о том, как взаимодействовать с внешними сервисами по API.
Технологии и API:
- Python — язык программирования,
- Flask — фреймворк для создания веб-приложений,
- Telegram Bot API,
- Weatherstack API,
- Ngrok — сервис для создания туннеля к localhost.
Как все будет работать?
На этом этапе нам нужно создать бота и получить к нему доступы. Для этого запускаем бота botfather в Telegram командой ниже.
Справка о Flask
Flask — фреймворк для создания веб-приложений на языке программирования Python, использующий набор инструментов Werkzeug, а также шаблонизатор Jinja2. Относится к категории так называемых микрофреймворков — минималистичных каркасов веб-приложений, сознательно предоставляющих лишь самые базовые возможности.
Поддерживается установка посредством пакетного менеджера PyPI, версия 1.0 совместима с Python 2.7, Python 3.3 и выше.
Установка Flask
Для изоляции зависимостей пакетов Python создадим папку проекта и виртуальное окружение. Для этого в терминале выполним команды ниже. Подробнее о виртуальных окружениях.
После завершения установки и активации виртуального окружения установим Flask.
Подробнее на странице Installation.
Запуск простейшего приложения Flask
В директории weather_bot создадим файл app.py с содержимым.
Запустим полученное приложение.
Перейдем по адресу http://127.0.0.1:5000/ и убедимся, что отображается текст "Hello, World!".
Подробнее на странице Quickstart.
Создание туннеля к localhost с помощью ngrok
Ngrok — это сервис, позволяющий создавать туннели на локальный компьютер пользователя.
Подробнее о cURL на странице wiki.
Если получен ответ "ok": true, то все в порядке.
Перезапустим Flask. Для этого остановим сервер из терминала комбинацией клавиш Ctrl+C и повторно запустим его.
Запросы будем делать с помощью библиотеки requests, которой нет в списке стандартных, поэтому установим ее. Для этого в терминале с активированным виртуальным окружением выполним команду нижу.
Добавим строку импорта requests сразу за строкой from flask import Flask, request в app.py .
Подробнее о библиотеке requests на странице.
Добавим вызов функции send_message() из receive_update() .
Вот так выглядит код в файле app.py
Отправка пользователю информации о погоде
Используем метод current Weatherstack API для получения информации о погоде.
Передадим 2 обязательных Query Params: access_key — секретный ключ вида 86a3fe972756lk34a6a042bll348b1e3, который можно получить после регистрации, и query — город, по которому получаем информацию о погоде, в нашем случае — Moscow.
Подробнее на странице документации.
Добавим функцию для получения текущей температуры в Москве после строки app = Flask(__name__) .
Вот и всё! Таким несложным образом мы научили наш бот информировать нас о погоде в Москве.
Всем мир! Сегодня я вам на практике покажу, как с 0 написать несложного Telegram бота.
Для начала придумаем тестовое задание.
У меня есть сервер Counter Strike 1.6 на котором я временами играю с друзьями. Заходить в игру, чтобы проверить наличие там игроков, лень. Напишем бота, который будет доставать для нас информацию о сервере и список игроков со счетом и выводить в удобном формате.
Для того, чтобы проследить за действиями, достаточно базовых знаний linux, web и python.
Постановка задачи
Для работы телеграм бот, который крутится на нашей машине, должен получать обновления от сервера Telegram. Это можно сделать двумя методами:
- Long polling. Метод, когда ваша программа в определенный промежуток времени опрашивает сервер об обновлениях.
- Web hook. Тут вы поднимаете веб сервер, на который телеграм бот шлет обновления, если они есть.
Второй метод популярнее и считается надежнее, поэтому остановимся на нем.
Писать будем на Python с использованием Flask. В роли веб сервера используем nginx. В работе с сервером CS нам поможет чудесный модуль python-valve
Выбор сервера для хостинга нашего бота роли не играет, я буду работать с Digital Ocean.
Первым делом нам надо зарегистрировать своего бота у @BotFather. Он отвечает за управление информацией о боте и получение и обновление токенов для работы с ними. От него мы получим такую строку
Это ключ по которому сервера телеграм будут знать, что вы владельцы этого бота. Если вы его потеряете, вы можете получить новый у того же @BotFather.
Первый шаг сделали. Мы уже сейчас можем найти нашего бота в ТГ и писать ему, но это пока только оболочка и отвечать вам не будет. Ему нужен код/призрак.
Аренда выделенного сервера на DO
Как и любой сайт и серверсайд программа, наш код должен быть запущен на машине с белым ip и выходом в интернет. Для такого случая мы арендуем машину у Ditial Ocean
Показывать пошаговую регистрацию на сайте я не буду, покажу только как получить и настроить сам сервер. Кстати, если вы студент, можете попробовать получить 50$ на хостинг бесплатно.
Нажимаем на большую копку Create droplet.
Выбираем желаемую ОС. Я буду работать с Ubuntu.
Больше нам ничего менять тут не надо, нажимаем Create.
В течении пары минут мы получим ip адрес и root пароль от сервера на нашу почту. Все, машина работает. Можем коннектиться к ней по ssh.
Вводим пароль и получаем полный контроль над сервером. Возможно вас попросят сменить пароль, поставьте посложнее.
Первым делом нам сразу надо создать нового пользователя и входить на сервер из под него, чтобы не стать легкой мишенью для хакеров.
Теперь необходимо перезайти на сервер под новым пользователем
Установка нужных сервисов
Первая команда обновит локальные репозитории, чтобы не было проблем с поиском нужных пакетов. Вторая поставит PIP (систему управления пакетами python), веб сервер nginx и dev пакет python. Третья команда запустит веб сервер.
Если вы сейчас введете ip адрес вашего сервера в браузере любого компьютера подключенного к сети интернет, вы получите страницу приветствия nginx.
Выключим на пока наш веб сервер и займемся python.
Python и virtualenv
По хорошему, нам надо создавать окружения для каждого из наших python проектов, чтобы их зависимости не начали конфликтовать между собой. Для этого воспользуемся virtualenv.
Создаем папку проекта в домашней и стартуем в ней новое изолированное окружение.
Теперь у нас есть локальная копия python, pip и все python модули установленные внутри останутся в этом окружении.
Устанавливем Flask и UWSGI
Бота будем писать на микрофреймворке flask, который позволит нам сократит время на разработку. Для перенаправления запросов с nginx на flask будем пользоваться uwsgi.
Для начала запустим простую страничку в Flask и попробуем достучаться к ней через nginx.
В папке с проектом создадим наш главный файл в котором будет хранится код.
Так же напишем скрипт, который будет запускать наше Flask приложение.
Оба файла находятся в папке с проектом.
Запускам uwsgi командой:
Если все прошло успешно, вы, перейдя в своем браузере по адресу вашего сервера и порт 5000 должны увидеть It’s working.
Теперь напишем конфиг файл, чтобы Flask приложение поднималось само, даже если сервер перезагрузится. Сначала выйдем из нашего окружения.
Потом создадим .ini конфиг для uwsgi в папке с ботом по пути
/CSBot/csbot.ini . Конфиг задает количество процессов, имя сокета, права и файл для логирования.
Так же создадим папку для логов и сделаем ее владельцем себя.
Создадим так же systemd unit файл, для атвоматизации запуска нашего бота.
Теперь после ввода команды, мы должны увидеть сокет файл в нашей папке проекта.
Мы так же можем проверить работу с помощью просмотра логов в папке и статуса сервиса.
Настройка nginx
Дальше нам необходимо настроить веб сервер, чтобы свои запросы он направлял в сокет uwsgi.
Теперь нам надо сделать ссылку на конфиг, в папке sites-enabled
Мы можем проверить наши конфиг файлы с помощью nginx.
Если он сказал, что все ОК, перезапускаем веб сервер.
Теперь по ip адресу нашего сервера в браузере вы должны получить выдачу Flask приложения.
Сначала генерируем наш сертификат и ключ с помощью openssl.
На последней команде openssl задаст вам несколько вопросов. Можно игнорировать все, кроме Common Name (FQDN). В нем следует указать ip вашего сервера.
Следующей командой мы получим сертификат из сгененрированного выше приватного ключа.
Так-с, серты сгенерировали. Идем к настройке nginx.
Открываем конфиги нашего сайта в nginx:
Указвыаем новый порт взамен 80. Указвыаем ключи и сертификаты и протоколы, которые мы можем хендлить.
Проверяем конфиги и перезапускаем веб сервер
Пишем код для бота
Дошли до самого интересного.
Сначала установим модуль для работы с Telegram - python-telegram-bot
Теперь напишем код бота (
В начале мы импортируем нужные модули flask, request, telegram. Дальше мы создаем наше приложение, включаем режим отладки (надо присвоить False, когда закончим разработку).
После мы задаем наш token полученный при создании бота в самом начале, адрес сервера и создаем бота.
У нас есть два главных метода:
*set_webhook - отвечает за создание вебхука с сервером Telegram и вызывается один раз.
Давайте чуть усложним его и добавим кнопку “Обновить”.
Немного функционала
Напишем функцию, которая будет опрашивать наш CS сервер и выдавать информацию по нему.
Для начала установим наш модуль для работы с valve серверами. Не забудьте перейти в окружение перед установкой.
Теперь в коде определим новую функцию, которая будет генерить строку ответ и возвращать ее нам, для отправки пользователю.
Код сам по себе не сложен, но давайте разберем. Сначала задаем адрес и порт сервера и создаем объект.
Данная заметка это продолжение статьи про написание telegram бота, в ней я постараюсь максимально подробно осветить тему разворачивания (deploy) полноценного, хотя и маленького, Django приложения в production среде на ОС Linux, Ubuntu 14.04 LTS. К концу статьи у нас будет полноценный telegram бот, крутящийся в вебе и принимающий команды от пользователей этого мессенджера.
Чему вы научитесь после прочтения заметки:
- Разворачивать Django приложение (да и любое WSGI приложение) на хостинге Digital Ocean в среде Linux
- Работать с веб-серверами nginx и gunicorn
- Управлять процессами, используя утилиту supervisord
- Настраивать virtualenv с помощью pyenv
- Автоматически запускать веб-приложение даже после перезагрузки сервера
В сентябре 2015 года мы проводили Python митап в Алматы на котором я выступал с докладом на тему веб-разработки на Python. Во время выступления я вкратце описал веб эко-систему Python и сделал краткий обзор популярного инструментария. К сожалению, формат митапа не предусматривал детальный разбор темы, поэтому новичкам в этой области обычно приходится дальше копаться самостоятельно. Сегодня я постараюсь восполнить этот пробел и немного углубиться в "горячую" тему деплоя веб приложений на Python. Несмотря на то, что в статье речь будет идти о Django приложении, описываемые рецепты будут актуальны и для других веб-проектов, разработанных на Python с использованием WSGI-совместимых фреймворков (Flask, Bottle, Pyramid, Falcon, web2py и так далее).
В заметке я буду делать деплой на виртуальном хостинге от Digital Ocean. Если вы зарегистрируетесь по этой ссылке, то после подтверждения платёжных данных, счёт вашего аккаунта сразу пополнится на $10, которые можно потратить на создание маленьких дроплетов (виртуальных серверов) и потренироваться в разворачивании веб проектов на Python. Сразу скажу, что вам необязательно всё делать на удалённой машине и вообще использовать хостинг-провайдер, можно обойтись и локальной виртуалкой, например, используя VirtualBox и Vagrant (но в таком случае невозможно будет установить webhook).
Создание виртуального сервера
Как я ранее уже упоминал, деплой мы будет производить на одном из виртуальных серверов DigitalOcean с его мощным API :)
Создаём дроплет, нажимая на "Create droplet" в правом верхнем углу панели управления:
Выбираем самый минимальный тариф за 5 долларов в месяц с операционной системой Ubuntu 14.04.4 LTS на борту будущей виртуальной машины.
В качестве дата-центра я практически всегда выбираю Frankfurt, так как до него у меня самый лучший пинг. После заполнения всех необходимых полей, нажимаем кнопку "Create". Дроплет создаётся в течение 60 секунд после которых на почту поступает вся необходимая для доступа информация о новой виртуальной машине: IP адрес, логин и пароль.
Настройка сервера
После успешного создания нам необходимо авторизоваться на сервере. Сразу после входа, система попросит установить новый пароль для суперпользователя root.
Далее необходимо завести отдельного sudo пользователя из под которого будем запускать Django приложение.
Заходим под новым юзером django на сервер, и все остальные команды выполняем из под данного юзера.
Устанавливаем необходимый арсенал для настройки виртуального окружения через Pyenv и сборки самой последней версии Python (2.7.11).
После этого ставим сам Pyenv. Подробнее о том что такое Pyenv и как его настроить можно прочитать здесь:
Устанавливаем Python самой последней версии (Python 2.7.11):
Выполнение команды займёт некоторое время (скрипт скачает Python и скомпилирует его из исходников). Устанавливая отдельный интерпретатор питона мы тем самым никак не влияем на работу системного, более того, в последней LTS версии Ubuntu (14.04) используется версия 2.7.6, в которой существует ряд серьёзных уязвимостей, включая баг с SSL, а также отсутствует поддержка TLS 1.2
Клонируем репозиторий с Django проектом:
Далее настраиваем виртуальное окружения Python, используя всё тот же pyenv.
Ставим зависимости через менеджер пакетов pip.
Django приложение, написанное в первой части, претерпело незначительные изменения. В частности я перенёс изменяемые части кода в специальный .env файл, используя библиотеку django-environ. Ознакомиться с изменениями можно по этой ссылке.
Создаём .env файл из шаблона и заполняем необходимые настройки.
В частности необходимо изменить режим DEBUG на False, прописать токен для Telegram бота и указать дополнительный хост через запятую в ALLOWED_HOSTS. В моём случае ALLOWED_HOSTS выглядит вот так:
То есть я завёл дополнительный поддомен на котором и будет крутиться Telegram бот.
Настройка SSL сертификата
В прошлой статье я писал о том, что в случае использования API вызова setWehook, хосту необходимо иметь валидный SSL сертификатом (Telegram позволяет использовать также самоподписанные сертификаты). Сертификат мы будет создавать через бесплатный сервис выдачи SSL сертификатов Let's Encrypt.
Настройка Nginx
Заполняем новый файл telegram_bot.conf следующим содержимым:
Прописываем наш новый конфиг в настройки nginx и перезагружаем его, чтобы изменения вступили в силу:
Что мы только что сделали?
Чтобы проверить успешность наших настроек, можно запустить django приложение через тестовый сервер командой runserver на 8001 порту и зайти на сайт:
URL Not Found это нормальное явление, так как у нас задан всего 1 валидный URL для непосредственной работы с Telegram - /planet/bot/<BOT_TOKEN>/ (не считая настройки Django админки).
Настройка Gunicorn через Supervisor
Пора приступить к настройке production-ready HTTP сервера Gunicorn, который, кстати, полностью написан на языке Python и хорошо зарекомендовал себя в реальном бою (к слову, во всех "живых" проектах я использую именно эту связку: nginx+gunicorn)
Что такое Supervisor?
Supervisor это утилита процесс-менеджер. Она "следит за здоровьем" ваших процессов-демонов и в случае их падения, старается снова их поднять. Если в ходе работы Gunicorn "падает" (системная ошибка, не та фаза луны и так далее), Supervisor старается его снова "поднять", таким образом работоспособность сайта не страдает. К слову, у меня в планах есть идея написать небольшую заметку про эту утилиту, так сказать Supervisor Advanced Usage. Стоит отметить, что все процессы, запущенные в Supervisor должны работать в foreground режиме, чтобы утилита понимала когда что-то идёт не по плану.
Для начала составим конфигурационный файл для запуска Gunicorn внутри Supervisor. Его содержимое выглядит вот так:
Сохраняем файл под именем gunicorn.conf (
/planetpython_telegrambot/gunicorn.conf). К слову, Gunicorn прописан в зависимостях нашего проекта (requirements.txt) и так как мы его уже установили в наше окружение, то узнать путь исполняемого файла можно выполнив команду внутри активированного виртуального окружения (активация происходит автоматически при переходе в директорию веб-приложения из-за наличия там файла .python-version, созданного через pyenv local):
Содержимое конфигурационного файла для supervisord:
Далее выполняем запуск Supervisor демона командой:
Запуск должен пройти без каких либо ошибок. Чтобы узнать статус текущих процессов, запускаем утилиту supervisorctl:
Для получения помощи, можно выполнить команду help. А для получения информации о команде - help . Например:
После успешного запуска supervisor, сайт должен быть доступен онлайн.
Автозапуск веб-приложения при перезагрузке
Доводилось ли вам слышать про так называемые upstart файлы? Именно написанием одного из них мы сейчас и займёмся. К слову, на текущий момент Upstart признана устаревшей и в новых версиях ОС на базе Linux планируется полный переход на systemd.
Файл должен быть помещён в /etc/init/ (в моём случае я дал ему имя telegram_bot.conf). Если ранее все запуски не вызывали проблем, то после рестарта системы, приложение автоматически будет запущено:
Теперь необходимо прописать наш URL на стороне Telegram используя вызов API метода setWebhook:
На этом настройка бота закончена. Посылаем команды нашему боту @PythonPlanetBot и получаем адекватные ответы :)
Читайте также: