{"id":28168,"library":"scheduler","title":"Scheduler","description":"A simple in-process Python scheduler library with asyncio, threading, and timezone support. Current version 0.8.11 supports Python >=3.10. Released as needed.","status":"active","version":"0.8.11","language":"python","source_language":"en","source_url":"https://github.com/dbader/scheduler","tags":["scheduler","asyncio","threading","timezone","task-scheduling"],"install":[{"cmd":"pip install scheduler","lang":"bash","label":"install from PyPI"}],"dependencies":[],"imports":[{"note":"Top-level import only; submodule import breaks compatibility.","wrong":"from scheduler.scheduler import Scheduler","symbol":"Scheduler","correct":"from scheduler import Scheduler"},{"note":"Async scheduler lives in a submodule import asyncio.Scheduler","wrong":"from scheduler import AsyncIOScheduler","symbol":"AsyncIOScheduler","correct":"from scheduler.asyncio import Scheduler as AsyncIOScheduler"},{"note":"Threading scheduler lives in a submodule import threading.Scheduler","wrong":"from scheduler import ThreadingScheduler","symbol":"ThreadingScheduler","correct":"from scheduler.threading import Scheduler as ThreadingScheduler"}],"quickstart":{"code":"from scheduler import Scheduler\nimport time\n\nscheduler = Scheduler()\n\ndef my_task():\n    print(\"Task executed\")\n\n# Schedule every 5 seconds\nscheduler.cyclic(5, my_task)\n\n# Run for 10 seconds\nstart = time.time()\nwhile time.time() - start < 10:\n    scheduler.exec_jobs()\n    time.sleep(0.1)","lang":"python","description":"Basic usage: create a Scheduler, schedule a cyclic task, then repeatedly call exec_jobs() in a loop."},"warnings":[{"fix":"Run scheduler.exec_jobs() inside a while loop or use the provided async/threading wrappers.","message":"The library requires manual calling of exec_jobs() in a loop; it does not run automatically. Failing to call exec_jobs() in a loop will result in no tasks executing.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure exec_jobs() is called frequently enough to avoid missing scheduled times, or adjust for missed executions manually.","message":"Timing changes between exec_jobs() calls are skipped if the next execution time is in the past. Tasks are not caught up; they wait for the next scheduled time.","severity":"gotcha","affected_versions":"all"},{"fix":"Use scheduler.cyclic(interval, job) instead of scheduler.schedule(interval, job).","message":"The method 'schedule' was renamed to 'cyclic' in version 0.8.0. Using 'schedule' raises AttributeError.","severity":"deprecated","affected_versions":">=0.8.0"},{"fix":"Upgrade to Python >=3.10 or pin to scheduler==0.7.3.","message":"Support for Python <3.10 dropped in version 0.8.0. Installing on older Python versions will fail.","severity":"breaking","affected_versions":">=0.8.0"}],"env_vars":null,"last_verified":"2026-05-09T00:00:00.000Z","next_check":"2026-08-07T00:00:00.000Z","problems":[{"fix":"Use 'from scheduler import Scheduler' (top-level).","cause":"Importing the wrong path (e.g., from scheduler.scheduler import Scheduler) in older versions or using a stale installation.","error":"AttributeError: module 'scheduler' has no attribute 'Scheduler'"},{"fix":"Replace 'scheduler.schedule(interval, job)' with 'scheduler.cyclic(interval, job)'.","cause":"Calling the old method name 'schedule' which was renamed to 'cyclic' in v0.8.0.","error":"AttributeError: 'Scheduler' object has no attribute 'schedule'"},{"fix":"Use 'from scheduler.asyncio import Scheduler as AsyncIOScheduler'.","cause":"Trying to import the async scheduler directly from the top-level package, but it is in a submodule.","error":"ImportError: cannot import name 'AsyncIOScheduler' from 'scheduler'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}