Example #1
0
 def remote_endpoint(
         self,
         endpoint_url: str,
         endpoint_method: str = RemoteEndpoint.METHOD_POST) -> None:
     raise_if_variable_not_expected_type(value=endpoint_url,
                                         expected_type=endpoint_url,
                                         variable_name="endpoint_url")
     raise_if_value_not_in_list(
         value=endpoint_method,
         list_object=self.RemoteEndpoint.AVAILABLE_METHODS,
         variable_name="endpoint_method")
     self._remote_endpoint = self.RemoteEndpoint
 def playerActivity(self, playerActivity: str) -> None:
     raise_if_value_not_in_list(
         value=playerActivity,
         list_object=self.AVAILABLE_PLAYER_ACTIVITIES,
         variable_name="playerActivity")
     self._playerActivity = playerActivity
Example #3
0
 def clearBehavior(self, clearBehavior: str) -> None:
     raise_if_value_not_in_list(value=clearBehavior,
                                list_object=self.AVAILABLE_CLEAR_BEHAVIORS,
                                variable_name="clearBehavior")
     self._clearBehavior = clearBehavior
Example #4
0
 def playBehavior(self, playBehavior: str) -> None:
     raise_if_value_not_in_list(value=playBehavior,
                                list_object=self.AVAILABLE_PLAY_BEHAVIORS,
                                variable_name="playBehavior")
     self._playBehavior = playBehavior
Example #5
0
 def type(self, type_value: str) -> None:
     raise_if_value_not_in_list(value=type_value,
                                list_object=self.AVAILABLE_TYPES,
                                variable_name="type")
     self._type = type_value
