Welcome to the first article in a series of articles on Python projects for beginners!
In this tutorial we’re going to build a Bitcoin price notification service—
During this project you’ll learn about HTTP requests and how to send them using the (appropriately named) requests
package.
You’re going to learn about webhooks and how you can use them to connect your Python app to external services, such as phone notifications or Telegram messages.
With relatively little code (~50 lines) you’re going to arrive at a full-fledged Bitcoin price notification service that will be easily extendable to other cryptocurrencies and services.
So let’s jump right in:
Bitcoin Price Notifications With Python
As we all know, Bitcoin price is a fickle thing. You never really know where it’s going to be at the end of the day. So, instead of constantly checking various sites for the latest updates, let’s make a Python app to do the work for you.
For this, we’re going to use the popular automation website IFTTT. IFTTT (“if this, then that”) is a web service that bridges the gap between different apps and devices.
We’re going to create two IFTTT applets:
- One for emergency notification when Bitcoin price falls under a certain threshold; and
- another for regular Telegram updates on the Bitcoin price.
Both will be triggered by our Python app which will consume the data from the Coinmarketcap API.
An IFTTT applet is composed of two parts: a trigger and an action.
In our case, the trigger will be a webhook service provided by IFTTT. You can think of webhooks as “user-defined HTTP callbacks” and you can read more about them here.
Our Python app will make an HTTP request to the webhook URL which will trigger an action. Now, this is the fun part—the action could be almost anything you want. IFTTT offers a multitude of actions like sending an email, updating a Google Spreadsheet and even calling your phone.
Project Setup
Let’s start by setting up a virtual environment. Run this command to get a new Python 3 virtual environment:
$ mkvirtualenv -p $(which python3) bitcoin_notifications
Before continuing you have to activate the virtual environment and install the required dependencies:
$ workon bitcoin_notifications # To activate the virtual environment
$ pip install requests==2.18.4 # We only need the requests package
You can deactivate the virtual environment by running the deactivate
shell command.
Retrieving the Bitcoin Price
Time to get our hands dirty. We can start by getting the latest price from the Coinmarketcap API in the Python console:
First, we have to import the requests
module and define the bitcoin_api_url
variable which contains the Coinmarketcap API URL for Bitcoin.
Next, we send an HTTP GET request to the URL using the requests.get()
function and save the response. Since the API returns a JSON response, we can convert it to a Python object by calling the .json()
function on the response. As you can see, the API returned a list with one element containing the Bitcoin price data:
>>> 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
<class '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'}
The property that we’re most interested in is 'price_usd'
—the Bitcoin price in US dollars.
Sending a Test IFTTT Notification
Now we can move onto the IFTTT side of things. To use IFTTT you’ll first need to set up a new account and install their mobile app (if you want to receive phone notifications from your Python app). Once you set that up, we’re going to create a new IFTTT applet for testing purposes.
To create a new test applet follow these steps:
- Click on the big “this” button
- Search for the “webhooks” service and select the “Receive a web request” trigger
- Let’s name the event
test_event
- Now select the big “that” button
- Search for the “notifications” service and select the “Send a notification from the IFTTT app”
- Change the message to
I just triggered my first IFTTT action!
and click on “Create action” - Click on the “Finish” button and we’re done
To see the documentation on how to use the IFTTT webhooks go to this page and click on the “Documentation” button in the top right corner. The documentation page contains the webhook URL and it looks like this:
https://maker.ifttt.com/trigger/{event}/with/key/{your-IFTTT-key}
Next up, you’ll need to substitute the {event}
part with whatever name you gave our event in step 3, when you created the applet. The {your-IFTTT-key}
part is already populated with your IFTTT key.
Now copy the webhook URL and start another Python console. Again we import the requests
module and define the webhook URL variable. Now we just have to send an HTTP POST request to the IFTTT webhook URL using the requests.post()
function:
>>> 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)
<Response [200]>
After running the last line you should see a notification on your phone:
Creating IFTTT Applets
Now we’re finally ready for the main part. Before starting with the code we need to create two new IFTTT applets: one for emergency Bitcoin price notifications and one for regular updates.
Emergency bitcoin price notification applet:
- Choose the “webhooks” service and select the “Receive a web request” trigger
- Name the event
bitcoin_price_emergency
- For the action select the “Notifications” service and select the “Send a rich notification from the IFTTT app” action
- Give it a title, like “Bitcoin price emergency!”
- Set the message to
Bitcoin price is at ${{Value1}}. Buy or sell now!
(we’ll return to the{{Value1}}
part later on) - Optionally you could add a Link URL to the Coinmarketcap Bitcoin page:
https://coinmarketcap.com/currencies/bitcoin/
- Create the action and finish setting up the applet
Regular price updates applet:
- Again choose the “webhooks” service and select the “Receive a web request” trigger
- Name the event
bitcoin_price_update
- For the action select the “Telegram” service and select the “Send message” action
- Set the message text to:
Latest bitcoin prices:<br>{{Value1}}
- Create the action and finish with the applet
Note: When creating this applet you will have to authorize the IFTTT Telegram bot.
Putting It All Together
Now that we have IFTTT out of the way, let’s start coding! You’ll start by creating the standard Python command-line app skeleton shown below. Take this code and save it in a file called bitcoin_notifications.py
:
import requests
import time
from datetime import datetime
def main():
pass
if __name__ == '__main__':
main()
Next, we have to translate the two previous Python console sessions into two functions that will return the latest Bitcoin price and post to the IFTTT webhook respectively. Add the following functions above the main function:
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)
The get_latest_bitcoin_price
is pretty much the same, except for the part where we have to convert the price from a string to a floating point number. The post_ifttt_webhook
takes in two parameters: event
and value
.
The event
parameter corresponds to whatever event name we gave to our trigger when setting up the IFTTT applet. Also, the IFTTT webhooks allow us to send additional data along with the request as JSON-formatted data.
That’s why we need the value
parameter: When setting up our applets we left a {{Value1}}
tag in our message fields. This tag is replaced with the 'value1'
text from the JSON payload. The requests.post()
function allows us to send additional JSON data just by adding the json
keyword.
Now we can move on to the core of our app in the main
function. It will consist of a while True
loop since we want our app to run forever. In the loop
we will call the Coinmarketcap API to get the latest Bitcoin price and record the current date and time.
Based on the current price we will decide if we want to send an emergency notification. For our regular Telegram updates we will also append the current price and date to a bitcoin_history
list. Once the list reaches a certain number of items (e.g. 5) we will format the items, send the update to Telegram, and reset the history for future updates.
Wheew! As you can see, there’s a lot going on in this app. If you’re having trouble following the code we’ve got thus far then take a quick break and re-read the above section again slowly. This stuff isn’t easy, so take your time and don’t worry about getting everything perfect the first time around.
An important thing is to avoid sending out these requests too frequently, for two reasons:
- the Coinmarketcap API states that they update the data only once every 5 minutes, so there’s no point in reloading the latest pricing info more frequently than that
- if your app sends too many requests to the Coinmarketcap API your IP might get banned or temporarily suspended.
That is why we need to “go to sleep” (stop the execution of the loop) for at least 5 minutes before we get new data. The code below implements all of the required features I stated above:
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)
We’re almost done! The only thing missing is the format_bitcoin_history
function. It takes the bitcoin_history
as an argument
and formats it using some of the basic HTML tags allowed by Telegram, like <br>
, <b>
, <i>
, and so on. Copy this function
above the main
function:
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']
# <b> (bold) tag creates bolded text
# 24.02.2018 15:09: $<b>10123.4</b>
row = '{}: $<b>{}</b>'.format(date, price)
rows.append(row)
# Use a <br> (break) tag to create a new line
# Join the rows delimited by <br> tag: row1<br>row2<br>row3
return '<br>'.join(rows)
This is what the end result should look like on your phone:
To run your price notification app, execute the following in your command-line terminal:
$ python bitcoin_notifications.py
That’s it! In little over 50 lines of Python code, you’ve created your very own Bitcoin notification service. Congratulations! Below I’ve added the entire code so you can compare and see if you’ve missed anything:
import requests
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()
Recap and Next Steps
In this article, we created our very own Bitcoin notification service. You learned how to send HTTP GET and POST requests using the requests
package. You saw how easy it was to connect your Python app to external services using IFTTT and webhooks.
Now, where should you go next? With Python and IFTTT the sky is the limit. But here are some suggestions that can get you started:
- Like spreadsheets? Use an IFTTT action that will add the Bitcoin prices to a Google Spreadsheet
- Improve the
if price < BITCOIN_PRICE_THRESHOLD
condition to get the notification only once per day (otherwise it will get quite annoying if Bitcoin is consistently low) - Like Ethereum/Litecoin/Dogecoin better? Change the
get_latest_bitcoin_price
toget_latest_cryptocurrency_price
that will take a cryptocurrency as a parameter and return its price - You want the price in a different currency? Check the Coinmarketcap API for the
convert
parameter.
Also, this will be an ongoing series with more Python projects you can build to grow your skills. Don’t miss out on the next tutorial:
Don’t miss the follow up tutorial: Click here to join the Real Python Newsletter and you’ll know when the next installment comes out.
Good luck and Happy Pythoning! Let me know what you’ve built using Python and IFTTT in the comments below!