def patch()

in src/lambdas/r8s_api_handler/processors/algorithm_processor.py [0:0]


    def patch(self, event):
        _LOG.debug(f'Update algorithm event: {event}')
        validate_params(event, (NAME_ATTR,))
        optional_attrs = (REQUIRED_DATA_ATTRS_ATTR, METRIC_ATTRS_ATTR,
                          TIMESTAMP_ATTR, CLUSTERING_SETTINGS_ATTR,
                          RECOMMENDATION_SETTINGS_ATTR, METRIC_FORMAT_ATTR)
        if not any([event.get(attr) for attr in optional_attrs]):
            _LOG.error(f'At least one of the following attributes must be '
                       f'specified: {optional_attrs}')
            return build_response(
                code=RESPONSE_BAD_REQUEST_CODE,
                content=f'At least one of the following attributes must be '
                        f'specified: {optional_attrs}'
            )
        name = event.get(NAME_ATTR)

        _LOG.debug(f'Describing algorithm by name \'{name}\'')
        algorithm: Algorithm = self.algorithm_service.get_by_name(name=name)

        if not algorithm:
            _LOG.debug(f'Algorithm with name \'{name}\' does not exist.')
            return build_response(
                code=RESPONSE_RESOURCE_NOT_FOUND_CODE,
                content=f'Algorithm with name \'{name}\' does not exist.'
            )

        user_customer = event.get(PARAM_USER_CUSTOMER)
        user_id = event.get(USER_ID_ATTR)
        if user_customer != 'admin' and algorithm.customer != user_customer:
            _LOG.warning(f'User \'{user_id}\' is not authorize to affect '
                         f'customer \'{algorithm.customer}\' entities.')
            return build_response(
                code=RESPONSE_RESOURCE_NOT_FOUND_CODE,
                content=f'Algorithm with name \'{name}\' does not exist.'
            )

        clustering_settings = event.get(CLUSTERING_SETTINGS_ATTR, {})
        clustering_settings = {k: v for k, v in clustering_settings.items()
                               if k in CLUSTERING_SETTINGS_ATTRS}

        recommendation_settings = event.get(RECOMMENDATION_SETTINGS_ATTR, {})
        recommendation_settings = {k: v for k, v
                                   in recommendation_settings.items()
                                   if k in RECOMMENDATION_SETTINGS_ATTRS}
        if algorithm.licensed and (clustering_settings or
                                   recommendation_settings):
            _LOG.error(f'\'{RECOMMENDATION_SETTINGS_ATTR}\' and '
                       f'\'{CLUSTERING_SETTINGS_ATTR}\' are forbidden '
                       f'to update in licensed algorithm')
            return build_response(
                code=RESPONSE_FORBIDDEN_CODE,
                content=f'\'{RECOMMENDATION_SETTINGS_ATTR}\' and '
                        f'\'{CLUSTERING_SETTINGS_ATTR}\' are forbidden '
                        f'to update in licensed algorithm'
            )

        if clustering_settings:
            _LOG.debug(f'Updating algorithm clustering settings')
            self._validate_clustering_settings(
                clustering_settings=clustering_settings)
            self.algorithm_service.update_clustering_settings(
                algorithm=algorithm,
                clustering_settings=clustering_settings
            )

        if recommendation_settings:
            _LOG.debug(f'Updating algorithm recommendation settings')
            self._validate_recommendation_settings(
                recommendation_settings=recommendation_settings)
            self.algorithm_service.update_recommendation_settings(
                algorithm=algorithm,
                recommendation_settings=recommendation_settings
            )

        required_data_attributes = event.get(REQUIRED_DATA_ATTRS_ATTR)
        if required_data_attributes:
            _LOG.debug(f'Updating algorithm \'{REQUIRED_DATA_ATTRS_ATTR}\'')
            self._validate_list_of_str(attr_name=REQUIRED_DATA_ATTRS_ATTR,
                                       value=required_data_attributes)
            algorithm.required_data_attributes = required_data_attributes

        metric_attrs = event.get(METRIC_ATTRS_ATTR)
        if metric_attrs:
            _LOG.debug(f'Updating algorithm \'{METRIC_ATTRS_ATTR}\'')
            self._validate_list_of_str(attr_name=METRIC_ATTRS_ATTR,
                                       value=metric_attrs)
            algorithm.metric_attributes = metric_attrs

        timestamp_attribute = event.get(TIMESTAMP_ATTR)
        if timestamp_attribute:
            _LOG.debug(f'Updating algorithm \'{TIMESTAMP_ATTR}\' to '
                       f'{timestamp_attribute}')
            self._validate_timestamp_attr(
                required_data_attrs=algorithm.required_data_attributes,
                timestamp_attr=timestamp_attribute)
            algorithm.timestamp_attribute = timestamp_attribute

        metric_format = event.get(METRIC_FORMAT_ATTR, {})
        metric_format = {k: v for k, v in metric_format.items()
                         if k in METRIC_FORMAT_ATTRS}
        if metric_format:
            _LOG.debug(f'Updating algorithm metric format settings')
            self._validate_metric_format_settings(metric_format=metric_format)
            self.algorithm_service.update_metric_format_settings(
                algorithm=algorithm, metric_format_settings=metric_format)

        try:
            _LOG.debug(f'Saving updated algorithm')
            self.algorithm_service.save(algorithm=algorithm)
        except ValidationError as e:
            _LOG.error(f'Error occurred while saving updated algorithm: '
                       f'{str(e)}')
            return build_response(
                code=RESPONSE_BAD_REQUEST_CODE,
                content=e.message
            )
        _LOG.debug(f'Describing algorithm dto')
        algorithm_dto = algorithm.get_dto()

        _LOG.debug(f'Response: {algorithm_dto}')
        return build_response(
            code=RESPONSE_OK_CODE,
            content=algorithm_dto
        )