Пример #1
0
    def iam_role(self) -> SafeDict:
        if self._iam_role is None:
            try:
                self._iam_role = SafeDict(self.iam.get_role(RoleName=self.role_name)["Role"])
            except botocore.exceptions.ClientError:
                # If a ClientError happened while getting the role, it means he do not exist.
                logging.debug(f"Creating {self.role_name} IAM Role..")

                attach_policy_obj = json.loads(self.attach_policy)
                assume_policy_obj = json.loads(self.assume_policy)

                self._iam_role = SafeDict(self.iam.create_role(RoleName=self.role_name, AssumeRolePolicyDocument=self.assume_policy)["Role"])

                # create or update the role's policies if needed
                policy = self.iam_resource.RolePolicy(self.role_name, "inoft-vocal-permissions")
                try:
                    if policy.policy_document != attach_policy_obj:
                        logging.debug(f"Updating inoft-vocal-permissions policy on {self.role_name} IAM Role.")
                        policy.put(PolicyDocument=self.attach_policy)

                except botocore.exceptions.ClientError:
                    logging.debug(f"Creating inoft-vocal-permissions policy on {self.role_name} IAM Role.")
                    policy.put(PolicyDocument=self.attach_policy)

                role_policy_dict = self._iam_role.get("AssumeRolePolicyDocument").to_dict()
                if role_policy_dict != assume_policy_obj:
                    if (SafeDict(role_policy_dict["Statement"][0]).get("Principal").get("Service").to_any()
                            != assume_policy_obj["Statement"][0]["Principal"]["Service"]):

                        logging.debug(f"Updating assume role policy on {self.role_name} IAM Role.")
                        self.iam_client.update_assume_role_policy(RoleName=self.role_name, PolicyDocument=self.assume_policy)

        return self._iam_role
Пример #2
0
 def session_attributes(self) -> SafeDict:
     if not isinstance(self._session_attributes, SafeDict):
         if isinstance(self.session.attributes, dict):
             self._session_attributes = SafeDict(self.session.attributes)
         else:
             self._session_attributes = SafeDict()
     return self._session_attributes
    def _load_smart_session_user_data(self):
        # We use a separate function to load the smart session user data, and we do not include it in the property itself,
        # because this function can be called by the smart_session_user_data property or the session_been_resumed property.
        if self._smart_session_user_data is None:
            if self.sessions_users_data_disable_database is False:
                self._smart_session_user_data, self._session_been_resumed = self.dynamodb_adapter.get_smart_session_attributes(
                    user_id=self.persistent_user_id, session_id=self.session_id, timeout_seconds=self.default_session_data_timeout)

                if not isinstance(self._smart_session_user_data, SafeDict):
                    self._smart_session_user_data = SafeDict()
            else:
                self._smart_session_user_data = SafeDict()
        logging.debug(f"_smart_session_user_data = {self._smart_session_user_data}")
Пример #4
0
    def create_and_setup_api_routes(self, api_id: str, lambda_arn: str):
        integration_creation_response = SafeDict(self.api_gateway_client.create_integration(ApiId=api_id,
            IntegrationType="AWS_PROXY", PayloadFormatVersion="2.0", IntegrationUri=lambda_arn, TimeoutInMillis=10000))

        integration_id = integration_creation_response.get("IntegrationId").to_str(default=None)
        if integration_id is None:
            raise Exception(f"Error while creating the route integration of the api towards the lambda_function."
                            f"The integration_id was not found in the integration creation response."
                            f"Please delete the api and redo the deployment."
                            f"If the issue persist, create an Issue topic on the github page of the framework.")

        route_names = ["amazonAlexaV1", "googleAssistantDialogflowV1", "samsungBixbyV1", "appleSiriV1"]
        route_names_to_settings_keys = {"amazonAlexaV1": "alexaApiEndpointUrlNotRecommendedToUse",
                                        "googleAssistantDialogflowV1": "googleAssistantApiEndointUrl",
                                        "samsungBixbyV1": "samsungBixbyApiEndointUrl",
                                        "appleSiriV1": "siriApiEndointUrl"}

        api_gateway_root_url = self.api_gateway_v2_url(api_id=api_id)
        for route_name in route_names:
            self.boto_session.get_credentials()
            response = self.api_gateway_client.create_route(
                ApiId=api_id,
                AuthorizationType="None",
                RouteKey=f"ANY /{route_name}",
                # A space is required between the HTTP method and the /
                Target=f"integrations/{integration_id}",
            )
            self.add_lambda_permission_to_call_api_resource(lambda_arn=lambda_arn, api_id=api_id, route_key=route_name)
            api_route_url = f"{api_gateway_root_url}/{route_name}"
            click.echo(f"Api route {click.style(route_name, fg='green')} creation complete accessible on {api_route_url}")
            self.settings.settings.get_set("deployment", {}).get_set("endpoints", {}).put(
                route_names_to_settings_keys[route_name], api_route_url).reset_navigated_dict()
 def persistent_user_data(self) -> SafeDict:
     if self._persistent_user_data is None:
         if self.sessions_users_data_disable_database is False:
             self._persistent_user_data = self.dynamodb_adapter.get_persistent_attributes(user_id=self.persistent_user_id)
         if not isinstance(self._persistent_user_data, SafeDict):
             self._persistent_user_data = SafeDict()
         logging.debug(f"_persistent_user_data = {self._persistent_user_data}")
     return self._persistent_user_data
 def settings(self) -> SafeDict:
     if Settings.settings_loaded is not True:
         if self.raise_if_not_loaded is True:
             raise Exception(
                 f"The settings have not yet been loaded and are : {Settings.settings}"
             )
         else:
             Settings._settings = SafeDict()
     return Settings._settings
