Пример #1
0
    def get_ion_node_agents(self, node):
        """
        Return a list of agents for the given ion_node
        :param node: a node within the ION
        :return: List of agents for the given ion_node
        :raises MLOpsException for invalid arguments
        """

        # Getting by component name
        if isinstance(node, six.string_types):
            if node not in self._ion.node_by_name:
                raise MLOpsException("Node {} is not part of current {}".format(
                    node, Constants.ION_LITERAL))

            node_obj = self._ion.node_by_name[node]
            if node_obj.ee_id not in self._ees_dict:
                raise MLOpsException("Component {} had ee_id {} which is not part of valid ees".format(
                    node_obj.name, node_obj.ee_id))

            ee_obj = self._ees_dict[node_obj.ee_id]
            # Note: calling deepcopy in order for the user to get a copy of agents objects and not point to internal
            # data
            agent_list = copy.deepcopy(ee_obj.agents)
            return agent_list
        else:
            raise MLOpsException("component argument should be component name (string)")
Пример #2
0
    def _detect_mlops_server_via_zk(self):
        """
        Detect the active mlops server via the ZK
        :return:
        """
        zk = None
        try:
            zk = KazooClient(hosts=self._ci.zk_host, read_only=True)
            zk.start()
            if zk.exists(Constants.MLOPS_ZK_ACTIVE_HOST_PORT):
                data, stat = zk.get(Constants.MLOPS_ZK_ACTIVE_HOST_PORT)
                eco_host_port = data.decode("utf-8").split(':')

                if len(eco_host_port) is 2:
                    self._ci.mlops_server = eco_host_port[0]
                    self._ci.mlops_port = eco_host_port[1]
                else:
                    raise MLOpsException("Internal Error: Invalid zookeeper active server entry, host_port: {}"
                                         .format(eco_host_port))
            else:
                raise MLOpsException("Unable to connect to the active MLOps server, zk_host: {}"
                                     .format(self._ci.zk_host))
        except Exception as e:
            raise MLOpsException("{}, zk_host: {}".format(e, self._ci.zk_host))
        finally:
            if zk:
                zk.stop()
Пример #3
0
    def set_event(self, name, type=None, data=None, is_alert=False, timestamp=None):
        """
        Generate an event which is sent to MLOps.

        :param name: name for the event
        :param type: type of :class:`Event`
        :param data: Any python object, which will be serialized (pickle) and stored in the PM System. It can later
                     be fetched for further manipulation.
        :param is_alert: Boolean indicating whether this event is an alert.
        :param timestamp: optional datetime.datetime timestamp. If None, the current timestamp will be provided.
        :return: The current mlops instance for further calls
        :raises: MLOpsException
        """
        self._verify_mlops_is_ready()

        if name is None:
            raise MLOpsException("Name argument must be a string or an event object")

        if isinstance(name, six.string_types):
            if type is None:
                raise MLOpsException("Type of event can not be None")
            event_obj = Event(label=name, event_type=type, description=None, data=data,
                              is_alert=is_alert, timestamp=timestamp)

        elif isinstance(name, Event):
            event_obj = name
        else:
            raise MLOpsException("Name argument can be a string or event object only")

        if self._api_test_mode:
            self._logger.info("API testing mode - returning without performing call")
            return

        self._event_broker.send_event(event_obj)
        return self
