mlrun 1.7.0rc13__py3-none-any.whl → 1.7.0rc15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mlrun might be problematic. Click here for more details.

Files changed (85) hide show
  1. mlrun/__main__.py +0 -105
  2. mlrun/artifacts/__init__.py +1 -2
  3. mlrun/artifacts/base.py +8 -250
  4. mlrun/artifacts/dataset.py +1 -190
  5. mlrun/artifacts/manager.py +2 -41
  6. mlrun/artifacts/model.py +1 -140
  7. mlrun/artifacts/plots.py +1 -375
  8. mlrun/common/schemas/model_monitoring/__init__.py +4 -0
  9. mlrun/common/schemas/model_monitoring/constants.py +24 -3
  10. mlrun/common/schemas/model_monitoring/model_endpoints.py +13 -1
  11. mlrun/common/schemas/project.py +1 -0
  12. mlrun/config.py +14 -4
  13. mlrun/data_types/to_pandas.py +4 -4
  14. mlrun/datastore/base.py +41 -9
  15. mlrun/datastore/datastore_profile.py +50 -3
  16. mlrun/datastore/hdfs.py +5 -0
  17. mlrun/datastore/inmem.py +2 -2
  18. mlrun/datastore/sources.py +43 -2
  19. mlrun/datastore/store_resources.py +2 -6
  20. mlrun/datastore/targets.py +125 -6
  21. mlrun/datastore/v3io.py +1 -1
  22. mlrun/db/auth_utils.py +152 -0
  23. mlrun/db/base.py +1 -1
  24. mlrun/db/httpdb.py +69 -33
  25. mlrun/feature_store/__init__.py +0 -2
  26. mlrun/feature_store/api.py +12 -47
  27. mlrun/feature_store/feature_set.py +9 -0
  28. mlrun/feature_store/retrieval/base.py +9 -4
  29. mlrun/feature_store/retrieval/conversion.py +4 -4
  30. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  31. mlrun/feature_store/retrieval/job.py +2 -0
  32. mlrun/feature_store/retrieval/local_merger.py +2 -0
  33. mlrun/feature_store/retrieval/spark_merger.py +5 -0
  34. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +5 -10
  35. mlrun/kfpops.py +5 -10
  36. mlrun/launcher/base.py +1 -1
  37. mlrun/launcher/client.py +1 -1
  38. mlrun/lists.py +2 -2
  39. mlrun/model.py +36 -9
  40. mlrun/model_monitoring/api.py +41 -18
  41. mlrun/model_monitoring/application.py +5 -305
  42. mlrun/model_monitoring/applications/__init__.py +11 -0
  43. mlrun/model_monitoring/applications/_application_steps.py +158 -0
  44. mlrun/model_monitoring/applications/base.py +282 -0
  45. mlrun/model_monitoring/applications/context.py +214 -0
  46. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  47. mlrun/model_monitoring/applications/histogram_data_drift.py +92 -77
  48. mlrun/model_monitoring/applications/results.py +99 -0
  49. mlrun/model_monitoring/controller.py +3 -1
  50. mlrun/model_monitoring/db/stores/sqldb/models/base.py +7 -6
  51. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +1 -1
  52. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +67 -4
  53. mlrun/model_monitoring/evidently_application.py +6 -118
  54. mlrun/model_monitoring/helpers.py +1 -1
  55. mlrun/model_monitoring/model_endpoint.py +3 -2
  56. mlrun/model_monitoring/stream_processing.py +2 -3
  57. mlrun/model_monitoring/writer.py +69 -39
  58. mlrun/platforms/iguazio.py +2 -2
  59. mlrun/projects/pipelines.py +24 -7
  60. mlrun/projects/project.py +130 -65
  61. mlrun/render.py +2 -10
  62. mlrun/run.py +1 -4
  63. mlrun/runtimes/__init__.py +3 -3
  64. mlrun/runtimes/base.py +3 -3
  65. mlrun/runtimes/funcdoc.py +0 -28
  66. mlrun/runtimes/local.py +1 -1
  67. mlrun/runtimes/mpijob/__init__.py +0 -20
  68. mlrun/runtimes/mpijob/v1.py +1 -1
  69. mlrun/runtimes/nuclio/api_gateway.py +275 -153
  70. mlrun/runtimes/nuclio/function.py +1 -1
  71. mlrun/runtimes/pod.py +5 -5
  72. mlrun/runtimes/utils.py +1 -1
  73. mlrun/serving/states.py +53 -2
  74. mlrun/utils/helpers.py +27 -40
  75. mlrun/utils/notifications/notification/slack.py +31 -8
  76. mlrun/utils/notifications/notification_pusher.py +133 -14
  77. mlrun/utils/version/version.json +2 -2
  78. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/METADATA +2 -2
  79. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/RECORD +84 -79
  80. mlrun/runtimes/mpijob/v1alpha1.py +0 -29
  81. /mlrun/{runtimes → common/runtimes}/constants.py +0 -0
  82. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/LICENSE +0 -0
  83. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/WHEEL +0 -0
  84. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/entry_points.txt +0 -0
  85. {mlrun-1.7.0rc13.dist-info → mlrun-1.7.0rc15.dist-info}/top_level.txt +0 -0
