def _run_on_element(self, element: Element, agent_task: Dict = None, update: bool = False, doc_id: str = None) -> Optional[Element]: """ Running on a target element... :param element: own_adapter.element.Element on which the agent should run... :param agent_task: an agent_task with answers for an agent to process :param update: if an element is being updated :param doc_id: optional id of a document in Firestore to send messages from Agent :return: Target element or None if board or board.element or task are not defined """ if not element: logger.exception(self.name, 'Element was not provided') return None board = element.get_board() if not board: logger.exception(self.name, f'Board is undefined.') return None if agent_task: return self.identify_and_pass_task(element, agent_task, update) return None
def __upload_jokes(self, element: Element, query: str) -> Optional[List]: """ Uploads the metadata for the given query __it uses REST-API__ :param query: Query to find jokes about :return: Plain or None """ logger.debug(self.name, 'Privately started to upload jokes') board = element.get_board() if not board: logger.error(self.name, f'Couldn\'t get the board of element [{element}].') return None response = None try: logger.debug( self.name, f'Connecting to {self.redis_name} via REST for [{query}]') self.update_element_caption(element, query) # Compose the data to be sent to the agent. data = { REQ_QUERY_KEY: query, } # Get the result-data from Jokes-agent's REST-API. request_method = 'POST' request_flask_endpoint = '' jokes_response = self.send_request_to_agent_handler( method=request_method, url=request_flask_endpoint, params={}, data=data) # Check if we get successful response. if not jokes_response or jokes_response.status_code != HTTPStatus.OK: logger.exception( self.name, f'Error: upload jokes about {query} failed.' f' Skipped. Response: {response.status_code if response else None}', response) return None # Parse the received data. logger.debug(self.name, 'Success. Parsing the data') response_data = jokes_response.json() # Return the results. logger.info(self.name, 'Success, returning the data', response) return response_data except Exception as excpt: logger.exception( self.name, f'Error: upload of query [{query}; {year}] is failed. ' f'Skipped. Error type: {excpt}', response) return None
def get_jokes(self, element: Element, agent_task: Dict) -> Optional[Element]: """ Run on element which requested jokes. :param element: own_adapter.element.Element on which Jokes-agent should run. :param agent_task: An agent task to get details from. :return: Target element or None if something gone wrong """ board = element.get_board() # Extract the topic for the joke. topic = get_answer_from_agent_task_answers(agent_task, answer_index=1) topic = str(topic[0]) if topic else '' # Put start-message on the board. start_msg = f'Time to find a joke for thee.' if topic: start_msg += f' "{topic}" you say? Let\'s see...' board.put_message(start_msg) try: # Get the jokes from the agent. uploaded_jokes = self.__upload_jokes(element=element, query=topic) if not uploaded_jokes: # No jokes for you. message = f'I could not find any jokes on "{topic}".' \ if topic \ else 'There are no more jokes in this world.' board.put_message(message) return None # Compose successful report message. message = f'"{uploaded_jokes}"' # Make a joke in a joke from time to time. if randint(-3, 10) < 0: prefix = 'I haven\'t found a thing. Just joking, here you go:\n' message = prefix + message board.put_message(message) except AttributeError as attr_err: logger.exception( self.name, f'Some attribute was incorrect while running Jokes-agent on element: {attr_err}' ) return None return element
def _run_on_element_and_save_task(self, element: Element, task_name: str, query_id: str, agent_task: Dict = None, start_listener: bool = False, update: bool = False, constant_monitoring: bool = False) \ -> Optional[Element]: """ Create document to communicate with agent, run on a target element :param query_id: an id of agent task query :param task_name: a name of task which is being executed :param update: if an element is being updated :param element: own_adapter.element.Element on which the agent should run :param agent_task: an agent_task with answers for an agent to process :param constant_monitoring: whether this task should run in constant monitoring mode :param start_listener: if a communication listener should be started for this task :return: Target element """ self.db.delete_old_agent_tasks(element.get_id()) doc_ref = self.db.create_new_doc_for_task( element.get_board().get_id(), element.get_id(), query_id, task_name, update_period=self.updating_time_interval, constant_monitoring=constant_monitoring, agent_task=agent_task) doc_id = self.db.get_doc_id(doc_ref) try: self.task_running_updaters[doc_id] = doc_ref if start_listener or constant_monitoring: threading.Thread( target=lambda: self.communication_handling(doc_ref), daemon=True).start() res = self._run_on_element(element, agent_task, update, doc_id) if not res: self.db.delete_doc(doc_ref) return res except Exception as e: logger.exception( self.name, f'Couldn\'t run updates on element for task: {task_name}. Error: {e}' ) finally: self.db.finish_monitoring_task(doc_ref, update=True) self.task_running_updaters.pop(doc_id)