Package: evenity
Evenity - Pluggable event hook libaryInstallationpipinstallevenityImportant Notes!Observables tracks observers with a weakref, if the reference to the observable is lost the observer automatically does not track the object anymore.
So keep track of the observers in a variable to keep them receive observable events.
It could've happened that when you delete an observer, the observable keeping track of the object made the garbage collector not delete it since it still kept its reference. In this case the observer continued to handle the events.
Currently, however, the reference is maintained through a weakref which is why you need to be careful to keep the observer in a variable otherwise if you lose track of it, the observable will lose track of it and it will die.
This is a safety measure to avoid memory leaks.
(Thankskrow89)UsageSee examples folder athttps://github.com/baldimario/evenity"""Example"""fromevenity.observableimportObservablefromevenity.observerimportObserverclassEventDispatcher(Observable):"""EventDispatcher class"""def__init__(self):super().__init__()defdispatch(self,topic,event):"""Consume the observable"""self.notify_observers(topic,event)classEventListener(Observer):"""EventListener class"""def__init__(self,observable):super().__init__(observable)self.listen("test",self.on_test)self.listen("foo",self.on_test)defon_test(self,event):"""On test event"""print(f"1{event}")defon_foo(self,event):"""On test event"""print(f"2{event}")defmain():dispatcher=EventDispatcher()listener=EventListener(dispatcher)# Simulate dispatching of some eventsevents=[["test","Hello World!"],["foo","Foo Bar!"],]foreventinevents:dispatcher.dispatch(event[0],event[1])if__name__=='__main__':main()# 1 Hello World!# 2 Foo Bar!simple.pyThis file contains an implementation of observers and observable
It shows how simple is to implement your own observable and register all the observers as you wantkafka.pyThis script contains an implementations of some listeners (observers) for the kafka pluginThis subscribe some listeners for the KafkaObservableConsumer listening for events from many topicsdependency: kafka-pythonfromevenity.observerimportObserverfromevenity.plugins.kafkaimportKafkaObservableConsumerclassListener(Observer):"""ImporterListener class"""def__init__(self,observable):super().__init__(observable)self.listen("topic1",self.on_topic1)self.listen("topic2",self.on_topic2)defon_topic1(self,event):"""On test event"""print(event.decode('utf-8'))defon_topic2(self,event):"""On test event"""print(event.decode('utf-8'))consumer=KafkaObservableConsumer(servers=os.environ.get('KAFKA_SERVERS').split(','),group="mygroup",topics=["topic1","topic2"])listener=Listener(consumer)consumer.consume()ftp.pyftp.py contains an example listener for the ftp observableThis can be useful wen you want to handle file uploaded in an event waydependency: pyftpdlibfromevenity.observerimportObserverfromevenity.event.plugins.ftpimportFTPObservableConsumerclassListener(Observer):"""FTPListener class"""def__init__(self,observable):super().__init__(observable)self.listen("ftp",self.on_ftp)defon_ftp(self,file):"""On ftp event"""print(f'Got file, path:{file}')os.unlink(file)consumer=FTPObservableConsumer(user=os.environ.get('FTP_USER'),password=os.environ.get('FTP_PASSWORD'),port=os.environ.get('FTP_PORT'),path=os.path.join(ABSPATH,os.environ.get('FTP_PATH')),host=os.environ.get('FTP_BIND_ADDRESS'),on_file_received_event='ftp')listener=Listener(consumer)consumer.consume()shell.pyThis file contains an example listener for the shell observableThe use case is to read an output steam from a program (or fifo file) and receive an event for each line printedfromevenity.plugins.shellimportShellObservableConsumerfromevenity.observerimportObserverclassListener(Observer):"""ShellListener class"""def__init__(self,observable):super().__init__(observable)self.first_run=True# self.observable.commandself.listen('monitor-sensor --accel',self.fetch)deffetch(self,line):"""Update method"""print(line)observable=ShellObservableConsumer('monitor-sensor --accel')listener=Listener(observable)observable.consume()telegram.pyThis script contains an example listener for telegram bot events (updates, texts and commands)The observers will be notified for each telegram bot eventdependency: telepotimporttimefromevenity.observerimportObserverfromevenity.plugins.telegramimportAsyncTelegramaObservableConsumerclassListener(Observer):def__init__(self,observable):super().__init__(observable)self.listen("telegram",self.on_telegram)defon_telegram(self,message):if'chat'inmessage:user=message['username']chat_id=message['chat']['id']text=message['text']self.observable.bot.sendMessage(chat_id,f'User{user}with chat id{chat_id}sent "{text}"')consumer=AsyncTelegramaObservableConsumer(token=os.environ.get('TOKEN'),on_message_received_event='telegram')listener=Listener(consumer)consumer.consume()whileTrue:time.sleep(10)ws.pyThis scripts contains an example for websocket connection (open, close, error, message)Handle websocket eventsdependency: websocket-clientfromevenity.plugins.websocketimportWebsocketObservablefromevenity.observerimportObserverclassListener(Observer):"""Websocket listener."""def__init__(self,observable):super().__init__(observable)self.listen("message",self.on_message)self.listen("close",self.on_close)self.listen("error",self.on_error)self.listen("open",self.on_open)defon_message(self,event):"""Update websocket listener."""websocket=event['websocket']message=event['event']print(websocket,message)defon_error(self,event):"""Update websocket listener."""websocket=event['websocket']message=event['event']print(websocket,message)defon_open(self,event):"""Update websocket listener."""websocket=event['websocket']message=event['event']print(websocket,message)defon_close(self,event):"""Update websocket listener."""websocket=event['websocket']message=event['event']print(websocket,message)consumer=WebsocketObservable("wss://localhost/foo",on_open_event='open',on_error_event='error',on_close_event='close',on_message_event='message')listener=Listener(consumer)consumer.consume()SimpleObserverYou can use the SimpleObserver to create observers without defining a new class but using callbacks insteadfromevenity.observerimportSimpleObserverfromevenity.plugins.kafkaimportKafkaObservableConsumerconsumer=KafkaObservableConsumer(servers=os.environ.get('KAFKA_SERVERS').split(','),group="mygroup",topics=["topic1","topic2"])defon_topic1(event):"""On test event"""print(event.decode('utf-8'))listener=SimpleObserver(consumer,{'topic1':on_topic1,'topic2':lambdaevent:print(event.decode('utf-8'))})consumer.consume()