def reply_on_local_port(self, msg: KQMLPerformative,
                            reply_msg: KQMLPerformative):
        """Replies to a message on the local port (listener port)

        Args:
            msg (KQMLPerformative): message to reply to
            reply_msg (KQMLPerformative): message to reply with
        """
        sender = msg.get('sender')
        if sender is not None:
            reply_msg.set('receiver', sender)
        reply_with = msg.get('reply-with')
        if reply_with is not None:
            reply_msg.set('in-reply-to', reply_with)
        self.send_on_local_port(reply_msg)
예제 #2
0
    def receive_ask_one(self, msg: KQMLPerformative, content: KQMLList):
        """Override of default ask one, creates Companions style responses.
        Gets the arguments bindings from the cdr of the content. The predicate
        (car) is then used to find the function bound to the ask predicate, and
        that function is called with the bounded argument list unpacked into
        it's own inputs. The resulting query is then passed along to the
        response_to_query helper which will properly respond to patterns or
        bindings based on out response type.

        Arguments:
            msg (KQMLPerformative): reply mechanism
            content (KQMLList): predicate to look up in asks dict, arguments of
                the ask call - to be passed in to the call.

        Returns:
            None: returns only to exit function early if conditions aren't met
        """
        if content.head() not in self.asks:
            error_msg = f'No ask query predicate named {content.head()} known'
            LOGGER.warning(error_msg)
            self.error_reply(msg, error_msg)
            return
        bounded = []
        for each in content.data[1:]:
            if str(each[0]) != '?':
                bounded.append(each)
        ask_question = self.asks[content.head()]
        # TODO - same argument structure issue as achieve, won't work with self
        expected_args = len(getfullargspec(ask_question).args)
        if expected_args != len(bounded):
            error_msg = (f'Expected {expected_args} input arguments to query '
                         f'predicate {content.head()}, got {len(bounded)}')
            LOGGER.warning(error_msg)
            self.error_reply(msg, error_msg)
            return
        LOGGER.info('received ask-one %s', content.head())
        try:
            results = self.asks[content.head()](*bounded)
        except (TypeError, ValueError) as except_msg:
            LOGGER.warning('Failed execution: %s, %s', except_msg, print_exc())
            error_msg = f'An error occurred while executing: {content.head()}'
            self.error_reply(msg, error_msg)
            return
        LOGGER.debug('Ask-one returned results: %s', results)
        self.response_to_query(msg, content, results, msg.get('response'))