Пример #7
0
    def simple_session_user_data(self) -> SafeDict:
        for output_context in self.request.queryResult.outputContexts:
            if isinstance(output_context,
                          dict) and "name" in output_context.keys(
                          ) and "parameters" in output_context.keys():
                all_texts_after_slash = output_context["name"].split("/")
                last_text_after_slash = all_texts_after_slash[
                    len(all_texts_after_slash) - 1]
                if str(last_text_after_slash).lower() == "sessiondata":
                    # We lower the text, to make sure that it will work even if the cases have been lowered. Because for some reasons,
                    # google is lowering the keys, so even if the key in the framework os sessionData, google might return sessiondata.
                    parameters_stringed_dict_or_dict = output_context[
                        "parameters"]
                    if parameters_stringed_dict_or_dict is not None:
                        if isinstance(parameters_stringed_dict_or_dict, str):
                            parameters_stringed_dict_or_dict = json_loads(
                                parameters_stringed_dict_or_dict)
                        if isinstance(parameters_stringed_dict_or_dict, dict):
                            # The data key contains an stringed dictionary of the data we are interested by.
                            if "data" in parameters_stringed_dict_or_dict.keys(
                            ):
                                parameters_stringed_dict_or_dict = parameters_stringed_dict_or_dict[
                                    "data"]

                            if isinstance(parameters_stringed_dict_or_dict,
                                          str):
                                parameters_stringed_dict_or_dict = json_loads(
                                    parameters_stringed_dict_or_dict)
                            if isinstance(parameters_stringed_dict_or_dict,
                                          dict):
                                self._simple_session_user_data = SafeDict(
                                    parameters_stringed_dict_or_dict)
                            else:
                                self._simple_session_user_data = SafeDict()
                        else:
                            raise Exception(
                                f"parameters_stringed_dict_or_dict was nto None, not a str, dict and could"
                                f"not be json converted to a dict : {parameters_stringed_dict_or_dict}"
                            )

        if not isinstance(self._simple_session_user_data, SafeDict):
            self._simple_session_user_data = SafeDict()
        return self._simple_session_user_data
Пример #8
0
    def create_api_gateway(self, lambda_arn: str, lambda_name: str, description: str = None) -> str:
        # todo: fix bug if id of api gateway is present in file, but the api has been deleted, it will not try to recreate it
        api_name = lambda_name or lambda_arn.split(":")[-1]

        api_creation_response = SafeDict(self.api_gateway_client.create_api(Name=api_name,
            Description=description or self.default_description, Target=lambda_arn, ProtocolType="HTTP"))
        api_id = api_creation_response.get("ApiId").to_str()

        self.create_and_setup_api_routes(api_id=api_id, lambda_arn=lambda_arn)
        return api_id
