{"id":6968,"library":"aiojobs","title":"aiojobs","description":"aiojobs is an asyncio-based job scheduler for managing background tasks. It allows spawning and tracking long-running coroutines, handling their cancellation, and ensuring graceful shutdown. The current version is 1.4.0, and it follows an active release cadence with minor updates and bug fixes.","status":"active","version":"1.4.0","language":"en","source_language":"en","source_url":"https://github.com/aio-libs/aiojobs","tags":["asyncio","jobs","scheduler","background tasks","concurrency"],"install":[{"cmd":"pip install aiojobs","lang":"bash","label":"Install aiojobs"}],"dependencies":[{"reason":"Required for Python versions older than 3.11. Removed for Python 3.11+ in v1.2.0.","package":"async-timeout","optional":true},{"reason":"Required for aiohttp integration features (e.g., using aiohttp.web.AppKey).","package":"aiohttp","optional":true}],"imports":[{"note":"The `create_scheduler` function was removed in v1.1.0; `Scheduler` should be instantiated directly.","wrong":"import aiojobs; aiojobs.create_scheduler()","symbol":"Scheduler","correct":"from aiojobs import Scheduler"},{"symbol":"Job","correct":"from aiojobs import Job"}],"quickstart":{"code":"import asyncio\nfrom aiojobs import Scheduler\n\nasync def worker(task_id: int):\n    print(f\"Worker {task_id}: Starting...\")\n    try:\n        await asyncio.sleep(2) # Simulate work\n        print(f\"Worker {task_id}: Finished.\")\n    except asyncio.CancelledError:\n        print(f\"Worker {task_id}: Cancelled during sleep.\")\n\nasync def main():\n    # Use async with for graceful shutdown (introduced in v1.3.0)\n    async with Scheduler() as scheduler:\n        print(\"Scheduler created.\")\n\n        job1 = await scheduler.spawn(worker(1))\n        job2 = await scheduler.spawn(worker(2))\n\n        print(f\"Spawned jobs: {scheduler.pending_count}\")\n\n        # Wait for job1 to complete (optional)\n        await job1.wait()\n        print(f\"Job 1 status: {job1.closed}\")\n\n    print(\"Scheduler closed. All pending tasks should be done or cancelled.\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())","lang":"python","description":"This quickstart demonstrates how to create a `Scheduler` using the `async with` context (recommended for graceful shutdown since v1.3.0), spawn background tasks using `scheduler.spawn()`, and optionally wait for individual jobs to complete with `job.wait()`."},"warnings":[{"fix":"Replace `await aiojobs.create_scheduler()` with `Scheduler()`.","message":"The `aiojobs.create_scheduler()` function was removed. `Scheduler` objects must now be instantiated directly.","severity":"breaking","affected_versions":"v1.1.0 and later"},{"fix":"Upgrade your Python environment to 3.9 or higher (current minimum requirement for v1.4.0).","message":"Python 3.7 support was dropped.","severity":"breaking","affected_versions":"v1.2.0 and later"},{"fix":"Use `async with Scheduler() as scheduler:` or manually call `await scheduler.wait_and_close()` before your application exits.","message":"Tasks spawned by `Scheduler` may be abruptly cancelled during application shutdown if `Scheduler.wait_and_close()` is not called, or if the `Scheduler` is not used within an `async with` block.","severity":"gotcha","affected_versions":"All versions, specifically pre-v1.3.0 users without manual shutdown handling."},{"fix":"Always ensure your `aiojobs` operations are executed within an `async` function called by `asyncio.run()` or within an existing `asyncio` event loop.","message":"While `Scheduler` creation (v1.4.0+) no longer strictly requires a *running* event loop, tasks spawned by it still need an event loop to *execute*. Running `Scheduler` operations outside an `asyncio.run` context or a running event loop will lead to `RuntimeError` when tasks attempt to start.","severity":"gotcha","affected_versions":"v1.4.0 and later (new behavior)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Instantiate `Scheduler` directly: `scheduler = Scheduler()`.","cause":"Attempting to use the old API function `aiojobs.create_scheduler()` which was removed.","error":"AttributeError: module 'aiojobs' has no attribute 'create_scheduler'"},{"fix":"Ensure graceful shutdown. Use `async with Scheduler() as scheduler:` or explicitly call `await scheduler.wait_and_close()` before closing your application.","cause":"The asyncio event loop was closed or the application exited while `aiojobs` tasks were still running or pending, without proper shutdown handling.","error":"Task was destroyed but it is pending!"},{"fix":"Instantiate `Scheduler` without `await`: `scheduler = Scheduler()`.","cause":"Attempting to `await` the `Scheduler` instantiation (e.g., `await Scheduler()`) which is not necessary and incorrect for direct instantiation.","error":"TypeError: 'Scheduler' object is not awaitable"}]}