mlrun 1.7.0rc14__py3-none-any.whl → 1.7.0rc16__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 (107) hide show
  1. mlrun/__init__.py +10 -1
  2. mlrun/__main__.py +18 -109
  3. mlrun/{runtimes/mpijob/v1alpha1.py → alerts/__init__.py} +2 -16
  4. mlrun/alerts/alert.py +141 -0
  5. mlrun/artifacts/__init__.py +8 -3
  6. mlrun/artifacts/base.py +36 -253
  7. mlrun/artifacts/dataset.py +9 -190
  8. mlrun/artifacts/manager.py +20 -41
  9. mlrun/artifacts/model.py +8 -140
  10. mlrun/artifacts/plots.py +14 -375
  11. mlrun/common/schemas/__init__.py +4 -2
  12. mlrun/common/schemas/alert.py +46 -4
  13. mlrun/common/schemas/api_gateway.py +4 -0
  14. mlrun/common/schemas/artifact.py +15 -0
  15. mlrun/common/schemas/auth.py +2 -0
  16. mlrun/common/schemas/model_monitoring/__init__.py +8 -1
  17. mlrun/common/schemas/model_monitoring/constants.py +40 -4
  18. mlrun/common/schemas/model_monitoring/model_endpoints.py +73 -2
  19. mlrun/common/schemas/project.py +2 -0
  20. mlrun/config.py +7 -4
  21. mlrun/data_types/to_pandas.py +4 -4
  22. mlrun/datastore/base.py +41 -9
  23. mlrun/datastore/datastore_profile.py +54 -4
  24. mlrun/datastore/inmem.py +2 -2
  25. mlrun/datastore/sources.py +43 -2
  26. mlrun/datastore/store_resources.py +2 -6
  27. mlrun/datastore/targets.py +106 -39
  28. mlrun/db/base.py +23 -3
  29. mlrun/db/httpdb.py +101 -47
  30. mlrun/db/nopdb.py +20 -2
  31. mlrun/errors.py +5 -0
  32. mlrun/feature_store/__init__.py +0 -2
  33. mlrun/feature_store/api.py +12 -47
  34. mlrun/feature_store/feature_set.py +9 -0
  35. mlrun/feature_store/retrieval/base.py +9 -4
  36. mlrun/feature_store/retrieval/conversion.py +4 -4
  37. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  38. mlrun/feature_store/retrieval/job.py +2 -0
  39. mlrun/feature_store/retrieval/local_merger.py +2 -0
  40. mlrun/feature_store/retrieval/spark_merger.py +5 -0
  41. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +5 -10
  42. mlrun/launcher/base.py +4 -3
  43. mlrun/launcher/client.py +1 -1
  44. mlrun/lists.py +4 -2
  45. mlrun/model.py +25 -11
  46. mlrun/model_monitoring/__init__.py +1 -1
  47. mlrun/model_monitoring/api.py +41 -18
  48. mlrun/model_monitoring/application.py +5 -305
  49. mlrun/model_monitoring/applications/__init__.py +11 -0
  50. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  51. mlrun/model_monitoring/applications/base.py +282 -0
  52. mlrun/model_monitoring/applications/context.py +214 -0
  53. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  54. mlrun/model_monitoring/applications/histogram_data_drift.py +132 -91
  55. mlrun/model_monitoring/applications/results.py +99 -0
  56. mlrun/model_monitoring/controller.py +3 -1
  57. mlrun/model_monitoring/db/__init__.py +2 -0
  58. mlrun/model_monitoring/db/stores/base/store.py +9 -36
  59. mlrun/model_monitoring/db/stores/sqldb/models/base.py +7 -6
  60. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +63 -110
  61. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +104 -187
  62. mlrun/model_monitoring/db/tsdb/__init__.py +71 -0
  63. mlrun/model_monitoring/db/tsdb/base.py +135 -0
  64. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  65. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  66. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +404 -0
  67. mlrun/model_monitoring/db/v3io_tsdb_reader.py +134 -0
  68. mlrun/model_monitoring/evidently_application.py +6 -118
  69. mlrun/model_monitoring/helpers.py +1 -1
  70. mlrun/model_monitoring/model_endpoint.py +3 -2
  71. mlrun/model_monitoring/stream_processing.py +48 -213
  72. mlrun/model_monitoring/writer.py +101 -121
  73. mlrun/platforms/__init__.py +10 -9
  74. mlrun/platforms/iguazio.py +21 -202
  75. mlrun/projects/operations.py +11 -7
  76. mlrun/projects/pipelines.py +13 -76
  77. mlrun/projects/project.py +73 -45
  78. mlrun/render.py +11 -13
  79. mlrun/run.py +6 -41
  80. mlrun/runtimes/__init__.py +3 -3
  81. mlrun/runtimes/base.py +6 -6
  82. mlrun/runtimes/funcdoc.py +0 -28
  83. mlrun/runtimes/kubejob.py +2 -1
  84. mlrun/runtimes/local.py +1 -1
  85. mlrun/runtimes/mpijob/__init__.py +0 -20
  86. mlrun/runtimes/mpijob/v1.py +1 -1
  87. mlrun/runtimes/nuclio/api_gateway.py +75 -9
  88. mlrun/runtimes/nuclio/function.py +9 -35
  89. mlrun/runtimes/pod.py +16 -36
  90. mlrun/runtimes/remotesparkjob.py +1 -1
  91. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  92. mlrun/runtimes/utils.py +1 -39
  93. mlrun/utils/helpers.py +72 -71
  94. mlrun/utils/notifications/notification/base.py +1 -1
  95. mlrun/utils/notifications/notification/slack.py +12 -5
  96. mlrun/utils/notifications/notification/webhook.py +1 -1
  97. mlrun/utils/notifications/notification_pusher.py +134 -14
  98. mlrun/utils/version/version.json +2 -2
  99. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/METADATA +4 -3
  100. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/RECORD +105 -95
  101. mlrun/kfpops.py +0 -865
  102. mlrun/platforms/other.py +0 -305
  103. /mlrun/{runtimes → common/runtimes}/constants.py +0 -0
  104. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/LICENSE +0 -0
  105. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/WHEEL +0 -0
  106. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/entry_points.txt +0 -0
  107. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc16.dist-info}/top_level.txt +0 -0