Пример #4
0
    def stat(self,
             name,
             data,
             model_id,
             category=None,
             model=None,
             model_stat=None):
        if category in (StatCategory.CONFIG, StatCategory.TIME_SERIES):
            self._logger.debug(
                "{} stat called: name: {} data_type: {} class: {}".format(
                    Constants.OFFICIAL_NAME, name, type(data), category))

            single_value = SingleValue().name(name).value(data).mode(category)
            self.stat_object(single_value.get_mlops_stat(model_id))

        elif category is StatCategory.INPUT:
            self._logger.info(
                "{} stat called: name: {} data_type: {} class: {}".format(
                    Constants.OFFICIAL_NAME, name, type(data), category))

            # right now, only for ndarray or dataframe, we can generate input stats.
            if isinstance(data, ndarray):
                dims = data.shape

                feature_length = 1
                try:
                    feature_length = dims[1]
                except Exception as e:
                    data = data.reshape(dims[0], -1)
                    pass

                array_of_features = []
                for i in range(feature_length):
                    array_of_features.append("c" + str(i))

                features_values = data
                features_names = array_of_features

            elif isinstance(data, pd.DataFrame):
                features_values = np.array(data.values)
                features_names = list(data.columns)

            else:
                raise MLOpsException(
                    "stat_class: {} not supported yet for data: {}".format(
                        category, data))

            self._logger.info("model_stat is: {}".format(model_stat))

            PythonChannelHealth.generate_health_and_heatmap_stat(
                stat_object_method=self.stat_object,
                logger=self._logger,
                features_values=features_values,
                features_names=features_names,
                model_stat=model_stat,
                model_id=model_id,
                num_bins=13)
        else:
            raise MLOpsException(
                "stat_class: {} not supported yet".format(category))
Пример #5
0
def check_list_of_str(list_of_str, error_prefix="Columns names"):
    if not isinstance(list_of_str, list):
        raise MLOpsException(
            "{} should be provided as a list".format(error_prefix))

    if not all(isinstance(item, six.string_types) for item in list_of_str):
        raise MLOpsException("{} should be strings".format(error_prefix))
Пример #6
0
    def __init__(self,
                 label,
                 description=None,
                 data=None,
                 event_type=ReflexEvent.GenericEvent,
                 is_alert=False,
                 timestamp=None):

        # TODO: make sure event_type is an event type and not something else

        if not isinstance(label, six.string_types):
            raise MLOpsException(
                "Invalid 'label' type! Expecting string! label: " +
                type(label))

        if description is None:
            description = ""

        if not isinstance(description, six.string_types):
            raise MLOpsException(
                "Invalid 'description' type! Expecting string! desc: " +
                description)

        self.type = event_type
        self.label = label
        self.description = description
        self.data = str(pickle.dumps(data))
        self.is_alert = is_alert
        self.timestamp = timestamp
Пример #7
0
    def _assemble_nodes_and_agents(self, ion, node, agent):

        # Assemble a list of nodes and for each node the list of agents.
        agents_per_node = OrderedDict()
        if node is not None:
            node_obj = self.get_node(node)
            if node_obj is None:
                msg = "{} Node: [{}] is not present in {}".format(Constants.ION_LITERAL, node,
                                                                  Constants.ION_LITERAL)
                self._logger.error(msg)
                raise MLOpsException(msg)
            if agent is None:
                agents_per_node[node_obj.name] = self.get_agents(node_obj.name)
            else:
                if isinstance(agent, six.string_types):
                    agent_id = agent
                else:
                    agent_id = agent.id
                agent_obj = self.get_agent(node_obj.name, agent_id)
                if agent_obj is None:
                    raise MLOpsException("Agent: {} is not found in node {}".format(agent, node_obj.name))
                agents_per_node[node_obj.name] = [agent_obj]
        else:
            node_list = ion.node_by_id.values()
            for node_obj in node_list:
                agents_per_node[node_obj.name] = self.get_agents(node_obj.name)

        return agents_per_node
Пример #8
0
    def post_model_as_file(self, model_file_path, params, metadata):
        """
        Posts a file to the server
        :param model_file_path: model file to upload
        :param params: parameters dictionary
        :param metadata: extended metadata(currently not used with rest connected)
        :return: model_id
        """

        if metadata and not isinstance(metadata, ModelMetadata):
            raise MLOpsException(
                "metadata argument must be a ModelMetadata object, got {}".
                format(type(metadata)))

        required_params = ["modelId"]

        for param_name in required_params:
            if param_name not in params:
                raise MLOpsException(
                    'parameter {} is required for publishing model'.format(
                        param_name))

        model_id = params["modelId"]

        if metadata:
            model_meta_file = os.path.join(self._meta_dir, model_id)
            with open(model_meta_file, 'w') as outfile:
                json.dump(metadata.to_dict(), outfile)

        model_data_file = os.path.join(self._data_dir, model_id)
        with open(model_data_file, "w+") as data_file:
            # maybe should be changed to shutil.copyfile
            data_file.write(open(model_file_path, "r").read())

        return model_id
