示例#1
0
    def integrate(self, query):
        if "options" in query and query["options"] is not None:
            if re.search("integrate=.+", query["options"]):
                integrate_option = query["options"]
                eprint(integrate_option)
                target_string = re.sub("integrate=", "", integrate_option)
                targets = re.split(",", target_string)
                eprint(targets)

                final_message = Message()

                for reasoner_id in targets:
                    eprint("Looping with reasoner_id=" + reasoner_id)
                    query["options"] = "foo"
                    url = None
                    if reasoner_id == "RTX":
                        url = "https://arax.rtx.ai/devED/api/rtx/v1/query"
                    elif reasoner_id == "Robokop":
                        url = "http://robokop.renci.org:6011/api/query"
                    elif reasoner_id == "Indigo":
                        url = "https://indigo.ncats.io/reasoner/api/v0/query"
                        url = None
                    else:
                        eprint("ERROR: Unrecognized target '" + target + "'")
                    if url is not None:
                        eprint("Querying url " + url)
                        message_content = requests.post(
                            url,
                            headers={'accept': 'application/json'},
                            json=query)
                        status_code = message_content.status_code
                        message_dict = message_content.json()
                        message = Message.from_dict(message_dict)
                        if reasoner_id == "RTX":
                            final_message = message
                        if reasoner_id == "Robokop" or reasoner_id == "Indigo":
                            #if reasoner_id == "Robokop":
                            eprint("Merging in " + reasoner_id)
                            message = self.fix_message(query, message,
                                                       reasoner_id)
                            if message.results is not None:
                                final_message = self.merge_message2(
                                    final_message, message)

                return (final_message)
            return (None)
        return (None)
def add_message(agentIdPath, body):  # noqa: E501
    """Add a new message (to the agent's multichain stream)

    Adds a new Message  # noqa: E501

    :param agentIdPath: ID of marketplace agent
    :type agentIdPath: str
    :param body: Message that should to be added to the blockchain
    :type body: dict | bytes

    :rtype: Message
    """
    if connexion.request.is_json:
        json_body = connexion.request.get_json()
        body = Message.from_dict(json_body)  # noqa: E501
        body.indexkeys.append('id:'+body.id)
        json_body['indexkeys'].append('id:'+json_body['id'])
        multichain_client.publish(agentIdPath,body.indexkeys, json_body)
        return Response(status=201, mimetype='application/json')
    else:
        return Response(status=405, mimetype='application/json')
示例#3
0
def message(message=None):  # noqa: E501
    """requesting chatbot to handle task

    ask bot # noqa: E501

    :param message: 
    :type message: dict | bytes

    :rtype: InlineResponse200
    """     
    if connexion.request.is_json:
        message = Message.from_dict(connexion.request.get_json())  # noqa: E501

    msg = message._message
    bot = RiveScript()
    path = os.path.dirname(os.path.realpath(__file__))+'/brain'
    bot.load_directory(path)
    bot.sort_replies()

    reply = bot.reply("localuser", msg)
    
    if reply == '[ERR: No Reply Matched]':
        reply = "The bot can not understand you question:("   
    return reply , 200, None
