{"id":13534189,"url":"https://github.com/aiokitchen/aiomisc","last_synced_at":"2026-02-12T14:17:56.322Z","repository":{"id":33199676,"uuid":"129414094","full_name":"aiokitchen/aiomisc","owner":"aiokitchen","description":"aiomisc - miscellaneous utils for asyncio","archived":false,"fork":false,"pushed_at":"2024-04-12T04:52:36.000Z","size":2161,"stargazers_count":363,"open_issues_count":7,"forks_count":25,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-04-14T13:38:11.761Z","etag":null,"topics":["aiomisc","async-await","async-python","asynchronous","asyncio","colorlogger","miscellaneous","server-client","service","uvloop"],"latest_commit_sha":null,"homepage":"","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/aiokitchen.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-04-13T14:33:37.000Z","updated_at":"2024-04-18T17:38:51.662Z","dependencies_parsed_at":"2024-04-18T17:49:01.293Z","dependency_job_id":null,"html_url":"https://github.com/aiokitchen/aiomisc","commit_stats":{"total_commits":772,"total_committers":17,"mean_commits":"45.411764705882355","dds":"0.23316062176165808","last_synced_commit":"39fd00cedc3b071d36e8ec046599456bbd273215"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aiokitchen%2Faiomisc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aiokitchen%2Faiomisc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aiokitchen%2Faiomisc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aiokitchen%2Faiomisc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aiokitchen","download_url":"https://codeload.github.com/aiokitchen/aiomisc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222779876,"owners_count":17036542,"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":["aiomisc","async-await","async-python","asynchronous","asyncio","colorlogger","miscellaneous","server-client","service","uvloop"],"created_at":"2024-08-01T07:01:27.591Z","updated_at":"2026-02-12T14:17:56.309Z","avatar_url":"https://github.com/aiokitchen.png","language":"Python","funding_links":[],"categories":["Python","Asynchronous Programming","Misc"],"sub_categories":[],"readme":"aiomisc - miscellaneous utils for asyncio\n=========================================\n\n.. image:: https://coveralls.io/repos/github/aiokitchen/aiomisc/badge.svg?branch=master\n   :target: https://coveralls.io/github/aiokitchen/aiomisc\n   :alt: Coveralls\n\n.. image:: https://github.com/aiokitchen/aiomisc/actions/workflows/tests.yml/badge.svg\n   :target: https://github.com/aiokitchen/aiomisc/actions/workflows/tests.yml\n   :alt: Actions\n\n.. image:: https://img.shields.io/pypi/v/aiomisc.svg\n   :target: https://pypi.python.org/pypi/aiomisc/\n   :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/wheel/aiomisc.svg\n   :target: https://pypi.python.org/pypi/aiomisc/\n\n.. image:: https://img.shields.io/pypi/pyversions/aiomisc.svg\n   :target: https://pypi.python.org/pypi/aiomisc/\n\n.. image:: https://img.shields.io/pypi/l/aiomisc.svg\n   :target: https://pypi.python.org/pypi/aiomisc/\n\n\nMiscellaneous utils for asyncio.\n\nAs a programmer, you are no stranger to the challenges that come with building\nand maintaining software applications. One area that can be particularly\ndifficult is designing the architecture of software that uses asynchronous I/O.\n\nThis is where aiomisc comes in. aiomisc is a Python library that provides a\ncollection of utility functions and classes for working with asynchronous I/O\nin a more intuitive and efficient way. It is built on top of the ``asyncio``\nlibrary and is designed to make it easier for developers to write\nasynchronous code that is both reliable and scalable.\n\nWith aiomisc, you can take advantage of powerful features like\n``worker pools``, ``connection pools``, ``circuit breaker pattern``,\nand retry mechanisms such as ``asyncbackoff`` and ``asyncretry`` to make your\nasyncio code more robust and easier to maintain. In this documentation,\nwe'll take a closer look at what ``aiomisc`` has to offer and how it can\nhelp you streamline your asyncio service development.\n\nWhy use aiomisc?\n----------------\n\n**Problem:** Production asyncio applications require significant boilerplate\nfor logging, graceful shutdown, thread pools, and error handling.\n\n**Solution:** aiomisc handles infrastructure so you can focus on business logic.\n\n+---------------------------+---------------------------+\n| Plain asyncio             | With aiomisc              |\n+===========================+===========================+\n| Manual signal handling    | Built into entrypoint     |\n+---------------------------+---------------------------+\n| Manual logging setup      | Single parameter          |\n+---------------------------+---------------------------+\n| Manual thread pool        | Automatic + @threaded     |\n+---------------------------+---------------------------+\n| Try/finally cleanup       | Service stop() method     |\n+---------------------------+---------------------------+\n\nInstallation\n------------\n\nInstallation is possible in standard ways, such as PyPI or installation from\na git repository directly.\n\nInstalling from PyPI_:\n\n.. code-block:: bash\n\n    pip3 install aiomisc\n\nInstalling from github.com:\n\n.. code-block:: bash\n\n    # Using git tool\n    pip3 install git+https://github.com/aiokitchen/aiomisc.git\n\n    # Alternative way using http\n    pip3 install \\\n        https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip\n\nThe package contains several extras and you can install additional dependencies\nif you specify them in this way.\n\nWith uvloop_:\n\n.. code-block:: bash\n\n    pip3 install \"aiomisc[uvloop]\"\n\n\nWith aiohttp_:\n\n.. code-block:: bash\n\n    pip3 install \"aiomisc[aiohttp]\"\n\nComplete table of extras below:\n\n+-----------------------------------+------------------------------------------------+\n| example                           |  description                                   |\n+===================================+================================================+\n| ``pip install aiomisc[aiohttp]``  | For running aiohttp_ applications.             |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[asgi]``     | For running ASGI_ applications                 |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[carbon]``   | Sending metrics to carbon_ (part of graphite_) |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[cron]``     | use croniter_ for scheduling tasks             |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[raven]``    | Sending exceptions to sentry_ using raven_     |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[rich]``     | Use rich_ for logging                          |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[uvicorn]``  | For running ASGI_ application using uvicorn_   |\n+-----------------------------------+------------------------------------------------+\n| ``pip install aiomisc[uvloop]``   | use uvloop_ as a default event loop            |\n+-----------------------------------+------------------------------------------------+\n\n.. _ASGI: https://asgi.readthedocs.io/en/latest/\n.. _PyPI: https://pypi.org/\n.. _aiohttp: https://pypi.org/project/aiohttp\n.. _carbon: https://pypi.org/project/carbon\n.. _croniter: https://pypi.org/project/croniter\n.. _graphite: http://graphiteapp.org\n.. _raven: https://pypi.org/project/raven\n.. _rich: https://pypi.org/project/rich\n.. _sentry: https://sentry.io/\n.. _uvloop: https://pypi.org/project/uvloop\n.. _uvicorn: https://pypi.org/project/uvicorn\n\nYou can combine extras values by separating them with commas, for example:\n\n.. code-block:: bash\n\n    pip3 install \"aiomisc[aiohttp,cron,rich,uvloop]\"\n\n\nQuick Start\n-----------\n\nThis section will cover how this library creates and uses the event loop and\ncreates services. Of course, you can't write about everything here, but you\ncan read about a lot in the Tutorial_ section, and you can\nalways refer to the Modules_ and `API reference`_ sections for help.\n\nEvent-loop and entrypoint\n+++++++++++++++++++++++++\n\nLet's look at this simple example first:\n\n.. code-block:: python\n\n    import asyncio\n    import logging\n\n    import aiomisc\n\n    log = logging.getLogger(__name__)\n\n    async def main():\n        log.info('Starting')\n        await asyncio.sleep(3)\n        log.info('Exiting')\n\n\n    if __name__ == '__main__':\n        with aiomisc.entrypoint(log_level=\"info\", log_format=\"color\") as loop:\n            loop.run_until_complete(main())\n\n\nThis code declares an asynchronous ``main()`` function that exits after\n3 seconds. It would seem nothing interesting, but the whole point is in\nthe ``entrypoint``.\n\nWhat does the ``entrypoint`` do, it would seem not so much, it creates an\nevent-loop and transfers control to the user. However, under the hood, the\nlogger is configured in a separate thread, a pool of threads is created,\nservices are started, but more on that later and there are no services\nin this example.\n\nAlternatively, you can use the standard ``asyncio.Runner``:\n\n.. code-block:: python\n    :name: test_index_runner\n\n    import asyncio\n\n    async def main():\n        await asyncio.sleep(1)\n\n    if __name__ == '__main__':\n        with asyncio.Runner() as runner:\n            runner.run(main())\n\nServices\n++++++++\n\nThe main thing that an ``entrypoint`` does is start and gracefully\nstop services.\n\nThe service concept within this library means a class derived from\nthe ``aiosmic.Service`` class and implementing the\n``async def start(self) -\u003e None:`` method and optionally the\n``async def stop(self, exc: Optional[ Exception]) -\u003e None`` method.\n\nThe concept of stopping a service is not necessarily is pressing ``Ctrl+C``\nkeys by user, it's actually just exiting the ``entrypoint`` context manager.\n\nThe example below shows what your service might look like:\n\n.. code-block:: python\n\n    from aiomisc import entrypoint, Service\n\n    class MyService(Service):\n        async def start(self):\n            do_something_when_start()\n\n        async def stop(self, exc):\n            do_graceful_shutdown()\n\n\n    with entrypoint(MyService()) as loop:\n        loop.run_forever()\n\nThe entry point can start as many instances of the service as it likes,\nand all of them will start concurrently.\n\nThere is also a way if the ``start`` method is a payload for a service,\nand then there is no need to implement the stop method, since the running\ntask with the ``start`` function will be canceled at the stop stage.\nBut in this case, you will have to notify the ``entrypoint`` that the\ninitialization of the service instance is complete and it can continue.\n\nLike this:\n\n.. code-block:: python\n\n    import asyncio\n    from threading import Event\n    from aiomisc import entrypoint, Service\n\n    event = Event()\n\n    class MyService(Service):\n        async def start(self):\n            # Send signal to entrypoint for continue running\n            self.start_event.set()\n            await asyncio.sleep(3600)\n\n\n    with entrypoint(MyService()) as loop:\n        assert event.is_set()\n\n.. note::\n\n    The ``entrypoint`` passes control to the body of the context manager only\n    after all service instances have started. As mentioned above, a start is\n    considered to be the completion of the ``start`` method or the setting of\n    an start event with ``self.start_event.set()``.\n\nThe whole power of this library is in the set of already implemented or\nabstract services.\nSuch as: ``AIOHTTPService``, ``ASGIService``, ``TCPServer``,\n``UDPServer``, ``TCPClient``, ``PeriodicService``, ``CronService`` and so on.\n\nUnfortunately in this section it is not possible to pay more attention to this,\nplease pay attention to the Tutorial_ section section, there are more\nexamples and explanations, and of cource you always can find out an answer on\nthe `/api/index` or in the source code. The authors have tried to make\nthe source code as clear and simple as possible, so feel free to explore it.\n\n\nVersioning\n----------\n\nThis software follows `Semantic Versioning`_\n\nSummary: it's given a version number MAJOR.MINOR.PATCH, increment the:\n\n* MAJOR version when you make incompatible API changes\n* MINOR version when you add functionality in a backwards compatible manner\n* PATCH version when you make backwards compatible bug fixes\n* Additional labels for pre-release and build metadata are available as\n  extensions to the MAJOR.MINOR.PATCH format.\n\nIn this case, the package version is assigned automatically with poem-plugins_,\nit using on the tag in the repository as a major and minor and the counter,\nwhich takes the number of commits between tag to the head of branch.\n\n.. _poem-plugins: https://pypi.org/project/poem-plugins\n\n\nHow to develop?\n---------------\n\nThis project, like most open source projects, is developed by enthusiasts,\nyou can join the development, submit issues, or send your merge requests.\n\nIn order to start developing in this repository, you need to do the\nfollowing things.\n\nShould be installed:\n\n* Python 3.7+ as ``python3``\n* Installed Poetry_ as ``poetry``\n\n.. _Poetry: https://python-poetry.org/docs/\n\nFor setting up developer environment just execute:\n\n    .. code-block::\n\n        # installing all dependencies\n        poetry install\n\n        # setting up pre-commit hooks\n        poetry run pre-commit install\n\n        # adding poem-plugins to the poetry\n        poetry self add poem-plugins\n\n\n.. _Semantic Versioning: http://semver.org/\n\n.. _API reference: https://docs.aiomisc.com/api/index.html\n.. _Modules: https://docs.aiomisc.com/modules.html\n.. _Tutorial: https://docs.aiomisc.com/tutorial.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faiokitchen%2Faiomisc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faiokitchen%2Faiomisc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faiokitchen%2Faiomisc/lists"}