def read(self, topic, blocks=True): """ Read from one or several topics. it is non blocking returning None if nothing is available :param topic: can be str: single topic; or str list: several topics :param blocks: indicates if it should wait and block until a message is present or returns None :return: topic, key, message; or None if blocks==True """ try: if isinstance(topic, (list, tuple)): topic_list = topic else: topic_list = (topic, ) while True: for single_topic in topic_list: if single_topic not in self.files: self.files[single_topic] = open( self.path + single_topic, "a+") self.buffer[single_topic] = "" self.buffer[single_topic] += self.files[ single_topic].readline() if not self.buffer[single_topic].endswith("\n"): continue msg_dict = yaml.load(self.buffer[single_topic]) self.buffer[single_topic] = "" assert len(msg_dict) == 1 for k, v in msg_dict.items(): return single_topic, k, v if not blocks: return None sleep(2) except Exception as e: # TODO refine raise MsgException(str(e))
async def aioread(self, topic, loop=None, callback=None, *args): """ Asyncio read from one or several topics. It blocks :param topic: can be str: single topic; or str list: several topics :param loop: asyncio loop :callback: callback function that will handle the message in kafka bus :*args: optional arguments for callback function :return: topic, key, message """ if not loop: loop = self.loop try: if isinstance(topic, (list, tuple)): topic_list = topic else: topic_list = (topic, ) self.consumer = AIOKafkaConsumer(loop=loop, bootstrap_servers=self.broker) await self.consumer.start() self.consumer.subscribe(topic_list) async for message in self.consumer: if callback: callback(message.topic, yaml.load(message.key), yaml.load(message.value), *args) else: return message.topic, yaml.load(message.key), yaml.load( message.value) except KafkaError as e: raise MsgException(str(e)) finally: await self.consumer.stop()
def read(self, topic): #self.topic_lst.append(topic) try: return self.loop.run_until_complete(self.aioread(topic)) except Exception as e: raise MsgException("Error reading {} topic: {}".format( topic, str(e)))
def write(self, topic, key, msg): try: self.loop.run_until_complete( self.aiowrite(topic=topic, key=key, msg=yaml.safe_dump(msg, default_flow_style=True), loop=self.loop)) except Exception as e: raise MsgException("Error writing {} topic: {}".format( topic, str(e)))
def connect(self, config): try: if "logger_name" in config: self.logger = logging.getLogger(config["logger_name"]) self.host = config["host"] self.port = config["port"] self.loop = asyncio.get_event_loop() self.broker = str(self.host) + ":" + str(self.port) except Exception as e: # TODO refine raise MsgException(str(e))
def connect(self, config): try: if "logger_name" in config: self.logger = logging.getLogger(config["logger_name"]) self.path = config["path"] if not self.path.endswith("/"): self.path += "/" if not os.path.exists(self.path): os.mkdir(self.path) except MsgException: raise except Exception as e: # TODO refine raise MsgException(str(e))
def read(self, topic): """ Read from one or several topics. it is non blocking returning None if nothing is available :param topic: can be str: single topic; or str list: several topics :return: topic, key, message; or None """ try: return self.loop.run_until_complete(self.aioread(topic, self.loop)) except MsgException: raise except Exception as e: raise MsgException("Error reading {} topic: {}".format( topic, str(e)))
async def aioread(self, topic, loop=None): if not loop: loop = self.loop self.consumer = AIOKafkaConsumer(loop=loop, bootstrap_servers=self.broker) await self.consumer.start() self.consumer.subscribe([topic]) try: async for message in self.consumer: return yaml.load(message.key), yaml.load(message.value) except KafkaError as e: raise MsgException(str(e)) finally: await self.consumer.stop()
def write(self, topic, key, msg): """ Insert a message into topic :param topic: topic :param key: key text to be inserted :param msg: value object to be inserted :return: None or raises and exception """ try: if topic not in self.files: self.files[topic] = open(self.path + topic, "a+") yaml.safe_dump({key: msg}, self.files[topic], default_flow_style=True) self.files[topic].flush() except Exception as e: # TODO refine raise MsgException(str(e))
async def aiowrite(self, topic, key, msg, loop=None): try: if not loop: loop = self.loop self.producer = AIOKafkaProducer(loop=loop, key_serializer=str.encode, value_serializer=str.encode, bootstrap_servers=self.broker) await self.producer.start() await self.producer.send(topic=topic, key=key, value=msg) except Exception as e: raise MsgException("Error publishing to {} topic: {}".format( topic, str(e))) finally: await self.producer.stop()
async def aioread(self, topic, loop): """ Asyncio read from one or several topics. It blocks :param topic: can be str: single topic; or str list: several topics :param loop: asyncio loop :return: topic, key, message """ try: while True: msg = self.read(topic, blocks=False) if msg: return msg await asyncio.sleep(2, loop=loop) except MsgException: raise except Exception as e: # TODO refine raise MsgException(str(e))
def read(self, topic): try: msg = "" if topic not in self.files: self.files[topic] = open(self.path + topic, "a+") # ignore previous content for line in self.files[topic]: if not line.endswith("\n"): msg = line msg += self.files[topic].readline() if not msg.endswith("\n"): return None msg_dict = yaml.load(msg) assert len(msg_dict) == 1 for k, v in msg_dict.items(): return k, v except Exception as e: # TODO refine raise MsgException(str(e))
async def aiowrite(self, topic, key, msg, loop=None): if not loop: loop = self.loop try: self.producer = AIOKafkaProducer(loop=loop, key_serializer=str.encode, value_serializer=str.encode, bootstrap_servers=self.broker) await self.producer.start() await self.producer.send(topic=topic, key=key, value=yaml.safe_dump( msg, default_flow_style=True)) except Exception as e: raise MsgException( "Error publishing topic '{}', key '{}': {}".format( topic, key, e)) finally: await self.producer.stop()
async def aioread(self, topic, loop=None): try: msg = "" if not loop: loop = asyncio.get_event_loop() if topic not in self.files: self.files[topic] = open(self.path + topic, "a+") # ignore previous content for line in self.files[topic]: if not line.endswith("\n"): msg = line while True: msg += self.files[topic].readline() if msg.endswith("\n"): break await asyncio.sleep(2, loop=loop) msg_dict = yaml.load(msg) assert len(msg_dict) == 1 for k, v in msg_dict.items(): return k, v except Exception as e: # TODO refine raise MsgException(str(e))
def disconnect(self): try: self.loop.close() except Exception as e: # TODO refine raise MsgException(str(e))