Skip to main content

Cron scheduling extension for FastAPI with decorators, async support, Hooks, CLI, and SQLite job tracking.

Project description

Python CI PyPI - Version GitHub Release

FASTAPI-CRONS

Effortlessly schedule and manage your background tasks.


Built with the tools and technologies:

FastAPI Crons โ€“ Developer Guide

Welcome to the official guide for using fastapi_crons, a high-performance, developer-friendly cron scheduling extension for FastAPI. This library enables you to define, monitor, and control scheduled background jobs using simple decorators and provides CLI tools, web-based monitoring, and SQLite-based job tracking.


๐Ÿš€ Features

  • Native integration with FastAPI using from fastapi import FastAPI, Crons
  • Define cron jobs with decorators
  • Async + sync job support
  • SQLite job state persistence
  • CLI for listing and managing jobs
  • Automatic monitoring endpoint (/crons)
  • Named jobs, tags, and metadata
  • Easy to plug into any FastAPI project

๐Ÿ“ฆ Installation

pip install fastapi-crons

๐Ÿ› ๏ธ Quick Start

1. Setup FastAPI with Crons

from fastapi import FastAPI
from fastapi_crons import Crons, get_cron_router

app = FastAPI()
crons = Crons(app)

app.include_router(get_cron_router())

@app.get("/")
def root():
    return {"message": "Hello from FastAPI"}

2. Define Cron Jobs

@crons.cron("*/5 * * * *", name="print_hello")
def print_hello():
    print("Hello! I run every 5 minutes.")

@crons.cron("0 0 * * *", name="daily_task", tags=["rewards"])
async def run_daily_task():
    # Distribute daily rewards or any async task
    await some_async_function()

Cron Expression overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ minute (0 - 59)
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ hour (0 - 23)
โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ day of the month (1 - 31)
โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ month (1 - 12)
โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ day of the week (0 - 6) (Sunday to Saturday)
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
* * * * *

Examples:

  • * * * * *: Every minute
  • */15 * * * *: Every 15 minutes
  • 0 * * * *: Every hour
  • 0 0 * * *: Every day at midnight
  • 0 0 * * 0: Every Sunday at midnight

๐Ÿ–ฅ๏ธ Cron Monitoring Endpoint

Once included, visit:

GET /crons

You'll get a full list of jobs with:

  • name
  • expr (cron expression)
  • tags
  • last_run (from SQLite)
  • next_run

๐Ÿงฉ SQLite Job State Tracking

We use SQLite (via aiosqlite) to keep a persistent record of when each job last ran. This allows observability and resilience during restarts.

๐Ÿ—„๏ธ SQLAlchemy State Backend

For projects already using SQLAlchemy or SQLModel with PostgreSQL or MySQL, you can reuse your existing database connection instead of SQLite.

pip install fastapi-crons[sqlalchemy]
# or
pip install fastapi-crons[sqlmodel]
from sqlalchemy.ext.asyncio import create_async_engine
from fastapi_crons import Crons
from fastapi_crons.state.sqlalchemy import SQLAlchemyStateBackend

engine  = create_async_engine("postgresql+asyncpg://user:pass@host/db")
backend = SQLAlchemyStateBackend(engine)
crons   = Crons(app, state_backend=backend)

Works with sync engines too:

from sqlalchemy import create_engine
engine  = create_engine("postgresql://user:pass@host/db")
backend = SQLAlchemyStateBackend(engine)

Alembic Integration

# env.py
from fastapi_crons.state.sqlalchemy import cron_metadata
target_metadata = [Base.metadata, cron_metadata]

๐Ÿ”’ SQLAlchemy Lock Backend

pip install fastapi-crons[sqlalchemy]
from fastapi_crons.locking.sqlalchemy import SQLAlchemyLockBackend
from fastapi_crons.locking import DistributedLockManager
from fastapi_crons import CronConfig

engine  = create_async_engine("postgresql+asyncpg://...")
backend = SQLAlchemyLockBackend(engine)
manager = DistributedLockManager(backend, CronConfig())
crons   = Crons(app, lock_manager=manager)

