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?
| Approach | Best for | Survives app restarts? |
|---|---|---|
| Plain crontab entry | Simple, standalone scripts | Yes (OS-level) |
| python-crontab | Apps that install their own jobs at deploy time | Yes (writes to OS crontab) |
| croniter | Calculating next run inside your app, no scheduling itself | N/A - calculator only |
| APScheduler | Long-running apps that need an in-process scheduler | No - dies with the process |
| Celery Beat | Distributed systems already using Celery | No - 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.