Overview of APScheduler
masterasyncio or Trio) applications. It is designed to scale from single-process use cases to large, multi-node deployments using shared data stores for high availability and horizontal scaling.repository·master·Indexed 27 days ago
https://github.com/agronholm/apschedulerA flexible in-process task scheduler and queue system for Python with Cron-like capabilities. It supports both synchronous and asynchronous environments, ranging from simple scripts to distributed multi-node production systems. The library includes various scheduler classes, job executors, data stores for persistence (SQLAlchemy, MongoDB, Memory), event brokers (Redis, MQTT, Asyncpg, Psycopg), and multiple trigger types including Cron, Interval, and Date triggers.
asyncio or Trio) applications. It is designed to scale from single-process use cases to large, multi-node deployments using shared data stores for high availability and horizontal scaling.Understanding the fundamental components:
True from callable() (e.g., functions, methods, lambdas, or classes with a __call__ method).You can use the scheduler as a job queue to run tasks directly without a schedule.
Scheduler.run_job.Scheduler.add_job.result_expiration_time to Scheduler.add_job to ensure the result is saved, then use Scheduler.get_job_result with the job ID returned by add_job.To preview changes to the documentation before committing, use tox to build the Sphinx HTML documentation. The output will be located in build/sphinx/html/index.html.
tox -e docsTo schedule a task, you need a task (or a callable) and a trigger.
Built-in Triggers:
DateTrigger: Run once at a specific time.IntervalTrigger: Run at fixed intervals.CronTrigger: Run periodically at specific times (e.g., daily at 10:00).CalendarIntervalTrigger: Run on calendar-based intervals (e.g., every 2 months).from apscheduler.triggers.combining import OrTrigger
from apscheduler.triggers.cron import CronTrigger
# Example: Combining triggers with OrTrigger
trigger = OrTrigger(
CronTrigger(day_of_week="mon-fri", hour=10),
CronTrigger(day_of_week="sat-sun", hour=11),
)Settings (like job_executor or misfire_grace_time) follow a specific priority order. If a parameter is unset at one level, it is looked up in the parent level.
Priority Order for Task Configuration:
AsyncScheduler.configure_task.@task decorator.TaskDefaults.Inheritance Flow:
Metadata Inheritance: Metadata keys are merged, with more explicit configurations overwriting generic ones.
APScheduler uses pre-commit to perform code style and quality checks. It is recommended to install these hooks locally to ensure your changes pass the checks performed on GitHub.
pre-commit installIf your application runs on asyncio or Trio, use AsyncScheduler. You must use the scheduler as an asynchronous context manager (async with).
Use await scheduler.run_until_stopped() to block the event loop.
Use await scheduler.start_in_background() to run the scheduler as a background task within the event loop.
import asyncio
from apscheduler import AsyncScheduler
async def main():
# Background task mode
async with AsyncScheduler() as scheduler:
# Add schedules, configure tasks here
await scheduler.start_in_background()
# OR Foreground blocking mode
# async with AsyncScheduler() as scheduler:
# await scheduler.run_until_stopped()
asyncio.run(main())When running in production with persistent stores, assign a unique, stable identity to each scheduler instance. This helps identify which jobs are running where and allows crashed jobs to be cleaned up more efficiently by other schedulers.
To integrate APScheduler with WSGI-based web frameworks, use the synchronous Scheduler class. You should start the scheduler as a side effect of importing the module containing your application instance.
When using uWSGI, you must include the --enable-threads (or -T) flag in your command, as uWSGI disables threads by default, which will prevent the scheduler from running.
Note that calling Scheduler.start_in_background() installs an atexit hook to ensure the scheduler shuts down gracefully when the worker process exits.
from apscheduler import Scheduler
def app(environ, start_response):
"""Trivial example of a WSGI application."""
response_body = b"Hello, World!"
response_headers = [
("Content-Type", "text/plain"),
("Content-Length", str(len(response_body))),
]
start_response(200, response_headers)
return [response_body]
scheduler = Scheduler()
scheduler.start_in_background()To run with uWSGI:
uwsgi --enable-threads --http :8080 --wsgi-file example.pyThe scheduler API has changed significantly in v4.0:
Scheduler.add_schedule() for scheduled tasks. The add_job() method is now reserved for one-off runs (previously requiring a DateTrigger with the current time).BlockingScheduler and BackgroundScheduler are merged into a single Scheduler class.Scheduler.run_until_stopped() to replace BlockingScheduler behavior.Scheduler.start_in_background() to replace BackgroundScheduler behavior.AsyncScheduler replaces the old asyncio scheduler and is based on AnyIO (supporting both asyncio and Trio). Note: AsyncScheduler must be used as an async context manager.configure() method has been removed. All configuration is now passed as keyword arguments directly to the scheduler class.Install the core library using pip:
$ pip install apschedulerTo ensure compatibility with external services, you can install specific extras. This is preferred over installing the libraries separately. You can install multiple extras by providing them as a comma-separated list inside brackets.
pip install apscheduler