For PostgreSQL, advisory locks are available as a lighter alternative (no table required):

from fastapi_crons.locking.sqlalchemy import PostgreSQLAdvisoryLockBackend

backend = PostgreSQLAdvisoryLockBackend(engine)

Table:

CREATE TABLE IF NOT EXISTS job_state (
    name TEXT PRIMARY KEY,
    last_run TEXT
);

Configuration

By default, job state is stored in a SQLite database named cron_state.db in the current directory. You can customize the database path:

from fastapi_crons import Crons, SQLiteStateBackend

# Custom database path
state_backend = SQLiteStateBackend(db_path="/path/to/my_crons.db")
crons = Crons(state_backend=state_backend)

๐Ÿงต Async + Thread Execution

The scheduler supports both async and sync job functions Jobs can be:

  • async def โ†’ run in asyncio loop
  • def โ†’ run safely in background thread using await asyncio.to_thread(...)

๐Ÿงช CLI Support

# List all registered jobs
fastapi-crons list

# Manually run a specific job
fastapi-crons run_job <job_name>

๐Ÿงฉ Advanced Features

  • Distributed locking via Redis
  • Retry policies
  • Manual run triggers via HTTP
  • Admin dashboard with metrics

Job Tags

You can add tags to jobs for better organization:

@cron_job("*/5 * * * *", tags=["maintenance", "cleanup"])
async def cleanup_job():
    # This job has tags for categorization
    pass

โš™๏ธ Architecture Overview

FastAPI App
โ”‚
โ”œโ”€โ”€ Crons()
โ”‚   โ”œโ”€โ”€ Registers decorated jobs
โ”‚   โ”œโ”€โ”€ Starts background scheduler (async)
โ”‚
โ”œโ”€โ”€ SQLite Backend
โ”‚   โ”œโ”€โ”€ Tracks last run for each job
โ”‚
โ”œโ”€โ”€ /crons endpoint
โ”‚   โ”œโ”€โ”€ Shows current job status (with timestamps)
โ”‚
โ””โ”€โ”€ CLI Tool
    โ”œโ”€โ”€ List jobs / Run manually

๐Ÿง  Contributing

We welcome PRs and suggestions! If you'd like this added to FastAPI officially, fork the repo, polish it, and submit to FastAPI with a clear integration proposal.


๐Ÿ›ก๏ธ Error Handling

  • Each job has an isolated error handler
  • Errors are printed and don't block scheduler
  • Future: Add error logging / alert hooks

๐Ÿ“„ License

Licence


Need help? Reach out:

Email me

github

Read Documentation at:

Documentation

๐Ÿ’ฌ Credits

Made with โค๏ธ by Mehar Umar.
Designed to give developers freedom, flexibility, and control when building production-grade FastAPI apps.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_crons-2.3.0.tar.gz (62.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_crons-2.3.0-py3-none-any.whl (76.2 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_crons-2.3.0.tar.gz.

File metadata

  • Download URL: fastapi_crons-2.3.0.tar.gz
  • Upload date:
  • Size: 62.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for fastapi_crons-2.3.0.tar.gz
Algorithm Hash digest
SHA256 fb7312d941dd5b7f4f43aeb0848d1bf7894f5770cf5828df699c44cf9bcfb651
MD5 f2ad600755775419d3be66395d55f98f
BLAKE2b-256 127490adb7d13e520ed4ba1b0a4f941ce855b36b5ae7103ee7950ef56f940cdc

See more details on using hashes here.

File details

Details for the file fastapi_crons-2.3.0-py3-none-any.whl.

File metadata

  • Download URL: fastapi_crons-2.3.0-py3-none-any.whl
  • Upload date:
  • Size: 76.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for fastapi_crons-2.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a8acf30ed3f24fc690aad111b91e7e3379773f62608bf4c90d76b9e59799ba40
MD5 496aa6f99a06da17a4b93b48f1b24cb5
BLAKE2b-256 b4e11490cb3e682ba1b0d895873363b03b5fc7da568f2259681e8ca8d6ef2f4e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page