schedule
In-process Python job scheduling with a friendly, readable syntax for running functions on a fixed cadence.
Repository Health
Technical Analysis
schedule is a lightweight, pure-Python library for running functions periodically inside a long-lived process, without needing cron, a message broker, or any external service. Jobs are declared with a fluent, English-like syntax such as schedule.every(10).minutes.do(job), and executed by calling run_pending() from your own loop.
It has zero required dependencies, supports second-through-week interval units, specific times of day, weekday-only jobs, randomized intervals, deadline-based cancellation, and optional pytz-backed timezone handling, making it a common choice for small scripts and services that want recurring tasks without adopting a full task-queue system like Celery.
What You Get
- A single-file, pure-Python scheduler with no required runtime dependencies
- A chainable API for expressing intervals in seconds, minutes, hours, days, and weeks
- Built-in support for weekday-specific and time-of-day (
.at()) scheduling - Optional pytz-backed timezone support for
.at()calls via thetimezoneextra
Common Use Cases
- Running periodic maintenance or polling functions inside a long-lived process
- Replacing ad hoc
time.sleep()loops with declarative interval scheduling - Lightweight recurring-task scheduling for scripts that don’t need a broker-backed queue
- Timezone-aware daily jobs for services operating across regions
Under The Hood
Architecture
The library is a single module (schedule/__init__.py) containing two classes: Scheduler (holds a list of Job instances and exposes run_pending/run_all/get_jobs/clear/cancel_job/every) and Job (a fluent builder that accumulates interval/unit/at_time/tags via chained property access and terminates with .do(), which computes next_run via _schedule_next_run() and registers itself on the scheduler’s job list). Module-level functions (every, run_pending, repeat, etc.) are thin wrappers around a shared default_scheduler singleton, so most user code never touches Scheduler directly. Job.__lt__ makes jobs sortable by next_run, which run_pending() relies on to execute due jobs in time order. There’s no internal threading or event loop — callers poll run_pending() from their own loop, and timezone correctness for .at() is isolated to a handful of _correct_utc_offset/_move_to_at_time helpers, keeping the core execution model simple and traceable end to end.
Tech Stack
Pure Python 3.7+ with zero required runtime dependencies (dependencies = [] in pyproject.toml); the only optional dependency is pytz, gated behind the timezone extra and imported lazily inside Job.at() only when a timezone argument is passed. Packaging uses setuptools with a pyproject.toml build-system and dynamic metadata. Testing runs through tox across multiple Python versions (with and without pytz) using pytest, pytest-cov, and mypy, orchestrated in CI via tox-gh-actions on GitHub Actions with Coveralls reporting. Documentation is built with Sphinx and published to Read the Docs. There are no database, network, or web-framework dependencies of any kind.
Code Quality
The repo has extensive test coverage — a single test file with dozens of test methods covering interval calculations, .at() time parsing and validation, timezone/DST edge cases (using mocked datetimes and POSIX TZ strings for several real timezones), tag filtering, cancellation, and randomized intervals. Tests use unittest.mock and the standard-library unittest.TestCase, run through tox/pytest-cov, and CI additionally runs mypy for static type-checking against a fully type-annotated source. Error handling is explicit and typed — a small exception hierarchy (ScheduleError -> ScheduleValueError -> IntervalError) is raised for misuse rather than failing silently. Code style is enforced via black --check in a dedicated tox environment, and naming is consistent throughout.
What Makes It Unique
schedule’s distinguishing choice is its fully in-process, English-readable builder syntax that requires no broker, daemon, or config file — unlike Celery or APScheduler it has zero infrastructure to run, at the cost of only firing while the host process’s own loop calls run_pending(). Its randomized-interval and deadline-based auto-cancellation features are relatively uncommon conveniences for lightweight schedulers, and the DST-aware timezone-correction logic for pinned .at() calls solves a genuinely fiddly correctness problem most simple schedulers ignore. These are incremental refinements on a well-established declarative in-process scheduling pattern rather than a novel architecture — a well-executed take on a known idea rather than a groundbreaking one.
Used by 3 apps in this directory
argilla
AI Development · Data Engineering
Collaborate on high-quality AI training data with a self-hosted annotation platform built for LLMs, NLP, and multimodal models.
Khoj
AI Assistants · Knowledge Management · Productivity
A self-hostable AI second brain that chats with your documents, searches the web, builds custom agents, and runs entirely on your own LLM.
Odoo
ERP · CRM · Productivity
The open source ERP platform that integrates CRM, accounting, inventory, manufacturing, and 60+ business apps into one seamlessly connected suite.