{"id":16543215,"url":"https://github.com/codemation/easyschedule","last_synced_at":"2025-03-21T10:31:27.269Z","repository":{"id":39831776,"uuid":"345126704","full_name":"codemation/easyschedule","owner":"codemation","description":"Easily schedule single or recurring sync/async tasks","archived":false,"fork":false,"pushed_at":"2021-04-28T19:58:54.000Z","size":102,"stargazers_count":18,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-01T05:12:16.975Z","etag":null,"topics":["cron","scheduler"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/easyschedule/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codemation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.MD","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-06T15:28:14.000Z","updated_at":"2024-04-17T05:51:08.000Z","dependencies_parsed_at":"2022-09-08T20:22:00.737Z","dependency_job_id":null,"html_url":"https://github.com/codemation/easyschedule","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Feasyschedule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Feasyschedule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Feasyschedule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Feasyschedule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codemation","download_url":"https://codeload.github.com/codemation/easyschedule/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244777864,"owners_count":20508801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","scheduler"],"created_at":"2024-10-11T18:59:39.910Z","updated_at":"2025-03-21T10:31:26.967Z","avatar_url":"https://github.com/codemation.png","language":"Python","readme":"![](./docs/images/logo3.png)\n\n\u003ch3\u003eAn asynchronus scheduler for python tasks, which uses Cron schedules for precise scheduling recurring tasks\u003c/h3\u003e\n\n[![Documentation Status](https://readthedocs.org/projects/easyschedule/badge/?version=latest)](https://easyschedule.readthedocs.io/en/latest/?badge=latest) [![PyPI version](https://badge.fury.io/py/easyschedule.svg)](https://pypi.org/project/easyschedule/)\n#\n\n## Documenation\n[https://easyschedule.readthedocs.io/en/latest/](https://easyschedule.readthedocs.io/en/latest/)\n\n#\n\n## Get Started\n```bash\npip install easyschedule\n```\n\n```python\nimport asyncio\nfrom easyschedule import EasyScheduler\n\nscheduler = EasyScheduler()\n\ndefault_args = {'args': [1, 2, 3]}\nweekday_every_minute = '* * * * MON-FRI'\n\n@scheduler(schedule=weekday_every_minute, default_args=default_args)\ndef weekday_stuff(a, b, c):\n    print(f\"a {a} b: {b} c {c}\")\n\n@scheduler.delayed_start(delay_in_seconds=30)\nasync def delay_startup():\n    print(f\"## startup task - started ##\")\n    await asyncio.sleep(10)\n    print(f\"## startup task - ended ##\")\n\n@scheduler.shutdown()\nasync def shutdown():\n    print(f\"## shutdown task - started ##\")\n    await asyncio.sleep(10)\n    print(f\"## shutdown task - ended ##\")\n\n@scheduler.once(date_string='2022-03-12 16:18:03')\nasync def next_year():\n    print(f\"That was a long year\")\n\nasync def main():\n    # start scheduler\n    sched = asyncio.create_task(scheduler.start())\n    await asyncio.sleep(10)\n\n    # dynamicly schedule task\n    wk_end_args = {'kwargs': {'count': 5}}\n    weekend = '30 17-23,0-5 * * SAT,SUN'\n\n    def weekend_stuff(count: int):\n        for _ in range(count):\n            weekday_stuff(3,4,5)\n            weekday_stuff(5,6,7)\n\n    scheduler.schedule(\n        weekend_stuff, \n        schedule=weekend,\n        default_args=wk_end_args\n    )\n    await sched\n\nasyncio.run(main())\n```\n```bash\n03-13 09:09:25 EasyScheduler WARNING  weekday_stuff next_run_time: 2021-03-15 00:01:00.143645\n03-13 09:09:25 EasyScheduler WARNING  single task delay_startup scheduled to run at 2021-03-13 09:09:55.143337 in 30.0 s\n03-13 09:09:25 EasyScheduler WARNING  single task next_year scheduled to run at 2022-03-12 16:18:03 in 31475317.856636 s\n03-13 09:09:35 EasyScheduler WARNING  weekend_stuff next_run_time: 2021-03-13 17:31:00.152428\n03-13 09:09:48 EasyScheduler WARNING  shutdown task shutdown triggered at 2021-03-13 09:09:48.937516\n## shutdown task - started ##\n## shutdown task - ended ##\nTraceback (most recent call last):\n  File \"test.py\", line 50, in \u003cmodule\u003e\n    asyncio.run(main())\nKeyboardInterrupt\n```\n## Cron syntax Compatability\n\nEasySchedule is capable of parsing most cron schedule syntax\n\n#\n## Monthly\nFirst of month at 11:00 PM\n```bash\n0 23 1 * *\n```\n#\n\n## Daily\nEvery 2 Hours\n```bash\n0 */2 * *\n```\n#\n\n## Weekends Only \nEvery Hour Between 5:30 PM  - 5:30 AM ##\n```bash\n30 17-23,0-5 * * SAT,SUN\n```\n## Cron Generator\nAn easy \u0026 interactive way to build a cron schedule is available via \u003cem\u003e[crontab.guru](https://crontab.guru/) \u003c/em\u003e\n\n### Note: unsupported syntax (currently)\n```bash\n@(non-standard) \n@hourly\n@daily \n@anually\n```\n\n#\n## Scheduluing Single Tasks\nEasySchedule is complete with single task scheduling\n\n### Usage with 'once' decorator\n```python\nfrom datetime import datetime, timedelta\n\nnext_year = datetime.now() + timedelta(days=365)\n\n@scheduler.once(date=next_year)\nasync def future_task():\n    ## future work\n    pass\n\n# current month: 2021-03-13 00:00:00\n@scheduler.once(date_string='2021-04-13 00:00:00')\nasync def run_at_date():\n    ## future work\n    pass\n\n# current month: 2021-03-13 00:00:00\n@scheduler.once(delta=timedelta(days=3))\nasync def run_after_delta():\n    ## future work\n    pass\n\nnow_args={'kwargs': {'work': \"Lots of work\"}}\n\n@scheduler.once(now=True, default_args=now_args)\nasync def run_now(work):\n    ## future work\n    print(f\"starting {work}\")\n    pass\n```\n#\n## Schedule a task at or near application startup\n```python\nnotify = {\n    'kwargs': { 'emails': ['admin@company.org'] }\n    }\n\n@scheduler.delayed_start(delay_in_seconds=30, default_args=notify)\nasync def notify_online(emails: str):\n    message = f\"server is operational\"\n    await send_emails(message, emails)\n    #something else\n\nasync def get_data():\n    return await requests.get('http://data-source')\n\n@scheduler.startup()\nasync def update_database():\n    data = await get_data()\n    await db.update(data)\n    #something else\n```\n#\n## Schedule a task to run at application shutdown\n```python\nnotify = {\n    'kwargs': { 'emails': ['admin@company.org'] }\n    }\n\n@scheduler.shutdown(default_args=notify)\nasync def notify_shutdown(emails: str):\n    message = f\"server is shutting down\"\n    await send_emails(message, emails)\n    #something else?\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemation%2Feasyschedule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodemation%2Feasyschedule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemation%2Feasyschedule/lists"}