def update_profile()

in source/controlplaneapi/runtime/app.py [0:0]


def update_profile(name):
    """
    Update a processing profile by name.

    Body:

    .. code-block:: python

        {
            "Description": string,
            "ContentGroups": list,
            "ChunkSize": number,
            "MaxSegmentLengthSeconds": number,
            "ProcessingFrameRate": number,
            "Classifier": {
                "Name": string,
                "ModelEndpoint": {
                    "Name": string,
                    "Version": string
                },
                "Configuration" : {
                    "configuration1": "value1",
                    ...
                },
                "DependentPlugins": [
                    {
                        "Name": string,
                        "ModelEndpoint": {
                            "Name": string,
                            "Version": string
                        },
                        "Configuration" : {
                            "configuration1": "value1",
                            ...
                        }   
                    },
                    ...
                ]
            },
            "Optimizer": {
                "Name": string,
                "ModelEndpoint": {
                    "Name": string,
                    "Version": string
                },
                "Configuration" : {
                    "configuration1": "value1",
                    ...
                },
                "DependentPlugins": [
                    {
                        "Name": string,
                        "ModelEndpoint": {
                            "Name": string,
                            "Version": string
                        },
                        "Configuration" : {
                            "configuration1": "value1",
                            ...
                        }   
                    },
                    ...
                ]
            },
            "Labeler": {
                "Name": string,
                "ModelEndpoint": {
                    "Name": string,
                    "Version": string
                },
                "Configuration" : {
                    "configuration1": "value1",
                    ...
                },
                "DependentPlugins": [
                    {
                        "Name": string,
                        "ModelEndpoint": {
                            "Name": string,
                            "Version": string
                        },
                        "Configuration" : {
                            "configuration1": "value1",
                            ...
                        }   
                    },
                    ...
                ]
            },
            "Featurers": [
                {
                    "Name": string,
                    "ModelEndpoint": {
                        "Name": string,
                        "Version": string
                    },
                    "Configuration" : {
                        "configuration1": "value1",
                        ...
                    },
                    "DependentPlugins": [
                        {
                            "Name": string,
                            "ModelEndpoint": {
                                "Name": string,
                                "Version": string
                            },
                            "Configuration" : {
                                "configuration1": "value1",
                                ...
                            }   
                        },
                        ...
                    ]
                },
                ...
            ]
        }

    Returns:

        None

    Raises:
        400 - BadRequestError
        404 - NotFoundError
        500 - ChaliceViewError
    """
    try:
        name = urllib.parse.unquote(name)
        profile = json.loads(app.current_request.raw_body.decode(), parse_float=Decimal)

        validate(instance=profile, schema=API_SCHEMA["update_profile"])

        print("Got a valid profile schema")

        print(f"Updating the profile '{name}'")

        profile_table = ddb_resource.Table(PROFILE_TABLE_NAME)

        response = profile_table.get_item(
            Key={
                "Name": name
            },
            ConsistentRead=True
        )

        if "Item" not in response:
            raise NotFoundError(f"Profile '{name}' not found")

        profile["Description"] = profile["Description"] if "Description" in profile else (
            response["Item"]["Description"] if "Description" in response["Item"] else "")
        profile["ContentGroups"] = profile["ContentGroups"] if "ContentGroups" in profile else response["Item"][
            "ContentGroups"]
        profile["ChunkSize"] = profile["ChunkSize"] if "ChunkSize" in profile else response["Item"]["ChunkSize"]
        profile["MaxSegmentLengthSeconds"] = profile[
            "MaxSegmentLengthSeconds"] if "MaxSegmentLengthSeconds" in profile else response["Item"][
            "MaxSegmentLengthSeconds"]
        profile["ProcessingFrameRate"] = profile["ProcessingFrameRate"] if "ProcessingFrameRate" in profile else \
            response["Item"]["ProcessingFrameRate"]
        profile["Classifier"] = profile["Classifier"] if "Classifier" in profile else response["Item"]["Classifier"]
        profile["Optimizer"] = profile["Optimizer"] if "Optimizer" in profile else (
            response["Item"]["Optimizer"] if "Optimizer" in response["Item"] else {})
        profile["Featurers"] = profile["Featurers"] if "Featurers" in profile else (
            response["Item"]["Featurers"] if "Featurers" in response["Item"] else [])
        profile["Labeler"] = profile["Labeler"] if "Labeler" in profile else (
            response["Item"]["Labeler"] if "Labeler" in response["Item"] else {})

        state_definition, plugin_definitions = profile_state_definition_helper(name, replace_decimals(profile))
        profile["StateDefinition"] = state_definition

        # === Enrich profile by adding the latest version number of all the plugins provided in the profile ===
        # Classifier and its DependentPlugins
        profile["Classifier"]["Version"] = plugin_definitions[profile["Classifier"]["Name"]]["Latest"]

        if "DependentPlugins" in profile["Classifier"]:
            for index, d_plugin in enumerate(profile["Classifier"]["DependentPlugins"]):
                profile["Classifier"]["DependentPlugins"][index]["Version"] = plugin_definitions[d_plugin["Name"]]["Latest"]

        # Optimizer and its DependentPlugins
        if "Optimizer" in profile and profile["Optimizer"]:
            profile["Optimizer"]["Version"] = plugin_definitions[profile["Optimizer"]["Name"]]["Latest"]

            if "DependentPlugins" in profile["Optimizer"]:
                for index, d_plugin in enumerate(profile["Optimizer"]["DependentPlugins"]):
                    profile["Optimizer"]["DependentPlugins"][index]["Version"] = plugin_definitions[d_plugin["Name"]]["Latest"]

        # Labeler and its DependentPlugins
        if "Labeler" in profile and profile["Labeler"]:
            profile["Labeler"]["Version"] = plugin_definitions[profile["Labeler"]["Name"]]["Latest"]

            if "DependentPlugins" in profile["Labeler"]:
                for index, d_plugin in enumerate(profile["Labeler"]["DependentPlugins"]):
                    profile["Labeler"]["DependentPlugins"][index]["Version"] = plugin_definitions[d_plugin["Name"]]["Latest"]

        # Featurers and their DependentPlugins
        if "Featurers" in profile and profile["Featurers"]:
            for p_index, featurer in enumerate(profile["Featurers"]):
                profile["Featurers"][p_index]["Version"] = plugin_definitions[featurer["Name"]]["Latest"]

                if "DependentPlugins" in featurer:
                    for c_index, d_plugin in enumerate(featurer["DependentPlugins"]):
                        profile["Featurers"][p_index]["DependentPlugins"][c_index]["Version"] = plugin_definitions[d_plugin["Name"]]["Latest"]
        # === End of enrichment ===

        # Update the Step Function State Machine
        state_machine_arn = response["Item"]["StateMachineArn"]

        print(f"Updating the StepFunction State Machine '{state_machine_arn}'")

        sfn_client.update_state_machine(
            stateMachineArn=state_machine_arn,
            definition=profile["StateDefinition"]
        )

        profile_table.update_item(
            Key={
                "Name": name
            },
            UpdateExpression="SET #Description = :Description, #ContentGroups = :ContentGroups, #ChunkSize = :ChunkSize, #MaxSegmentLengthSeconds = :MaxSegmentLengthSeconds, #ProcessingFrameRate = :ProcessingFrameRate, #Classifier = :Classifier, #Optimizer = :Optimizer, #Featurers = :Featurers, #Labeler = :Labeler, #StateDefinition = :StateDefinition, #LastModified = :LastModified",
            ExpressionAttributeNames={
                "#Description": "Description",
                "#ContentGroups": "ContentGroups",
                "#ChunkSize": "ChunkSize",
                "#MaxSegmentLengthSeconds": "MaxSegmentLengthSeconds",
                "#ProcessingFrameRate": "ProcessingFrameRate",
                "#Classifier": "Classifier",
                "#Optimizer": "Optimizer",
                "#Featurers": "Featurers",
                "#Labeler": "Labeler",
                "#StateDefinition": "StateDefinition",
                "#LastModified": "LastModified"
            },
            ExpressionAttributeValues={
                ":Description": profile["Description"],
                ":ContentGroups": profile["ContentGroups"],
                ":ChunkSize": profile["ChunkSize"],
                ":MaxSegmentLengthSeconds": profile["MaxSegmentLengthSeconds"],
                ":ProcessingFrameRate": profile["ProcessingFrameRate"],
                ":Classifier": profile["Classifier"],
                ":Optimizer": profile["Optimizer"],
                ":Featurers": profile["Featurers"],
                ":Labeler": profile["Labeler"],
                ":StateDefinition": profile["StateDefinition"],
                ":LastModified": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
            }
        )

    except ValidationError as e:
        print(f"Got jsonschema ValidationError: {str(e)}")
        raise BadRequestError(e.message)

    except NotFoundError as e:
        print(f"Got chalice NotFoundError: {str(e)}")
        raise

    except Exception as e:
        print(f"Unable to update the profile '{name}': {str(e)}")
        raise ChaliceViewError(f"Unable to update the profile '{name}': {str(e)}")

    else:
        print(f"Successfully updated the profile: {json.dumps(profile, cls=DecimalEncoder)}")

        return {}