Пример #9
0
    def __init__(self,
                 modelId,
                 name="",
                 model_format=ModelFormat.UNKNOWN,
                 description="",
                 user_defined="",
                 size=0):
        if model_format and not isinstance(model_format, ModelFormat):
            raise MLOpsException(
                "model_format object must be an instance of ModelFormat class! provided: "
                "{}, type: {}".format(model_format, type(model_format)))
        if model_format == ModelFormat.UNKNOWN:
            raise MLOpsException(
                "model_format can not be {}. Did you forget to set a format for model?"
                .format(model_format.value))
        self.modelId = modelId
        self.name = name
        self.modelFormat = model_format
        self.description = description
        self.user_defined = user_defined
        self.size = size

        # these fields are set by MCenter server
        self.source = ""
        self.user = ""
        self.state = ""
        self.createdTimestamp = ""
        self.workflowRunId = ""
Пример #10
0
 def post_event(self, pipeline_inst_id, event):
     """
     Post event using protobuf format
     :param pipeline_inst_id:  pipeline instance identifier
     :param event:             ReflexEvent based on protobuf
     :return:                  Json response from agent
     """
     url = build_url(self._mlops_server, self._mlops_port,
                     MLOpsRestHandles.EVENTS, pipeline_inst_id)
     try:
         payload = encoder(event)
         headers = {"Content-Type": "application/json;charset=UTF-8"}
         r = requests.post(url,
                           data=payload,
                           headers=headers,
                           cookies=self._return_cookie())
         if r.ok:
             return r.json()
         else:
             raise MLOpsException(
                 'Call {} with payload {} failed text:[{}]'.format(
                     url, event, r.text))
     except requests.exceptions.ConnectionError as e:
         self._error(e)
         raise MLOpsException(
             "Connection to MLOps agent [{}:{}] refused".format(
                 self._mlops_server, self._mlops_port))
     except Exception as e:
         raise MLOpsException('Call ' + str(url) + ' failed with error ' +
                              str(e))
Пример #11
0
def verify_table_from_list_of_lists(tbl_data):
    """
    Verify that tbl_data is in the format expected
    :param tbl_data:
    :return: Throws an exception in case of badly formatted table data
    """
    if not isinstance(tbl_data, list):
        raise MLOpsException(
            "Table data is not in the format of list of lists")

    row_idx = 0
    for item in tbl_data:
        if not isinstance(item, list):
            raise MLOpsException(
                "Each item of tbl_data should be a list - row {} is not a list"
                .format(row_idx))
        row_idx += 1

    if len(tbl_data) < 2:
        raise MLOpsException(
            "Table data must contain at least column names and one row of data"
        )

    nr_cols = len(tbl_data[0])
    row_idx = 0
    for row in tbl_data:
        if len(row) != nr_cols:
            raise MLOpsException(
                "Row {} items number is {} which is not equal to number of columns provided {}"
                .format(row_idx, len(row), nr_cols))
        row_idx += 1
Пример #12
0
    def feature_importance(self,
                           feature_importance_vector=None,
                           feature_names=None,
                           model=None,
                           df=None):

        self._validate_specific_importance_inputs(df)

        # Get the feature importance vector
        if feature_importance_vector:
            feature_importance_vector_final = feature_importance_vector
        else:
            try:
                feature_importance_vector_final = model.feature_importances_
            except Exception as e:
                raise MLOpsException("Got an exception:{}".format(e))

        if feature_names:
            important_named_features = [[
                name, feature_importance_vector_final[imp_idx]
            ] for imp_idx, name in enumerate(feature_names)]
            return important_named_features
        else:
            try:
                feature_names = df.columns[1:]
                important_named_features = [[
                    name, feature_importance_vector_final[imp_idx]
                ] for imp_idx, name in enumerate(feature_names)]
                return important_named_features
            except Exception as e:
                raise MLOpsException("Got an exception:{}".format(e))
