def create_message(self, describe=False): """ Creates a basic empty Message object with basic boilerplate metadata :return: Response object with execution information and the new message object inside the data envelope :rtype: Response """ # Internal documentation setup #allowable_parameters = { 'action': { 'None' } } allowable_parameters = { 'dsl_command': '`create_message()`' } # can't get this name at run-time, need to manually put it in per https://www.python.org/dev/peps/pep-3130/ if describe: allowable_parameters[ 'brief_description'] = """The `create_message` method creates a basic empty Message object with basic boilerplate metadata such as reasoner_id, schema_version, etc. filled in. This DSL command takes no arguments""" return allowable_parameters #### Define a default response response = Response() self.response = response #### Create the top-level message response.info("Creating an empty template ARAX Message") message = Message() self.message = message #### Fill it with default information message.id = None message.type = "translator_reasoner_message" message.reasoner_id = "ARAX" message.tool_version = RTXConfiguration().version message.schema_version = "0.9.3" message.message_code = "OK" message.code_description = "Created empty template Message" message.context = "https://raw.githubusercontent.com/biolink/biolink-model/master/context.jsonld" #### Why is this _datetime ?? FIXME message._datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") #### Create an empty master knowledge graph message.knowledge_graph = KnowledgeGraph() message.knowledge_graph.nodes = [] message.knowledge_graph.edges = [] #### Create an empty query graph message.query_graph = QueryGraph() message.query_graph.nodes = [] message.query_graph.edges = [] #### Create empty results message.results = [] message.n_results = 0 #### Return the response response.data['message'] = message return response
def createMessage(self): #### Create the message object and fill it with attributes about the message message = Message() message.message_code = "OK" message.code_description = "??" return message
def query(self, query): #### Get our configuration information #### Create a Message object as a response response = Message() execution_string = None #### Determine a plan for what to do based on the input result = self.examine_incoming_query(query) if result["message_code"] != "OK": response.message_code = result["message_code"] response.code_description = result["code_description"] return response #### If we have a previous message processing plan, handle that if "have_previous_message_processing_plan" in result: rtxFeedback = RTXFeedback( ) # FIXME. This should be a separate class I think, not the Feedback class. TODO: Separate them rtxFeedback.connect() message = rtxFeedback.processExternalPreviousMessageProcessingPlan( query) rtxFeedback.disconnect() return (message) #### If we have a query_graph, pass this on to the QueryGraphReasoner if "have_query_graph" in result: qgr = QueryGraphReasoner() message = qgr.answer(query["message"]["query_graph"], TxltrApiFormat=True) #self.log_query(query,message,'new') rtxFeedback = RTXFeedback() rtxFeedback.connect() rtxFeedback.addNewMessage(message, query) rtxFeedback.disconnect() self.limit_message(message, query) return (message) #### Otherwise extract the id and the terms from the incoming parameters else: id = query["message"]["query_type_id"] terms = query["message"]["terms"] #### Check to see if the query_options indicates to query named resource and integrate the results if "have_query_type_id_and_terms" in result and "message" in query and "query_options" in query[ "message"] and "integrate" in query["message"]["query_options"]: response = self.integrate(query) #self.log_query(query,response,'remote') return response #### Create an RTX Feedback management object #eprint(query) rtxFeedback = RTXFeedback() rtxFeedback.connect() cachedMessage = rtxFeedback.getCachedMessage(query) #### If we can find a cached message for this query and this version of RTX, then return the cached message if (cachedMessage is not None): apiMessage = Message().from_dict(cachedMessage) rtxFeedback.disconnect() self.limit_message(apiMessage, query) if apiMessage.message_code is None: if apiMessage.result_code is not None: apiMessage.message_code = apiMessage.result_code else: apiMessage.message_code = "wha??" self.log_query(query, apiMessage, 'cached') return apiMessage #### Still have special handling for Q0 if id == 'Q0': q0 = Q0() message = q0.answer(terms["term"], use_json=True) if 'original_question' in query["message"]: message.original_question = query["message"][ "original_question"] message.restated_question = query["message"][ "restated_question"] message.query_type_id = query["message"]["query_type_id"] message.terms = query["message"]["terms"] id = message.id codeString = message.message_code self.log_query(query, message, 'new') rtxFeedback.addNewMessage(message, query) rtxFeedback.disconnect() self.limit_message(message, query) return (message) #### Else call out to original solution scripts for an answer else: #### If some previous processing has determined what the solution script to use is, then use that if execution_string is not None: command = "python3 " + execution_string #### Else use the ParseQuestion system to determine what the execution_string should be else: txltr = ParseQuestion() command = "python3 " + txltr.get_execution_string(id, terms) #### Set CWD to the QuestioningAnswering area and then invoke from the shell the Q1Solution code cwd = os.getcwd() os.chdir( os.path.dirname(os.path.abspath(__file__)) + "/../../../reasoningtool/QuestionAnswering") eprint(command) returnedText = subprocess.run([command], stdout=subprocess.PIPE, shell=True) os.chdir(cwd) #### reformat the stdout result of the shell command into a string reformattedText = returnedText.stdout.decode('utf-8') #eprint(reformattedText) #### Try to decode that string into a message object try: #data = ast.literal_eval(reformattedText) data = json.loads(reformattedText) message = Message.from_dict(data) if message.message_code is None: if message.result_code is not None: message.message_code = message.result_code else: message.message_code = "wha??" #### If it fails, the just create a new Message object with a notice about the failure except: message = Message() message.message_code = "InternalError" message.code_description = "Error parsing the message from the reasoner. This is an internal bug that needs to be fixed. Unable to respond to this question at this time. The unparsable message was: " + reformattedText #print(query) if 'original_question' in query["message"]: message.original_question = query["message"][ "original_question"] message.restated_question = query["message"][ "restated_question"] message.query_type_id = query["message"]["query_type_id"] message.terms = query["message"]["terms"] #### Log the result and return the Message object self.log_query(query, message, 'new') rtxFeedback.addNewMessage(message, query) rtxFeedback.disconnect() #### Limit message self.limit_message(message, query) return (message) #### If the query type id is not triggered above, then return an error message = Message() message.message_code = "UnsupportedQueryTypeID" message.code_description = "The specified query id '" + id + "' is not supported at this time" rtxFeedback.disconnect() return (message)