Мы с вами научились выкладывать наши сайты и ботов на Pythonanywhere, но это не единственный вариант. Существуют другие подобные сервисы - Heroku, Scalingo, Openshift.
Все они являются PaaS - Platform-as-a-Service, которые позволяют вам очень просто пользоваться облачным хостингом и быстро выкладывать свои приложения вместо того, чтобы самостоятельно настраивать сервер.
От Pythonanywhere они отличаются тем, что для них разработчиками не всегда предоставлен такой же удобный веб-интерфейс, в котором многое делается кнопочками в панели управления, и нужный функционал мы получем через командную строку Unix. Но ощее с Pythonanywhere у них то, что там есть возможность делать хотя бы что-то из того, что вам нужно, бесплатно.
Дело в том, что вслед за компанией Amazon многие другие IT-компании стали предоставлять пользователям (в числе которых и частные лица, и компании поменьше) облачные сервисы, то есть возможность не содержать на свои средства большой парк серверов (это часто неудобно, потому что бесперебойную работу серверов обеспечить не так просто), а покупать место на мощных серверах, которые содержит хозяин облака. Основные конкурирующие на этом поле сервисы -- это Amazon Web Services, Google Cloud и Microsoft Azure. Все они платные (Google предоставляет на своей платформе условно-бесплатный тестовый период в один месяц), но мощные и надёжные.
У бесплатных аккаунтов Heroku есть некоторое количество преимуществ перед аналогичными аккаунтами Pythonanywhere:
Pythonanywhere | Heroku |
---|---|
только одно приложение | несколько приложений |
свой домен - платная функция | позволяет использовать собственное доменое имя |
ограниченный доступ к внешним ресурсам | доступ к внешним ресурсам не ограничен |
Подробнее про ограниченный доступ: на Pythonanywhere можно обращаться лишь к тем сайтам, которые входят в белый список разрешенных ресурсов. Т.е. например, наш сайт, который регулярно скачивает новости с hse.ru не будет работать на Pythonanywhere, потому что hse.ru не включен в белый список. На Heroku таких ограничений нет.
Подробнее про количество бесплатных приложений: на Heroku можно создавать несколько приложений бесплатно лишь до тех пор, пока у вас есть свободные Dyno (про это будет ниже).
- Чтобы наш фласк-сайт или фласк-бот заработал на Heroku, нужно убедиться, что в конце основной программы написан вот такой код:
if __name__ == '__main__':
import os
app.debug = True
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port)
-
В директории с вашим фласк-приложением обязательно должны быть следующие три файла:
-
requirements.txt
- в этом файле нужно перечислить все не стандартные питоновские модули, которые необходимы для вашей программы. В списке нужно указать не только название модуля, но и нужную вам версию. Выглядеть это будет примерно так:Flask==0.12.1 pymorphy2==0.8 pymystem3==0.1.5 requests==2.13.0
Обратите внимание, что в этот список НЕ НУЖНО писать setuptools и pip!
Когда вы будете выкладывать приложение, Heroku прочитает файл
requirements.txt
и установит все перечисленные модули командойpip install -r requirements.txt
.-
runtime.txt
- в этом файле нужно написать одну строчку:python-3.6.1
Если в директории нет
runtime.txt
, то Heroku будет по умолчанию думать, что ваше приложение написано на Python 2.7.-
Procfile
- обратите внимание, что у файла нет расширения, иначе heroku не сможет прочитать его содержимое. В этом файле нужно написать одну строчку:web: python flask_app.py
Вместо
flask_app.py
нужно написать название вашего файла с фласк-приложением.Procfile
- это специальный файл, в котором нужно объяснить Heroku, как именно нужно запускать ваше приложение.web
значит, что мы написали приложение, которое отвечает на http-запросы,python flask_app.py
обозначает команду, с помощью которой приложение запускается. -
-
Для выкладывания приложений на Heroku используется git. Поэтому если в вашей директории с проектом еще нет git-репозитория, его нужно создать. Открываем терминал (Mac, Linux) или командную строку (Windows) и пишем:
cd путь-к-директории
- переходим в директорию с нашим фласк-проектом,git init
- создаем в текущей директории репозиторий,git add *
- говорим гиту следить за всеми файлами в репозитории,git commit -m 'Initial commit'
- делаем первый коммит.
-
Зарегистрироваться на сайте Heroku, ваш email будет логином. Когда вы зарегистрировались, вы попадаете в Dashboard. Сейчас у вас там ничего нет - вам предлагают создать приложение (an app) или пройти туториал по работе с Heroku и выбранного вами языка программирования. Туториал по питону там ориентирован на джанго, мы работаем с фласком, так что наши действия будут слегка отличаться.
-
Скачать установщик для вашей ОС и установить Heroku CLI - Command Line Interface - https://devcenter.heroku.com/articles/heroku-cli
-
Открыть терминал (Mac, Linux) или командную строку (Windows) и выполнить команды:
cd путь-к-директории
- переходим в директорию с нашим фласк-проектом,heroku login
- логинимся в наш аккаунт Heroku,- ввести свой емейл и пароль, с которыми мы зарегистрировались,
heroku create
- создаем приложение, которое поможет Heroku получить наш код и запустить его. В этот момент Heroku делает сразу несколько вещей.
Во-первых, он генерирует случайное название для нашего приложения, но можно передать ваше собственное название, например,
heroku create my-app-04062017
. Ваш сайт будет доступен по адресуимя-приложения.herokuapp.com
.Во-вторых, к вашему репозиторию добавляется удаленный репозиторий (git remote), который называется
heroku
. У одного локального репозитория на вашем компьютере может быть несколько удаленных (например, у вас может бытьorigin
- это ваш удаленный репозиторий на GitHub, иheroku
- удаленный репозиторий на Heroku.)-
git push heroku master
- эта команда отправляет наш код на облачный хостринг, и Heroku устанавливает нужные модули. -
heroku ps:scale web=1
- эта команда говорит запустить наш фласк-сайт на одном dyno.A dyno is a lightweight Linux container that runs a single user-specified command.
То есть ваш сайт или бот будет работать на маленьком виртуальном Линукс-"сервере". Бесплатно вам доступно 550 или 1000 таких dyno.
-
heroku open
- эта команда открывает ваш сайт в браузере. Ура! Все готово! -
Если по какой-то причине сайт не заработал, то нужно посмотреть логи:
heroku logs
- эта команда распечатает 100 последних строчек логов, т.е. если произошла какая-то ошибка, то информацию об этой ошибке вы увидите в конце логов.- или
heroku logs --tail
- эта команда показывает логи в реальном времени, т.е. если ваша программа что-то печатает в консоль с помощьюprint(...)
или питон печатает сообщение об ошибке, то вы будете в реальном времени видеть, что именно происходит. - подробнее - https://devcenter.heroku.com/articles/logging
Когда вы меняете что-то в вашей программе\директории, то изменения нужно отправить на Heroku:
git add *
git commit -m "Demo"
git push heroku master
heroku ps:scale web=1
Поскольку мы отправляем все файлы на Heroku через git, возникает небольшая проблема:
Что если у нас есть секретные файлы (например, API-токены или пароли), которые включены в .gitignore
? Получается, мы никак не сможем отправить эти секретные файлы на облачный хостинг через git.
Для работы с секретами рекомендуется использовать переменные среды: ваши ключи будут храниться в текстовых переменных вашей системы и в вашем Heroku-приложении, но при этом они никогда не попадут в открытый git-репозиторий.
Раньше мы с вами писали секретные ключи в игнорируемый файл (например, TOKEN = "......"
внутри conf.py
) и импортировали секретные переменные с помощью from conf import *
.
Вместо этого, можно установить переменную среды прямо в терминале\командной строке:
- Mac, Linux -
export SOME_SECRET_KEY=1c3-cr3am-15-yummy
- Windows -
set SOME_SECRET_KEY 1c3-cr3am-15-yummy
(если у вас Windows 10, тоsetx
) - Heroku -
heroku config:set SOME_SECRET_KEY=1c3-cr3am-15-yummy
После этого и на вашем компьютере, и в облачном хостинге Heroku переменную среды можно прочитать с помощью питона:
>>> import os
>>> os.environ["SOME_SECRET_KEY"]
"1c3-cr3am-15-yummy"
То есть строчку from conf import *
вам придется заменить на строчки вида:
import os
SOME_SECRET_KEY = os.environ["SOME_SECRET_KEY"]
Кроме того, старые вебхуки с адресом на pythonanywhere уже не действительны, и их надо заменить на адрес вашего приложения. В целом, код очень простого бота из первого конспекта по телеграму, адаптированный под Heroku, будет выглядеть вот так:
import flask
import telebot
import os
TOKEN = os.environ["TOKEN"]
bot = telebot.TeleBot(TOKEN, threaded=False)
bot.remove_webhook()
bot.set_webhook(url="https://<your app_name>.herokuapp.com/bot")
app = flask.Flask(__name__)
@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
bot.send_message(message.chat.id, "Здравствуйте! Это бот, который считает длину вашего сообщения.")
@bot.message_handler(func=lambda m: True) # этот обработчик реагирует все прочие сообщения
def send_len(message):
bot.send_message(message.chat.id, 'В вашем сообщении {} символов.'.format(len(message.text)))
@app.route("/", methods=['GET', 'HEAD'])
def index():
return 'ok'
# страница для нашего бота
@app.route("/bot", methods=['POST'])
def webhook():
if flask.request.headers.get('content-type') == 'application/json':
json_string = flask.request.get_data().decode('utf-8')
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return ''
else:
flask.abort(403)
if __name__ == '__main__':
import os
app.debug = True
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port)
Если вы делаете какой-то веб-сервис, который должен обновлять какие-то данные через определённые промежутки времени (например, каждый день в 12:00 или каждый четверг в 17:25), то вы можете настроить стандартную Unix-утилиту cron, которая умеет запускать на сервере какой-то нужный пользователю процесс в тот момент, когда это ему необходимо.
Утилита cron обычно уже входит в стандартную сборку дистрибутива и устанавливать её не нужно. Она имеет текстовый интерфейс настройки, то есть расписание придётся писать через консоль, в одном из консольных текстовых редакторов. Наиболее популярный из них -- Vim. Он не очень прост в обращении, потому что неинтуитивен. Перед тем, как его запускать, узнайте, как его закрыть (почти как в сказке, нужно помнить про "горшочек, не вари", прежде чем сказать "горшочек, вари"). Недавно крупный сайт подсказок и ответов на вопросы о программировании Stackoverflow опубликовал новость, из которой следует, что вопрос "как выйти из Vim" является чуть ли не самым популярным при поиске вопросом.
Есть и другой консольный редактор, nano, он проще и все команды, которые вы должны выполнить для тех или иных действий, постоянно показываются внизу экрана ("крышечка" означает "Ctrl"):
Однако он не установлен по умолчанию во всех дистрибутивах, и, возможно, его придётся установить самостоятельно.
Создать или отредактировать расписание можно вызовом команды crontab -e
. В открывшемся окне нужно будет описать в формате cron, что вы хотите, чтобы было сделано, и когда это должно быть сделано. Формат cron подразумевает, что вы напишете минута час день_месяца месяц день_недели команда
, а потом -- то, что должно будет запуститься, в том виде, в котором бы вы сами это запускали вручную в командной строке.
Примеры расписания в cron:
# нечто будет выполняться каждую минуту:
* * * * * python3 /home/user/script.py
# только по выходным:
* * * * 6,7 python3 /home/user/weekend.py
# дважды в день:
20 11,16 * * * python3 /home/user/twice.py
# один раз в году, в полночь 1-го января:
0 0 1 1 * python3 /home/user/HappyNewYear.py
Обратите внимание, что к программам нужно писать полный путь, потому что cron ничего не знает про то, какую директорию вы считаете рабочей.
Тут можно найти ещё одно руководство по запуску бота на хероку.