Published on

πŸš€ Deploy Python Cron Job Scripts on Heroku

Authors
  • avatar
    Name
    Saqib Ameen
    Twitter

Recently, I was doing a proof of concept for a client and I got to deploy a Python script with cron jobs. I searched around for a guide to follow and get things done. But I couldn't find a single guide to get it done.

I ended up utilizing multiple sources to figure out things and deploy the script. Today, I decided to write about it to help other folks in case if they struggle with the same situation.

So, let's get started!

Step #0

Once you have installed CLI, use the command heroku --version to verify the installation. After that, login with your Heroku credentials to login using heroku --login command. See the gits below to get an idea of how it should look like:

$ heroku --version
# heroku/7.30.0 darwin-x64 node-v11.14.0

# Login to Heroku
$ heroku --login

It saves your credentials and authentication token inside ~/.netrc. Check the file to double check and you are all set!

Step #1

After setting up the Heroku CLI on your machine, the next step is to setup the project which uses cron jobs. For this purpose, I have create a small Python project which utilizes Advanced Python Scheduler to set cron jobs.

So, clone this repo on your machine and open the project. It contains two main files:

  1. main.py: It contains following piece of code:
from datetime import datetime

def cronjob():
    """
    Main cron job.
    The main cronjob to be run continuously.
    """
    print("Cron job is running")
    print("Tick! The time is: %s" % datetime.now())

All it doing is, importing datetime function from the built-in library and using it to print the current time. W will use this function in our cron job.

  1. cronjob.py: It contains following piece of code:
# Package Scheduler.
from apscheduler.schedulers.blocking import BlockingScheduler

# Main cronjob function.
from main import cronjob

# Create an instance of scheduler and add function.
scheduler = BlockingScheduler()
scheduler.add_job(cronjob, "interval", seconds=30)

scheduler.start()

Like main.py, this is also pretty straight forward. All I'm doing is, importing blocking scheduler from the library, initializing an instance, and then setting the cronjob function to start it.

You can also run it locally. To do so, simply hit following commands in your terminal:

# Make sure you have pipenv setup.
$ pipenv install # Will install all dependencies.

# Run.
$ python cronjob.py
# Cron job is running
# Tick! The time is: 2019-09-23 01:54:15.210989

Step #2

Once you have cloned the repository, go to your project directory and hit the following command to initialize Heroku project.

$ Heroku create

# Creating app... done, β¬’ secret-garden-90909
# https://secret-garden-90909.herokuapp.com/ | https://git.heroku.com/secret-garden-90909.git

The commented portion contains the expected output. It contains two URLs:

  1. The first one is the link to your Heroku Application. Since in our case, there wont't be any page but only a script, so we can ignore it.
  2. Second is the remote git URL which Heroku automatically add to your project. That's how you push your project to Heroku. Coming up next.

Step #3

The next step is to create the Procfile. Procfile tells Heroku what to do. When you deploy your project on Heroku, Procfile file says to Herokue Hey you gotta run these things!

So let's create a Procfile:

$ touch Procfile # It's case sensitive

Now, inside your Procfile, paste the following line of code:

clock: python cronjob.py

It says, Hey Heroku, run this command and it's a clock process. Heroku uses clock processes to run the cron jobs.

Step #4

The final step is to deploy the project to Heroku. Run the following command to deploy the project on Heroku:

$ git push heroku deploy:master

It will take a couple of seconds to deploy. Once deployed, you will get a message saying:

# remote: Verifying deploy... done.

Your script has been deployed successfully. The very last step is to spin a clock process for our app.

Now, by default, your Heroku environment does not have a clock process. But since we have specified in our Procfile that we are going to use it, so we have to provision one. To do so, run the following command:

$ heroku ps:scale clock=1

It will take a couple of seconds and show following message on completion.

# Scaling dynos... done, now running clock at 1:Free

🎯That's all! You have successfully deployed your first script on Heroku for free. Just a couple of steps and you are all set.

Verification

Since, we only have two print statements in our cron job, so they get printed on in the logs. So, we have to take a look at our logs to verify if the script is working perfectly fine. To do so, run the following command in your project directory to get real time logs:

$ heroku logs --tail

Below is the screenshot of how it might look like.

Heroku Live Logs Image

All rightyy! That was all for today, if you have any questions, feel free to reach me out, would love to help you out. Peace! ✌️