Package: avents
Author:Price HillerContributors:-Jacob B. SandersDescription:A python library for emitting and reading events asynchronously.Type:LibraryLicense:BSD 3-Clause LicenseCopyright:2021, Price HillerAsync EventsA(n) OOP asynchronous Python library capable of emitting custom events based on string matching.Table Of ContentsAsync EventsTable Of ContentsInstallationUsageBasic UsageAdvanced UsageEvent TypesCustom Event ListenersInstallationFrom pippython3-mpipinstallaventsInstallation from Sourcepython[3]setup.pyinstallUsageBasic UsageUsing thelistendecorator you can define a function to listen for an event like so and attach a parser for the events:fromaventsimportlisten# the listener that matches for a string via `listen("some string")`fromaventsimportEvent# an event object defining a name of the event and the event contentfromaventsimportparse# the parser required to emit events via `await parse(Event("some event", "event content")# The listener@listen("event","another event")# A listener can listen to multiple eventsasyncdefexample_event_function(event:Event):print(f"Received event:\"{event.name}\", with content:\"{event.content}\"")# The parserasyncdefparser():# The actual parsing of an event belowawaitparse(Event(name="event",content="example event content"))awaitparse(Event(name="another event",content="another event for the same handler"))A full, runnable, example:importasyncio# Required to run the application# avents importsfromaventsimportlisten# the listener that matches for a string via `listen("some string")`fromaventsimportEvent# an event object defining a name of the event and the event contentfromaventsimportparse# the parser required to emit events via `await parse(Event("some event", "event content")# The listener@listen("event")asyncdefyour_event(event:Event):print(f"Received event:\"{event.name}\", with content:\"{event.content}\"")asyncdefmain():# The actual parsing of an event belowawaitparse(Event(name="event",content="this is some event content"))if__name__=="__main__":loop=asyncio.get_event_loop()loop.run_until_complete(main())Advanced UsageEvent TypesInstead of using raw strings in thelistendecorator, for larger projects it may become much more practical to use a
class container of events to listen for.Avents provides a base event type class to inherit from, that beingBaseEventTypewhich is an enum object.To define event type enums inherit from the said base class:fromaventsimportBaseEventTypeclassCustomEventType(BaseEventType):SOME_EVENT:str="an event"This can then be used in conjunction with thelistendecorator to maintain consistency throughout a larger project
like so:fromaventsimportBaseEventTypefromaventsimportlistenfromaventsimportEventclassCustomEventType(BaseEventType):SOME_EVENT:str="an event"@listen(CustomEventType.SOME_EVENT)asyncdefsome_event(event:Event):print(event)Custom Event ListenersIn the scenario in which you may want to parse a base event and then pass it to further sub event parsing creating a
custom event listener can save quite the headache.In a basic use case we only used theEventListeneras provided to us by avents which is exposed bylistenandparsein more simplistic use cases.With the custom listener inheriting the baseEventListenerexposes custom listening:fromaventsimportEventListenerclassCustomEventListener(EventListener):...Or you can include a constructor as well:fromaventsimportEventListenerclassCustomEventListener(EventListener):def__init__(self):super().__init__()Once a custom event listener has been created thelistenandparsemethods are immediately available:fromaventsimportEventListenerfromaventsimportEventclassCustomEventListener(EventListener):...asyncdefexample_event_emitter():foriinrange(2):awaitCustomEventListener.parse(Event(name=str(i),content=i))@CustomEventListener.listen("0","1","2")# Listen() can take multiple events to listen forasyncdeflisten_for_one(event:Event):print(event)It can be extended further by incorporating theEventListenerclass as the base event handler in the following
pattern:fromaventsimportEventListenerfromaventsimportEventclassCustomEventListener(EventListener):...asyncdefexample_event_emitter():foriinrange(2):awaitEventListener.parse(Event(name=str(i),content=i))@EventListener.listen("0")asyncdefbase_event_handler(event:Event):awaitCustomEventListener.parse(Event(name=event.content+1,content="We incremented to generate a design pattern"))@CustomEventListener.listen("1")asyncdeflisten_for_one(event:Event):print(event)Notice that we use the baseEventListenerfor the initial parsing of an emitted event byexample_event_emitterwhich will then be passed to thebase_event_handlerwhen an event of name0is emitted which then does subparsing
for theCustomEventListenerclass.This can be extended to create entire command structures or other such hierarchical structures.