Пример #13
0
    def add_row(self, arg1, arg2=None):
        """
        Add a row to the table.

        :param arg1: Name of the row, or list of data items
        :param arg2: List of data items (if argument 1 was provided)
        :return: self

        """
        row_name = ""
        row_data = []
        if isinstance(arg1, six.string_types):
            # The case where we get the name of the row as the first argument
            row_name = copy.deepcopy(arg1)
            if arg2 is None:
                raise MLOpsException("no data provided for row")
            if not isinstance(arg2, list):
                raise MLOpsException("Data should be provided as a list")
            row_data = copy.deepcopy(arg2)
        elif isinstance(arg1, list):
            # The case where we get only data without the line/row name
            row_data = copy.deepcopy(arg1)
        else:
            raise MLOpsException("Either provide row_name, data or just data")

        if len(self._tbl_rows) > 0:
            if len(self._tbl_rows[0]) != len(row_data):
                raise MLOpsException(
                    "row length must be equal to length of previously provided rows"
                )

        self._tbl_rows.append(row_data)
        self._rows_names.append(row_name)
        return self
Пример #14
0
def verify_json_content(fname, expected_content):

    first_line_dict = json.load(open(fname, 'r'))

    for key in expected_content:

        if key not in first_line_dict:
            raise MLOpsException("File {} did not have key {}".format(
                fname, key))
        elif key == "Value":
            expected_values = expected_content[key]
            first_line_values = first_line_dict[key]
            sub_keys = [
                "Data", "GraphType", "Mode", "ShouldTransfer", "TransferType"
            ]
            for sub_key in sub_keys:
                if expected_values[sub_key] != first_line_values[sub_key]:
                    raise MLOpsException("{} did not match: {} {}".format(
                        sub_key, first_line_values[sub_key],
                        expected_values[sub_key]))
        elif expected_content[key] != first_line_dict[key]:
            raise MLOpsException(
                "File {} had a value {} for key {} that did not match {}".
                format(fname, first_line_dict[key], key,
                       expected_content[key]))
Пример #15
0
def verify_csv_content(fname, first_line, expected_content):

    first_line = first_line.strip().split(", ")
    expected_content = expected_content.strip().split(", ")

    first_line_minus_json = first_line[1:4]
    expected_content_minus_json = expected_content[1:4]

    for i, (produced_elem, expected_elem) in enumerate(
            zip(first_line_minus_json, expected_content_minus_json)):
        if produced_elem != expected_elem:
            raise MLOpsException(
                "File {} has unexpected elem: {}. Expected {}".format(
                    fname, produced_elem, expected_elem))

    first_line_json_str = ', '.join(first_line[4:]).replace("'", "\"")
    expected_content_json_str = ', '.join(expected_content[4:]).replace(
        "'", "\"")
    first_line_json = json.loads(first_line_json_str)
    expected_content_json = json.loads(expected_content_json_str)

    if first_line_json != expected_content_json:
        raise MLOpsException(
            "File {} has unexpected json: {}. Expected {}".format(
                fname, first_line_json, expected_content_json))
Пример #16
0
    def annotate(self, label, x=None, y=None):
        """
        Add an annotation to a point on a line

        :param label: annotation to add
        :param x: x value for the annotation
        :param y: y value for the annotation
        :return: self
        """
        if self._x_series is None:
            raise MLOpsException(
                "Can not add annotations before setting x_series data")

        if x is not None and y is not None:
            raise MLOpsException("Annotation can be either x or y annotation")

        if x is not None:
            if not isinstance(x, (six.integer_types, float)):
                raise MLOpsException("x argument should be a number")
            self._x_annotations.append({"label": label, "value": x})
        elif y is not None:
            if not isinstance(y, (six.integer_types, float)):
                raise MLOpsException("y argument should be a number")
            self._y_annotations.append({"label": label, "value": y})
        else:
            raise MLOpsException("Annotation must provide an axis")

        return self
