Package: event-notifier
event-notifierLibrary providing event registration and routing infrastructure.ContentsBackgroundInstallationExampleConstructorAPI OverviewTestsLicenseContributingBackgroundThis is an implementation of event notifier (also known as emitter or dispatcher) allowing to notify one or more subscribers of an event that just occurred.Any python object inheriting from or containing a notifier can act as event sender and any callable object can act as event receiver.
Allows to register receivers having variable number of arguments.Installationpip install -U event-notifierExamplefromEventNotifierimportNotifier# Imagine we have a piece of code which is interested in some events# occurring in other pieces of the code...classFileWatchDog():defonOpen(self,fileName,openMode):print(f"File{fileName}opened with{openMode}mode")defonClose(self,fileName):print(f"File{fileName}closed")watchDog=FileWatchDog()# Create Notifier object by providing a list of events other components might be interesting innotifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])# From now other objects are able to subscribe to events we've declared above# Its important to use the same name as it was declared while creating Notifier object# Consider using constant declarations or enums in order to avoid typos herenotifier.subscribe("onOpen",watchDog.onOpen)notifier.subscribe("onClose",watchDog.onClose)notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")# order of named parameters is not importantnotifier.raise_event("onClose",fileName="test_file.txt")Will produce:$pythontest.pyFile test_file.txt opened with w+ modeFile test_file.txt closedConstructorNotifier(eventNames:list,logger=None)ParameterseventNames-list of any- mandatory, provides list of all supported events. Values provided here can be used for raising events later.
Values provided in this list can be of any type.logger-object- optional, logger supporting standard logging methods (info, warning error, etc..), default:None.
If None is provided, then internal logger outputting warnings and errors to console will be created.ExampleAny object can be used as event name. Example below illustrates that:fromEventNotifierimportNotifierclassBox:def__init__(self,name):self.name=namea=Box("name_BoxA")b=Box("name_BoxB")notifier=Notifier(["onCreate",5,22.58,"onDelete",a,b])notifier.subscribe("onCreate",onCreateCallback)notifier.subscribe(5,on5Callback)notifier.subscribe(22.58,onFloatCallback)notifier.subscribe(a,onBoxACallback)notifier.subscribe(b,onBoxBCallback)notifier.raise_event(5,"event: ! 5 !")# on5Callback will be called with "event: ! 5 !" as parameternotifier.raise_event(22.58,"event: ! 22.58 !")# onFloatCallback will be called with "event: ! 22.58 !" as parameternotifier.raise_event(b,"event: Box b")# onBoxBCallback will be called with "event: Box b" as parameterAPI Overviewsubscribe(eventName, subscriber)DescriptionAdds callable subscribers interested in some particular event.ParameterseventName-any- mandatory, specifies name of the event, subscriber will be interested in.subscriber-any- mandatory, callable subscriber (function, class method or class withcallimplemented)ExamplefromEventNotifierimportNotifierclassCallableFileWatchdog:def__init__(self,pathToWatch):self.pathToWatch=pathToWatchdef__call__(self,*args,**kwargs):iflen(args)>0:print(f"Event{args[0]}at path{self.pathToWatch}is called with following simple args:{[*args]}and with following keyword args:{{**kwargs}}")callableWatchdog=CallableFileWatchdog("some\path\here")notifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])notifier.subscribe("onCreate",callableWatchdog)notifier.subscribe("onOpen",callableWatchdog)notifier.raise_event("onCreate","onCreate",fileName="test_file.txt")notifier.raise_event("onOpen","onOpen",openMode="w+",fileName="test_file.txt")gives:Event onCreate at path some\path\here is called with following simple args: ['onCreate'] and with following keyword args: {'fileName': 'test_file.txt'}Event onOpen at path some\path\here is called with following simple args: ['onOpen'] and with following keyword args: {'openMode': 'w+', 'fileName': 'test_file.txt'}subscribe_to_all(subscriber):DescriptionMethod allows to register one callable for all events supported by notifier.Parameterssubscriber-callable- mandatory, will be called when event rises.ExamplefromEventNotifierimportNotifierclassCallableFileWatchdog:def__init__(self,pathToWatch):self.pathToWatch=pathToWatchdef__call__(self,*args,**kwargs):iflen(args)>0:print\(f"Event{args[0]}at path{self.pathToWatch}is called with following simple args:{[*args]}and with following keyword args:{{**kwargs}}")callable_watchog=CallableFileWatchdog("some\\path\\here")notifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])notifier.subscribe_to_all(callable_watchog)notifier.raise_event("onCreate","onCreate",fileName="test_file.txt")notifier.raise_event("onOpen","onOpen",openMode="w+",fileName="test_file.txt")Console output:Event onCreate at path some\path\here is called with following simple args: ['onCreate'] and with following keyword args: {'fileName': 'test_file.txt'}Event onOpen at path some\path\here is called with following simple args: ['onOpen'] and with following keyword args: {'openMode': 'w+', 'fileName': 'test_file.txt'}get_registered_events():DescriptionReturns all supported events as a list.ExamplefromEventNotifierimportNotifiernotifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])print(notifier.get_registered_events())will output:['onCreate', 'onOpen', 'onModify', 'onClose', 'onDelete']raise_event(eventName, *args, **kwargs)DescriptionRises specific event registered during initialization.ParameterseventName-any- mandatory, name of the event to be raised.*args-list- optional, all simple parameters we want to pass to our subscribers (param1, param2, param3...).**kwargs-dictionary- optional, all named parameters we want to pass (param1=value1, param2=value2, param3=value3)ExampleCheck subscribe method's example linkabove.remove_subscribers_by_event_name(event_name)DescriptionRemoves all subscribers for the specified event_nameParameterseventName-any- mandatory, name of the event we want to remove subscribers for.ExamplefromEventNotifierimportNotifierclassFileWatchDog():defonOpen(self,fileName,openMode):print(f"File{fileName}opened with{openMode}mode")defonClose(self,fileName):print(f"File{fileName}closed")defonOpenStandaloneMethod(fileName,openMode):print(f"StandaloneMethod: File{fileName}opened with{openMode}mode")watchDog=FileWatchDog()notifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])notifier.subscribe("onOpen",watchDog.onOpen)notifier.subscribe("onOpen",onOpenStandaloneMethod)notifier.subscribe("onClose",watchDog.onClose)print("\nAfter subscription:")notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")# order of named parameters is not importantnotifier.raise_event("onClose",fileName="test_file.txt")notifier.remove_subscribers_by_event_name("onOpen")print("\nAfter removal of onOpen subscribers:")notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")# order of named parameters is not importantnotifier.raise_event("onClose",fileName="test_file.txt")notifier.remove_subscribers_by_event_name("onClose")print("\nAfter removal of onClose subscribers:")notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")# order of named parameters is not importantnotifier.raise_event("onClose",fileName="test_file.txt")will output:After subscription:File test_file.txt opened with w+ modeStandaloneMethod: File test_file.txt opened with w+ modeFile test_file.txt closedAfter removal of onOpen subscribers:File test_file.txt closedAfter removal of onClose subscribers:remove_all_subscribers()DescriptionRemoves all subscribers for all eventsExamplefromEventNotifierimportNotifierclassFileWatchDog():defonOpen(self,fileName,openMode):print(f"File{fileName}opened with{openMode}mode")defonClose(self,fileName):print(f"File{fileName}closed")defonOpenStandaloneMethod(fileName,openMode):print(f"StandaloneMethod: File{fileName}opened with{openMode}mode")watchDog=FileWatchDog()notifier=Notifier(["onCreate","onOpen","onModify","onClose","onDelete"])notifier.subscribe("onOpen",watchDog.onOpen)notifier.subscribe("onOpen",onOpenStandaloneMethod)notifier.subscribe("onClose",watchDog.onClose)print("\nAfter subscription:")notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")notifier.raise_event("onClose",fileName="test_file.txt")notifier.remove_all_subscribers()print("\nAfter removal of all subscribers:")notifier.raise_event("onOpen",openMode="w+",fileName="test_file.txt")notifier.raise_event("onClose",fileName="test_file.txt")will give:After subscription:File test_file.txt opened with w+ modeStandaloneMethod: File test_file.txt opened with w+ modeFile test_file.txt closedAfter removal of all subscribers:TestsPyTestis used for tests. Python 2 is not supported.Install PyTest$pipinstallpytestRun tests$pytesttest/*Check test coverageIn order to generate test coverage report install pytest-cov:$pipinstallpytest-covThen inside test subdirectory call:pytest--cov=../EventNotifier--cov-report=htmlLicenseLicense
Copyright (C) 2020 Vitalij Gotovskijevent-notifier binaries and source code can be used according to the MIT LicenseContributeTBD