예제 #1
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()
예제 #2
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
예제 #3
0
class LaunchRequestHandler:
    CLASS_TYPE = "RequestHandler"

    def __init__(self, node_dict: dict):
        self.node_safedict = SafeDict(node_dict)
        self.node_name = self.node_safedict.get("name").to_str()
        self.class_name = to_class_name(self.node_name)
        self.code = None
        self.state_handler_class = None

    def process(self, parent_core: Core):
        next_paths = self.node_safedict.get("next").to_list()
        if len(next_paths) > 0:
            self.state_handler_class = StateHandler(node_name=self.node_name)
            for path in next_paths:
                self.state_handler_class.next_paths.append(
                    path)  # all_nodes_classes_dict[next_paths[0]["name"]]

    def render(
            self,
            parent_core: Core):  # dict, parent_all_nodes_classes_dict: dict):
        created_classes = list()

        next_state_handler_class = None
        if self.state_handler_class is not None:
            state_handler = StateHandler(node_name=self.node_name)
            state_handler.process(parent_core=parent_core)
            state_handler.render(parent_core=parent_core)
            created_classes.append(state_handler)
            next_state_handler_class = f"{self.class_name}StateHandler"

        self.code = TemplatesAccess().launch_request_handler_template.render(
            class_name=self.class_name,
            node_name=self.node_name,
            next_state_handler_class=next_state_handler_class,
            code_elements=parent_core.process_on_enter(
                self.node_safedict.get("onEnter").to_list()))

        created_classes.insert(0, self)
        # We always want for the request handler to be the first element in the classes.
        return created_classes
