Проект Python для начинающих: уведомления о ценах на биткойны

Проект Python для начинающих: уведомления о ценах на биткойны

Добро пожаловать в первую статью из серии статей о проектах Python для начинающих!

В этом уроке мы собираемся создать сервис уведомления о ценах в биткойнах -

В рамках этого проекта вы узнаете о HTTP-запросах и о том, как их отправлять с помощью пакета (с соответствующим названием)requests.

Вы узнаете о веб-хуках и о том, как их можно использовать для подключения приложения Python к внешним службам, таким как телефонные уведомления или сообщения Telegram.

С относительно небольшим кодом (~ 50 строк) вы получите полноценную услугу уведомления о ценах в биткойнах, которая будет легко распространяться на другие криптовалюты и сервисы.

Итак, давайте прыгнем прямо в:

Уведомления о ценах на биткойны с Python

Как мы все знаем, цена биткойна - вещь непостоянная. Вы никогда не знаете, где это будет в конце дня. Итак, вместо того, чтобы постоянно проверять различные сайты на наличие последних обновлений, давайте сделаем приложение Python, которое сделает всю работу за вас.

Для этого мы воспользуемся популярным сайтом автоматизацииIFTTT. IFTTT («если это, то это») - это веб-сервис, который устраняет разрыв между различными приложениями и устройствами.

Мы собираемся создать два апплета IFTTT:

  • Один для экстренного уведомления, когда цена биткойна падает ниже определенного порога; и

  • другой для регулярных обновленийTelegram о цене биткойнов.

Оба будут запущены нашим приложением Python, которое будет потреблять данные изCoinmarketcap API.

Апплет IFTTT состоит из двух частей: триггера и действия.

В нашем случае триггером будет услуга webhook, предоставляемая IFTTT. Вы можете думать о веб-перехватчиках как о «определяемых пользователем обратных вызовах HTTP», и вы можете прочитать о них большеhere.

Наше приложение Python сделает HTTP-запрос к URL-адресу webhook, который запустит действие. Теперь это забавная часть - действие может быть почти любым, что вы хотите. IFTTT предлагает множество действий, таких как отправка электронной почты, обновление таблицы Google и даже вызов вашего телефона.

Настройка проекта

Начнем с настройкиvirtual environment. Запустите эту команду, чтобы получить новую виртуальную среду Python 3:

$ mkvirtualenv -p $(which python3) bitcoin_notifications

Прежде чем продолжить, вы должны активировать виртуальную среду и установить необходимые зависимости:

$ workon bitcoin_notifications  # To activate the virtual environment
$ pip install requests==2.18.4  # We only need the requests package

Вы можете деактивировать виртуальную среду, выполнив команду оболочкиdeactivate.

Получение биткойн-цены

Время пачкать руки. Мы можем начать с получения последней цены от API Coinmarketcap в консоли Python:

Во-первых, мы должны импортировать модульrequests и определить переменнуюbitcoin_api_url, которая содержит URL-адрес API Coinmarketcap для биткойнов.

Затем мы отправляем HTTP-запрос GET на URL-адрес с помощью функцииrequests.get() и сохраняем ответ. Поскольку API возвращает ответ JSON, мы можем преобразовать его в объект Python, вызвав функцию.json() в ответе. Как видите, API вернул список с одним элементом, содержащим данные о ценах биткойнов:

>>>

>>> import requests
>>> bitcoin_api_url = 'https://api.coinmarketcap.com/v1/ticker/bitcoin/'
>>> response = requests.get(bitcoin_api_url)
>>> response_json = response.json()
>>> type(response_json) # The API returns a list

>>> # Bitcoin data is the first element of the list
>>> response_json[0]
{'id': 'bitcoin', 'name': 'Bitcoin', 'symbol': 'BTC', 'rank': '1',
 'price_usd': '10226.7', 'price_btc': '1.0', '24h_volume_usd': '7585280000.0',
 'market_cap_usd': '172661078165', 'available_supply': '16883362.0',
 'total_supply': '16883362.0', 'max_supply': '21000000.0',
 'percent_change_1h': '0.67', 'percent_change_24h': '0.78',
 'percent_change_7d': '-4.79', 'last_updated': '1519465767'}

Свойство, которое нас больше всего интересует, - это'price_usd' - цена биткойнов в долларах США.

Отправка тестового уведомления IFTTT

Теперь мы можем перейти на сторону IFTTT. Чтобы использовать IFTTT, вам сначала потребуетсяset up a new account и установить его мобильное приложение (если вы хотите получать телефонные уведомления из приложения Python). После того, как вы это настроите, мы собираемся использоватьcreate новый апплет IFTTT дляtesting purposes.

Чтобы создать новый тестовый апплет, выполните следующие действия:

  1. Нажмите на большую кнопку“this”

  2. Найдите сервис“webhooks” и выберите триггер“Receive a web request”

  3. Назовем событиеtest_event

  4. Теперь нажмите большую кнопку“that”

  5. Найдите сервис“notifications” и выберите“Send a notification from the IFTTT app”

  6. Измените сообщение наI just triggered my first IFTTT action! и нажмите“Create action”

  7. Нажмите на кнопку“Finish”, и все готово

