Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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)