@@ -24,7 +24,6 @@ from mlrun.utils.helpers import (
24
24
  )
25
25
 
26
26
  from ..utils import (
27
- is_legacy_artifact,
28
27
  is_relative_path,
29
28
  logger,
30
29
  validate_artifact_key_name,
@@ -33,56 +32,28 @@ from ..utils import (
33
32
  from .base import (
34
33
  Artifact,
35
34
  DirArtifact,
36
- LegacyArtifact,
37
- LegacyDirArtifact,
38
- LegacyLinkArtifact,
39
35
  LinkArtifact,
40
36
  )
41
37
  from .dataset import (
42
38
  DatasetArtifact,
43
- LegacyDatasetArtifact,
44
- LegacyTableArtifact,
45
39
  TableArtifact,
46
40
  )
47
- from .model import LegacyModelArtifact, ModelArtifact
41
+ from .model import ModelArtifact
48
42
  from .plots import (
49
- BokehArtifact,
50
- ChartArtifact,
51
- LegacyBokehArtifact,
52
- LegacyChartArtifact,
53
- LegacyPlotArtifact,
54
- LegacyPlotlyArtifact,
55
43
  PlotArtifact,
56
44
  PlotlyArtifact,
57
45
  )
58
46
 
59
- # TODO - Remove deprecated types when deleted in 1.7.0
60
47
  artifact_types = {
61
48
  "": Artifact,
62
49
  "artifact": Artifact,
63
50
  "dir": DirArtifact,
64
51
  "link": LinkArtifact,
65
52
  "plot": PlotArtifact,
66
- "chart": ChartArtifact,
67
53
  "table": TableArtifact,
68
54
  "model": ModelArtifact,
69
55
  "dataset": DatasetArtifact,
70
56
  "plotly": PlotlyArtifact,
71
- "bokeh": BokehArtifact,
72
- }
73
-
74
- # TODO - Remove this when legacy types are deleted in 1.7.0
75
- legacy_artifact_types = {
76
- "": LegacyArtifact,
77
- "dir": LegacyDirArtifact,
78
- "link": LegacyLinkArtifact,
79
- "plot": LegacyPlotArtifact,
80
- "chart": LegacyChartArtifact,
81
- "table": LegacyTableArtifact,
82
- "model": LegacyModelArtifact,
83
- "dataset": LegacyDatasetArtifact,
84
- "plotly": LegacyPlotlyArtifact,
85
- "bokeh": LegacyBokehArtifact,
86
57
  }
87
58
 
88
59
 
@@ -102,15 +73,8 @@ class ArtifactProducer:
102
73
 
103
74
 
104
75
  def dict_to_artifact(struct: dict) -> Artifact:
105
- # Need to distinguish between LegacyArtifact classes and Artifact classes. Use existence of the "metadata"
106
- # property to make this distinction
107
76
  kind = struct.get("kind", "")
108
-
109
- if is_legacy_artifact(struct):
110
- return mlrun.artifacts.base.convert_legacy_artifact_to_new_format(struct)
111
-
112
77
  artifact_class = artifact_types[kind]
113
-
114
78
  return artifact_class.from_dict(struct)
115
79
 
116
80
 
@@ -308,10 +272,7 @@ class ArtifactManager:
308
272
  # before uploading the item, we want to ensure that its tags are valid,
309
273
  # so that we don't upload something that won't be stored later
310
274
  validate_tag_name(item.metadata.tag, "artifact.metadata.tag")
311
- if is_legacy_artifact(item):
312
- item.upload()
313
- else:
314
- item.upload(artifact_path=artifact_path)
275
+ item.upload(artifact_path=artifact_path)
315
276
 
316
277
  if db_key:
317
278
  self._log_to_db(db_key, project, producer.inputs, item)
mlrun/artifacts/model.py CHANGED
@@ -18,7 +18,6 @@ from typing import Any, Optional
18
18
 
19
19
  import pandas as pd
20
20
  import yaml
21
- from deprecated import deprecated
22
21
 
23
22
  import mlrun
24
23
  import mlrun.datastore
@@ -27,7 +26,7 @@ from ..data_types import InferOptions, get_infer_interface
27
26
  from ..features import Feature
28
27
  from ..model import ObjectList
29
28
  from ..utils import StorePrefix, is_relative_path
30
- from .base import Artifact, ArtifactSpec, LegacyArtifact, upload_extra_data
29
+ from .base import Artifact, ArtifactSpec, upload_extra_data
31
30
 
32
31
  model_spec_filename = "model_spec.yaml"
33
32
 
@@ -397,144 +396,6 @@ class ModelArtifact(Artifact):
397
396
  return mlrun.get_dataitem(target_model_path).get()
398
397
 
399
398
 
400
- # TODO: remove in 1.7.0
401
- @deprecated(
402
- version="1.3.0",
403
- reason="'LegacyModelArtifact' will be removed in 1.7.0, use 'ModelArtifact' instead",
404
- category=FutureWarning,
405
- )
406
- class LegacyModelArtifact(LegacyArtifact):
407
- """ML Model artifact
408
-
409
- Store link to ML model file(s) along with the model metrics, parameters, schema, and stats
410
- """
411
-
412
- _dict_fields = LegacyArtifact._dict_fields + [
413
- "model_file",
414
- "metrics",
415
- "parameters",
416
- "inputs",
417
- "outputs",
418
- "framework",
419
- "algorithm",
420
- "extra_data",
421
- "feature_vector",
422
- "feature_weights",
423
- "feature_stats",
424
- "model_target_file",
425
- ]
426
- kind = "model"
427
- _store_prefix = StorePrefix.Model
428
-
429
- def __init__(
430
- self,
431
- key=None,
432
- body=None,
433
- format=None,
434
- model_file=None,
435
- metrics=None,
436
- target_path=None,
437
- parameters=None,
438
- inputs=None,
439
- outputs=None,
440
- framework=None,
441
- algorithm=None,
442
- feature_vector=None,
443
- feature_weights=None,
444
- extra_data=None,
445
- model_target_file=None,
446
- **kwargs,
447
- ):
448
- super().__init__(key, body, format=format, target_path=target_path, **kwargs)
449
- self._inputs: Optional[ObjectList] = None
450
- self._outputs: Optional[ObjectList] = None
451
-
452
- self.model_file = model_file
453
- self.parameters = parameters or {}
454
- self.metrics = metrics or {}
455
- self.inputs = inputs or []
456
- self.outputs = outputs or []
457
- self.extra_data = extra_data or {}
458
- self.framework = framework
459
- self.algorithm = algorithm
460
- self.feature_vector = feature_vector
461
- self.feature_weights = feature_weights
462
- self.feature_stats = None
463
- self.model_target_file = model_target_file
464
-
465
- @property
466
- def inputs(self) -> Optional[ObjectList]:
467
- """input feature list"""
468
- return self._inputs
469
-
470
- @inputs.setter
471
- def inputs(self, inputs: list[Feature]) -> None:
472
- self._inputs = ObjectList.from_list(Feature, inputs)
473
-
474
- @property
475
- def outputs(self) -> Optional[ObjectList]:
476
- """output feature list"""
477
- return self._outputs
478
-
479
- @outputs.setter
480
- def outputs(self, outputs: list[Feature]) -> None:
481
- self._outputs = ObjectList.from_list(Feature, outputs)
482
-
483
- def infer_from_df(self, df, label_columns=None, with_stats=True, num_bins=None):
484
- """infer inputs, outputs, and stats from provided df (training set)
485
-
486
- :param df: dataframe to infer from
487
- :param label_columns: name of the label (target) column
488
- :param with_stats: infer statistics (min, max, .. histogram)
489
- :param num_bins: number of bins for histogram
490
- """
491
- subset = df
492
- inferer = get_infer_interface(subset)
493
- if label_columns:
494
- if not isinstance(label_columns, list):
495
- label_columns = [label_columns]
496
- subset = df.drop(columns=label_columns)
497
- inferer.infer_schema(subset, self.inputs, {}, options=InferOptions.Features)
498
- if label_columns:
499
- inferer.infer_schema(
500
- df[label_columns], self.outputs, {}, options=InferOptions.Features
501
- )
502
- if with_stats:
503
- self.feature_stats = inferer.get_stats(
504
- df, options=InferOptions.Histogram, num_bins=num_bins
505
- )
506
-
507
- @property
508
- def is_dir(self):
509
- return True
510
-
511
- def before_log(self):
512
- if not self.model_file:
513
- raise ValueError("model_file attr must be specified")
514
-
515
- super().before_log()
516
-
517
- if self.framework:
518
- self.labels = self.labels or {}
519
- self.labels["framework"] = self.framework
520
-
521
- def upload(self):
522
- target_model_path = path.join(self.target_path, self.model_file)
523
- body = self.get_body()
524
- if body:
525
- self._upload_body(body, target=target_model_path)
526
- else:
527
- src_model_path = _get_src_path(self, self.model_file)
528
- if not path.isfile(src_model_path):
529
- raise ValueError(f"model file {src_model_path} not found")
530
- self._upload_file(src_model_path, target=target_model_path)
531
-
532
- upload_extra_data(self, self.extra_data)
533
-
534
- spec_path = path.join(self.target_path, model_spec_filename)
535
- mlrun.datastore.store_manager.object(url=spec_path).put(self.to_yaml())
536
-
537
-
538
399
  def _get_src_path(model_spec: ModelArtifact, filename):
539
400
  if model_spec.src_path:
540
401
  return path.join(model_spec.src_path, filename)
mlrun/artifacts/plots.py CHANGED
@@ -15,12 +15,9 @@ import base64
15
15
  import typing
16
16
  from io import BytesIO
17
17
 
18
- from deprecated import deprecated
19
-
20
18
  import mlrun
21
19
 
22
- from ..utils import dict_to_json
23
- from .base import Artifact, LegacyArtifact
20
+ from .base import Artifact
24
21
 
25
22
  if typing.TYPE_CHECKING:
26
23
  from plotly.graph_objs import Figure
@@ -70,138 +67,6 @@ class PlotArtifact(Artifact):
70
67
  )
71
68
 
72
69
 
73
- # TODO: remove in 1.7.0
74
- @deprecated(
75
- version="1.5.0",
76
- reason="'ChartArtifact' will be removed in 1.7.0, use 'Artifact' instead",
77
- category=FutureWarning,
78
- )
79
- class ChartArtifact(Artifact):
80
- kind = "chart"
81
-
82
- _TEMPLATE = """
83
- <html>
84
- <head>
85
- <script
86
- type="text/javascript"
87
- src="https://www.gstatic.com/charts/loader.js"></script>
88
- <script type="text/javascript">
89
- google.charts.load('current', {'packages':['corechart']});
90
- google.charts.setOnLoadCallback(drawChart);
91
- function drawChart() {
92
- var data = google.visualization.arrayToDataTable($data$);
93
- var options = $opts$;
94
- var chart = new google.visualization.$chart$(
95
- document.getElementById('chart_div'));
96
- chart.draw(data, options);
97
- }
98
- </script>
99
- </head>
100
- <body>
101
- <div id="chart_div" style="width: 100%; height: 500px;"></div>
102
- </body>
103
- </html>
104
- """
105
-
106
- def __init__(
107
- self,
108
- key=None,
109
- data=None,
110
- header=None,
111
- options=None,
112
- title=None,
113
- chart=None,
114
- target_path=None,
115
- ):
116
- data = [] if data is None else data
117
- options = {} if options is None else options
118
- super().__init__(key, target_path=target_path)
119
- self.viewer = "chart"
120
- self.header = header or []
121
- self.title = title
122
- self.rows = []
123
- if data:
124
- if header:
125
- self.rows = data
126
- else:
127
- self.header = data[0]
128
- self.rows = data[1:]
129
- self.options = options
130
- self.chart = chart or "LineChart"
131
- self.format = "html"
132
-
133
- def add_row(self, row):
134
- self.rows += [row]
135
-
136
- def get_body(self):
137
- if not self.options.get("title"):
138
- self.options["title"] = self.title or self.key
139
- data = [self.header] + self.rows
140
- return (
141
- self._TEMPLATE.replace("$data$", dict_to_json(data))
142
- .replace("$opts$", dict_to_json(self.options))
143
- .replace("$chart$", self.chart)
144
- )
145
-
146
-
147
- # TODO: remove in 1.7.0
148
- @deprecated(
149
- version="1.5.0",
150
- reason="'BokehArtifact' will be removed in 1.7.0, use 'Artifact' instead",
151
- category=FutureWarning,
152
- )
153
- class BokehArtifact(Artifact):
154
- """
155
- Bokeh artifact is an artifact for saving Bokeh generated figures. They will be stored in a html format.
156
- """
157
-
158
- kind = "bokeh"
159
-
160
- def __init__(
161
- self,
162
- figure=None,
163
- key: str = None,
164
- target_path: str = None,
165
- ):
166
- """
167
- Initialize a Bokeh artifact with the given figure.
168
-
169
- :param figure: Bokeh figure ('bokeh.plotting.Figure' object) to save as an artifact.
170
- :param key: Key for the artifact to be stored in the database.
171
- :param target_path: Path to save the artifact.
172
- """
173
- # Validate input:
174
- try:
175
- from bokeh.plotting import Figure
176
- except (ModuleNotFoundError, ImportError) as Error:
177
- raise Error(
178
- "Using 'BokehArtifact' requires bokeh package. Use pip install mlrun[bokeh] to install it."
179
- )
180
- if figure is not None and not isinstance(figure, Figure):
181
- raise ValueError(
182
- "BokehArtifact requires the figure parameter to be a "
183
- f"'bokeh.plotting.Figure' but received '{type(figure)}'"
184
- )
185
-
186
- # Call the artifact initializer:
187
- super().__init__(key=key, target_path=target_path, viewer="bokeh")
188
-
189
- # Continue initializing the bokeh artifact:
190
- self._figure = figure
191
- self.spec.format = "html"
192
-
193
- def get_body(self):
194
- """
195
- Get the artifact's body - the bokeh figure's html code.
196
-
197
- :return: The figure's html code.
198
- """
199
- from bokeh.embed import file_html
200
- from bokeh.resources import CDN
201
-
202
- return file_html(self._figure, CDN, self.metadata.key)
203
-
204
-
205
70
  class PlotlyArtifact(Artifact):
206
71
  """
207
72
  Plotly artifact is an artifact for saving Plotly generated figures. They will be stored in a html format.
@@ -258,242 +123,3 @@ class PlotlyArtifact(Artifact):
258
123
  :return: The figure's html code.
259
124
  """
260
125
  return self._figure.to_html()
261
-
262
-
263
- # TODO: remove in 1.7.0
264
- @deprecated(
265
- version="1.3.0",
266
- reason="'LegacyPlotArtifact' will be removed in 1.7.0, use 'PlotArtifact' instead",
267
- category=FutureWarning,
268
- )
269
- class LegacyPlotArtifact(LegacyArtifact):
270
- _TEMPLATE = """
271
- <h3 style="text-align:center">{}</h3>
272
- <img title="{}" src="data:image/png;base64,{}">
273
- """
274
- kind = "plot"
275
-
276
- def __init__(
277
- self, key=None, body=None, is_inline=False, target_path=None, title=None
278
- ):
279
- super().__init__(key, body, format="html", target_path=target_path)
280
- self.description = title
281
-
282
- def before_log(self):
283
- self.viewer = "chart"
284
- import matplotlib
285
-
286
- if not self._body or not isinstance(
287
- self._body, (bytes, matplotlib.figure.Figure)
288
- ):
289
- raise ValueError(
290
- "matplotlib fig or png bytes must be provided as artifact body"
291
- )
292
-
293
- def get_body(self):
294
- """Convert Matplotlib figure 'fig' into a <img> tag for HTML use
295
- using base64 encoding."""
296
- if isinstance(self._body, bytes):
297
- data = self._body
298
- else:
299
- from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
300
-
301
- canvas = FigureCanvas(self._body)
302
- png_output = BytesIO()
303
- canvas.print_png(png_output)
304
- data = png_output.getvalue()
305
-
306
- data_uri = base64.b64encode(data).decode("utf-8")
307
- return self._TEMPLATE.format(self.description or self.key, self.key, data_uri)
308
-
309
-
310
- # TODO: remove in 1.7.0
311
- @deprecated(
312
- version="1.3.0",
313
- reason="'LegacyChartArtifact' will be removed in 1.7.0, use 'ChartArtifact' instead",
314
- category=FutureWarning,
315
- )
316
- class LegacyChartArtifact(LegacyArtifact):
317
- _TEMPLATE = """
318
- <html>
319
- <head>
320
- <script
321
- type="text/javascript"
322
- src="https://www.gstatic.com/charts/loader.js"></script>
323
- <script type="text/javascript">
324
- google.charts.load('current', {'packages':['corechart']});
325
- google.charts.setOnLoadCallback(drawChart);
326
- function drawChart() {
327
- var data = google.visualization.arrayToDataTable($data$);
328
- var options = $opts$;
329
- var chart = new google.visualization.$chart$(
330
- document.getElementById('chart_div'));
331
- chart.draw(data, options);
332
- }
333
- </script>
334
- </head>
335
- <body>
336
- <div id="chart_div" style="width: 100%; height: 500px;"></div>
337
- </body>
338
- </html>
339
- """
340
-
341
- kind = "chart"
342
-
343
- def __init__(
344
- self,
345
- key=None,
346
- data=None,
347
- header=None,
348
- options=None,
349
- title=None,
350
- chart=None,
351
- target_path=None,
352
- ):
353
- data = [] if data is None else data
354
- options = {} if options is None else options
355
- super().__init__(key, target_path=target_path)
356
- self.viewer = "chart"
357
- self.header = header or []
358
- self.title = title
359
- self.rows = []
360
- if data:
361
- if header:
362
- self.rows = data
363
- else:
364
- self.header = data[0]
365
- self.rows = data[1:]
366
- self.options = options
367
- self.chart = chart or "LineChart"
368
- self.format = "html"
369
-
370
- def add_row(self, row):
371
- self.rows += [row]
372
-
373
- def get_body(self):
374
- if not self.options.get("title"):
375
- self.options["title"] = self.title or self.key
376
- data = [self.header] + self.rows
377
- return (
378
- self._TEMPLATE.replace("$data$", dict_to_json(data))
379
- .replace("$opts$", dict_to_json(self.options))
380
- .replace("$chart$", self.chart)
381
- )
382
-
383
-
384
- # TODO: remove in 1.7.0
385
- @deprecated(
386
- version="1.3.0",
387
- reason="'LegacyBokehArtifact' will be removed in 1.7.0, use 'BokehArtifact' instead",
388
- category=FutureWarning,
389
- )
390
- class LegacyBokehArtifact(LegacyArtifact):
391
- """
392
- Bokeh artifact is an artifact for saving Bokeh generated figures. They will be stored in a html format.
393
- """
394
-
395
- kind = "bokeh"
396
-
397
- def __init__(
398
- self,
399
- figure=None,
400
- key: str = None,
401
- target_path: str = None,
402
- ):
403
- """
404
- Initialize a Bokeh artifact with the given figure.
405
- :param figure: Bokeh figure ('bokeh.plotting.Figure' object) to save as an artifact.
406
- :param key: Key for the artifact to be stored in the database.
407
- :param target_path: Path to save the artifact.
408
- """
409
- # Validate input:
410
- try:
411
- from bokeh.plotting import Figure
412
- except (ModuleNotFoundError, ImportError) as Error:
413
- raise Error(
414
- "Using 'BokehArtifact' requires bokeh package. Use pip install mlrun[bokeh] to install it."
415
- )
416
- if figure is not None and not isinstance(figure, Figure):
417
- raise ValueError(
418
- "BokehArtifact requires the figure parameter to be a "
419
- f"'bokeh.plotting.Figure' but received '{type(figure)}'"
420
- )
421
-
422
- # Call the artifact initializer:
423
- super().__init__(key=key, target_path=target_path, viewer="bokeh")
424
-
425
- # Continue initializing the bokeh artifact:
426
- self._figure = figure
427
- self.format = "html"
428
-
429
- def get_body(self):
430
- """
431
- Get the artifact's body - the bokeh figure's html code.
432
- :return: The figure's html code.
433
- """
434
- from bokeh.embed import file_html
435
- from bokeh.resources import CDN
436
-
437
- return file_html(self._figure, CDN, self.key)
438
-
439
-
440
- # TODO: remove in 1.7.0
441
- @deprecated(
442
- version="1.3.0",
443
- reason="'LegacyPlotlyArtifact' will be removed in 1.7.0, use 'PlotlyArtifact' instead",
444
- category=FutureWarning,
445
- )
446
- class LegacyPlotlyArtifact(LegacyArtifact):
447
- """
448
- Plotly artifact is an artifact for saving Plotly generated figures. They will be stored in a html format.
449
- """
450
-
451
- kind = "plotly"
452
-
453
- def __init__(
454
- self,
455
- figure=None,
456
- key: str = None,
457
- target_path: str = None,
458
- ):
459
- """
460
- Initialize a Plotly artifact with the given figure.
461
- :param figure: Plotly figure ('plotly.graph_objs.Figure' object) to save as an artifact.
462
- :param key: Key for the artifact to be stored in the database.
463
- :param target_path: Path to save the artifact.
464
- """
465
- # Validate the plotly package:
466
- try:
467
- from plotly.graph_objs import Figure
468
- except ModuleNotFoundError:
469
- raise mlrun.errors.MLRunMissingDependencyError(
470
- "Using `PlotlyArtifact` requires plotly package. Use `pip install mlrun[plotly]` to install it."
471
- )
472
- except ImportError:
473
- import plotly
474
-
475
- raise mlrun.errors.MLRunMissingDependencyError(
476
- f"Using `PlotlyArtifact` requires plotly version >= 5.4.0 but found version {plotly.__version__}. "
477
- f"Use `pip install -U mlrun[plotly]` to install it."
478
- )
479
-
480
- # Call the artifact initializer:
481
- super().__init__(key=key, target_path=target_path, viewer="plotly")
482
-
483
- # Validate input:
484
- if figure is not None and not isinstance(figure, Figure):
485
- raise mlrun.errors.MLRunInvalidArgumentError(
486
- f"PlotlyArtifact requires the figure parameter to be a "
487
- f"`plotly.graph_objs.Figure` but received '{type(figure)}'"
488
- )
489
-
490
- # Continue initializing the plotly artifact:
491
- self._figure = figure
492
- self.format = "html"
493
-
494
- def get_body(self):
495
- """
496
- Get the artifact's body - the Plotly figure's html code.
497
- :return: The figure's html code.
498
- """
499
- return self._figure.to_html()
@@ -25,6 +25,7 @@ from .constants import (
25
25
  FeatureSetFeatures,
26
26
  FileTargetKind,
27
27
  FunctionURI,
28
+ MetricData,
28
29
  ModelEndpointTarget,
29
30
  ModelMonitoringMode,
30
31
  ModelMonitoringStoreKinds,
@@ -32,6 +33,7 @@ from .constants import (
32
33
  ProjectSecretKeys,
33
34
  PrometheusEndpoints,
34
35
  PrometheusMetric,
36
+ ResultData,
35
37
  SchedulingKeys,
36
38
  TimeSeriesTarget,
37
39
  VersionedModel,
@@ -51,6 +53,8 @@ from .model_endpoints import (
51
53
  ModelEndpoint,
52
54
  ModelEndpointList,
53
55
  ModelEndpointMetadata,
56
+ ModelEndpointMonitoringMetric,
57
+ ModelEndpointMonitoringMetricType,
54
58
  ModelEndpointSpec,
55
59
  ModelEndpointStatus,
56
60
  )