Пример #17
0
    def untar_timeline_capture(self):
        """
        The function untars the timeline capture file to a local folder and saves the file names
         into a list and the files themselves into a dict

        :param self:
        :return:
        """
        try:
            print("self._input_timeline_capture", self._input_timeline_capture)
            print("self._tmpdir", self._tmpdir)
            with tarfile.open(self._input_timeline_capture) as tar_obj:
                tar_obj.extractall(self._tmpdir)
        except Exception as e:
            print("Unable to open the timeline capture file")
            raise MLOpsException(e)
        self._file_names = os.listdir(self._extracted_dir)

        try:
            for file_name in self._file_names:
                if 'csv' in file_name:
                    with open(self._extracted_dir + file_name, 'r') as f:
                        reader = csv.reader(f)
                        parsed_list = list(reader)
                    self._timeline_capture[file_name] = parsed_list[1:-1]
                    self._timeline_capture[file_name].append(parsed_list[-1])
                    self._timeline_capture[file_name +
                                           'header'] = parsed_list[0]
        except Exception as err:
            self._timeline_capture = {}
            raise MLOpsException(err)
Пример #18
0
def check_vec_of_numbers(vec_of_numbers, error_prefix="Data"):
    if not isinstance(vec_of_numbers, list):
        raise MLOpsException("{} should be a list got {}".format(
            error_prefix, type(vec_of_numbers)))
    if not all(
            isinstance(item, (six.integer_types, float))
            for item in vec_of_numbers):
        raise MLOpsException(
            "{} should be a list of int or floats".format(error_prefix))
Пример #19
0
    def stat(self,
             name,
             data,
             modelId,
             category=None,
             model=None,
             model_stat=None):
        if category in (StatCategory.CONFIG, StatCategory.TIME_SERIES):
            self._logger.info(
                "{} stat called: name: {} data_type: {} class: {}".format(
                    Constants.OFFICIAL_NAME, name, type(data), category))

            stat_mode, graph_type = self.resolve_type(data, category)

            self._jvm_mlops.stat(name, data, modelId, graph_type, stat_mode)
        elif category is StatCategory.INPUT:
            if model_stat:
                hist_rdd = self._sc.parallelize(model_stat)
            else:
                hist_rdd = self._sc.emptyRDD()

            if isinstance(data, pyspark.rdd.PipelinedRDD):
                self._jvm_mlops.inputStatsFromRDD(
                    name, modelId, ml._py2java(self._sc, data),
                    ml._py2java(self._sc, hist_rdd))
            elif isinstance(data, pyspark.sql.DataFrame):

                try:
                    self._logger.info(
                        "Spark ML is provided to help MCenter calculate Health!"
                    )
                    if model:
                        spark_ml_model = model._to_java()
                        self._jvm_mlops.inputStatsFromDataFrame(
                            name, modelId, ml._py2java(self._sc, data),
                            ml._py2java(self._sc, hist_rdd), spark_ml_model)
                    else:
                        self._jvm_mlops.inputStatsFromDataFrame(
                            name, modelId, ml._py2java(self._sc, data),
                            ml._py2java(self._sc, hist_rdd))

                except Exception as e:
                    self._logger.info(
                        "model does not seem to have _to_java method \n{}".
                        format(e))
                    raise MLOpsException(
                        "Unable to convert from python to java {}".format(e))
            else:
                raise MLOpsException(
                    "Statistic type {} is not supported for data type {}".
                    format(StatCategory.INPUT, type(data)))
        else:
            raise MLOpsException(
                "stat_class: {} not supported yet".format(category))