예제 #4
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
예제 #5
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
예제 #6
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()
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()
예제 #8
0
class Core(CoreClients):
    def __init__(self):  # , pool: ThreadPoolExecutor):
        super().__init__()
        self.settings = Settings()
        self.tags = {"framework": "InoftVocalFramework"}

        self._iam_role = None
        self._credentials_arn = None
        self._aws_account_id = None

        self._session_unix_time = None
        self._session_count_created_statement_ids = 0

        self.role_name = "InoftVocalFrameworkLambdaExecution"
        self.http_methods = ['ANY']

        self.default_description = "Created with the Inoft Vocal Framework"

    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()

    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

    def get_lambda_function_versions(self, function_name: str) -> list:
        try:
            response = self.lambda_client.list_versions_by_function(FunctionName=function_name)
            return response.get('Versions', list())
        except Exception as e:
            click.echo(f"Lambda function {function_name} not found. Error : {e}")
            return list()

    def create_lambda_function(self, bucket=None, s3_key: str = None, local_zip: bytes = None, function_name: str = None, handler=None,
                               description: str = "Inoft Vocal Framework Deployment",
                               timeout: int = 30, memory_size: int = 512, publish: bool = True, runtime=None):
        """
        Given a bucket and key (or a local path) of a valid Lambda-zip, a function name and a handler, register that Lambda function.
        """
        kwargs = dict(
            FunctionName=function_name,
            Runtime=runtime,
            Role=self.credentials_arn,  # "arn:aws:iam::631258222318:role/service-role/alexa_hackaton-cite-des-sciences_fakenews-challeng-role-ck3sxsyt",  # self.credentials_arn,
            # todo: make dynamic and create automaticly role if missing
            Handler=handler,
            Description=description,
            Timeout=timeout,
            MemorySize=memory_size,
            Publish=publish,
            Layers=[
                "arn:aws:lambda:eu-west-3:631258222318:layer:inoft-vocal-framework_0-38-5:1",
            ]
        )
        if local_zip is not None:
            kwargs['Code'] = {
                'ZipFile': local_zip
            }
        else:
            kwargs['Code'] = {
                'S3Bucket': bucket,
                'S3Key': s3_key
            }

        response = self.lambda_client.create_function(**kwargs)

        lambda_arn = response["FunctionArn"]
        version = response['Version']

        click.echo(f"Created new lambda function {function_name} with arn of {lambda_arn}")
        return lambda_arn

    def update_lambda_function_code(self, lambda_arn: str, object_key_name: str, bucket_name: str):
        response = self.lambda_client.update_function_code(
            FunctionName=lambda_arn,
            S3Bucket=bucket_name,
            S3Key=object_key_name,
            Publish=True,
        )

    def update_lambda_function_configuration(self, function_name: str, handler_function_path: str = None, lambda_layers_arns: list = None):
        kwargs = dict(FunctionName=function_name)
        if handler_function_path is not None:
            kwargs["Handler"] = handler_function_path
        if lambda_layers_arns is not None and len(lambda_layers_arns) > 0:
            kwargs["Layers"] = lambda_layers_arns

        response = self.lambda_client.update_function_configuration(**kwargs)


    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

    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()
            # We reset the navigated dict after a final put

    def add_lambda_permission_to_call_api_resource(self, lambda_arn: str, api_id: str, route_key: str):
        response = self.lambda_client.add_permission(
            FunctionName=lambda_arn,
            StatementId=self.get_session_new_statement_id(),
            Action="lambda:InvokeFunction",
            Principal="apigateway.amazonaws.com",
            SourceArn=f"arn:aws:execute-api:{self.boto_session.region_name}:{self.aws_account_id}:{api_id}/*/*/{route_key}",
        )

    @property
    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

    @property
    def credentials_arn(self):
        if self._credentials_arn is None:
            self._credentials_arn = self.iam_role.get("Arn").to_str()
        return self._credentials_arn

    @credentials_arn.setter
    def credentials_arn(self, credentials_arn) -> None:
        self._credentials_arn = credentials_arn

    @property
    def aws_account_id(self) -> str:
        if self._aws_account_id is None:
            self._aws_account_id = boto3.client("sts").get_caller_identity().get("Account")
        return self._aws_account_id

    def get_session_new_statement_id(self) -> str:
        # No restriction is set on the statement id. To created my type of ids, i take the same unix
        # time across the session, and each time we generated a new statement id, i add 1 to the unix time.
        # Dumb and simple, but it assure that i will never have the same id twice.
        if self._session_unix_time is None:
            self._session_unix_time = time.time()
        self._session_count_created_statement_ids += 1

        # After turning the modified unix time into a string, we remove any point, that would have
        # been used to  separate the decimals, because AWS cannot accept a point in a id string.
        return str(self._session_unix_time + self._session_count_created_statement_ids).replace(".", "")

    def create_s3_bucket_if_missing(self, bucket_name: str, region_name: str):
        try:
            self.s3_client.head_bucket(Bucket=bucket_name)
        except ClientError as e:
            click.echo(f"Trying to create a new S3 Bucket with name {click.style(text=bucket_name, fg='yellow', bold=True)}"
                  f" in region {click.style(text=region_name, fg='yellow', bold=True)}")
            available_regions_for_s3 = self.boto_session.get_available_regions(service_name="s3")
            if region_name not in available_regions_for_s3:
                raise Exception(f"The region {region_name} was not available for s3. Here is the available regions : {available_regions_for_s3}")

            self.s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={"LocationConstraint": region_name})
            click.echo(f"Completed creation of the new bucket.")

    def upload_to_s3(self, filepath: str, object_key_name: str, bucket_name: str, region_name: str) -> bool:
        # If an error happen while uploading to S3, then the upload will not be
        # successful. We use that as our way to send a success response.
        try:
            self.create_s3_bucket_if_missing(bucket_name=bucket_name, region_name=region_name)
            self.s3_client.upload_file(Filename=filepath, Bucket=bucket_name, Key=object_key_name)
            return True
        except NoCredentialsError as e:
            click.echo(f"Almost there ! You just need to configure your AWS credentials."
                  f"\nYou can follow the official documentation (you will need to install the awscli by running pip install awscli) "
                  f"then go to https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html#configuration"
                  f"\nOr you can follow a video made by Robinson Labourdette from Inoft, as a guide to configure your credentials.")
            if click.confirm("Press Y to access the video."):
                selected_language = click.prompt("Type the language in which you would like the video. The followings are available :", type=click.Choice(["English", "French"]))
                if selected_language == "English":
                    click.echo("English here you go !")
                elif selected_language == "French":
                    click.echo("Français la voila !")
                click.echo("Follow the instructions that is available in the video, then when you are all set up, redo the command you just tried")
                while True:
                    if click.confirm("Press y to exit"):
                        exit(201)
                        break
                        # A little break, just to make sure that if the exit do not work, we do not stay stuck in this loop.
            else:
                click.echo("Ok, then follow the boto documentation, and once you have configured your credentials, relaunch the cli command that you were trying to use"
                      " (https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html#configuration)")
        except Exception as e:
            click.echo(f"Error while getting/creating/uploading to the S3 bucket : {e}")
            return False

    def remove_from_s3(self, file_name: str, bucket_name: str):
        try:
            self.s3_client.head_bucket(Bucket=bucket_name)
        except botocore.exceptions.ClientError as e:
            # If a client error is thrown, then check that it was a 404 error.
            # If it was a 404 error, then the bucket does not exist.
            error_code = int(e.response["Error"]["Code"])
            if error_code == 404:
                return False

        try:
            self.s3_client.delete_object(Bucket=bucket_name, Key=file_name)
            return True
        except (botocore.exceptions.ParamValidationError, botocore.exceptions.ClientError):
            return False
 def from_dict(self, speech_safedict: SafeDict):
     self.probability_value = speech_safedict.get("probability").to_float(
         default=None)
     self.speech = speech_safedict.get("speech").to_str()
     return self
    def _process_and_set_list_to_object(
            object_class_to_set_to, list_object: list,
            key_names_identifier_objects_to_go_into: list):
        unprocessed_vars_dict = vars(object_class_to_set_to)
        from types import MappingProxyType
        if isinstance(unprocessed_vars_dict, MappingProxyType):
            # Sometimes the vars dict is put in a MappingProxy object instead of a dict. A MappingProxy is like a dict,
            # but cannot have its values modified, so we convert it back to a dict since we will need to modify the values.
            unprocessed_vars_dict = dict(unprocessed_vars_dict)

        vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names = SafeDict(
        )
        for key_unprocessed_var in unprocessed_vars_dict.keys():
            processed_current_key_name = NestedObjectToDict.get_json_key_from_variable_name(
                variable_name=key_unprocessed_var)
            vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names.put(
                dict_key=processed_current_key_name,
                value_to_put=key_unprocessed_var)

        for child_item in list_object:
            if isinstance(child_item, dict):
                for key_child_item, value_child_item in child_item.items():
                    current_unprocessed_variable_name = vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names.get(
                        key_child_item).to_any()
                    if current_unprocessed_variable_name is not None:
                        current_child_element_object = unprocessed_vars_dict[
                            current_unprocessed_variable_name]

                        if current_child_element_object is not None:
                            found_accepted_key_name_in_vars_of_current_object = False

                            for accepted_child_key_name in key_names_identifier_objects_to_go_into:
                                if hasattr(current_child_element_object,
                                           accepted_child_key_name):
                                    found_accepted_key_name_in_vars_of_current_object = True

                                    NestedObjectToDict.process_and_set_json_to_object(
                                        object_class_to_set_to=
                                        unprocessed_vars_dict[
                                            current_unprocessed_variable_name],
                                        request_json_dict_stringed_dict_or_list
                                        =value_child_item,
                                        key_names_identifier_objects_to_go_into=
                                        key_names_identifier_objects_to_go_into
                                    )

                            if not found_accepted_key_name_in_vars_of_current_object:
                                do_not_include_current_item = False

                                if (isinstance(value_child_item, str) or
                                    (type(value_child_item) == type
                                     and "str" in value_child_item.__bases__)):
                                    if value_child_item.replace(" ", "") == "":
                                        do_not_include_current_item = True

                                elif (
                                        isinstance(value_child_item, dict)
                                        or isinstance(value_child_item, list)
                                        or
                                    (type(value_child_item) == type and
                                     ("dict" in value_child_item.__bases__ or
                                      "list" in value_child_item.__bases__))):
                                    if not len(value_child_item) > 0:
                                        do_not_include_current_item = True

                                if not do_not_include_current_item:
                                    custom_set_from_function = getattr(
                                        current_child_element_object,
                                        "custom_set_from", None)
                                    if custom_set_from_function is None:
                                        unprocessed_vars_dict[
                                            current_unprocessed_variable_name] = value_child_item
                                    else:
                                        custom_set_from_function(
                                            value_child_item)

            elif isinstance(child_item,
                            list) or (type(child_item) == type
                                      and "list" in child_item.__bases__):
                NestedObjectToDict._process_and_set_list_to_object(
                    object_class_to_set_to=child_item,
                    list_object=child_item,
                    key_names_identifier_objects_to_go_into=
                    key_names_identifier_objects_to_go_into)
    def _process_and_set_dict_to_object(
            object_class_to_set_to, dict_object: dict,
            key_names_identifier_objects_to_go_into: list):
        from inoft_vocal_framework.platforms_handlers.alexa_v1.context import Context

        unprocessed_vars_dict = vars(object_class_to_set_to)
        from types import MappingProxyType
        if isinstance(unprocessed_vars_dict, MappingProxyType):
            # Sometimes the vars dict is put in a MappingProxy object instead of a dict. A MappingProxy is like a dict,
            # but cannot have its values modified, so we convert it back to a dict since we will need to modify the values.
            unprocessed_vars_dict = dict(unprocessed_vars_dict)

        vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names = SafeDict(
        )
        for key_unprocessed_var, value_var_object in unprocessed_vars_dict.items(
        ):
            found_accepted_key_name = False

            for accepted_child_key_name in key_names_identifier_objects_to_go_into:
                if hasattr(value_var_object, accepted_child_key_name):
                    # If the object contains an accepted child key name, we use it as the processed variable name. Like that, we have a
                    # total freedom to respect Python convention for the variable names, and still handle any type of object child name.
                    vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names.put(
                        dict_key=getattr(value_var_object,
                                         accepted_child_key_name),
                        value_to_put=key_unprocessed_var)
                    found_accepted_key_name = True

            if found_accepted_key_name is False:
                # Otherwise we do a bit of processing on the variable name itself (like removing underscores) then we use it.
                processed_current_key_name = NestedObjectToDict.get_json_key_from_variable_name(
                    variable_name=key_unprocessed_var)
                vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names.put(
                    dict_key=processed_current_key_name,
                    value_to_put=key_unprocessed_var)

        keys_to_pop_after_loop_finished = list()
        for key_request_element, value_request_element in dict_object.items():
            key_request_element = str(key_request_element).replace(" ", "")
            # In the received requests, there can sometimes be spaces in a key before closing it with an apostrophe.
            # Having a single empty space at the end of a key would not be the same as the key without the space.

            current_unprocessed_variable_name = vars_safedict_key_processed_keys_names_with_value_unprocessed_variables_names.get(
                key_request_element).to_any()
            if current_unprocessed_variable_name is not None:
                current_child_element_object = unprocessed_vars_dict[
                    current_unprocessed_variable_name]

                found_accepted_key_name_in_vars_of_current_object = False
                if current_child_element_object is not None:
                    for accepted_child_key_name in key_names_identifier_objects_to_go_into:
                        if hasattr(current_child_element_object,
                                   accepted_child_key_name):
                            found_accepted_key_name_in_vars_of_current_object = True

                            NestedObjectToDict.process_and_set_json_to_object(
                                object_class_to_set_to=unprocessed_vars_dict[
                                    current_unprocessed_variable_name],
                                request_json_dict_stringed_dict_or_list=
                                value_request_element,
                                key_names_identifier_objects_to_go_into=
                                key_names_identifier_objects_to_go_into)

                # Even if the current child element object is None we will try to set a value to it, because a None value is just
                # a variable not initialized (like how often after an init). It does not means that it should not contain a value.
                if not found_accepted_key_name_in_vars_of_current_object:
                    do_not_include_current_item = False

                    if (isinstance(value_request_element, str)
                            or (type(value_request_element) == type
                                and "str" in value_request_element.__bases__)):
                        if value_request_element.replace(" ", "") == "":
                            do_not_include_current_item = True

                    elif (isinstance(value_request_element, dict)
                          or isinstance(value_request_element, list)
                          or (type(value_request_element) == type and
                              ("dict" in value_request_element.__bases__
                               or "list" in value_request_element.__bases__))):
                        if not len(value_request_element) > 0:
                            do_not_include_current_item = True

                    if not do_not_include_current_item:
                        # if (type(value_request_element) == type(current_child_element_object)
                        # or (((isinstance(value_request_element, float) or isinstance(value_request_element, int))
                        #     and type(current_child_element_object) in [int, float]))):
                        # For some variables, we might receive them in int or float, where the framework would store
                        # them with the other variable type. So we say that if the received variable is an int or a float,
                        # its considered compatible with the variable in the object if it is also a float or an int.

                        custom_set_from_function = getattr(
                            current_child_element_object, "custom_set_from",
                            None)
                        if custom_set_from_function is None:
                            unprocessed_vars_dict[
                                current_unprocessed_variable_name] = value_request_element
                        # elif type(value_request_element) in current_child_element_object.__bases__:
                        else:
                            custom_set_from_function(value_request_element)

        for key_to_pop in keys_to_pop_after_loop_finished:
            unprocessed_vars_dict.pop(key_to_pop)