Чтобы увидеть документацию по использованию веб-перехватчиков IFTTT, перейдите к этомуpage и нажмите кнопку“Documentation” в правом верхнем углу. Страница документации содержит URL-адрес webhook и выглядит так:

https://maker.ifttt.com/trigger/{event}/with/key/{your-IFTTT-key}

Далее вам нужно будет заменить часть{event} тем именем, которое вы дали нашему событию на шаге 3, когда вы создавали апплет. Часть{your-IFTTT-key} уже заполнена вашим ключом IFTTT.

Теперь скопируйте URL-адрес webhook и запустите другую консоль Python. Мы снова импортируем модульrequests и определяем переменную URL-адреса веб-перехватчика. Теперь нам просто нужно отправить HTTP-запрос POST на URL-адрес веб-перехватчика IFTTT, используя функциюrequests.post():

>>>

>>> import requests
>>> # Make sure that your key is in the URL
>>> ifttt_webhook_url = 'https://maker.ifttt.com/trigger/test_event/with/key/{your-IFTTT-key}'
>>> requests.post(ifttt_webhook_url)

После запуска последней строки на вашем телефоне должно появиться уведомление:

Python + IFTTT: Test Notification

Создание IFTTT апплетов

Теперь мы наконец готовы к основной части. Перед тем, как начать с кода, нам нужно создать два новых апплета IFTTT: один для экстренных уведомлений о цене биткойнов и один для регулярных обновлений.

Апплет аварийного уведомления о цене биткойнов:

  1. Выберите сервис“webhooks” и выберите триггер“Receive a web request”

  2. Назовите событиеbitcoin_price_emergency

  3. Для действия выберите сервис“Notifications” и выберите действие“Send a rich notification from the IFTTT app”

  4. Дайте ему название, например“Bitcoin price emergency!”

  5. Установите для сообщения значениеBitcoin price is at ${{Value1}}. Buy or sell now! (мы вернемся к части{{Value1}} позже)

  6. При желании вы можете добавить URL-адрес ссылки на страницу биткойнов Coinmarketcap:https://coinmarketcap.com/currencies/bitcoin/

  7. Создайте действие и завершите настройку апплета

Апплет регулярного обновления цен:

  1. Снова выберите сервис“webhooks” и выберите триггер“Receive a web request”

  2. Назовите событиеbitcoin_price_update

  3. Для действия выберите сервис“Telegram” и выберите действие“Send message”

  4. Задайте текст сообщения:Latest bitcoin prices:<br>{{Value1}}

  5. Создайте действие и закончите апплетом

Note: При создании этого апплета вам нужно будет авторизовать бота IFTTT Telegram.

Собираем все вместе

Теперь, когда у нас есть IFTTT, давайте начнем кодировать! Вы начнете с создания стандартного каркаса приложения командной строки Python, показанного ниже. Возьмите этот код и сохраните его в файле с именемbitcoin_notifications.py:

import requests
import time
from datetime import datetime

def main():
    pass

if __name__ == '__main__':
    main()

Затем мы должны перевести два предыдущих сеанса консоли Python в две функции, которые будут возвращать последнюю цену биткойнов и публиковать их в веб-крюке IFTTT соответственно. Добавьте следующие функции над основной функцией:

BITCOIN_API_URL = 'https://api.coinmarketcap.com/v1/ticker/bitcoin/'
IFTTT_WEBHOOKS_URL = 'https://maker.ifttt.com/trigger/{}/with/key/{your-IFTTT-key}'

def get_latest_bitcoin_price():
    response = requests.get(BITCOIN_API_URL)
    response_json = response.json()
    # Convert the price to a floating point number
    return float(response_json[0]['price_usd'])


def post_ifttt_webhook(event, value):
    # The payload that will be sent to IFTTT service
    data = {'value1': value}
    # inserts our desired event
    ifttt_event_url = IFTTT_WEBHOOKS_URL.format(event)
    # Sends a HTTP POST request to the webhook URL
    requests.post(ifttt_event_url, json=data)

get_latest_bitcoin_price почти такой же, за исключением той части, где нам нужно преобразовать цену из строки в число с плавающей запятой. post_ifttt_webhook принимает два параметра:event иvalue.

Параметрevent соответствует любому имени события, которое мы дали нашему триггеру при настройке апплета IFTTT. Кроме того, веб-зацепки IFTTT позволяют нам отправлять дополнительные данные вместе с запросом в виде данных в формате JSON.

Вот почему нам нужен параметрvalue: при настройке наших апплетов мы оставили тег{{Value1}} в наших полях сообщений. Этот тег заменяется текстом'value1' из полезных данных JSON. Функцияrequests.post() позволяет нам отправлять дополнительные данные JSON, просто добавляя ключевое словоjson.

Теперь мы можем перейти к ядру нашего приложения в функцииmain. Он будет состоять из циклаwhile True, поскольку мы хотим, чтобы наше приложение работало вечно. В цикле мы будем вызывать API Coinmarketcap, чтобы получить последнюю цену биткойна и записать текущую дату и время.

