# Send daily email alerts of the Bitcoin Price

My script sends daily alerts of the bitcoin price to my inbox. I am using CoinDesks API, and the following libraries:

requests==2.18.4

schedule==0.5.0

and gmail sender: https://github.com/paulchakravarti/gmail-sender

Here is my code:

"""Send daily Bitcoin price alerts to inbox."""
from time import sleep

from requests import get
import schedule
from gmail import GMail, Message

def get_bitcoin_price():
"""Get current Bitcoin price in USD using Coindesk's real-time API"""
response = get('https://api.coindesk.com/v1/bpi/currentprice.json').json()

return response['bpi']['USD']['rate']

def send_email(recipient: str='walid.mujahid.dev@gmail.com'):
bitcoin_price = get_bitcoin_price()

# enter actual password, otherwise, nothing happens.
gmail = GMail('Price Alert <walid.mujahid.open@gmail.com>',
message = Message(f'Bitcoin is at {bitcoin_price} right now!',
to=recipient,
text=f'The current Bitcoin price is {bitcoin_price}.')

gmail.send(message)

if __name__ == '__main__':
schedule.every().day.at("06:30").do(send_email)

while True:
schedule.run_pending()
sleep(1)

• How/when do you run a script like this? Im learning but I assume you run the .py and just keep the IDE open? It's not a "run and done" type program, right? – BruceWayne Jan 4 '18 at 1:51
• @BruceWayne I would not keep it running through the IDE, rather I would open up the terminal and keep it running. To be honest, though, this specific script was made as a demonstration, I just wanted to see what could be improved. If were going to set it up for real, I would do so on here and use nohup. – Walid Mujahid وليد مجاهد Jan 4 '18 at 3:13
• It's amazing how few lines of code this is – Keatinge Jan 4 '18 at 11:57
• Instead of embedding the scheduling logic into the script, you could schedule your script from cron. – user84207 Jan 4 '18 at 14:02
• Enjoy Python, @Keatinge :) – Pitto Jan 4 '18 at 15:19

### Define some constants

I'd make some constants and put them at the top of the program because if your program becomes bigger, it'll be harder to change their values:

EMAIL_TIME = '06:30'
SLEEP_TIME = 1
URL = 'https://api.coindesk.com/v1/bpi/currentprice.json'


### Never store your credentials in clear-text

Here, you replaced your actual password with a placeholder, but what if you mistakenly commit&push it to your public git repository? More, at the moment I can also take your email and send those nice Viagra emails.

What I usually do is store my credentials in a different config file which is in .gitignore as well (it's not A LOT safer, but at least you can't see them + it adds an extra layer of security anyways).

As an alternative, you can create environment variables to store them there if you'd like.

### Error handling

Try to add some exception handling to let the user know if something went wrong with its script. You can even create your own exception class:

class RetrieveUrlException(Exception):
pass


Which you can then call like this:

...
raise RetrieveUrlException('The URL could not be accessed')

• I think it's a big assumption that "you replaced your actual password with a placeholder". It wouldn't surprise me at all if this "open" account has that password. – TemporalWolf Jan 4 '18 at 19:04
• Indeed :) It wouldn't be a surprise – Grajdeanu Alex. Jan 4 '18 at 19:05

It seems to me that running a specific command at a specific time each day is more the job of a cron daemon than of said command. As such, I would simplify the executable part of the script to:

if __name__ == '__main__':
send_email()


and add an entry in your cron configuration that read something like

30 6 * * * /usr/bin/env python /path/to/your/script.py