Пример #9
0
 def _fetch_attributes(self, user_id: str) -> SafeDict:
     try:
         response = self.dynamodb.get_item(
             TableName=self.table_name,
             Key={"id": self.utils.python_to_dynamodb(user_id)},
             ConsistentRead=True)
         if "Item" in response:
             return SafeDict(self.utils.dynamodb_to_python(
                 response["Item"]))
         else:
             return SafeDict()
     except ResourceNotExistsError:
         raise Exception(
             f"DynamoDb table {self.table_name} do not exist or in the process"
             "of being created. Failed to get attributes from DynamoDb table."
         )
     except Exception as e:
         raise Exception(
             f"Failed to retrieve attributes from DynamoDb table."
             f"Exception of type {type(e).__name__} occurred: {str(e)}")
 def settings(self, settings_dict: dict):
     validator = self.ExtendedValidator()
     is_valid = validator.validate(settings_dict,
                                   self._settings_file_validator_schema)
     if is_valid is not True:
         raise Exception(
             f"The settings file was not valid. Please modify it or recreate it : {validator.errors}"
         )
     else:
         Settings._settings = SafeDict(settings_dict)
         Settings.settings_loaded = True
    def simple_session_user_data(self) -> SafeDict:
        if self._simple_session_user_data is None:
            if self.is_alexa_v1 is True:
                self._simple_session_user_data = self.alexaHandlerInput.session_attributes
            elif self.is_dialogflow_v1 is True:
                self._simple_session_user_data = self.dialogFlowHandlerInput.simple_session_user_data
            elif self.is_bixby_v1 is True:
                print("simple_session_user_data is not implemented for the bixby platform.")

            if not isinstance(self._simple_session_user_data, SafeDict):
                self._simple_session_user_data = SafeDict()
        return self._simple_session_user_data
Пример #12
0
 def __init__(self):
     self._queryText = str()
     self._action = str()
     self._parameters = SafeDict()
     self._allRequiredParamsPresent = bool()
     self._fulfillmentText = str()
     self._fulfillmentMessages = list()
     self._outputContexts = list()
     self._intent = Intent()
     self._intentDetectionConfidence = int()
     self._diagnosticInfo = dict()
     self._languageCode = str()
Пример #13
0
    def get_smart_session_attributes(self, user_id: str, session_id: str,
                                     timeout_seconds: int) -> (SafeDict, bool):
        # If the value from get_field is of dict or list type, the SafeDict will be populated, otherwise it will be empty without errors.
        timeout_expired = True

        last_session_id = self.get_field(user_id=user_id,
                                         field_key="lastSessionId")
        if session_id == last_session_id:
            timeout_expired = False
        else:
            last_interaction_time = self.get_field(
                user_id=user_id, field_key="lastInteractionTime")
            if last_interaction_time is not None and time.time(
            ) <= last_interaction_time + timeout_seconds:
                timeout_expired = False

        if timeout_expired is False:
            return SafeDict(
                self.get_field(
                    user_id=user_id,
                    field_key=self.smart_session_attributes_key_name)), True
        else:
            return SafeDict(), False
    def __init__(self, identifier: str, audio_item_dict: dict = None):
        self.identifier = identifier

        if audio_item_dict is not None:
            if isinstance(audio_item_dict, dict):
                audio_item_dict = SafeDict(audio_item_dict)
            if not isinstance(audio_item_dict, SafeDict):
                raise Exception(
                    f"The audio_item_dict must be of type dict or SafeDict but was {type(audio_item_dict)}: {audio_item_dict}"
                )

            self.mp3_file_url = audio_item_dict.get("url").to_str()
            self.title = audio_item_dict.get("title").to_str()
            self.subtitle = audio_item_dict.get("subtitle").to_str()
            self.offset_in_milliseconds = audio_item_dict.get(
                "offsetInMilliseconds").to_int()
            self.icon_image_url = audio_item_dict.get("iconImageUrl").to_str()
            self.background_image_url = audio_item_dict.get(
                "backgroundImageUrl").to_str()
    def persistent_user_id(self) -> str:
        if not isinstance(self._persistent_user_id, str) or (self._persistent_user_id.replace(" ", "") == ""):
            if self.is_alexa_v1 is True:
                user_id = SafeDict(self.alexaHandlerInput.session.user).get("userId").to_str(default=None)
            elif self.is_dialogflow_v1 is True:
                user_id = self.dialogFlowHandlerInput.user_id
            elif self.is_bixby_v1 is True:
                user_id = self.bixbyHandlerInput.request.context.userId

            if not isinstance(user_id, str) or user_id.replace(" ", "") == "":
                from inoft_vocal_framework.utils.general import generate_uuid4
                self._persistent_user_id = generate_uuid4()
                # We need to set the persistent_user_id before memorizing it, because the memorize function will access the
                # persistent_user_data, and if the user_id is not set, we will get stuck in an infinite recursion loop
                self.persistent_memorize("userId", user_id)
                print(f"user_id {self._persistent_user_id} has been memorized in the database.")
            else:
                self._persistent_user_id = user_id
            logging.debug(f"_persistent_user_id = {self._persistent_user_id}")
        return self._persistent_user_id
