Skip to content

APScheduler

The native APScheduler adapter for z4j. With the producer setup below, it supports inventory, create, edit, pause, resume, delete and Run now from the z4j dashboard.

APScheduler 3.10.2+; Python 3.11+. APScheduler 4 uses a different API; pin apscheduler<4 in the host application.

Run the z4j server, z4j-core, z4j-bare and z4j-apscheduler from the same release, and install the native scheduler and broker/store dependencies used by your application. The example assumes your task code, writable application-state directory and agent credentials already exist. Use the project UUID from agent registration.

import os
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from z4j_apscheduler import APSchedulerAdapter
from z4j_bare import install_agent
from myapp.jobs import cleanup
scheduler = BackgroundScheduler(
timezone="UTC",
jobstores={"default": SQLAlchemyJobStore(url="sqlite:////var/lib/myapp/jobs.sqlite3")},
)
scheduler.start()
adapter = APSchedulerAdapter(scheduler=scheduler, tasks={"myapp.cleanup": cleanup})
agent = install_agent(
engines=[], schedulers=[adapter],
brain_url=os.environ["Z4J_BRAIN_URL"], token=os.environ["Z4J_TOKEN"],
hmac_secret=os.environ["Z4J_HMAC_SECRET"], project_id=os.environ["Z4J_PROJECT_ID"],
)
# Keep the application alive; on shutdown call agent.stop() and scheduler.shutdown().

Install SQLAlchemy separately for this example. Bind the adapter to the running scheduler in the process that actually dispatches jobs. AsyncIOScheduler operations are marshalled onto its owning event loop. The default jobstore is managed; select another using jobstore="name". Configure one adapter/producer for the selected project and owner. Do not share an APScheduler 3 jobstore between scheduler processes.

Definitions and pause state live in the selected native jobstore. An in-memory jobstore is deliberately not restart-persistent; use a persistent store when that is required. The live qualification uses SQLAlchemy with SQLite. Other APScheduler 3 jobstores use the same APIs but are not all deployment-qualified.

The connected producer supports inventory, create, edit, pause, resume, delete and Run now. A write is complete only after z4j accepts a snapshot confirming the native source. The dashboard uses the current connection's advertised capabilities; an unavailable producer cannot accept new edits. Repeating an operation ID does not submit it twice. A timeout or uncertain outcome requires inspection before submitting a new request.

A pause prevents future scheduling. Work already queued or running can finish. Run now submits an additional execution without resuming a paused schedule. Native scheduling keeps the upstream scheduler's timing and delivery semantics; it does not acquire z4j-scheduler's catch-up, overlap or exactly-once guarantees. Queue task history requires the corresponding engine adapter in the workers.

  • Create/edit supports five-field cron, positive intervals in seconds, and offset-aware one-shot datetimes.
  • Numeric cron weekdays use Monday=0 through Sunday=6, following APScheduler.
  • Existing advanced CronTrigger settings are preserved when editing other fields.
  • Existing jobs supply their callable; tasks={name: callable} registers additional safe dashboard choices. Job IDs cannot be renamed through an edit.
  • Run now submits through the native executor and preserves the original next run and pause state.
  • Queue overrides are unavailable; the selected native executor runs the callable.