24
\$\begingroup\$

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>',
                  password='password')
    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)
\$\endgroup\$
  • 1
    \$\begingroup\$ 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? \$\endgroup\$ – BruceWayne Jan 4 '18 at 1:51
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – Walid Mujahid وليد مجاهد Jan 4 '18 at 3:13
  • 2
    \$\begingroup\$ It's amazing how few lines of code this is \$\endgroup\$ – Keatinge Jan 4 '18 at 11:57
  • 4
    \$\begingroup\$ Instead of embedding the scheduling logic into the script, you could schedule your script from cron. \$\endgroup\$ – user84207 Jan 4 '18 at 14:02
  • 1
    \$\begingroup\$ Enjoy Python, @Keatinge :) \$\endgroup\$ – Pitto Jan 4 '18 at 15:19
22
\$\begingroup\$

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')
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – TemporalWolf Jan 4 '18 at 19:04
  • \$\begingroup\$ Indeed :) It wouldn't be a surprise \$\endgroup\$ – Grajdeanu Alex. Jan 4 '18 at 19:05
16
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.