Пример #20
0
    def post_model_as_file(self, model_file_path, params, metadata):
        """
        Posts a file to the server
        :param model_file_path: model file to upload
        :param params: parameters dictionary
        :param metadata: extended metadata(currently not used with rest connected)
        :return: model_id
        """

        if metadata and not isinstance(metadata, ModelMetadata):
            raise MLOpsException(
                "metadata argument must be a ModelMetadata object, got {}".
                format(type(metadata)))

        required_params = [
            "modelName", "modelId", "format", "workflowInstanceId",
            "pipelineInstanceId", "description"
        ]

        for param_name in required_params:
            if param_name not in params:
                raise MLOpsException(
                    'parameter {} is required for publishing model'.format(
                        param_name))

        url = build_url(self._mlops_server, self._mlops_port,
                        MLOpsRestHandles.MODELS, params["pipelineInstanceId"])

        files = {
            'file': ("file", open(model_file_path,
                                  'rb'), "application/octet-stream")
        }

        try:
            r = requests.post(url,
                              files=files,
                              params=params,
                              cookies=self._return_cookie())
            if r.ok:
                return r.json()
            else:
                raise MLOpsException(
                    'Call {} with filename {} failed text:[{}]'.format(
                        url, model_file_path, r.text))
        except requests.exceptions.ConnectionError as e:
            self._error(e)
            raise MLOpsException(
                "Connection to MLOps server [{}:{}] refused".format(
                    self._mlops_server, self._mlops_port))
        except Exception as e:
            raise MLOpsException('Call ' + str(url) + ' failed with error ' +
                                 str(e))
Пример #21
0
    def _validate_config(self):
        """
        Validate that all config information is present
        :return:
        :raises MLOpsException for invalid configurations
        """
        if self._ci.token is None:
            raise MLOpsException("Internal Error: No auth token provided")

        if self._ci.mlops_server is None or self._ci.mlops_port is None:
            raise MLOpsException("MLOps server host or port were not provided")

        if self._ci.ion_id is None:
            MLOpsException("{} instance id not provided".format(Constants.ION_LITERAL))
Пример #22
0
    def set_kpi(self, name, data, model_id, timestamp, units):

        if not isinstance(name, six.string_types):
            raise MLOpsException("name argument must be a string")
        if not isinstance(data, (six.integer_types, float)):
            raise MLOpsException("KPI data must be a number")

        kpi_value = KpiValue(name, data, timestamp, units)

        if self._api_test_mode:
            self._logger.info("API testing mode - returning without performing call")
            return

        self._output_channel.stat_object(kpi_value.get_mlops_stat(model_id))
Пример #23
0
    def post_model_as_file(self, model):
        """
        Posts a file to the server
        :param model: :class:`Model` object to publish
        :return: model_id
        """

        request_params = {
            models.json_fields.MODEL_NAME_FIELD:
            model.metadata.name,
            models.json_fields.MODEL_ID_FIELD:
            model.metadata.modelId,
            models.json_fields.MODEL_FORMAT_FIELD:
            model.metadata.modelFormat.value,
            models.json_fields.MODEL_DESCRIPTION_FIELD:
            model.metadata.description,
            models.json_fields.MODEL_ANNOTATIONS_FIELD:
            json.dumps(model.get_annotations()),
            Constants.PIPELINE_INSTANCE_ID:
            model._pipeline_instance_id
        }

        url = build_url(self._mlops_server, self._mlops_port,
                        MLOpsRestHandles.MODELS, model._pipeline_instance_id)

        files = {
            'file': ("file", open(model._path_to_publish,
                                  'rb'), "application/octet-stream")
        }

        try:
            r = requests.post(url,
                              files=files,
                              params=request_params,
                              cookies=self._return_cookie())
            if r.ok:
                return r.json()
            else:
                raise MLOpsException(
                    'Call {} with filename {} failed text:[{}]'.format(
                        url, model_file_path, r.text))
        except requests.exceptions.ConnectionError as e:
            self._error(e)
            raise MLOpsException(
                "Connection to MLOps server [{}:{}] refused".format(
                    self._mlops_server, self._mlops_port))
        except Exception as e:
            raise MLOpsException('Call ' + str(url) + ' failed with error ' +
                                 str(e))
Пример #24
0
    def _validate_specific_importance_inputs(self, model, df):
        """

        :param model: sparkML pipeline model
        :param df: sparkML dataframe
        :return:
        """

        if PipelineModel is not None and not isinstance(model, PipelineModel):
            raise MLOpsException(
                "Got an Exception. should be a pipeline model")

        if df is not None and not isinstance(df, DataFrame):
            raise MLOpsException(
                "Got an Exception. should be a sparkML dataframe")