mlrun/artifacts/model.py CHANGED
@@ -13,12 +13,12 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import tempfile
16
+ import warnings
16
17
  from os import path
17
18
  from typing import Any, Optional
18
19
 
19
20
  import pandas as pd
20
21
  import yaml
21
- from deprecated import deprecated
22
22
 
23
23
  import mlrun
24
24
  import mlrun.datastore
@@ -27,7 +27,7 @@ from ..data_types import InferOptions, get_infer_interface
27
27
  from ..features import Feature
28
28
  from ..model import ObjectList
29
29
  from ..utils import StorePrefix, is_relative_path
30
- from .base import Artifact, ArtifactSpec, LegacyArtifact, upload_extra_data
30
+ from .base import Artifact, ArtifactSpec, upload_extra_data
31
31
 
32
32
  model_spec_filename = "model_spec.yaml"
33
33
 
@@ -149,6 +149,12 @@ class ModelArtifact(Artifact):
149
149
  model_dir=None,
150
150
  **kwargs,
151
151
  ):
152
+ if key or body or format or target_path:
153
+ warnings.warn(
154
+ "Artifact constructor parameters are deprecated and will be removed in 1.9.0. "
155
+ "Use the metadata and spec parameters instead.",
156
+ DeprecationWarning,
157
+ )
152
158
  super().__init__(key, body, format=format, target_path=target_path, **kwargs)
153
159
  model_file = str(model_file or "")
154
160
  if model_file and "/" in model_file:
@@ -397,144 +403,6 @@ class ModelArtifact(Artifact):
397
403
  return mlrun.get_dataitem(target_model_path).get()
398
404
 
399
405
 
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
406
  def _get_src_path(model_spec: ModelArtifact, filename):
539
407
  if model_spec.src_path:
540
408
  return path.join(model_spec.src_path, filename)
mlrun/artifacts/plots.py CHANGED
@@ -13,14 +13,12 @@
13
13
  # limitations under the License.
14
14
  import base64
15
15
  import typing
16
+ import warnings
16
17
  from io import BytesIO
17
18
 
18
- from deprecated import deprecated
19
-
20
19
  import mlrun
21
20
 
22
- from ..utils import dict_to_json
23
- from .base import Artifact, LegacyArtifact
21
+ from .base import Artifact
24
22
 
25
23
  if typing.TYPE_CHECKING:
26
24
  from plotly.graph_objs import Figure
@@ -37,6 +35,12 @@ class PlotArtifact(Artifact):
37
35
  def __init__(
38
36
  self, key=None, body=None, is_inline=False, target_path=None, title=None
39
37
  ):
38
+ if key or body or is_inline or target_path:
39
+ warnings.warn(
40
+ "Artifact constructor parameters are deprecated and will be removed in 1.9.0. "
41
+ "Use the metadata and spec parameters instead.",
42
+ DeprecationWarning,
43
+ )
40
44
  super().__init__(key, body, format="html", target_path=target_path)
41
45
  self.metadata.description = title
42
46
 
@@ -70,138 +74,6 @@ class PlotArtifact(Artifact):
70
74
  )
71
75
 
72
76
 
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
77
  class PlotlyArtifact(Artifact):
206
78
  """
207
79
  Plotly artifact is an artifact for saving Plotly generated figures. They will be stored in a html format.
@@ -222,6 +94,12 @@ class PlotlyArtifact(Artifact):
222
94
  :param key: Key for the artifact to be stored in the database.
223
95
  :param target_path: Path to save the artifact.
224
96
  """
97
+ if key or target_path:
98
+ warnings.warn(
99
+ "Artifact constructor parameters are deprecated and will be removed in 1.9.0. "
100
+ "Use the metadata and spec parameters instead.",
101
+ DeprecationWarning,
102
+ )
225
103
  # Validate the plotly package:
226
104
  try:
227
105
  from plotly.graph_objs import Figure
@@ -258,242 +136,3 @@ class PlotlyArtifact(Artifact):
258
136
  :return: The figure's html code.
259
137
  """
260
138
  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()
@@ -14,7 +14,7 @@
14
14
  #
15
15
  # flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
16
16
 
17
- from .alert import AlertActiveState, AlertConfig, Event
17
+ from .alert import AlertActiveState, AlertConfig, AlertTemplate, Event
18
18
  from .api_gateway import (
19
19
  APIGateway,
20
20
  APIGatewayAuthenticationMode,
@@ -142,8 +142,10 @@ from .model_monitoring import (
142
142
  ModelMonitoringMode,
143
143
  ModelMonitoringStoreKinds,
144
144
  MonitoringFunctionNames,
145
+ MonitoringTSDBTables,
145
146
  PrometheusEndpoints,
146
- TimeSeriesTarget,
147
+ TimeSeriesConnector,
148
+ TSDBTarget,
147
149
  )
148
150
  from .notification import (
149
151
  Notification,