Пример #16
0
    def process_paths(self, parent_core: Core, paths: list) -> list:
        processed_paths = list()

        for i, path in enumerate(paths):
            path = SafeDict(path)
            path_condition = path.get("condition").to_str(default=None)
            path_target_node_name = path.get("node").to_str(default=None)

            if path_condition is not None and path_target_node_name is not None:
                current_path_instance = StateHandler.Path(
                    path_index=i,
                    condition=path_condition,
                    target_node_name=path_target_node_name)
                no_code_generated_for_path = current_path_instance.process(
                    parent_core=parent_core)
                if no_code_generated_for_path is False:
                    processed_paths.append(current_path_instance)
                else:
                    print(
                        f"\nWarning ! The node {self.node_name} had a condition {path_condition} that did not generated any code."
                    )
                    if path_target_node_name == "":
                        print(
                            "It is likely because you did not define a target node for this condition."
                        )
                    else:
                        print(
                            f"Yet you defined a target node. There is something fishy, you should look in botpress what is strange about the node {self.node_name}"
                        )

                if current_path_instance.condition_type == self.Path.CONDITION_TYPE_INTENT_NAME:
                    if current_path_instance.condition_intent_name in self.counts_used_condition_intent_names.keys(
                    ):
                        self.counts_used_condition_intent_names[
                            current_path_instance.condition_intent_name] += 1
                    else:
                        self.counts_used_condition_intent_names[
                            current_path_instance.condition_intent_name] = 1

        return processed_paths
Пример #17
0
    def handle_any_platform(self, event: dict, context: dict):
        print(f"Event = {json_dumps(event)}\nContext = {context}")
        self.check_everything_implemented()
        event_safedict = SafeDict(classic_dict=event)

        # The 'rawPath' is for ApiGatewayV2, use the key 'resource' (without the comma) if using ApiGatewayV1
        if event_safedict.get(
                "rawPath").to_str() == "/googleAssistantDialogflowV1":
            # A google-assistant or dialogflow request always pass trough an API gateway
            self.handler_input.is_dialogflow_v1 = True
            event = NestedObjectToDict.get_dict_from_json(
                event_safedict.get("body").to_str())

        elif event_safedict.get("rawPath").to_str() == "/samsungBixbyV1":
            # A samsung bixby request always pass trough an API gateway
            self.handler_input.is_bixby_v1 = True
            from urllib import parse
            event = {
                "context":
                NestedObjectToDict.get_dict_from_json(
                    stringed_json_dict=event_safedict.get("body").to_str())
                ["$vivContext"],
                "parameters":
                dict(
                    parse.parse_qsl(
                        event_safedict.get("rawQueryString").to_str()))
            }

        elif "amzn1." in event_safedict.get("context").get("System").get(
                "application").get("applicationId").to_str():
            # Alexa always go last, since it do not pass trough an api resource, its a less robust identification than the other platforms.
            self.handler_input.is_alexa_v1 = True
        else:
            from inoft_vocal_framework.messages import ERROR_PLATFORM_NOT_SUPPORTED
            raise Exception(ERROR_PLATFORM_NOT_SUPPORTED)

        self.handler_input.load_event(event=event)
        return self.process_request()