Example #6
0
    def process_request(self):
        output_event = None
        handler_to_use = None
        handler_is_an_alone_callback_function = False
        handler_is_an_audioplayer_handlers_group = False
        handler_is_a_then_state_handler = False
        handler_is_a_request_handler = False

        # Steps of priority

        # First, if the request is an interactive option made by the user
        if self.handler_input.is_option_select_request:
            # todo: rename is_option_select_request to need_to_be_handled_by_callback
            infos_callback_function_to_use = self.handler_input.interactivity_callback_functions.get(
                self.handler_input.selected_option_identifier).to_safedict(
                    default=None)

            if infos_callback_function_to_use is not None:
                from inoft_vocal_framework.skill_builder.utils import get_function_or_class_from_file_and_path
                handler_to_use = get_function_or_class_from_file_and_path(
                    file_filepath=infos_callback_function_to_use.get(
                        "file_filepath_containing_callback").to_str(),
                    path_qualname=infos_callback_function_to_use.get(
                        "callback_function_path").to_str())

                if handler_to_use is not None:
                    handler_is_an_alone_callback_function = True

        # Second, Alexa Audio Player
        if self.handler_input.is_alexa_v1:
            if self.handler_input.alexaHandlerInput.context.audioPlayer.token is not None:
                last_used_audioplayer_handlers_group_infos = self.handler_input.alexaHandlerInput.get_last_used_audioplayer_handlers_group(
                )
                from inoft_vocal_framework.skill_builder.utils import get_function_or_class_from_file_and_path
                audioplayer_handlers_group_class_type = get_function_or_class_from_file_and_path(
                    file_filepath=last_used_audioplayer_handlers_group_infos.
                    get("fileFilepathContainingClass").to_str(),
                    path_qualname=last_used_audioplayer_handlers_group_infos.
                    get("classPath").to_str())

                if audioplayer_handlers_group_class_type is not None:
                    raise_if_value_not_in_list(
                        value=InoftHandlersGroup,
                        list_object=list(
                            audioplayer_handlers_group_class_type.__bases__),
                        variable_name="audioplayer_handlers_group_class_type")

                    class_kwargs = last_used_audioplayer_handlers_group_infos.get(
                        "classKwargs").to_dict()
                    class_kwargs["parent_handler"] = self
                    handler_to_use = audioplayer_handlers_group_class_type(
                        **class_kwargs)

                    # When using an audioplayer handlers group, we will call its handle function (it will try every one of its
                    # handler, until he found one that return an output). If the output is None (no function out of every function
                    # of the audioplayer handlers group has returned something), then we will set back the handler_to_use to None,
                    # so that the others more traditional handlers can have a chance to be use (if we did not do that, and that
                    # no event was returned, the response would be the default fallback right away).
                    # The reason we do all of that, is that if the AudioPlayer object is present, but not in a state that is
                    # supported by the app trough a can_handle function (like if it is stopped, and no can_handle function of
                    # any class is triggered by the current state of the AudioPlayer), then we will not be able to give an
                    # interactive experience with the AudioPlayer, which translate into our output_event being None.
                    output_event = handler_to_use.handle()
                    if output_event is not None:
                        handler_is_an_audioplayer_handlers_group = True
                    else:
                        handler_to_use = None

        # Third, if the invocation is a new session, and a session can be resumed, we resume the last intent of the previous session
        if self.handler_input.is_invocation_new_session is True and self.handler_input.session_been_resumed is True:
            last_intent_handler_class_key_name = self.handler_input.session_remember(
                "lastIntentHandler")
            if last_intent_handler_class_key_name in self.request_handlers_chain.keys(
            ):
                handler_to_use = self.request_handlers_chain[
                    last_intent_handler_class_key_name]
            elif last_intent_handler_class_key_name in self.state_handlers_chain.keys(
            ):
                handler_to_use = self.state_handlers_chain[
                    last_intent_handler_class_key_name]

        # Fourth, loading of the then_state in the session
        if handler_to_use is None:
            last_then_state_class_name = self.handler_input.remember_session_then_state(
            )
            if last_then_state_class_name is not None:
                if last_then_state_class_name in self.state_handlers_chain.keys(
                ):
                    handler_to_use = self.state_handlers_chain[
                        last_then_state_class_name]
                    handler_is_a_then_state_handler = True
                    self.handler_input.forget_session_then_state()
                else:
                    logging.warning(
                        f"A thenState class name ({last_then_state_class_name}) was not None and has"
                        f" not been found in the available classes : {self.state_handlers_chain}"
                    )

        # Fifth, classical requests handlers
        if handler_to_use is None:
            for request_handler in self.request_handlers_chain.values():
                if request_handler.can_handle() is True:
                    handler_to_use = request_handler
                    handler_is_a_request_handler = True
                    break
                else:
                    logging.debug(
                        f"Not handled by : {request_handler.__class__}")

        if handler_to_use is not None:
            if handler_is_an_alone_callback_function is True:
                output_event = handler_to_use(
                    self.handler_input,
                    self.handler_input.selected_option_identifier)
                if output_event is not None:
                    logging.debug(
                        f"Successfully resumed by {handler_to_use} which returned {output_event}"
                    )
                else:
                    logging.info(
                        f"A callback function has been found {handler_to_use}. But nothing was returned,"
                        f" did you called the return self.to_platform_dict() function ?"
                    )

            if output_event is None and self.handler_input.session_been_resumed is True:
                logging.debug(
                    f"Handled and resumed by : {handler_to_use.__class__}")
                output_event = handler_to_use.handle_resume()

            if output_event is None:
                logging.debug(
                    f"Handled classically by : {handler_to_use.__class__}")
                output_event = handler_to_use.handle()
                if handler_is_a_then_state_handler is True and output_event is None:
                    # If the handle function of the a then_state handler do not return anything, we call its fallback
                    # function, and we set back the then_state to the session attributes (we do so before calling
                    # the fallback, in case the fallback function changed the then_state)
                    self.handler_input.memorize_session_then_state(
                        state_handler_class_type_or_name=
                        last_then_state_class_name)
                    output_event = handler_to_use.fallback()

        if output_event is not None:
            if handler_is_an_alone_callback_function is False and handler_is_an_audioplayer_handlers_group is False:
                # If the response is handled by a function, we do not save it as the last intent (we cannot actually,
                # and it would not make sense anyway). So we will keep the previous last intent as the new last intent.
                # We do the same thing it is handler by an audioplayer handlers group (since it is used to handle interactions too)
                self.handler_input.memorize_session_last_intent_handler(
                    handler_class_type_instance_name=handler_to_use)
        else:
            logging.debug(
                f"Handler by default fallback : {self.default_fallback_handler}"
            )
            output_event = self.default_fallback_handler.handle()

        self.handler_input.save_attributes_if_need_to()

        print(f"output_event = {output_event}")
        wrapped_output_event = LambdaResponseWrapper(
            response_dict=output_event).get_wrapped(
                handler_input=self.handler_input)
        return wrapped_output_event