Home › Cron Job in Python

Cron Job in Python

How to run a Python script as a cron job. Covers crontab setup, virtual environments, the python-crontab and croniter libraries, plus APScheduler and Celery Beat as alternatives.

Run a Python Script as a Cron Job

Running a Python script from cron requires the full path to the Python interpreter and the full path to the script. If your project uses a virtual environment - and it probably should - you need the Python binary inside the virtualenv, not the system one.

Without virtual environment:

0 2 * * * /usr/bin/python3 /home/user/scripts/backup.py

With virtual environment (recommended):

0 2 * * * /home/user/myproject/venv/bin/python /home/user/myproject/backup.py

Always use the virtualenv Python, not python3

If you just write python3 script.py in a cron job, cron will use the system Python - which does not have your project's dependencies installed. Your script imports requests or django and immediately crashes with ModuleNotFoundError. Use the full path to the Python binary inside your virtual environment:

which python  # run this inside your activated virtualenv to get the path

Step by Step Setup

1. Find your Python path

which python3
# or inside a virtualenv:
source venv/bin/activate && which python

2. Test the command manually

/home/user/venv/bin/python /home/user/script.py

Run this exact command before adding it to cron. If it works here, it will work in cron.

3. Add to crontab with logging

crontab -e
# add:
0 2 * * * /home/user/venv/bin/python /home/user/script.py >> /var/log/myjob.log 2>&1

4. Handle working directory

If your script uses relative paths, set the working directory explicitly:

0 2 * * * cd /home/user/myproject && /home/user/venv/bin/python script.py

Managing Crontab From Python Code

Two small libraries solve two different problems: editing the crontab programmatically, and parsing cron expressions inside your own Python code.

python-crontab

Reads and writes the system crontab from Python. Useful when an application needs to install or update its own cron jobs at deploy time, instead of asking someone to edit crontab -e manually.

pip install python-crontab
from crontab import CronTab
cron = CronTab(user=True)
job = cron.new(command='/usr/bin/python3 /home/user/script.py')
job.setall('0 2 * * *')
cron.write()

croniter

Parses a cron expression and calculates the next (or previous) run time. Does not touch the actual crontab - it is a pure scheduling calculator, often used inside web apps to show "next run" without shelling out to the OS.

pip install croniter
from croniter import croniter
from datetime import datetime
base = datetime.now()
itr = croniter('0 9 * * 1-5', base)
print(itr.get_next(datetime))

Environment Variables in Python Cron Jobs

Python projects often use .env files or environment variables for configuration. Cron does not load your shell profile, so those variables are not available. Three ways to handle this:

Option 1: Set in crontab

DATABASE_URL=postgres://...
0 2 * * * /venv/bin/python script.py

Variables defined above jobs apply to all jobs in the crontab.

Option 2: Use python-dotenv

from dotenv import load_dotenv
load_dotenv('/home/user/project/.env')

Load the .env file explicitly at the top of your script using an absolute path.

Option 3: Wrapper script

#!/bin/bash
source /home/user/project/.env
/venv/bin/python script.py

A bash wrapper that sources the env file before calling Python.

Python Scheduling Alternatives to Cron

When cron is not enough - or when you want to keep schedules inside your Python code instead of the system crontab:

APScheduler

In-process scheduler. Runs inside your Python application. Supports cron, interval and date triggers. Good for scripts that need to stay running.

pip install apscheduler

Celery Beat

Distributed task queue with periodic task support. Good for production systems that already use Celery workers. More setup, more power.

pip install celery

Django-crontab

For Django projects. Define schedules in settings.py, install them with one management command.

python manage.py crontab add

Which Approach Should You Use?

ApproachBest forSurvives app restarts?
Plain crontab entrySimple, standalone scriptsYes (OS-level)
python-crontabApps that install their own jobs at deploy timeYes (writes to OS crontab)
croniterCalculating next run inside your app, no scheduling itselfN/A - calculator only
APSchedulerLong-running apps that need an in-process schedulerNo - dies with the process
Celery BeatDistributed systems already using CeleryNo - needs the worker running

Build the cron expression for your Python job

Use the generator, copy the expression, paste it before your Python command in the crontab.