Пример #25
0
    def __init__(self, stats_helper, rest_helper, name, model_format, description, id=None):
        super(Model, self).__init__(rest_helper, id)

        model_id = self.get_id()
        if model_id is None or not isinstance(model_id, six.string_types) or model_id == "":
            raise MLOpsException('model id must be non zero valid string type, received: {}'.format(model_id))

        self.model_path = None
        self.metadata = ModelMetadata(self.get_id(), name, model_format, description)
        if stats_helper and not isinstance(stats_helper, StatsHelper):
            raise MLOpsException("stats_helper object must be an instance of StatsHelper class")
        self._stats_helper = stats_helper

        self._pipeline_instance_id = None
        self._path_to_publish = None
Пример #26
0
    def labels(self, label_list):
        """
        Set the labels for this multi-line graph

        :param label_list: List of strings to use as labels
        :return: self
        """
        if not isinstance(label_list, list):
            raise MLOpsException("Labels should be provided as a list")

        if not all(isinstance(item, six.string_types) for item in label_list):
            raise MLOpsException("Labels should be strings")

        self._label_list = copy.deepcopy(label_list)
        return self
Пример #27
0
 def value(self):
     if self._graph_type == StatGraphType.LINEGRAPH:
         return {self._key: self._value}
     else:
         raise MLOpsException(
             "Value graph type is not supported! key: {}, value: {}, graph_type: {}"
             .format(self._key, self._value, self._graph_type))
Пример #28
0
    def post_stat(self, pipeline_inst_id, stat):
        """
        Post stat to agent using json formatting
        :param pipeline_inst_id: pipeline instance identifier
        :param stat:             stat in json format
        :return:                 Json response from agent
        """
        if pipeline_inst_id is None:
            self._error("Missing pipeline instance id cannot post stat")
            return

        url = self.url_post_stat(pipeline_inst_id)
        try:
            payload = encoder(stat)
            headers = {"Content-Type": "application/json;charset=UTF-8"}
            r = requests.post(url,
                              data=payload,
                              headers=headers,
                              cookies=self._return_cookie())
            if r.ok:
                return r.json()
            else:
                self._error('Call {} with payload {} failed: text:[{}]'.format(
                    url, stat, r.text))
        except requests.exceptions.ConnectionError as e:
            self._error(e)
            raise MLOpsConnectionException(
                "Connection to MLOps agent [{}:{}] refused; {}".format(
                    self._mlops_server, self._mlops_port, e))
        except Exception as e:
            raise MLOpsException('Call ' + str(url) + ' failed with error ' +
                                 str(e))
Пример #29
0
    def get_model_by_id(self, model, download=False):
        """
        Return the model with this id

        :param model: the model id
        :param download: Boolean, whether to download the model
        :return: return model as a bytearray
        :raises: MLOpsException
        """
        self._verify_mlops_is_ready()

        if isinstance(model, six.string_types):
            model_id = model
        elif isinstance(model, Model):
            model_id = model.id
        else:
            raise MLOpsException("model parameter can be either a string or of class Model: got [{}]".format(
                type(model)))

        if self._api_test_mode:
            self._logger.info("API testing mode - returning without performing call - in {}".format(
                inspect.stack()[0][3]))

        model_filter = ModelFilter()
        model_filter.id = model_id
        model_df = self._model_helper.get_models_dataframe(model_filter=model_filter, download=download)

        return model_df
Пример #30
0
    def get_mlops_stat(self, model_id):

        if self._x_series is None:
            raise MLOpsException("No x_series was provided")
        if len(self._y_series) == 0:
            raise MLOpsException("At leat one y_series should be provided")

        tbl_data = self._to_dict()

        mlops_stat = MLOpsStat(name=self._name,
                               stat_type=InfoType_pb2.General,
                               graph_type=StatGraphType.GENERAL_GRAPH,
                               mode=StatsMode.Instant,
                               data=tbl_data,
                               model_id=model_id)
        return mlops_stat