Пример #18
0
    def process(self):
        for message_dict in self.input_messages_items:
            message_dict = SafeDict(message_dict)
            speech_items = list()

            # todo: make multilang (might require the premium version of botpress)
            main_speech_dict = message_dict.get("formData").to_dict()
            for key, value in main_speech_dict.items():
                if "text" in key:
                    if value is not None and value != "":
                        speech_items.append(prettify_speech_text(value))

                if "variations" in key:
                    if isinstance(value, list):
                        for speech_variation in value:
                            if speech_variation is not None and speech_variation != "":
                                speech_items.append(
                                    prettify_speech_text(value))

            message_item = self.MessageItem(
                id_value=message_dict.get("id").to_str(),
                speech_items=speech_items)
            self.output_messages_dict[message_item.id] = message_item
    def persistent_user_id(self) -> str:
        if not isinstance(self._persistent_user_id, str) or (
                not (len(self._persistent_user_id.replace(" ", "")) > 0)):
            user_id: Optional[str] = None
            if self.is_alexa is True:
                user_id = SafeDict(
                    self.alexaHandlerInput.session.user).get('userId').to_str(
                        default=None)
            elif self.is_dialogflow is True:
                user_id = self.dialogFlowHandlerInput.get_user_id()
            elif self.is_bixby is True:
                user_id = self.bixbyHandlerInput.request.context.userId
            elif self.is_discord is True:
                user_id = self.discordHandlerInput.request.author.id

            if user_id is None or not isinstance(
                    user_id, str) or not (len(user_id.replace(" ", "")) > 0):
                self._persistent_user_id = self.settings.user_data_plugin.register_new_user(
                )
            else:
                self._persistent_user_id = user_id
            logging.debug(f"_persistent_user_id = {self._persistent_user_id}")
        return self._persistent_user_id
 def get_last_used_audioplayer_handlers_group(self) -> SafeDict:
     return SafeDict(
         self._parent_handler_input.persistent_remember(
             'lastUsedAudioPlayerHandlersGroupClass',
             specific_object_type=dict))
import jinja2

from inoft_vocal_framework.bixby_core.templates.templates_access import TemplatesAccess
from inoft_vocal_framework.safe_dict import SafeDict
from inoft_vocal_framework.utils.general import load_json

model_dict = SafeDict(load_json("F:/Inoft/skill_histoire_decryptage_1/inoft_vocal_framework/bixby_core/test_model.json"))
intents = model_dict.get("intents").to_dict()

class Core:
    def render(self):
        out = TemplatesAccess().endpoints_template.render(intents=intents)
        print(out)

    @staticmethod
    def write_to_file(text: str, filepath: str):
        with open(filepath, "w+") as file:
            file.write(text)

Core().render()
Пример #22
0
 def api_gateway_v2_url(self, api_id: str):
     try:
         return SafeDict(self.api_gateway_client.get_api(ApiId=api_id)).get("ApiEndpoint").to_str(default=None)
     except Exception as e:
         return False
Пример #23
0
 def get_lambda_function_arn(self, function_name: str):
     return SafeDict(self.lambda_client.get_function(FunctionName=function_name)).get("Configuration").get("FunctionArn").to_str()
Пример #24
0
 def parameters(self, parameters: dict) -> None:
     if not isinstance(parameters, dict):
         raise Exception(
             f"parameters was type {type(parameters)} which is not valid value for his parameter."
         )
     self._parameters = SafeDict(parameters)
Пример #25
0
 def parameters(self) -> SafeDict:
     if isinstance(self._parameters, dict):
         self._parameters = SafeDict(self._parameters)
     return self._parameters
Пример #26
0
 def slots(self, slots: dict) -> None:
     if not isinstance(slots, dict):
         raise Exception(f"slots was type {type(slots)} which is not valid value for his parameter.")
     self._slots = SafeDict(slots)
Пример #27
0
 def slots(self) -> SafeDict:
     if isinstance(self._slots, dict):
         self._slots = SafeDict(self._slots)
     return self._slots
Пример #28
0
 def __init__(self):
     self._name = str()
     self._confirmationStatus = str()
     self._slots = SafeDict()
Пример #29
0
 def _speech_dicts_to_speech_items(self, speech_dicts: list) -> list:
     output_list = list()
     for speech_dict in speech_dicts:
         output_list.append(
             Speech().from_dict(speech_safedict=SafeDict(speech_dict)))
     return output_list
Пример #30
0
 def get_persistent_attributes(self, user_id: str) -> SafeDict:
     # If the value from get_field is of dict or list type, the SafeDict will be populated, otherwise it will be empty without errors.
     return SafeDict(
         self.get_field(user_id=user_id,
                        field_key=self.persistent_attributes_key_name))