philiprehberger-task-scheduler
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:
License
Metadata
Release files for philiprehberger-task-scheduler 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| philiprehberger_task_scheduler-0.4.0.tar.gz | 193.4 kB | Without provenance | Details for philiprehberger_task_scheduler-0.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| philiprehberger_task_scheduler-0.4.0-py3-none-any.whl | Python 3 | none | any | Details for philiprehberger_task_scheduler-0.4.0-py3-none-any.whl |
Total release size: 202.6 kB
Release files / philiprehberger_task_scheduler-0.4.0.tar.gz
| Download URL | philiprehberger_task_scheduler-0.4.0.tar.gz |
|---|---|
| Size | 193.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d8fe9f4412b5775f484b50eeb3ae8cf6120066f75d6826d185111890dbd1e4df
|
|
BLAKE2b-256 checksum How to use checksums |
5a5deaac8f843bf1fd721b4c372471aa2a533422da7fcc16adbb4c7800c06105
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_task_scheduler-0.4.0-py3-none-any.whl
| Download URL | philiprehberger_task_scheduler-0.4.0-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c98949271bee8d64c336904552ac8218c6c0b6fa811cb5ad4f9c33442f0834b0
|
|
BLAKE2b-256 checksum How to use checksums |
8b9d21edac73b979ac895c2fa2dfa2d21800755f5d5723690f17dd4a869008f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for philiprehberger-task-scheduler 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.