Skip to main content

Cron-like task scheduler with overlap prevention and interval support.

Project description

philiprehberger-task-scheduler

Tests PyPI version Last updated

Cron-like task scheduler with overlap prevention and interval support.

Installation

pip install philiprehberger-task-scheduler

Usage

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()

@scheduler.cron("*/5 * * * *")  # every 5 minutes
def check_health():
    ping_server()

scheduler.start()  # blocks

Interval Scheduling

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()

@scheduler.interval(seconds=30)
def poll_queue():
    process_messages()

@scheduler.interval(minutes=5, overlap=False)
def sync_data():
    pull_latest_data()

One-Shot Tasks

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()

@scheduler.once(delay=10)  # run once after 10 seconds
def startup_task():
    warm_cache()

Background Mode

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.start(background=True)
# ... your app continues running ...
scheduler.stop()

Programmatic API

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.add("my-job", fn=my_function, cron="0 * * * *")
scheduler.add("poller", fn=poll, interval_seconds=60)
scheduler.remove("my-job")

Execution History

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler(history_limit=50)
scheduler.add("job", fn=my_function, interval_seconds=60)
scheduler.start(background=True)

# Get all history (newest first)
for record in scheduler.history:
    print(f"{record.job_name}: {record.status.value} in {record.duration_seconds:.2f}s")

# Get history for a specific job
for record in scheduler.get_job_history("job"):
    if record.error:
        print(f"Error: {record.error}")

Next Run Preview

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.add("job", fn=my_function, cron="0 * * * *")

for name, next_time in scheduler.next_runs():
    print(f"{name}: next at {next_time}")

Task Dependencies

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()

@scheduler.interval(seconds=60, name="fetch-data")
def fetch_data():
    download_latest()

@scheduler.interval(seconds=60, name="process-data", depends_on="fetch-data")
def process_data():
    transform_and_store()

Graceful Shutdown

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.start(background=True)

# Wait for running tasks to finish before stopping
scheduler.stop(wait=True)

# Or set a timeout (seconds)
scheduler.stop(wait=True, timeout=10)

Missed Job Handling

from philiprehberger_task_scheduler import Scheduler, MissedJobPolicy

scheduler = Scheduler()

@scheduler.cron("0 * * * *", missed_policy=MissedJobPolicy.RUN_ONCE)
def hourly_sync():
    sync_data()

@scheduler.cron("*/5 * * * *", missed_policy=MissedJobPolicy.RUN_ALL)
def critical_check():
    check_systems()

Pause and Resume Jobs

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.add("my-job", fn=my_function, interval_seconds=60)

scheduler.pause("my-job")   # job won't run during ticks
scheduler.resume("my-job")  # job runs again

Job Management

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.add("job1", fn=fn1, interval_seconds=60)
scheduler.add("job2", fn=fn2, cron="0 * * * *")

print(scheduler.job_count)   # 2
print(scheduler.is_running)  # False

scheduler.clear()            # remove all jobs
print(scheduler.job_count)   # 0

Introspecting jobs

from philiprehberger_task_scheduler import Scheduler

scheduler = Scheduler()
scheduler.add("poller", fn=poll, interval_seconds=60)

print(scheduler.job_count)              # 1

job = scheduler.find_job("poller")
if job is not None:
    print(job.name, job.interval_seconds)  # poller 60

# find_job returns None on a miss — no exception to catch
assert scheduler.find_job("missing") is None

Cron Syntax

Standard 5-field cron expressions:

minute (0-59)
hour (0-23)
day of month (1-31)
month (1-12)
day of week (0-6, Mon-Sun)

Supports: *, ranges (1-5), lists (1,3,5), steps (*/5).

API

Function / Class Description
Scheduler(history_limit) Task scheduler with cron, interval, and one-shot scheduling
Scheduler.cron(expression, overlap, name, depends_on, missed_policy) Decorator to schedule with a cron expression
Scheduler.interval(seconds, minutes, hours, overlap, name, depends_on, missed_policy) Decorator to schedule at a fixed interval
Scheduler.once(delay, name) Decorator to schedule a one-shot task
Scheduler.add(name, fn, cron, interval_seconds, overlap, depends_on, missed_policy) Programmatically add a job
Scheduler.remove(name) Remove a job by name
Scheduler.pause(name) Pause a job without removing it
Scheduler.resume(name) Resume a paused job
Scheduler.clear() Remove all registered jobs
Scheduler.job_count Number of registered jobs
Scheduler.find_job(name) Return the job with the given name, or None if not registered
Scheduler.is_running Whether the scheduler is currently running
Scheduler.start(background) Start the scheduler (blocks unless background=True)
Scheduler.stop(wait, timeout) Stop the scheduler with optional graceful shutdown
Scheduler.next_runs() Get the next run time for each job
Scheduler.history Execution history (newest first)
Scheduler.get_job_history(name) Execution history for a specific job
Job A scheduled job with name, function, schedule config, and next_run property
ExecutionRecord Record of a job execution with status, duration, and error
ExecutionStatus Enum: SUCCESS, FAILED
MissedJobPolicy Enum: SKIP, RUN_ONCE, RUN_ALL

Development

pip install -e .
python -m pytest tests/ -v

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

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

philiprehberger_task_scheduler-0.4.0.tar.gz (193.4 kB view details)

Uploaded Source

Built Distribution

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

File details

Details for the file philiprehberger_task_scheduler-0.4.0.tar.gz.

File metadata

File hashes

Hashes for philiprehberger_task_scheduler-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d8fe9f4412b5775f484b50eeb3ae8cf6120066f75d6826d185111890dbd1e4df
MD5 7626871fd22ff935f036149c3cfceed7
BLAKE2b-256 5a5deaac8f843bf1fd721b4c372471aa2a533422da7fcc16adbb4c7800c06105

See more details on using hashes here.

File details

Details for the file philiprehberger_task_scheduler-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for philiprehberger_task_scheduler-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c98949271bee8d64c336904552ac8218c6c0b6fa811cb5ad4f9c33442f0834b0
MD5 bdd4c50791e4279a55fa443c06dd79a6
BLAKE2b-256 8b9d21edac73b979ac895c2fa2dfa2d21800755f5d5723690f17dd4a869008f2

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