На основании текущей цены мы решим, хотим ли мы отправить экстренное уведомление. Для наших регулярных обновлений Telegram мы также будем добавлять текущую цену и дату в списокbitcoin_history. Как только список достигает определенного количества предметов (например, 5) мы отформатируем элементы, отправим обновление в Telegram и сбросим историю для будущих обновлений.

Wheew! Как видите, в этом приложении происходит много всего. Если у вас возникли проблемы с выполнением кода, который мы получили до сих пор, сделайте небольшой перерыв и снова перечитайте приведенный выше раздел. Это нелегко, поэтому не торопитесь и не беспокойтесь о том, чтобы все было идеально с первого раза.

Важно избегать частой отправки этих запросов по двум причинам:

  • API Coinmarketcap утверждает, что они обновляют данные только раз в 5 минут, поэтому нет смысла перезагружать последнюю информацию о ценах чаще, чем это.

  • если ваше приложение отправляет слишком много запросов в API Coinmarketcap, ваш IP может быть заблокирован или временно приостановлен.

Вот почему нам нужно «пойти спать» (остановить выполнение цикла) как минимум на 5 минут, прежде чем мы получим новые данные. Код ниже реализует все необходимые функции, которые я изложил выше:

BITCOIN_PRICE_THRESHOLD = 10000  # Set this to whatever you like

def main():
    bitcoin_history = []
    while True:
        price = get_latest_bitcoin_price()
        date = datetime.now()
        bitcoin_history.append({'date': date, 'price': price})

        # Send an emergency notification
        if price < BITCOIN_PRICE_THRESHOLD:
            post_ifttt_webhook('bitcoin_price_emergency', price)

        # Send a Telegram notification
        # Once we have 5 items in our bitcoin_history send an update
        if len(bitcoin_history) == 5:
            post_ifttt_webhook('bitcoin_price_update',
                               format_bitcoin_history(bitcoin_history))
            # Reset the history
            bitcoin_history = []

        # Sleep for 5 minutes
        # (For testing purposes you can set it to a lower number)
        time.sleep(5 * 60)

Мы почти закончили! Не хватает только функцииformat_bitcoin_history. Он принимаетbitcoin_history в качестве аргумента и форматирует его, используя некоторые из основных HTML-тегов, разрешенных Telegram, например<br>,<b>,<i> и т. Д. Скопируйте эту функцию над функциейmain:

def format_bitcoin_history(bitcoin_history):
    rows = []
    for bitcoin_price in bitcoin_history:
        # Formats the date into a string: '24.02.2018 15:09'
        date = bitcoin_price['date'].strftime('%d.%m.%Y %H:%M')
        price = bitcoin_price['price']
        #  (bold) tag creates bolded text
        # 24.02.2018 15:09: $10123.4
        row = '{}: ${}'.format(date, price)
        rows.append(row)

    # Use a 
(break) tag to create a new line # Join the rows delimited by
tag: row1
row2
row3 return '
'.join(rows)

Вот как должен выглядеть конечный результат на вашем телефоне:

Python + IFTTT: Bitcoin Telegram

Чтобы запустить приложение для уведомления о ценах, выполните следующие действия в терминале командной строки:

$ python bitcoin_notifications.py

Это оно! В чуть более 50 строк кода Python вы создали свою собственную службу уведомлений Биткойн. Поздравляем! Ниже я добавил весь код, чтобы вы могли сравнить и посмотреть, пропустили ли вы что-нибудь:

Резюме и следующие шаги

В этой статье мы создали собственный сервис уведомлений о биткойнах. Вы узнали, как отправлять HTTP-запросы GET и POST с помощью пакетаrequests. Вы видели, как легко было подключить приложение Python к внешним сервисам, используя IFTTT и веб-хуки

Теперь, куда вы должны идти дальше? С Python и IFTTT небо - это предел. Но вот несколько советов, которые помогут вам начать:

  • Как электронные таблицы? Используйте действие IFTTT, которое добавит цены на биткойны в таблицу Google.

  • Улучшите условиеif price < BITCOIN_PRICE_THRESHOLD, чтобы получать уведомление только один раз в день (иначе это будет сильно раздражать, если биткойн будет постоянно низким)

  • Нравится Ethereum / Litecoin / Dogecoin лучше? Изменитеget_latest_bitcoin_price наget_latest_cryptocurrency_price, который будет принимать криптовалюту в качестве параметра и возвращать ее цену.

  • Вы хотите цену в другой валюте? Проверьте API Coinmarketcap на наличие параметраconvert.

Кроме того, это будет продолжающаяся серия с большим количеством проектов Python, которые вы можете построить, чтобы развивать свои навыки. Не пропустите следующий урок:

Get Notified: Не пропустите продолжение этого руководства - https: //realpython.com/bonus/newsletter-dont-miss-updates/ [Щелкните здесь, чтобы присоединиться к информационному бюллетеню Real Python], и вы узнаете, когда выходит следующая партия.

Удачи и Счастливого Питона! Дайте мне знать, что вы создали, используя Python и IFTTT в комментариях ниже!

Related