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

Содержание

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

Здесь я собираюсь создать службу уведомления о цене биткойнов

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

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

Уведомления о цене биткойнов с помощью Python    ↑

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

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

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

  1. Один для экстренного уведомления, когда цена биткойна опускается ниже определенного порога; и
  2. другой для регулярных обновлений Telegram о цене биткойнов.

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

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

В нашем случае триггером будет веб‑перехватчик, предоставляемый IFTTT. Вы можете думать о веб‑перехватчиках как о «определяемых пользователем обратных вызовах HTTP», и вы можете прочитать о них здесь. Наше приложение Python отправит HTTP‑запрос на URL‑адрес веб‑перехватчика, который вызовет действие. А теперь самое интересное — действие может быть чем угодно. IFTTT предлагает множество действий, таких как отправка электронного письма, обновление электронной таблицы Google и даже звонок на ваш телефон.

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

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

$ mkvirtualenv -p $(which python3) bitcoin_notifications

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

$ workon bitcoin_notifications  # Для активации виртуальной среды
$ pip install requests==2.18.4  # Нам нужен только пакет запросов

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

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

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

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

Затем мы отправляем 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) # API возвращает список

>>> # Биткойн-данные - это первый элемент списка
>>> 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, вам сначала нужно создать новую учетную запись и установить мобильное приложение (если вы хотите получать телефонные уведомления из своего приложения Python). Как только вы его настроите, мы создадим новый апплет IFTTT для тестирования.

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

  1. Нажмите на большую кнопку «this».
  2. Найдите службу «webhooks» и выберите триггер «Receive a web request».
  3. Назовем событие test_event
  4. Теперь нажмите большую кнопку «this»
  5. Найдите службу «notifications» и выберите «Отправить уведомление из приложения IFTTT».
  6. Измените сообщение на Я только что инициировал свое первое действие IFTTT! и нажмите «Send a notification from the IFTTT app»
  7. Нажмите кнопку «Finish», и все готово.

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

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

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

Теперь скопируйте URL‑адрес веб‑перехватчика и запустите другую консоль Python. Мы снова импортируем модуль запросов и определяем переменную 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)

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

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

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

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

  1. Выберите службу «webhooks» и выберите триггер «Receive a web reques».
  2. Назовите событие bitcoin_price_emergency.
  3. Для действия выберите службу «Notifications» и выберите действие «Send a rich notification from the IFTTT app».
  4. Дайте ему название, например «Bitcoin price emergency!»
  5. Установите сообщение в биткойнах, цена составляет ${{Value1}}. Купи или продай сейчас! (мы вернемся к части {{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. Задайте текст сообщения: Последние цены на биткойны:
    {{Value1}}
  5. Создайте действие и закончите с апплетом

Примечание. При создании этого апплета вам необходимо авторизовать бота 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.

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

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

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

  • API Coinmarketcap утверждает, что они обновляют данные только раз в 5 минут, поэтому нет смысла загружать самую свежую информацию о ценах чаще и
  • если ваше приложение отправляет слишком много запросов к Coinmarketcap API, ваш 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})

        # Отправить экстренное уведомление
        if price < BITCOIN_PRICE_THRESHOLD:
            post_ifttt_webhook('bitcoin_price_emergency', price)

        # Отправить уведомление в Telegram
        # Как только у нас будет 5 элементов в нашей bitcoin_history, отправьте обновление
        if len(bitcoin_history) == 5:
            post_ifttt_webhook('bitcoin_price_update', 
                               format_bitcoin_history(bitcoin_history))
            # Сбросить историю
            bitcoin_history = []

        # Спать 5 минут
        # (В целях тестирования вы можете установить меньшее число)
        time.sleep(5 * 60)

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

def format_bitcoin_history(bitcoin_history):
    rows = []
    for bitcoin_price in bitcoin_history:
        # Форматирует дату в строку: '24 .02.2018 15:09 '
        date = bitcoin_price['date'].strftime('%d.%m.%Y %H:%M')
        price = bitcoin_price['price']
        # Тег <b> (полужирный) создает полужирный текст
        # 24.02.2018 15:09: $<b>10123.4</b>
        row = '{}: $<b>{}</b>'.format(date, price)
        rows.append(row)

    # Используйте тег <br> (разрыв), чтобы создать новую строку
    # Присоединяйтесь к строкам, разделенным тегом <br>: row1 <br> row2 <br> row3
    return '<br>'.join(rows)

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

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

$ python bitcoin_notifications.py

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

import time
from datetime import datetime

BITCOIN_PRICE_THRESHOLD = 10000
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()
    return float(response_json[0]['price_usd'])  # Convert the price to a floating point number

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

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

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

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
        if len(bitcoin_history) == 5:  # Once we have 5 items in our bitcoin_history send an update
            post_ifttt_webhook('bitcoin_price_update', format_bitcoin_history(bitcoin_history))
            # Reset the history
            bitcoin_history = []

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

if __name__ == '__main__':
    main()

Резюме и идём дальше    ↑

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

Итак, куда вы должны пойти дальше? С Python и IFTTT нет предела. Но вот несколько советов, с которых можно начать:

  • Как электронные таблицы? Используйте действие IFTTT, которое добавит цены на биткойны в электронную таблицу Google.
  • Измените условие if price < BITCOIN_PRICE_THRESHOLD, чтобы получать уведомление только один раз в день (в противном случае, если биткойн будет постоянно низким, это будет сильно раздражать)
  • Нравится Ethereum/Litecoin/Dogecoin лучше? Измените get_latest_bitcoin_price на get_latest_cryptocurrency_price, который будет принимать криптовалюту в качестве параметра и возвращать ее цену.
  • Хотите цену в другой валюте? Проверьте Coinmarketcap API для параметра convert.

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

По мотивам Python Project for Beginners: Bitcoin Price Notifications

Print Friendly, PDF & Email

CC BY-NC 4.0 Python для начинающих: уведомления о цене биткойнов, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.


Респект и уважуха

Добавить комментарий