Package: aiomisc
Miscellaneous utils for asyncio.As a programmer, you are no stranger to the challenges that come with building
and maintaining software applications. One area that can be particularly
difficult is making architecture of the software that using asynchronous I/O.This is where aiomisc comes in. aiomisc is a Python library that provides a
collection of utility functions and classes for working with asynchronous I/O
in a more intuitive and efficient way. It is built on top of theasynciolibrary and is designed to make it easier for developers to write
asynchronous code that is both reliable and scalable.With aiomisc, you can take advantage of powerful features likeworker pools,connection pools,circuit breaker pattern,
and retry mechanisms such asasyncbackoffandasyncretryto make your
asyncio code more robust and easier to maintain. In this documentation,
we’ll take a closer look at whataiomischas to offer and how it can
help you streamline your asyncio service development.InstallationInstallation is possible in standard ways, such as PyPI or installation from
a git repository directly.Installing fromPyPI:pip3installaiomiscInstalling from github.com:# Using git toolpip3installgit+https://github.com/aiokitchen/aiomisc.git# Alternative way using httppip3install\https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zipThe package contains several extras and you can install additional dependencies
if you specify them in this way.Withuvloop:pip3install"aiomisc[uvloop]"Withaiohttp:pip3install"aiomisc[aiohttp]"Complete table of extras bellow:exampledescriptionpip install aiomisc[aiohttp]For runningaiohttpapplications.pip install aiomisc[asgi]For runningASGIapplicationspip install aiomisc[carbon]Sending metrics tocarbon(part ofgraphite)pip install aiomisc[cron]usecroniterfor scheduling taskspip install aiomisc[raven]Sending exceptions tosentryusingravenpip install aiomisc[rich]You might usingrichfor loggingpip install aiomisc[uvicorn]For runningASGIapplication usinguvicornpip install aiomisc[uvloop]useuvloopas a default event loopYou can combine extras values by separating them with commas, for example:pip3install"aiomisc[aiohttp,cron,rich,uvloop]"Quick StartThis section will cover how this library creates and uses the event loop and
creates services. Of course, you can’t write about everything here, but you
can read about a lot in theTutorialsection, and you can
always refer to theModulesandAPI referencesections for help.Event-loop and entrypointLet’s look at this simple example first:importasyncioimportloggingimportaiomisclog=logging.getLogger(__name__)asyncdefmain():log.info('Starting')awaitasyncio.sleep(3)log.info('Exiting')if__name__=='__main__':withaiomisc.entrypoint(log_level="info",log_format="color")asloop:loop.run_until_complete(main())This code declares an asynchronousmain()function that exits after
3 seconds. It would seem nothing interesting, but the whole point is in
theentrypoint.What does theentrypointdo, it would seem not so much, it creates an
event-loop and transfers control to the user. However, under the hood, the
logger is configured in a separate thread, a pool of threads is created,
services are started, but more on that later and there are no services
in this example.Alternatively, you can choose not to use an entrypoint, just create an
event-loop and set this as a default event loop for current thread:importasyncioimportaiomisc# * Installs uvloop event loop is it's has been installed.# * Creates and set `aiomisc.thread_pool.ThreadPoolExecutor`#   as a default executor# * Sets just created event-loop as a current event-loop for this thread.aiomisc.new_event_loop()asyncdefmain():awaitasyncio.sleep(1)if__name__=='__main__':loop=asyncio.get_event_loop()loop.run_until_complete(main())The example above is useful if your code is already using an implicitly created
event loop, you will have to modify less code, just addaiomisc.new_event_loop()and all calls toasyncio.get_event_loop()will return the created instance.However, you can do with one call. Following example closes implicitly created
asyncio event loop and install a new one:importasyncioimportaiomiscasyncdefmain():awaitasyncio.sleep(3)if__name__=='__main__':loop=aiomisc.new_event_loop()loop.run_until_complete(main())ServicesThe main thing that anentrypointdoes is start and gracefully
stop services.The service concept within this library means a class derived from
theaiosmic.Serviceclass and implementing theasync def start(self)->None:method and optionally theasync def stop(self, exc: Optional[ Exception])->Nonemethod.The concept of stopping a service is not necessarily is pressingCtrl+Ckeys by user, it’s actually just exiting theentrypointcontext manager.The example below shows what your service might look like:fromaiomiscimportentrypoint,ServiceclassMyService(Service):asyncdefstart(self):do_something_when_start()asyncdefstop(self,exc):do_graceful_shutdown()withentrypoint(MyService())asloop:loop.run_forever()The entry point can start as many instances of the service as it likes,
and all of them will start concurrently.There is also a way if thestartmethod is a payload for a service,
and then there is no need to implement the stop method, since the running
task with thestartfunction will be canceled at the stop stage.
But in this case, you will have to notify theentrypointthat the
initialization of the service instance is complete and it can continue.Like this:importasynciofromthreadingimportEventfromaiomiscimportentrypoint,Serviceevent=Event()classMyService(Service):asyncdefstart(self):# Send signal to entrypoint for continue runningself.start_event.set()awaitasyncio.sleep(3600)withentrypoint(MyService())asloop:assertevent.is_set()NoteTheentrypointpasses control to the body of the context manager only
after all service instances have started. As mentioned above, a start is
considered to be the completion of thestartmethod or the setting of
an start event withself.start_event.set().The whole power of this library is in the set of already implemented or
abstract services.
Such as:AIOHTTPService,ASGIService,TCPServer,UDPServer,TCPClient,PeriodicService,CronServiceand so on.Unfortunately in this section it is not possible to pay more attention to this,
please pay attention to theTutorialsection section, there are more
examples and explanations, and of cource you always can find out an answer on
the/api/indexor in the source code. The authors have tried to make
the source code as clear and simple as possible, so feel free to explore it.VersioningThis software followsSemantic VersioningSummary: it’s given a version number MAJOR.MINOR.PATCH, increment the:MAJOR version when you make incompatible API changesMINOR version when you add functionality in a backwards compatible mannerPATCH version when you make backwards compatible bug fixesAdditional labels for pre-release and build metadata are available as
extensions to the MAJOR.MINOR.PATCH format.In this case, the package version is assigned automatically withpoem-plugins,
it using on the tag in the repository as a major and minor and the counter,
which takes the number of commits between tag to the head of branch.Summary: it’s given a version number MAJOR.MINOR.PATCH, increment the:MAJOR version when you make incompatible API changesMINOR version when you add functionality in a backwards compatible mannerPATCH version when you make backwards compatible bug fixesAdditional labels for pre-release and build metadata are available as
extensions to the MAJOR.MINOR.PATCH format.In this case, the package version is assigned automatically withpoem-plugins,
it using on the tag in the repository as a major and minor and the counter,
which takes the number of commits between tag to the head of branch.How to develop?This project, like most open source projects, is developed by enthusiasts,
you can join the development, submit issues, or send your merge requests.In order to start developing in this repository, you need to do the
following things.Should be installed:Python 3.7+ aspython3InstalledPoetryaspoetryFor setting up developer environment just execute:# installing all dependencies
poetry install

# setting up pre-commit hooks
poetry run pre-commit install

# adding poem-plugins to the poetry
poetry self add poem-plugins