{"id":21860948,"url":"https://github.com/dymmond/asyncz","last_synced_at":"2025-04-06T00:08:20.039Z","repository":{"id":69022603,"uuid":"578565361","full_name":"dymmond/asyncz","owner":"dymmond","description":"A python scheduler that simply does the job","archived":false,"fork":false,"pushed_at":"2025-01-07T16:12:22.000Z","size":452,"stargazers_count":52,"open_issues_count":1,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-05T17:38:29.553Z","etag":null,"topics":["api","apscheduler","async","asyncio","framework","jobs","pydantic","python","python-scheduler","python3","scheduler","task-scheduler","tasks","taskscheduler"],"latest_commit_sha":null,"homepage":"https://asyncz.dymmond.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dymmond.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["tarsil"]}},"created_at":"2022-12-15T11:05:23.000Z","updated_at":"2025-03-25T00:38:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"8436ec4c-8c43-4ec2-9cf5-5c64bd3ec483","html_url":"https://github.com/dymmond/asyncz","commit_stats":{"total_commits":60,"total_committers":2,"mean_commits":30.0,"dds":"0.23333333333333328","last_synced_commit":"bf17580c56f126d16fda88513c1168aa71369b63"},"previous_names":["tarsil/asyncz"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dymmond%2Fasyncz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dymmond%2Fasyncz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dymmond%2Fasyncz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dymmond%2Fasyncz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dymmond","download_url":"https://codeload.github.com/dymmond/asyncz/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247415969,"owners_count":20935388,"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":["api","apscheduler","async","asyncio","framework","jobs","pydantic","python","python-scheduler","python3","scheduler","task-scheduler","tasks","taskscheduler"],"created_at":"2024-11-28T03:09:08.230Z","updated_at":"2025-04-06T00:08:20.012Z","avatar_url":"https://github.com/dymmond.png","language":"Python","readme":"# Asyncz\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://asyncz.tarsil.io\"\u003e\u003cimg src=\"https://res.cloudinary.com/tarsild/image/upload/v1687363326/packages/asyncz/asyncz-new_wiyih8.png\" alt='Asyncz'\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003e🚀 The scheduler that simply works. 🚀\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push\u0026branch=main\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/dymmond/asyncz/workflows/Test%20Suite/badge.svg?event=push\u0026branch=main\" alt=\"Test Suite\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://pypi.org/project/asyncz\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/asyncz?color=%2334D058\u0026label=pypi%20package\" alt=\"Package version\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://pypi.org/project/asyncz\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/asyncz.svg?color=%2334D058\" alt=\"Supported Python versions\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Documentation**: [https://asyncz.dymmond.com](https://asyncz.dymmond.com) 📚\n\n**Source Code**: [https://github.com/dymmond/asyncz](https://github.com/dymmond/asyncz)\n\n---\n\nAsyncz is a scheduler for any ASGI application that needs to have those complicated scheduled operations with the\nbest of what pydantic can offer.\n\n## Motivation\n\nNowadays using async frameworks with python is somewhat common and becoming even more mainstream. A lot of applications\nusually need a complex stack of technologies to fullfil their needs and directly or indirectly, a scheduler.\n\nThere are great frameworks out there that do the task extremely well, the best example is APScheduler, which is where\nAsyncz came from.\n\nTo be even more honest, Asyncz is a revamp of APScheduler. Without the APScheduler there is no Asyncz, so much that\neven the APScheduler tests are used within asyncz. That is how great APScheduler is!\n\nSo what was the reason why recreating another similar version of APScheduler? Well, it is not entirely the same\nthing. Asyncz was designed to work only with ASGI and AsyncIO as well as integrating pydantic and bring the modern\npython into the table.\n\nAPScheduler is widely used by millions of python developers and Asyncz **does not aim to replace** it, instead\nis a more focused and optimised solution for async and ASGI frameworks out there.\n\nSee the [vendors](./vendors/apscheduler/README.md) for more details.\n\n## Logging\n\nWe all struggle with the logging and the configurations and with that in mind Asyncz comes with natice support\nfor loguru.\n\nThis will make the logging a lot easier to understand and clear to read.\n\n## Async and ASGI\n\nWhat does this mean? Well, Asyncz does not need to run inside any specific framework, actually you can use it\ncompletely indepent from any framework as well as inside ASGI frameworks such as\n[Esmerald](https://esmerald.dymmond.com), FastAPI, Starlette, Starlite, Quart... You can pick one and go for it.\n\nAsyncz comes with special support to [Esmerald](https://esmerald.dymmond.com) for the simple reason that the author is\nthe same but it can be added more support. If you are interested in adding support to your favourite frameworks then\nsee the [contributing](https://asyncz.dymmond.com/contributing.md) section.\n\n## Concepts\n\nLike APScheduler, Asyncz also brings four kinds of components:\n\n* [Schedulers](https://asyncz.dymmond.com/schedulers.md)\n* [Triggers](https://asyncz.dymmond.com/triggers.md)\n* [Stores](https://asyncz.dymmond.com/stores.md)\n* [Executors](https://asyncz.dymmond.com/executors.md)\n\n## Requirements\n\n* Python 3.7+\n\nAsyncz wouldn't be possible without two giants:\n\n* \u003ca href=\"https://apscheduler.readthedocs.io/en/3.x/\" class=\"external-link\" target=\"_blank\"\u003eAPScheduler\u003c/a\u003e\n* \u003ca href=\"https://pydantic-docs.helpmanual.io/\" class=\"external-link\" target=\"_blank\"\u003ePydantic\u003c/a\u003e\n\n## Installation\n\n```shell\n$ pip install asyncz\n```\n\n## The right decisions\n\nHow do you know if you are choosing the right [scheduler](https://asyncz.dymmond.com/schedulers.md),\n[triggers](https://asyncz.dymmond.com/triggers.md), [stores](https://asyncz.dymmond.com/stores.md)\nand [executors](https://asyncz.dymmond.com/executors.md)?\n\nWell, Asyncz is intentionally designed for specific systems and already helps you out with some of\nthose questions.\n\n* **Schedulers** - Natively only supports the [AsyncIOScheduler](https://asyncz.dymmond.com/schedulers.md#asyncioscheduler).\n* **Triggers** - Here it will depend of the periocidity of our tasks. Example:\n    * [CronTrigger](https://asyncz.dymmond.com/triggers.md#crontrigger) - UNIX like cron and gives you the same feeling as\nscheduling a task on a native UNIX like based system.\n    * [DateTrigger](https://asyncz.dymmond.com/triggers.md#datetrigger) - When you need to run a task once on a specific\npoint of time.\n    * [IntervalTrigger](https://asyncz.dymmond.com/triggers.md#intervaltrigger) - When you need to run tasks in specific\nintervals of time.\n    * [OrTrigger](https://asyncz.dymmond.com/triggers.md#ortrigger)/[AndTrigger](https://asyncz.dymmond.com/triggers.md#andtrigger) - If you would\nlike to combine more than one trigger (cron, interval and date) together.\n* **Stores** - Natively only supports [redis](https://asyncz.dymmond.com/stores.md#redisstore),\n[mongo](https://asyncz.dymmond.com/stores.md#mongodbstore) and [memory](https://asyncz.dymmond.com/stores.md#memorystore).\n* **Executors** - Natively only supports [AsyncIOExecutor](https://asyncz.dymmond.com/executors.md#asyncioexecutor),\n[ThreadPoolExecutor](https://asyncz.dymmond.com/executors.md#threadpoolexecutor) and\n[ProcessPoolExecutor](https://asyncz.dymmond.com/executors.md#processpoolexecutor).\n\nSometimes having a lot of options makes the decision making very hard and Asyncz is intentionally\ndesigned and driven to simplify and for specific use cases but is not limited to those. In every\nsection you have the option of uilding your own stores, executors, triggers and schedulers.\n\n## Configuring the scheduler\n\nDue its simplificy, Asyncz provides some ways of configuring the scheduler for you.\n\nFirst way:\n\n```python\nfrom asyncz.schedulers.asyncio import AsyncIOScheduler\n\nscheduler = AsyncIOScheduler()\n```\n\nSecond way:\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\nscheduler = AsyncIOScheduler()\n```\n\nInitialize the rest of the application after the `scheduler` initialisation.\nMore [details](https://asyncz.dymmond.com/schedulers.md) can be found with more thorough explanations.\n\nThis is in simple terms and in a nutshell how to start with Asyncz quickly. For more information,\ndetails and examples how to leverage Asyncz simply navigate through the documentation and have\nfun 😁🎉.\n\n## ASGI support\n\nAsyncz currently supports ASGI, the [Esmerald framework](https://asyncz.dymmond.com/contrib/esmerald/)\nand brings some batteries that are currently used by Esmerald and leveraging Asyncz.\n\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n...\n\n# handle_lifespan is optional, set to True if you don't want to pass it down because the underlying app doesn't support it\n# this is true for django\napplication = AsyncIOScheduler().asgi(application, handle_lifespan=False)\n# or more simple (please do not use both together)\napplication = AsyncIOScheduler().asgi()(application)\n```\n\nUsing with lilya:\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\n# Lilya middleware doesn't pass lifespan events\n\napp = AsyncIOScheduler().asgi(Lilya(\n    routes=[...],\n))\n\n```\n\nOr manually:\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\nscheduler = AsyncIOScheduler()\n\napp = Lilya(\n    routes=[...],\n    on_startup=[scheduler.start],\n    on_shutdown=[scheduler.shutdown],\n)\n\n```\n\n\n## Contextmanager support\n\nUse as sync contextmanager\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\nwith AsyncIOScheduler() as scheduler:\n    ...\n```\n\nUse as async contextmanager\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\nasync with AsyncIOScheduler() as scheduler:\n    ...\n```\n\nFor using with lifespan of starlette:\n\n```python\nfrom asyncz.schedulers import AsyncIOScheduler\n\nasync lifespan(app):\n    with AsyncIOScheduler() as scheduler:\n        yield\n        # or yield a state\napp = Starlette(\n    lifespan=lifespan,\n)\n\n```\n\n## Security\n\nYou should use store encryption for security reasons.\n\nAll standard stores except MemoryStore support the environment variable `ASYNCZ_STORE_ENCRYPTION_KEY`.\nIf set and non-empty the hash of the value is used for AESGCM encrypting the elements before sending them\nto the store.\nThis way store entries are encrypted and authentificated so there is no security hole.\nThis is highly recommended! Because if someone can inject store entries he can execute code.\n\n## Sponsors\n\nCurrently there are no sponsors of **Asyncz** but you can financially help and support the author though\n[GitHub sponsors](https://github.com/sponsors/tarsil) and become a **Special one** or a **Legend**.\n","funding_links":["https://github.com/sponsors/tarsil"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdymmond%2Fasyncz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdymmond%2Fasyncz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdymmond%2Fasyncz/lists"}