mlrun 1.7.0rc5__py3-none-any.whl → 1.7.2__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.
- mlrun/__init__.py +11 -1
- mlrun/__main__.py +39 -121
- mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
- mlrun/alerts/alert.py +248 -0
- mlrun/api/schemas/__init__.py +4 -3
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +39 -254
- mlrun/artifacts/dataset.py +9 -190
- mlrun/artifacts/manager.py +73 -46
- mlrun/artifacts/model.py +30 -158
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +73 -2
- mlrun/common/db/sql_session.py +3 -2
- mlrun/common/formatters/__init__.py +21 -0
- mlrun/common/formatters/artifact.py +46 -0
- mlrun/common/formatters/base.py +113 -0
- mlrun/common/formatters/feature_set.py +44 -0
- mlrun/common/formatters/function.py +46 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/common/formatters/run.py +29 -0
- mlrun/common/helpers.py +11 -1
- mlrun/{runtimes → common/runtimes}/constants.py +32 -4
- mlrun/common/schemas/__init__.py +21 -4
- mlrun/common/schemas/alert.py +202 -0
- mlrun/common/schemas/api_gateway.py +113 -2
- mlrun/common/schemas/artifact.py +28 -1
- mlrun/common/schemas/auth.py +11 -0
- mlrun/common/schemas/client_spec.py +2 -1
- mlrun/common/schemas/common.py +7 -4
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +58 -28
- mlrun/common/schemas/frontend_spec.py +8 -0
- mlrun/common/schemas/function.py +11 -0
- mlrun/common/schemas/hub.py +7 -9
- mlrun/common/schemas/model_monitoring/__init__.py +21 -4
- mlrun/common/schemas/model_monitoring/constants.py +136 -42
- mlrun/common/schemas/model_monitoring/grafana.py +9 -5
- mlrun/common/schemas/model_monitoring/model_endpoints.py +89 -41
- mlrun/common/schemas/notification.py +69 -12
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +7 -0
- mlrun/common/schemas/project.py +67 -16
- mlrun/common/schemas/runs.py +17 -0
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/schemas/workflow.py +10 -2
- mlrun/common/types.py +14 -1
- mlrun/config.py +224 -58
- mlrun/data_types/data_types.py +11 -1
- mlrun/data_types/spark.py +5 -4
- mlrun/data_types/to_pandas.py +75 -34
- mlrun/datastore/__init__.py +8 -10
- mlrun/datastore/alibaba_oss.py +131 -0
- mlrun/datastore/azure_blob.py +131 -43
- mlrun/datastore/base.py +107 -47
- mlrun/datastore/datastore.py +17 -7
- mlrun/datastore/datastore_profile.py +91 -7
- mlrun/datastore/dbfs_store.py +3 -7
- mlrun/datastore/filestore.py +1 -3
- mlrun/datastore/google_cloud_storage.py +92 -32
- mlrun/datastore/hdfs.py +5 -0
- mlrun/datastore/inmem.py +6 -3
- mlrun/datastore/redis.py +3 -2
- mlrun/datastore/s3.py +30 -12
- mlrun/datastore/snowflake_utils.py +45 -0
- mlrun/datastore/sources.py +274 -59
- mlrun/datastore/spark_utils.py +30 -0
- mlrun/datastore/store_resources.py +9 -7
- mlrun/datastore/storeytargets.py +151 -0
- mlrun/datastore/targets.py +374 -102
- mlrun/datastore/utils.py +68 -5
- mlrun/datastore/v3io.py +28 -50
- mlrun/db/auth_utils.py +152 -0
- mlrun/db/base.py +231 -22
- mlrun/db/factory.py +1 -4
- mlrun/db/httpdb.py +864 -228
- mlrun/db/nopdb.py +268 -16
- mlrun/errors.py +35 -5
- mlrun/execution.py +111 -38
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +46 -53
- mlrun/feature_store/common.py +6 -11
- mlrun/feature_store/feature_set.py +48 -23
- mlrun/feature_store/feature_vector.py +13 -2
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +9 -4
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +13 -4
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +24 -32
- mlrun/feature_store/steps.py +38 -19
- mlrun/features.py +6 -14
- mlrun/frameworks/_common/plan.py +3 -3
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/parallel_coordinates.py +4 -4
- mlrun/frameworks/pytorch/__init__.py +2 -2
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/sklearn/mlrun_interface.py +13 -3
- mlrun/frameworks/tf_keras/__init__.py +5 -2
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/k8s_utils.py +57 -12
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +6 -5
- mlrun/launcher/client.py +13 -11
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +15 -5
- mlrun/launcher/remote.py +10 -3
- mlrun/lists.py +6 -2
- mlrun/model.py +297 -48
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +152 -357
- mlrun/model_monitoring/applications/__init__.py +10 -0
- mlrun/model_monitoring/applications/_application_steps.py +190 -0
- mlrun/model_monitoring/applications/base.py +108 -0
- mlrun/model_monitoring/applications/context.py +341 -0
- mlrun/model_monitoring/{evidently_application.py → applications/evidently_base.py} +27 -22
- mlrun/model_monitoring/applications/histogram_data_drift.py +227 -91
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +130 -303
- mlrun/model_monitoring/{stores/models/sqlite.py → db/__init__.py} +5 -10
- mlrun/model_monitoring/db/stores/__init__.py +136 -0
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/db/stores/base/store.py +213 -0
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +190 -0
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +103 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +659 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +726 -0
- mlrun/model_monitoring/db/tsdb/__init__.py +105 -0
- mlrun/model_monitoring/db/tsdb/base.py +448 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +298 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +42 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +522 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +158 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +849 -0
- mlrun/model_monitoring/features_drift_table.py +34 -22
- mlrun/model_monitoring/helpers.py +177 -39
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +165 -398
- mlrun/model_monitoring/tracking_policy.py +7 -1
- mlrun/model_monitoring/writer.py +161 -125
- mlrun/package/packagers/default_packager.py +2 -2
- mlrun/package/packagers_manager.py +1 -0
- mlrun/package/utils/_formatter.py +2 -2
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +67 -228
- mlrun/projects/__init__.py +6 -1
- mlrun/projects/operations.py +47 -20
- mlrun/projects/pipelines.py +396 -249
- mlrun/projects/project.py +1125 -414
- mlrun/render.py +28 -22
- mlrun/run.py +207 -180
- mlrun/runtimes/__init__.py +76 -11
- mlrun/runtimes/base.py +40 -14
- mlrun/runtimes/daskjob.py +9 -2
- mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +1 -29
- mlrun/runtimes/kubejob.py +34 -128
- mlrun/runtimes/local.py +39 -10
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +8 -8
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/runtimes/nuclio/api_gateway.py +646 -177
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +758 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/nuclio/function.py +188 -68
- mlrun/runtimes/nuclio/serving.py +57 -60
- mlrun/runtimes/pod.py +191 -58
- mlrun/runtimes/remotesparkjob.py +11 -8
- mlrun/runtimes/sparkjob/spark3job.py +17 -18
- mlrun/runtimes/utils.py +40 -73
- mlrun/secrets.py +6 -2
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/remote.py +2 -3
- mlrun/serving/routers.py +89 -64
- mlrun/serving/server.py +54 -26
- mlrun/serving/states.py +187 -56
- mlrun/serving/utils.py +19 -11
- mlrun/serving/v2_serving.py +136 -63
- mlrun/track/tracker.py +2 -1
- mlrun/track/trackers/mlflow_tracker.py +5 -0
- mlrun/utils/async_http.py +26 -6
- mlrun/utils/db.py +18 -0
- mlrun/utils/helpers.py +375 -105
- mlrun/utils/http.py +2 -2
- mlrun/utils/logger.py +75 -9
- mlrun/utils/notifications/notification/__init__.py +14 -10
- mlrun/utils/notifications/notification/base.py +48 -0
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +24 -1
- mlrun/utils/notifications/notification/ipython.py +2 -0
- mlrun/utils/notifications/notification/slack.py +96 -21
- mlrun/utils/notifications/notification/webhook.py +63 -2
- mlrun/utils/notifications/notification_pusher.py +146 -16
- mlrun/utils/regex.py +9 -0
- mlrun/utils/retryer.py +3 -2
- mlrun/utils/v3io_clients.py +2 -3
- mlrun/utils/version/version.json +2 -2
- mlrun-1.7.2.dist-info/METADATA +390 -0
- mlrun-1.7.2.dist-info/RECORD +351 -0
- {mlrun-1.7.0rc5.dist-info → mlrun-1.7.2.dist-info}/WHEEL +1 -1
- mlrun/feature_store/retrieval/conversion.py +0 -271
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/application.py +0 -310
- mlrun/model_monitoring/batch.py +0 -974
- mlrun/model_monitoring/controller_handler.py +0 -37
- mlrun/model_monitoring/prometheus.py +0 -216
- mlrun/model_monitoring/stores/__init__.py +0 -111
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +0 -574
- mlrun/model_monitoring/stores/model_endpoint_store.py +0 -145
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/models/base.py +0 -84
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
- mlrun/platforms/other.py +0 -305
- mlrun-1.7.0rc5.dist-info/METADATA +0 -269
- mlrun-1.7.0rc5.dist-info/RECORD +0 -323
- {mlrun-1.7.0rc5.dist-info → mlrun-1.7.2.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc5.dist-info → mlrun-1.7.2.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc5.dist-info → mlrun-1.7.2.dist-info}/top_level.txt +0 -0
mlrun/artifacts/plots.py
CHANGED
|
@@ -12,14 +12,16 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import base64
|
|
15
|
+
import typing
|
|
16
|
+
import warnings
|
|
15
17
|
from io import BytesIO
|
|
16
18
|
|
|
17
|
-
from deprecated import deprecated
|
|
18
|
-
|
|
19
19
|
import mlrun
|
|
20
20
|
|
|
21
|
-
from
|
|
22
|
-
|
|
21
|
+
from .base import Artifact
|
|
22
|
+
|
|
23
|
+
if typing.TYPE_CHECKING:
|
|
24
|
+
from plotly.graph_objs import Figure
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
class PlotArtifact(Artifact):
|
|
@@ -33,6 +35,12 @@ class PlotArtifact(Artifact):
|
|
|
33
35
|
def __init__(
|
|
34
36
|
self, key=None, body=None, is_inline=False, target_path=None, title=None
|
|
35
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
|
+
)
|
|
36
44
|
super().__init__(key, body, format="html", target_path=target_path)
|
|
37
45
|
self.metadata.description = title
|
|
38
46
|
|
|
@@ -66,138 +74,6 @@ class PlotArtifact(Artifact):
|
|
|
66
74
|
)
|
|
67
75
|
|
|
68
76
|
|
|
69
|
-
# TODO: remove in 1.7.0
|
|
70
|
-
@deprecated(
|
|
71
|
-
version="1.5.0",
|
|
72
|
-
reason="'ChartArtifact' will be removed in 1.7.0, use 'Artifact' instead",
|
|
73
|
-
category=FutureWarning,
|
|
74
|
-
)
|
|
75
|
-
class ChartArtifact(Artifact):
|
|
76
|
-
kind = "chart"
|
|
77
|
-
|
|
78
|
-
_TEMPLATE = """
|
|
79
|
-
<html>
|
|
80
|
-
<head>
|
|
81
|
-
<script
|
|
82
|
-
type="text/javascript"
|
|
83
|
-
src="https://www.gstatic.com/charts/loader.js"></script>
|
|
84
|
-
<script type="text/javascript">
|
|
85
|
-
google.charts.load('current', {'packages':['corechart']});
|
|
86
|
-
google.charts.setOnLoadCallback(drawChart);
|
|
87
|
-
function drawChart() {
|
|
88
|
-
var data = google.visualization.arrayToDataTable($data$);
|
|
89
|
-
var options = $opts$;
|
|
90
|
-
var chart = new google.visualization.$chart$(
|
|
91
|
-
document.getElementById('chart_div'));
|
|
92
|
-
chart.draw(data, options);
|
|
93
|
-
}
|
|
94
|
-
</script>
|
|
95
|
-
</head>
|
|
96
|
-
<body>
|
|
97
|
-
<div id="chart_div" style="width: 100%; height: 500px;"></div>
|
|
98
|
-
</body>
|
|
99
|
-
</html>
|
|
100
|
-
"""
|
|
101
|
-
|
|
102
|
-
def __init__(
|
|
103
|
-
self,
|
|
104
|
-
key=None,
|
|
105
|
-
data=None,
|
|
106
|
-
header=None,
|
|
107
|
-
options=None,
|
|
108
|
-
title=None,
|
|
109
|
-
chart=None,
|
|
110
|
-
target_path=None,
|
|
111
|
-
):
|
|
112
|
-
data = [] if data is None else data
|
|
113
|
-
options = {} if options is None else options
|
|
114
|
-
super().__init__(key, target_path=target_path)
|
|
115
|
-
self.viewer = "chart"
|
|
116
|
-
self.header = header or []
|
|
117
|
-
self.title = title
|
|
118
|
-
self.rows = []
|
|
119
|
-
if data:
|
|
120
|
-
if header:
|
|
121
|
-
self.rows = data
|
|
122
|
-
else:
|
|
123
|
-
self.header = data[0]
|
|
124
|
-
self.rows = data[1:]
|
|
125
|
-
self.options = options
|
|
126
|
-
self.chart = chart or "LineChart"
|
|
127
|
-
self.format = "html"
|
|
128
|
-
|
|
129
|
-
def add_row(self, row):
|
|
130
|
-
self.rows += [row]
|
|
131
|
-
|
|
132
|
-
def get_body(self):
|
|
133
|
-
if not self.options.get("title"):
|
|
134
|
-
self.options["title"] = self.title or self.key
|
|
135
|
-
data = [self.header] + self.rows
|
|
136
|
-
return (
|
|
137
|
-
self._TEMPLATE.replace("$data$", dict_to_json(data))
|
|
138
|
-
.replace("$opts$", dict_to_json(self.options))
|
|
139
|
-
.replace("$chart$", self.chart)
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# TODO: remove in 1.7.0
|
|
144
|
-
@deprecated(
|
|
145
|
-
version="1.5.0",
|
|
146
|
-
reason="'BokehArtifact' will be removed in 1.7.0, use 'Artifact' instead",
|
|
147
|
-
category=FutureWarning,
|
|
148
|
-
)
|
|
149
|
-
class BokehArtifact(Artifact):
|
|
150
|
-
"""
|
|
151
|
-
Bokeh artifact is an artifact for saving Bokeh generated figures. They will be stored in a html format.
|
|
152
|
-
"""
|
|
153
|
-
|
|
154
|
-
kind = "bokeh"
|
|
155
|
-
|
|
156
|
-
def __init__(
|
|
157
|
-
self,
|
|
158
|
-
figure=None,
|
|
159
|
-
key: str = None,
|
|
160
|
-
target_path: str = None,
|
|
161
|
-
):
|
|
162
|
-
"""
|
|
163
|
-
Initialize a Bokeh artifact with the given figure.
|
|
164
|
-
|
|
165
|
-
:param figure: Bokeh figure ('bokeh.plotting.Figure' object) to save as an artifact.
|
|
166
|
-
:param key: Key for the artifact to be stored in the database.
|
|
167
|
-
:param target_path: Path to save the artifact.
|
|
168
|
-
"""
|
|
169
|
-
# Validate input:
|
|
170
|
-
try:
|
|
171
|
-
from bokeh.plotting import Figure
|
|
172
|
-
except (ModuleNotFoundError, ImportError) as Error:
|
|
173
|
-
raise Error(
|
|
174
|
-
"Using 'BokehArtifact' requires bokeh package. Use pip install mlrun[bokeh] to install it."
|
|
175
|
-
)
|
|
176
|
-
if figure is not None and not isinstance(figure, Figure):
|
|
177
|
-
raise ValueError(
|
|
178
|
-
"BokehArtifact requires the figure parameter to be a "
|
|
179
|
-
f"'bokeh.plotting.Figure' but received '{type(figure)}'"
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
# Call the artifact initializer:
|
|
183
|
-
super().__init__(key=key, target_path=target_path, viewer="bokeh")
|
|
184
|
-
|
|
185
|
-
# Continue initializing the bokeh artifact:
|
|
186
|
-
self._figure = figure
|
|
187
|
-
self.spec.format = "html"
|
|
188
|
-
|
|
189
|
-
def get_body(self):
|
|
190
|
-
"""
|
|
191
|
-
Get the artifact's body - the bokeh figure's html code.
|
|
192
|
-
|
|
193
|
-
:return: The figure's html code.
|
|
194
|
-
"""
|
|
195
|
-
from bokeh.embed import file_html
|
|
196
|
-
from bokeh.resources import CDN
|
|
197
|
-
|
|
198
|
-
return file_html(self._figure, CDN, self.metadata.key)
|
|
199
|
-
|
|
200
|
-
|
|
201
77
|
class PlotlyArtifact(Artifact):
|
|
202
78
|
"""
|
|
203
79
|
Plotly artifact is an artifact for saving Plotly generated figures. They will be stored in a html format.
|
|
@@ -207,10 +83,10 @@ class PlotlyArtifact(Artifact):
|
|
|
207
83
|
|
|
208
84
|
def __init__(
|
|
209
85
|
self,
|
|
210
|
-
figure=None,
|
|
211
|
-
key: str = None,
|
|
212
|
-
target_path: str = None,
|
|
213
|
-
):
|
|
86
|
+
figure: typing.Optional["Figure"] = None,
|
|
87
|
+
key: typing.Optional[str] = None,
|
|
88
|
+
target_path: typing.Optional[str] = None,
|
|
89
|
+
) -> None:
|
|
214
90
|
"""
|
|
215
91
|
Initialize a Plotly artifact with the given figure.
|
|
216
92
|
|
|
@@ -218,6 +94,12 @@ class PlotlyArtifact(Artifact):
|
|
|
218
94
|
:param key: Key for the artifact to be stored in the database.
|
|
219
95
|
:param target_path: Path to save the artifact.
|
|
220
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
|
+
)
|
|
221
103
|
# Validate the plotly package:
|
|
222
104
|
try:
|
|
223
105
|
from plotly.graph_objs import Figure
|
|
@@ -247,249 +129,10 @@ class PlotlyArtifact(Artifact):
|
|
|
247
129
|
self._figure = figure
|
|
248
130
|
self.spec.format = "html"
|
|
249
131
|
|
|
250
|
-
def get_body(self):
|
|
132
|
+
def get_body(self) -> str:
|
|
251
133
|
"""
|
|
252
134
|
Get the artifact's body - the Plotly figure's html code.
|
|
253
135
|
|
|
254
136
|
:return: The figure's html code.
|
|
255
137
|
"""
|
|
256
138
|
return self._figure.to_html()
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
# TODO: remove in 1.7.0
|
|
260
|
-
@deprecated(
|
|
261
|
-
version="1.3.0",
|
|
262
|
-
reason="'LegacyPlotArtifact' will be removed in 1.7.0, use 'PlotArtifact' instead",
|
|
263
|
-
category=FutureWarning,
|
|
264
|
-
)
|
|
265
|
-
class LegacyPlotArtifact(LegacyArtifact):
|
|
266
|
-
_TEMPLATE = """
|
|
267
|
-
<h3 style="text-align:center">{}</h3>
|
|
268
|
-
<img title="{}" src="data:image/png;base64,{}">
|
|
269
|
-
"""
|
|
270
|
-
kind = "plot"
|
|
271
|
-
|
|
272
|
-
def __init__(
|
|
273
|
-
self, key=None, body=None, is_inline=False, target_path=None, title=None
|
|
274
|
-
):
|
|
275
|
-
super().__init__(key, body, format="html", target_path=target_path)
|
|
276
|
-
self.description = title
|
|
277
|
-
|
|
278
|
-
def before_log(self):
|
|
279
|
-
self.viewer = "chart"
|
|
280
|
-
import matplotlib
|
|
281
|
-
|
|
282
|
-
if not self._body or not isinstance(
|
|
283
|
-
self._body, (bytes, matplotlib.figure.Figure)
|
|
284
|
-
):
|
|
285
|
-
raise ValueError(
|
|
286
|
-
"matplotlib fig or png bytes must be provided as artifact body"
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
def get_body(self):
|
|
290
|
-
"""Convert Matplotlib figure 'fig' into a <img> tag for HTML use
|
|
291
|
-
using base64 encoding."""
|
|
292
|
-
if isinstance(self._body, bytes):
|
|
293
|
-
data = self._body
|
|
294
|
-
else:
|
|
295
|
-
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
|
|
296
|
-
|
|
297
|
-
canvas = FigureCanvas(self._body)
|
|
298
|
-
png_output = BytesIO()
|
|
299
|
-
canvas.print_png(png_output)
|
|
300
|
-
data = png_output.getvalue()
|
|
301
|
-
|
|
302
|
-
data_uri = base64.b64encode(data).decode("utf-8")
|
|
303
|
-
return self._TEMPLATE.format(self.description or self.key, self.key, data_uri)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
# TODO: remove in 1.7.0
|
|
307
|
-
@deprecated(
|
|
308
|
-
version="1.3.0",
|
|
309
|
-
reason="'LegacyChartArtifact' will be removed in 1.7.0, use 'ChartArtifact' instead",
|
|
310
|
-
category=FutureWarning,
|
|
311
|
-
)
|
|
312
|
-
class LegacyChartArtifact(LegacyArtifact):
|
|
313
|
-
_TEMPLATE = """
|
|
314
|
-
<html>
|
|
315
|
-
<head>
|
|
316
|
-
<script
|
|
317
|
-
type="text/javascript"
|
|
318
|
-
src="https://www.gstatic.com/charts/loader.js"></script>
|
|
319
|
-
<script type="text/javascript">
|
|
320
|
-
google.charts.load('current', {'packages':['corechart']});
|
|
321
|
-
google.charts.setOnLoadCallback(drawChart);
|
|
322
|
-
function drawChart() {
|
|
323
|
-
var data = google.visualization.arrayToDataTable($data$);
|
|
324
|
-
var options = $opts$;
|
|
325
|
-
var chart = new google.visualization.$chart$(
|
|
326
|
-
document.getElementById('chart_div'));
|
|
327
|
-
chart.draw(data, options);
|
|
328
|
-
}
|
|
329
|
-
</script>
|
|
330
|
-
</head>
|
|
331
|
-
<body>
|
|
332
|
-
<div id="chart_div" style="width: 100%; height: 500px;"></div>
|
|
333
|
-
</body>
|
|
334
|
-
</html>
|
|
335
|
-
"""
|
|
336
|
-
|
|
337
|
-
kind = "chart"
|
|
338
|
-
|
|
339
|
-
def __init__(
|
|
340
|
-
self,
|
|
341
|
-
key=None,
|
|
342
|
-
data=None,
|
|
343
|
-
header=None,
|
|
344
|
-
options=None,
|
|
345
|
-
title=None,
|
|
346
|
-
chart=None,
|
|
347
|
-
target_path=None,
|
|
348
|
-
):
|
|
349
|
-
data = [] if data is None else data
|
|
350
|
-
options = {} if options is None else options
|
|
351
|
-
super().__init__(key, target_path=target_path)
|
|
352
|
-
self.viewer = "chart"
|
|
353
|
-
self.header = header or []
|
|
354
|
-
self.title = title
|
|
355
|
-
self.rows = []
|
|
356
|
-
if data:
|
|
357
|
-
if header:
|
|
358
|
-
self.rows = data
|
|
359
|
-
else:
|
|
360
|
-
self.header = data[0]
|
|
361
|
-
self.rows = data[1:]
|
|
362
|
-
self.options = options
|
|
363
|
-
self.chart = chart or "LineChart"
|
|
364
|
-
self.format = "html"
|
|
365
|
-
|
|
366
|
-
def add_row(self, row):
|
|
367
|
-
self.rows += [row]
|
|
368
|
-
|
|
369
|
-
def get_body(self):
|
|
370
|
-
if not self.options.get("title"):
|
|
371
|
-
self.options["title"] = self.title or self.key
|
|
372
|
-
data = [self.header] + self.rows
|
|
373
|
-
return (
|
|
374
|
-
self._TEMPLATE.replace("$data$", dict_to_json(data))
|
|
375
|
-
.replace("$opts$", dict_to_json(self.options))
|
|
376
|
-
.replace("$chart$", self.chart)
|
|
377
|
-
)
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
# TODO: remove in 1.7.0
|
|
381
|
-
@deprecated(
|
|
382
|
-
version="1.3.0",
|
|
383
|
-
reason="'LegacyBokehArtifact' will be removed in 1.7.0, use 'BokehArtifact' instead",
|
|
384
|
-
category=FutureWarning,
|
|
385
|
-
)
|
|
386
|
-
class LegacyBokehArtifact(LegacyArtifact):
|
|
387
|
-
"""
|
|
388
|
-
Bokeh artifact is an artifact for saving Bokeh generated figures. They will be stored in a html format.
|
|
389
|
-
"""
|
|
390
|
-
|
|
391
|
-
kind = "bokeh"
|
|
392
|
-
|
|
393
|
-
def __init__(
|
|
394
|
-
self,
|
|
395
|
-
figure=None,
|
|
396
|
-
key: str = None,
|
|
397
|
-
target_path: str = None,
|
|
398
|
-
):
|
|
399
|
-
"""
|
|
400
|
-
Initialize a Bokeh artifact with the given figure.
|
|
401
|
-
:param figure: Bokeh figure ('bokeh.plotting.Figure' object) to save as an artifact.
|
|
402
|
-
:param key: Key for the artifact to be stored in the database.
|
|
403
|
-
:param target_path: Path to save the artifact.
|
|
404
|
-
"""
|
|
405
|
-
# Validate input:
|
|
406
|
-
try:
|
|
407
|
-
from bokeh.plotting import Figure
|
|
408
|
-
except (ModuleNotFoundError, ImportError) as Error:
|
|
409
|
-
raise Error(
|
|
410
|
-
"Using 'BokehArtifact' requires bokeh package. Use pip install mlrun[bokeh] to install it."
|
|
411
|
-
)
|
|
412
|
-
if figure is not None and not isinstance(figure, Figure):
|
|
413
|
-
raise ValueError(
|
|
414
|
-
"BokehArtifact requires the figure parameter to be a "
|
|
415
|
-
f"'bokeh.plotting.Figure' but received '{type(figure)}'"
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
# Call the artifact initializer:
|
|
419
|
-
super().__init__(key=key, target_path=target_path, viewer="bokeh")
|
|
420
|
-
|
|
421
|
-
# Continue initializing the bokeh artifact:
|
|
422
|
-
self._figure = figure
|
|
423
|
-
self.format = "html"
|
|
424
|
-
|
|
425
|
-
def get_body(self):
|
|
426
|
-
"""
|
|
427
|
-
Get the artifact's body - the bokeh figure's html code.
|
|
428
|
-
:return: The figure's html code.
|
|
429
|
-
"""
|
|
430
|
-
from bokeh.embed import file_html
|
|
431
|
-
from bokeh.resources import CDN
|
|
432
|
-
|
|
433
|
-
return file_html(self._figure, CDN, self.key)
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
# TODO: remove in 1.7.0
|
|
437
|
-
@deprecated(
|
|
438
|
-
version="1.3.0",
|
|
439
|
-
reason="'LegacyPlotlyArtifact' will be removed in 1.7.0, use 'PlotlyArtifact' instead",
|
|
440
|
-
category=FutureWarning,
|
|
441
|
-
)
|
|
442
|
-
class LegacyPlotlyArtifact(LegacyArtifact):
|
|
443
|
-
"""
|
|
444
|
-
Plotly artifact is an artifact for saving Plotly generated figures. They will be stored in a html format.
|
|
445
|
-
"""
|
|
446
|
-
|
|
447
|
-
kind = "plotly"
|
|
448
|
-
|
|
449
|
-
def __init__(
|
|
450
|
-
self,
|
|
451
|
-
figure=None,
|
|
452
|
-
key: str = None,
|
|
453
|
-
target_path: str = None,
|
|
454
|
-
):
|
|
455
|
-
"""
|
|
456
|
-
Initialize a Plotly artifact with the given figure.
|
|
457
|
-
:param figure: Plotly figure ('plotly.graph_objs.Figure' object) to save as an artifact.
|
|
458
|
-
:param key: Key for the artifact to be stored in the database.
|
|
459
|
-
:param target_path: Path to save the artifact.
|
|
460
|
-
"""
|
|
461
|
-
# Validate the plotly package:
|
|
462
|
-
try:
|
|
463
|
-
from plotly.graph_objs import Figure
|
|
464
|
-
except ModuleNotFoundError:
|
|
465
|
-
raise mlrun.errors.MLRunMissingDependencyError(
|
|
466
|
-
"Using `PlotlyArtifact` requires plotly package. Use `pip install mlrun[plotly]` to install it."
|
|
467
|
-
)
|
|
468
|
-
except ImportError:
|
|
469
|
-
import plotly
|
|
470
|
-
|
|
471
|
-
raise mlrun.errors.MLRunMissingDependencyError(
|
|
472
|
-
f"Using `PlotlyArtifact` requires plotly version >= 5.4.0 but found version {plotly.__version__}. "
|
|
473
|
-
f"Use `pip install -U mlrun[plotly]` to install it."
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
# Call the artifact initializer:
|
|
477
|
-
super().__init__(key=key, target_path=target_path, viewer="plotly")
|
|
478
|
-
|
|
479
|
-
# Validate input:
|
|
480
|
-
if figure is not None and not isinstance(figure, Figure):
|
|
481
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
482
|
-
f"PlotlyArtifact requires the figure parameter to be a "
|
|
483
|
-
f"`plotly.graph_objs.Figure` but received '{type(figure)}'"
|
|
484
|
-
)
|
|
485
|
-
|
|
486
|
-
# Continue initializing the plotly artifact:
|
|
487
|
-
self._figure = figure
|
|
488
|
-
self.format = "html"
|
|
489
|
-
|
|
490
|
-
def get_body(self):
|
|
491
|
-
"""
|
|
492
|
-
Get the artifact's body - the Plotly figure's html code.
|
|
493
|
-
:return: The figure's html code.
|
|
494
|
-
"""
|
|
495
|
-
return self._figure.to_html()
|
mlrun/common/constants.py
CHANGED
|
@@ -11,7 +11,78 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
IMAGE_NAME_ENRICH_REGISTRY_PREFIX = "." # prefix for image name to enrich with registry
|
|
16
|
-
|
|
16
|
+
MLRUN_SERVING_CONF = "serving-conf"
|
|
17
|
+
MLRUN_SERVING_SPEC_MOUNT_PATH = f"/tmp/mlrun/{MLRUN_SERVING_CONF}"
|
|
18
|
+
MLRUN_SERVING_SPEC_FILENAME = "serving_spec.json"
|
|
19
|
+
MLRUN_SERVING_SPEC_PATH = (
|
|
20
|
+
f"{MLRUN_SERVING_SPEC_MOUNT_PATH}/{MLRUN_SERVING_SPEC_FILENAME}"
|
|
21
|
+
)
|
|
22
|
+
MLRUN_FUNCTIONS_ANNOTATION = "mlrun/mlrun-functions"
|
|
17
23
|
MYSQL_MEDIUMBLOB_SIZE_BYTES = 16 * 1024 * 1024
|
|
24
|
+
MLRUN_LABEL_PREFIX = "mlrun/"
|
|
25
|
+
DASK_LABEL_PREFIX = "dask.org/"
|
|
26
|
+
NUCLIO_LABEL_PREFIX = "nuclio.io/"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MLRunInternalLabels:
|
|
30
|
+
### dask
|
|
31
|
+
dask_cluster_name = f"{DASK_LABEL_PREFIX}cluster-name"
|
|
32
|
+
dask_component = f"{DASK_LABEL_PREFIX}component"
|
|
33
|
+
|
|
34
|
+
### spark
|
|
35
|
+
spark_role = "spark-role"
|
|
36
|
+
|
|
37
|
+
### mpi
|
|
38
|
+
mpi_job_name = "mpi-job-name"
|
|
39
|
+
mpi_job_role = "mpi-job-role"
|
|
40
|
+
mpi_role_type = "mpi_role_type"
|
|
41
|
+
|
|
42
|
+
### nuclio
|
|
43
|
+
nuclio_project_name = f"{NUCLIO_LABEL_PREFIX}project-name"
|
|
44
|
+
nuclio_function_name = f"{NUCLIO_LABEL_PREFIX}function-name"
|
|
45
|
+
nuclio_class = f"{NUCLIO_LABEL_PREFIX}class"
|
|
46
|
+
|
|
47
|
+
### mlrun
|
|
48
|
+
mlrun_auth_key = "mlrun-auth-key"
|
|
49
|
+
mlrun_class = f"{MLRUN_LABEL_PREFIX}class"
|
|
50
|
+
client_python_version = f"{MLRUN_LABEL_PREFIX}client_python_version"
|
|
51
|
+
client_version = f"{MLRUN_LABEL_PREFIX}client_version"
|
|
52
|
+
function = f"{MLRUN_LABEL_PREFIX}function"
|
|
53
|
+
job = f"{MLRUN_LABEL_PREFIX}job"
|
|
54
|
+
name = f"{MLRUN_LABEL_PREFIX}name"
|
|
55
|
+
mlrun_owner = f"{MLRUN_LABEL_PREFIX}owner"
|
|
56
|
+
owner_domain = f"{MLRUN_LABEL_PREFIX}owner_domain"
|
|
57
|
+
project = f"{MLRUN_LABEL_PREFIX}project"
|
|
58
|
+
runner_pod = f"{MLRUN_LABEL_PREFIX}runner-pod"
|
|
59
|
+
schedule_name = f"{MLRUN_LABEL_PREFIX}schedule-name"
|
|
60
|
+
scrape_metrics = f"{MLRUN_LABEL_PREFIX}scrape-metrics"
|
|
61
|
+
tag = f"{MLRUN_LABEL_PREFIX}tag"
|
|
62
|
+
uid = f"{MLRUN_LABEL_PREFIX}uid"
|
|
63
|
+
username = f"{MLRUN_LABEL_PREFIX}username"
|
|
64
|
+
username_domain = f"{MLRUN_LABEL_PREFIX}username_domain"
|
|
65
|
+
task_name = f"{MLRUN_LABEL_PREFIX}task-name"
|
|
66
|
+
resource_name = f"{MLRUN_LABEL_PREFIX}resource_name"
|
|
67
|
+
created = f"{MLRUN_LABEL_PREFIX}created"
|
|
68
|
+
producer_type = f"{MLRUN_LABEL_PREFIX}producer-type"
|
|
69
|
+
app_name = f"{MLRUN_LABEL_PREFIX}app-name"
|
|
70
|
+
endpoint_id = f"{MLRUN_LABEL_PREFIX}endpoint-id"
|
|
71
|
+
host = "host"
|
|
72
|
+
job_type = "job-type"
|
|
73
|
+
kind = "kind"
|
|
74
|
+
component = "component"
|
|
75
|
+
mlrun_type = "mlrun__type"
|
|
76
|
+
|
|
77
|
+
owner = "owner"
|
|
78
|
+
v3io_user = "v3io_user"
|
|
79
|
+
workflow = "workflow"
|
|
80
|
+
feature_vector = "feature-vector"
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def all(cls):
|
|
84
|
+
return [
|
|
85
|
+
value
|
|
86
|
+
for key, value in cls.__dict__.items()
|
|
87
|
+
if not key.startswith("__") and isinstance(value, str)
|
|
88
|
+
]
|
mlrun/common/db/sql_session.py
CHANGED
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
#
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
from sqlalchemy import create_engine
|
|
18
17
|
from sqlalchemy.engine import Engine
|
|
19
18
|
from sqlalchemy.orm import Session
|
|
20
|
-
from sqlalchemy.orm import
|
|
19
|
+
from sqlalchemy.orm import (
|
|
20
|
+
sessionmaker as SessionMaker, # noqa: N812 - `sessionmaker` is a class
|
|
21
|
+
)
|
|
21
22
|
|
|
22
23
|
from mlrun.config import config
|
|
23
24
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2024 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
from .artifact import ArtifactFormat # noqa
|
|
17
|
+
from .function import FunctionFormat # noqa
|
|
18
|
+
from .pipeline import PipelineFormat # noqa
|
|
19
|
+
from .project import ProjectFormat # noqa
|
|
20
|
+
from .run import RunFormat # noqa
|
|
21
|
+
from .feature_set import FeatureSetFormat # noqa
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright 2024 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
import typing
|
|
17
|
+
|
|
18
|
+
import mlrun.common.types
|
|
19
|
+
|
|
20
|
+
from .base import ObjectFormat
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ArtifactFormat(ObjectFormat, mlrun.common.types.StrEnum):
|
|
24
|
+
full = "full"
|
|
25
|
+
minimal = "minimal"
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def format_method(_format: str) -> typing.Optional[typing.Callable]:
|
|
29
|
+
return {
|
|
30
|
+
ArtifactFormat.full: None,
|
|
31
|
+
ArtifactFormat.minimal: ArtifactFormat.filter_obj_method(
|
|
32
|
+
[
|
|
33
|
+
"kind",
|
|
34
|
+
"metadata",
|
|
35
|
+
"status",
|
|
36
|
+
"project",
|
|
37
|
+
"spec.producer",
|
|
38
|
+
"spec.db_key",
|
|
39
|
+
"spec.size",
|
|
40
|
+
"spec.framework",
|
|
41
|
+
"spec.algorithm",
|
|
42
|
+
"spec.metrics",
|
|
43
|
+
"spec.target_path",
|
|
44
|
+
]
|
|
45
|
+
),
|
|
46
|
+
}[_format]
|