示例#4
0
    def processExternalPreviousMessageProcessingPlan(self, inputEnvelope):
        debug = 1
        if debug:
            eprint(
                "DEBUG: Entering processExternalPreviousMessageProcessingPlan")
        messages = []
        finalMessage = None
        finalMessage_id = None
        query = None

        #### Pull out the main processing plan envelope
        envelope = PreviousMessageProcessingPlan.from_dict(
            inputEnvelope["previous_message_processing_plan"])

        #### If there are URIs provided, try to load them
        if envelope.previous_message_uris is not None:
            if debug: eprint("DEBUG: Got previous_message_uris")
            for uri in envelope.previous_message_uris:
                if debug: eprint("DEBUG:   messageURI=" + uri)
                matchResult = re.match(
                    r'http[s]://arax.ncats.io/.*api/rtx/.+/message/(\d+)', uri,
                    re.M | re.I)
                if matchResult:
                    message_id = matchResult.group(1)
                    if debug:
                        eprint(
                            "DEBUG: Found local ARAX identifier corresponding to message_id "
                            + message_id)
                    if debug: eprint("DEBUG: Loading message_id " + message_id)
                    message = self.getMessage(message_id)
                    #eprint(type(message))
                    if not isinstance(message, tuple):
                        if debug:
                            eprint("DEBUG: Original question was: " +
                                   message["original_question"])
                        messages.append(message)
                        finalMessage_id = message_id
                        query = {
                            "query_type_id": message["query_type_id"],
                            "restated_question": message["restated_question"],
                            "terms": message["terms"]
                        }
                    else:
                        eprint("ERROR: Unable to load message_id " +
                               message_id)
                        return ({
                            "status":
                            404,
                            "title":
                            "Message not found",
                            "detail":
                            "There is no local message corresponding to message_id="
                            + str(message_id),
                            "type":
                            "about:blank"
                        }, 404)

        #### If there are one or more previous_messages embedded in the POST, process them
        if envelope.previous_messages is not None:
            if debug: eprint("DEBUG: Got previous_messages")
            for uploadedMessage in envelope.previous_messages:
                if debug:
                    eprint("DEBUG: uploadedMessage is a " +
                           str(uploadedMessage.__class__))
                if str(uploadedMessage.__class__
                       ) == "<class 'swagger_server.models.message.Message'>":
                    if uploadedMessage.results:
                        message = ast.literal_eval(repr(uploadedMessage))
                        messages.append(message)

                        if message["terms"] is None:
                            message["terms"] = {"dummyTerm": "giraffe"}
                        if message["query_type_id"] is None:
                            message["query_type_id"] = "UnknownQ"
                        if message["restated_question"] is None:
                            message["restated_question"] = "What is life?"
                        if message["original_question"] is None:
                            message["original_question"] = "what is life"

                        query = {
                            "query_type_id": message["query_type_id"],
                            "restated_question": message["restated_question"],
                            "original_question": message["original_question"],
                            "terms": message["terms"]
                        }
                    else:
                        eprint(
                            "Uploaded message does not contain a results. May be the wrong format"
                        )
                        return ({
                            "status": 404,
                            "title": "Bad uploaded Message",
                            "detail":
                            "There is no results in the uploaded Message object=",
                            "type": "about:blank"
                        }, 404)
                else:
                    eprint(
                        "Uploaded message is not of type Message. It is of type"
                        + str(uploadedMessage.__class__))
                    return ({
                        "status":
                        404,
                        "title":
                        "Bad uploaded Message",
                        "detail":
                        "Uploaded message is not of type Message. It is of type"
                        + str(uploadedMessage.__class__),
                        "type":
                        "about:blank"
                    }, 404)

        #### Take different actions based on the number of messages we now have in hand
        n_messages = len(messages)
        if n_messages == 0:
            return ({
                "status": 499,
                "title": "No Messages",
                "detail": "Did not get any useful Message objects",
                "type": "about:blank"
            }, 499)
        elif n_messages == 1:
            finalMessage = messages[0]
        else:
            finalMessage = TxMessage.from_dict(messages[0])
            counter = 1
            while counter < n_messages:
                messageToMerge = TxMessage.from_dict(messages[counter])
                if messageToMerge.reasoner_id is None:
                    messageToMerge.reasoner_id = "Unknown"
                if messageToMerge.reasoner_id != "ARAX":
                    messageToMerge = self.fix_message(
                        query, messageToMerge, messageToMerge.reasoner_id)

                finalMessage = self.merge_message(finalMessage, messageToMerge)
                counter += 1
            finalMessage = ast.literal_eval(repr(finalMessage))
            #return( { "status": 498, "title": "Multiple Messages", "detail": "I have multiple messages. Merging code awaits!", "type": "about:blank" }, 498)

        #### Examine the options that were provided and act accordingly
        optionsDict = {}
        if envelope.options:
            if debug: eprint("DEBUG: Got options")
            for option in envelope.options:
                if debug: eprint("DEBUG:   option=" + option)
                optionsDict[option] = 1

        #### If there are processing_actions, then fulfill those
        processing_actions = []
        if envelope.processing_actions:
            if debug: eprint("DEBUG: Found processing_actions")
            actions_parser = ActionsParser()
            result = actions_parser.parse(envelope.processing_actions)
            if result.error_code != 'OK':
                eprint(result)
                raise ()

            #### Message suffers from a dual life as a dict and an object. above we seem to treat it as a dict. Fix that. FIXME
            #### Below we start treating it as and object. This should be the way forward.
            #### This is not a good place to do this, but may need to convert here
            from ARAX_messenger import ARAXMessenger
            finalMessage = ARAXMessenger().from_dict(finalMessage)

            #### Process each action in order
            action_stats = {}
            actions = result.data['actions']
            for action in actions:
                if debug:
                    eprint(
                        f"DEBUG: Considering action '{action['command']}' with parameters {action['parameters']}"
                    )
                #### If we encounter a return, then this is the end of the line
                if action['command'] == 'return':
                    action_stats['return_action'] = action
                    break
                if action['command'] == 'filter':
                    filter = ARAXFilter()
                    result = filter.apply(finalMessage, action['parameters'])
                if result.error_code != 'OK':
                    response = result
                    break
                else:
                    if debug:
                        eprint(
                            f"DEBUG: Action '{action['command']}' is not known"
                        )

            #### At the end, process the explicit return() action, or implicitly perform one
            return_action = {
                'command': 'return',
                'parameters': {
                    'message': 'false',
                    'store': 'false'
                }
            }
            if action is not None and action['command'] == 'return':
                return_action = action
                #### If an explicit one left out some parameters, set the defaults
                if 'store' not in return_action['parameters']:
                    return_action['parameters']['store'] == 'false'
                if 'message' not in return_action['parameters']:
                    return_action['parameters']['message'] == 'false'

        #if "AnnotateDrugs" in optionsDict:
        #  if debug: eprint("DEBUG: Annotating drugs")
        #  annotate_std_results(finalMessage)

        if return_action['parameters']['store'] == 'true':
            if debug: eprint("DEBUG: Storing resulting Message")
            finalMessage_id = self.addNewMessage(
                TxMessage.from_dict(finalMessage), query)

        #### If requesting a full redirect to the resulting message display. This doesn't really work I don't think
        #if "RedirectToMessage" in optionsDict:
        #  #redirect("https://arax.ncats.io/api/rtx/v1/message/"+str(finalMessage_id), code=302)
        #  #return( { "status": 302, "redirect": "https://arax.ncats.io/api/rtx/v1/message/"+str(finalMessage_id) }, 302)
        #  return( "Location: https://arax.ncats.io/api/rtx/v1/message/"+str(finalMessage_id), 302)

        #### If asking for the full message back
        if return_action['parameters']['message'] == 'true':
            return (finalMessage)

        #### Else just the id is returned
        else:
            #return( { "status": 200, "message_id": str(finalMessage_id), "n_results": finalMessage['n_results'], "url": "https://arax.ncats.io/api/rtx/v1/message/"+str(finalMessage_id) }, 200)
            return ({
                "status":
                200,
                "message_id":
                str(finalMessage_id),
                "n_results":
                finalMessage.n_results,
                "url":
                "https://arax.ncats.io/api/rtx/v1/message/" +
                str(finalMessage_id)
            }, 200)
示例#5
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)