mlrun 1.6.4rc2__py3-none-any.whl → 1.7.0rc20__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 (291) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +26 -112
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +5 -4
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +46 -257
  8. mlrun/artifacts/dataset.py +11 -192
  9. mlrun/artifacts/manager.py +47 -48
  10. mlrun/artifacts/model.py +31 -159
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +69 -0
  13. mlrun/common/db/sql_session.py +2 -3
  14. mlrun/common/formatters/__init__.py +19 -0
  15. mlrun/common/formatters/artifact.py +21 -0
  16. mlrun/common/formatters/base.py +78 -0
  17. mlrun/common/formatters/function.py +41 -0
  18. mlrun/common/formatters/pipeline.py +53 -0
  19. mlrun/common/formatters/project.py +51 -0
  20. mlrun/common/helpers.py +1 -2
  21. mlrun/common/model_monitoring/helpers.py +9 -5
  22. mlrun/{runtimes → common/runtimes}/constants.py +37 -9
  23. mlrun/common/schemas/__init__.py +24 -4
  24. mlrun/common/schemas/alert.py +203 -0
  25. mlrun/common/schemas/api_gateway.py +148 -0
  26. mlrun/common/schemas/artifact.py +18 -8
  27. mlrun/common/schemas/auth.py +11 -5
  28. mlrun/common/schemas/background_task.py +1 -1
  29. mlrun/common/schemas/client_spec.py +4 -1
  30. mlrun/common/schemas/feature_store.py +16 -16
  31. mlrun/common/schemas/frontend_spec.py +8 -7
  32. mlrun/common/schemas/function.py +5 -1
  33. mlrun/common/schemas/hub.py +11 -18
  34. mlrun/common/schemas/memory_reports.py +2 -2
  35. mlrun/common/schemas/model_monitoring/__init__.py +18 -3
  36. mlrun/common/schemas/model_monitoring/constants.py +83 -26
  37. mlrun/common/schemas/model_monitoring/grafana.py +13 -9
  38. mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
  39. mlrun/common/schemas/notification.py +4 -4
  40. mlrun/common/schemas/object.py +2 -2
  41. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  42. mlrun/common/schemas/pipeline.py +1 -10
  43. mlrun/common/schemas/project.py +24 -23
  44. mlrun/common/schemas/runtime_resource.py +8 -12
  45. mlrun/common/schemas/schedule.py +3 -3
  46. mlrun/common/schemas/tag.py +1 -2
  47. mlrun/common/schemas/workflow.py +2 -2
  48. mlrun/common/types.py +7 -1
  49. mlrun/config.py +54 -17
  50. mlrun/data_types/to_pandas.py +10 -12
  51. mlrun/datastore/__init__.py +5 -8
  52. mlrun/datastore/alibaba_oss.py +130 -0
  53. mlrun/datastore/azure_blob.py +17 -5
  54. mlrun/datastore/base.py +62 -39
  55. mlrun/datastore/datastore.py +28 -9
  56. mlrun/datastore/datastore_profile.py +146 -20
  57. mlrun/datastore/filestore.py +0 -1
  58. mlrun/datastore/google_cloud_storage.py +6 -2
  59. mlrun/datastore/hdfs.py +56 -0
  60. mlrun/datastore/inmem.py +2 -2
  61. mlrun/datastore/redis.py +6 -2
  62. mlrun/datastore/s3.py +9 -0
  63. mlrun/datastore/snowflake_utils.py +43 -0
  64. mlrun/datastore/sources.py +201 -96
  65. mlrun/datastore/spark_utils.py +1 -2
  66. mlrun/datastore/store_resources.py +7 -7
  67. mlrun/datastore/targets.py +358 -104
  68. mlrun/datastore/utils.py +72 -58
  69. mlrun/datastore/v3io.py +5 -1
  70. mlrun/db/base.py +185 -35
  71. mlrun/db/factory.py +1 -1
  72. mlrun/db/httpdb.py +614 -179
  73. mlrun/db/nopdb.py +210 -26
  74. mlrun/errors.py +12 -1
  75. mlrun/execution.py +41 -24
  76. mlrun/feature_store/__init__.py +0 -2
  77. mlrun/feature_store/api.py +40 -72
  78. mlrun/feature_store/common.py +1 -1
  79. mlrun/feature_store/feature_set.py +76 -55
  80. mlrun/feature_store/feature_vector.py +28 -30
  81. mlrun/feature_store/ingestion.py +7 -6
  82. mlrun/feature_store/retrieval/base.py +16 -11
  83. mlrun/feature_store/retrieval/conversion.py +11 -13
  84. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  85. mlrun/feature_store/retrieval/job.py +9 -3
  86. mlrun/feature_store/retrieval/local_merger.py +2 -0
  87. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  88. mlrun/feature_store/steps.py +37 -34
  89. mlrun/features.py +9 -20
  90. mlrun/frameworks/_common/artifacts_library.py +9 -9
  91. mlrun/frameworks/_common/mlrun_interface.py +5 -5
  92. mlrun/frameworks/_common/model_handler.py +48 -48
  93. mlrun/frameworks/_common/plan.py +2 -3
  94. mlrun/frameworks/_common/producer.py +3 -4
  95. mlrun/frameworks/_common/utils.py +5 -5
  96. mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
  97. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
  98. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
  99. mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
  100. mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
  101. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
  102. mlrun/frameworks/_ml_common/model_handler.py +24 -24
  103. mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
  104. mlrun/frameworks/_ml_common/plan.py +1 -1
  105. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
  106. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
  107. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  108. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
  109. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  110. mlrun/frameworks/_ml_common/utils.py +4 -4
  111. mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
  112. mlrun/frameworks/huggingface/model_server.py +4 -4
  113. mlrun/frameworks/lgbm/__init__.py +33 -33
  114. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  115. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
  116. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
  117. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
  118. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
  119. mlrun/frameworks/lgbm/model_handler.py +10 -10
  120. mlrun/frameworks/lgbm/model_server.py +6 -6
  121. mlrun/frameworks/lgbm/utils.py +5 -5
  122. mlrun/frameworks/onnx/dataset.py +8 -8
  123. mlrun/frameworks/onnx/mlrun_interface.py +3 -3
  124. mlrun/frameworks/onnx/model_handler.py +6 -6
  125. mlrun/frameworks/onnx/model_server.py +7 -7
  126. mlrun/frameworks/parallel_coordinates.py +4 -3
  127. mlrun/frameworks/pytorch/__init__.py +18 -18
  128. mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
  129. mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
  130. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
  131. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
  132. mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
  133. mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
  134. mlrun/frameworks/pytorch/model_handler.py +17 -17
  135. mlrun/frameworks/pytorch/model_server.py +7 -7
  136. mlrun/frameworks/sklearn/__init__.py +13 -13
  137. mlrun/frameworks/sklearn/estimator.py +4 -4
  138. mlrun/frameworks/sklearn/metrics_library.py +14 -14
  139. mlrun/frameworks/sklearn/mlrun_interface.py +3 -6
  140. mlrun/frameworks/sklearn/model_handler.py +2 -2
  141. mlrun/frameworks/tf_keras/__init__.py +10 -7
  142. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
  143. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
  144. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
  145. mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
  146. mlrun/frameworks/tf_keras/model_handler.py +14 -14
  147. mlrun/frameworks/tf_keras/model_server.py +6 -6
  148. mlrun/frameworks/xgboost/__init__.py +13 -13
  149. mlrun/frameworks/xgboost/model_handler.py +6 -6
  150. mlrun/k8s_utils.py +14 -16
  151. mlrun/launcher/__init__.py +1 -1
  152. mlrun/launcher/base.py +16 -15
  153. mlrun/launcher/client.py +8 -6
  154. mlrun/launcher/factory.py +1 -1
  155. mlrun/launcher/local.py +17 -11
  156. mlrun/launcher/remote.py +16 -10
  157. mlrun/lists.py +7 -6
  158. mlrun/model.py +238 -73
  159. mlrun/model_monitoring/__init__.py +1 -1
  160. mlrun/model_monitoring/api.py +138 -315
  161. mlrun/model_monitoring/application.py +5 -296
  162. mlrun/model_monitoring/applications/__init__.py +24 -0
  163. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  164. mlrun/model_monitoring/applications/base.py +282 -0
  165. mlrun/model_monitoring/applications/context.py +214 -0
  166. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  167. mlrun/model_monitoring/applications/histogram_data_drift.py +349 -0
  168. mlrun/model_monitoring/applications/results.py +99 -0
  169. mlrun/model_monitoring/controller.py +104 -84
  170. mlrun/model_monitoring/controller_handler.py +13 -5
  171. mlrun/model_monitoring/db/__init__.py +18 -0
  172. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  173. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  174. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +64 -40
  175. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  176. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  177. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  178. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  179. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  180. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  181. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  182. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +310 -165
  183. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  184. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  185. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  186. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  187. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  188. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  189. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  190. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  191. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  192. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  193. mlrun/model_monitoring/evidently_application.py +6 -118
  194. mlrun/model_monitoring/features_drift_table.py +134 -106
  195. mlrun/model_monitoring/helpers.py +127 -28
  196. mlrun/model_monitoring/metrics/__init__.py +13 -0
  197. mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
  198. mlrun/model_monitoring/model_endpoint.py +3 -2
  199. mlrun/model_monitoring/prometheus.py +1 -4
  200. mlrun/model_monitoring/stream_processing.py +62 -231
  201. mlrun/model_monitoring/tracking_policy.py +9 -2
  202. mlrun/model_monitoring/writer.py +152 -124
  203. mlrun/package/__init__.py +6 -6
  204. mlrun/package/context_handler.py +5 -5
  205. mlrun/package/packager.py +7 -7
  206. mlrun/package/packagers/default_packager.py +6 -6
  207. mlrun/package/packagers/numpy_packagers.py +15 -15
  208. mlrun/package/packagers/pandas_packagers.py +5 -5
  209. mlrun/package/packagers/python_standard_library_packagers.py +10 -10
  210. mlrun/package/packagers_manager.py +19 -23
  211. mlrun/package/utils/_formatter.py +6 -6
  212. mlrun/package/utils/_pickler.py +2 -2
  213. mlrun/package/utils/_supported_format.py +4 -4
  214. mlrun/package/utils/log_hint_utils.py +2 -2
  215. mlrun/package/utils/type_hint_utils.py +4 -9
  216. mlrun/platforms/__init__.py +11 -10
  217. mlrun/platforms/iguazio.py +24 -203
  218. mlrun/projects/operations.py +35 -21
  219. mlrun/projects/pipelines.py +68 -99
  220. mlrun/projects/project.py +830 -266
  221. mlrun/render.py +3 -11
  222. mlrun/run.py +162 -166
  223. mlrun/runtimes/__init__.py +62 -7
  224. mlrun/runtimes/base.py +39 -32
  225. mlrun/runtimes/daskjob.py +8 -8
  226. mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
  227. mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
  228. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  229. mlrun/runtimes/funcdoc.py +0 -28
  230. mlrun/runtimes/function_reference.py +1 -1
  231. mlrun/runtimes/kubejob.py +28 -122
  232. mlrun/runtimes/local.py +6 -3
  233. mlrun/runtimes/mpijob/__init__.py +0 -20
  234. mlrun/runtimes/mpijob/abstract.py +9 -10
  235. mlrun/runtimes/mpijob/v1.py +1 -1
  236. mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
  237. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  238. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  239. mlrun/runtimes/nuclio/application/application.py +523 -0
  240. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  241. mlrun/runtimes/{function.py → nuclio/function.py} +112 -73
  242. mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
  243. mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
  244. mlrun/runtimes/pod.py +286 -88
  245. mlrun/runtimes/remotesparkjob.py +2 -2
  246. mlrun/runtimes/sparkjob/spark3job.py +51 -34
  247. mlrun/runtimes/utils.py +7 -75
  248. mlrun/secrets.py +9 -5
  249. mlrun/serving/remote.py +2 -7
  250. mlrun/serving/routers.py +13 -10
  251. mlrun/serving/server.py +22 -26
  252. mlrun/serving/states.py +99 -25
  253. mlrun/serving/utils.py +3 -3
  254. mlrun/serving/v1_serving.py +6 -7
  255. mlrun/serving/v2_serving.py +59 -20
  256. mlrun/track/tracker.py +2 -1
  257. mlrun/track/tracker_manager.py +3 -3
  258. mlrun/track/trackers/mlflow_tracker.py +1 -2
  259. mlrun/utils/async_http.py +5 -7
  260. mlrun/utils/azure_vault.py +1 -1
  261. mlrun/utils/clones.py +1 -2
  262. mlrun/utils/condition_evaluator.py +3 -3
  263. mlrun/utils/db.py +3 -3
  264. mlrun/utils/helpers.py +183 -197
  265. mlrun/utils/http.py +2 -5
  266. mlrun/utils/logger.py +76 -14
  267. mlrun/utils/notifications/notification/__init__.py +17 -12
  268. mlrun/utils/notifications/notification/base.py +14 -2
  269. mlrun/utils/notifications/notification/console.py +2 -0
  270. mlrun/utils/notifications/notification/git.py +3 -1
  271. mlrun/utils/notifications/notification/ipython.py +3 -1
  272. mlrun/utils/notifications/notification/slack.py +101 -21
  273. mlrun/utils/notifications/notification/webhook.py +11 -1
  274. mlrun/utils/notifications/notification_pusher.py +155 -30
  275. mlrun/utils/retryer.py +208 -0
  276. mlrun/utils/singleton.py +1 -1
  277. mlrun/utils/v3io_clients.py +2 -4
  278. mlrun/utils/version/version.json +2 -2
  279. mlrun/utils/version/version.py +2 -6
  280. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
  281. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  282. mlrun/kfpops.py +0 -868
  283. mlrun/model_monitoring/batch.py +0 -1095
  284. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  285. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
  286. mlrun/platforms/other.py +0 -306
  287. mlrun-1.6.4rc2.dist-info/RECORD +0 -314
  288. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  289. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
  290. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  291. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
@@ -16,11 +16,15 @@ import typing
16
16
  from os.path import exists, isdir
17
17
  from urllib.parse import urlparse
18
18
 
19
+ import mlrun.common.schemas.artifact
19
20
  import mlrun.config
20
- from mlrun.utils.helpers import get_local_file_schema, template_artifact_path
21
+ from mlrun.utils.helpers import (
22
+ get_local_file_schema,
23
+ template_artifact_path,
24
+ validate_inline_artifact_body_size,
25
+ )
21
26
 
22
27
  from ..utils import (
23
- is_legacy_artifact,
24
28
  is_relative_path,
25
29
  logger,
26
30
  validate_artifact_key_name,
@@ -29,56 +33,28 @@ from ..utils import (
29
33
  from .base import (
30
34
  Artifact,
31
35
  DirArtifact,
32
- LegacyArtifact,
33
- LegacyDirArtifact,
34
- LegacyLinkArtifact,
35
36
  LinkArtifact,
36
37
  )
37
38
  from .dataset import (
38
39
  DatasetArtifact,
39
- LegacyDatasetArtifact,
40
- LegacyTableArtifact,
41
40
  TableArtifact,
42
41
  )
43
- from .model import LegacyModelArtifact, ModelArtifact
42
+ from .model import ModelArtifact
44
43
  from .plots import (
45
- BokehArtifact,
46
- ChartArtifact,
47
- LegacyBokehArtifact,
48
- LegacyChartArtifact,
49
- LegacyPlotArtifact,
50
- LegacyPlotlyArtifact,
51
44
  PlotArtifact,
52
45
  PlotlyArtifact,
53
46
  )
54
47
 
55
- # TODO - Remove deprecated types when deleted in 1.7.0
56
48
  artifact_types = {
57
49
  "": Artifact,
58
50
  "artifact": Artifact,
59
51
  "dir": DirArtifact,
60
52
  "link": LinkArtifact,
61
53
  "plot": PlotArtifact,
62
- "chart": ChartArtifact,
63
54
  "table": TableArtifact,
64
55
  "model": ModelArtifact,
65
56
  "dataset": DatasetArtifact,
66
57
  "plotly": PlotlyArtifact,
67
- "bokeh": BokehArtifact,
68
- }
69
-
70
- # TODO - Remove this when legacy types are deleted in 1.7.0
71
- legacy_artifact_types = {
72
- "": LegacyArtifact,
73
- "dir": LegacyDirArtifact,
74
- "link": LegacyLinkArtifact,
75
- "plot": LegacyPlotArtifact,
76
- "chart": LegacyChartArtifact,
77
- "table": LegacyTableArtifact,
78
- "model": LegacyModelArtifact,
79
- "dataset": LegacyDatasetArtifact,
80
- "plotly": LegacyPlotlyArtifact,
81
- "bokeh": LegacyBokehArtifact,
82
58
  }
83
59
 
84
60
 
@@ -96,17 +72,14 @@ class ArtifactProducer:
96
72
  def get_meta(self) -> dict:
97
73
  return {"kind": self.kind, "name": self.name, "tag": self.tag}
98
74
 
75
+ @property
76
+ def uid(self):
77
+ return None
78
+
99
79
 
100
80
  def dict_to_artifact(struct: dict) -> Artifact:
101
- # Need to distinguish between LegacyArtifact classes and Artifact classes. Use existence of the "metadata"
102
- # property to make this distinction
103
81
  kind = struct.get("kind", "")
104
-
105
- if is_legacy_artifact(struct):
106
- return mlrun.artifacts.base.convert_legacy_artifact_to_new_format(struct)
107
-
108
82
  artifact_class = artifact_types[kind]
109
-
110
83
  return artifact_class.from_dict(struct)
111
84
 
112
85
 
@@ -176,11 +149,13 @@ class ArtifactManager:
176
149
  upload=None,
177
150
  labels=None,
178
151
  db_key=None,
152
+ project=None,
153
+ is_retained_producer=None,
179
154
  **kwargs,
180
155
  ) -> Artifact:
181
156
  """
182
157
  Log an artifact to the DB and upload it to the artifact store.
183
- :param producer: The producer of the artifact, the producer depends from where the artifact is being logged.
158
+ :param producer: The producer of the artifact, the producer depends on where the artifact is being logged.
184
159
  :param item: The artifact to log.
185
160
  :param body: The body of the artifact.
186
161
  :param target_path: The target path of the artifact. (cannot be a relative path)
@@ -198,6 +173,9 @@ class ArtifactManager:
198
173
  :param labels: Labels to add to the artifact.
199
174
  :param db_key: The key to use when logging the artifact to the DB.
200
175
  If not provided, will generate a key based on the producer name and the artifact key.
176
+ :param project: The project to log the artifact to. If not provided, will use the producer's project.
177
+ :param is_retained_producer: Whether the producer is retained or not. Relevant to register artifacts flow
178
+ where a project may log artifacts which were produced by another producer.
201
179
  :param kwargs: Arguments to pass to the artifact class.
202
180
  :return: The logged artifact.
203
181
  """
@@ -212,6 +190,7 @@ class ArtifactManager:
212
190
  target_path = target_path or item.target_path
213
191
 
214
192
  validate_artifact_key_name(key, "artifact.key")
193
+ validate_inline_artifact_body_size(item.spec.inline)
215
194
  src_path = local_path or item.src_path # TODO: remove src_path
216
195
  self.ensure_artifact_source_file_exists(item=item, path=src_path, body=body)
217
196
  if format == "html" or (src_path and pathlib.Path(src_path).suffix == "html"):
@@ -221,7 +200,7 @@ class ArtifactManager:
221
200
 
222
201
  if db_key is None:
223
202
  # set the default artifact db key
224
- if producer.kind == "run":
203
+ if producer.kind == "run" and not is_retained_producer:
225
204
  # When the producer's type is "run,"
226
205
  # we generate a different db_key than the one we obtained in the request.
227
206
  # As a result, a new artifact for the requested key will be created,
@@ -246,8 +225,11 @@ class ArtifactManager:
246
225
  item.labels.update({"workflow-id": item.producer.get("workflow")})
247
226
 
248
227
  item.iter = producer.iteration
249
- project = producer.project
228
+ project = project or producer.project
250
229
  item.project = project
230
+ if is_retained_producer:
231
+ # if the producer is retained, we want to use the original target path
232
+ target_path = target_path or item.target_path
251
233
 
252
234
  # if target_path is provided and not relative, then no need to upload the artifact as it already exists
253
235
  if target_path:
@@ -255,7 +237,8 @@ class ArtifactManager:
255
237
  raise ValueError(
256
238
  f"target_path ({target_path}) param cannot be relative"
257
239
  )
258
- upload = False
240
+ if upload is None:
241
+ upload = False
259
242
 
260
243
  # if target_path wasn't provided, but src_path is not relative, then no need to upload the artifact as it
261
244
  # already exists. In this case set the target_path to the src_path and set upload to False
@@ -282,7 +265,9 @@ class ArtifactManager:
282
265
 
283
266
  if target_path and item.is_dir and not target_path.endswith("/"):
284
267
  target_path += "/"
285
- target_path = template_artifact_path(artifact_path=target_path, project=project)
268
+ target_path = template_artifact_path(
269
+ artifact_path=target_path, project=producer.project, run_uid=producer.uid
270
+ )
286
271
  item.target_path = target_path
287
272
 
288
273
  item.before_log()
@@ -292,13 +277,10 @@ class ArtifactManager:
292
277
  # before uploading the item, we want to ensure that its tags are valid,
293
278
  # so that we don't upload something that won't be stored later
294
279
  validate_tag_name(item.metadata.tag, "artifact.metadata.tag")
295
- if is_legacy_artifact(item):
296
- item.upload()
297
- else:
298
- item.upload(artifact_path=artifact_path)
280
+ item.upload(artifact_path=artifact_path)
299
281
 
300
282
  if db_key:
301
- self._log_to_db(db_key, producer.project, producer.inputs, item)
283
+ self._log_to_db(db_key, project, producer.inputs, item)
302
284
  size = str(item.size) or "?"
303
285
  db_str = "Y" if (self.artifact_db and db_key) else "N"
304
286
  logger.debug(
@@ -366,6 +348,23 @@ class ArtifactManager:
366
348
  project=project,
367
349
  )
368
350
 
351
+ def delete_artifact(
352
+ self,
353
+ item: Artifact,
354
+ deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
355
+ mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
356
+ ),
357
+ secrets: dict = None,
358
+ ):
359
+ self.artifact_db.del_artifact(
360
+ key=item.db_key,
361
+ project=item.project,
362
+ tag=item.tag,
363
+ tree=item.tree,
364
+ deletion_strategy=deletion_strategy,
365
+ secrets=secrets,
366
+ )
367
+
369
368
 
370
369
  def extend_artifact_path(artifact_path: str, default_artifact_path: str):
371
370
  artifact_path = str(artifact_path or "")
mlrun/artifacts/model.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
+
14
15
  import tempfile
16
+ import warnings
15
17
  from os import path
16
- from typing import Any
18
+ from typing import Any, Optional
17
19
 
18
20
  import pandas as pd
19
21
  import yaml
20
- from deprecated import deprecated
21
22
 
22
23
  import mlrun
23
24
  import mlrun.datastore
@@ -26,7 +27,7 @@ from ..data_types import InferOptions, get_infer_interface
26
27
  from ..features import Feature
27
28
  from ..model import ObjectList
28
29
  from ..utils import StorePrefix, is_relative_path
29
- from .base import Artifact, ArtifactSpec, LegacyArtifact, upload_extra_data
30
+ from .base import Artifact, ArtifactSpec, upload_extra_data
30
31
 
31
32
  model_spec_filename = "model_spec.yaml"
32
33
 
@@ -69,8 +70,8 @@ class ModelArtifactSpec(ArtifactSpec):
69
70
  model_file=None,
70
71
  metrics=None,
71
72
  paraemeters=None,
72
- inputs: list[Feature] = None,
73
- outputs: list[Feature] = None,
73
+ inputs: Optional[list[Feature]] = None,
74
+ outputs: Optional[list[Feature]] = None,
74
75
  framework=None,
75
76
  algorithm=None,
76
77
  feature_vector=None,
@@ -92,8 +93,8 @@ class ModelArtifactSpec(ArtifactSpec):
92
93
  self.model_file = model_file
93
94
  self.metrics = metrics or {}
94
95
  self.parameters = paraemeters or {}
95
- self.inputs: list[Feature] = inputs or []
96
- self.outputs: list[Feature] = outputs or []
96
+ self.inputs = inputs or []
97
+ self.outputs = outputs or []
97
98
  self.framework = framework
98
99
  self.algorithm = algorithm
99
100
  self.feature_vector = feature_vector
@@ -102,21 +103,21 @@ class ModelArtifactSpec(ArtifactSpec):
102
103
  self.model_target_file = model_target_file
103
104
 
104
105
  @property
105
- def inputs(self) -> list[Feature]:
106
+ def inputs(self) -> ObjectList:
106
107
  """input feature list"""
107
108
  return self._inputs
108
109
 
109
110
  @inputs.setter
110
- def inputs(self, inputs: list[Feature]):
111
+ def inputs(self, inputs: list[Feature]) -> None:
111
112
  self._inputs = ObjectList.from_list(Feature, inputs)
112
113
 
113
114
  @property
114
- def outputs(self) -> list[Feature]:
115
+ def outputs(self) -> ObjectList:
115
116
  """output feature list"""
116
117
  return self._outputs
117
118
 
118
119
  @outputs.setter
119
- def outputs(self, outputs: list[Feature]):
120
+ def outputs(self, outputs: list[Feature]) -> None:
120
121
  self._outputs = ObjectList.from_list(Feature, outputs)
121
122
 
122
123
 
@@ -148,6 +149,12 @@ class ModelArtifact(Artifact):
148
149
  model_dir=None,
149
150
  **kwargs,
150
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
+ )
151
158
  super().__init__(key, body, format=format, target_path=target_path, **kwargs)
152
159
  model_file = str(model_file or "")
153
160
  if model_file and "/" in model_file:
@@ -176,22 +183,22 @@ class ModelArtifact(Artifact):
176
183
  self._spec = self._verify_dict(spec, "spec", ModelArtifactSpec)
177
184
 
178
185
  @property
179
- def inputs(self) -> list[Feature]:
186
+ def inputs(self) -> ObjectList:
180
187
  """input feature list"""
181
188
  return self.spec.inputs
182
189
 
183
190
  @inputs.setter
184
- def inputs(self, inputs: list[Feature]):
191
+ def inputs(self, inputs: list[Feature]) -> None:
185
192
  """input feature list"""
186
193
  self.spec.inputs = inputs
187
194
 
188
195
  @property
189
- def outputs(self) -> list[Feature]:
196
+ def outputs(self) -> ObjectList:
190
197
  """input feature list"""
191
198
  return self.spec.outputs
192
199
 
193
200
  @outputs.setter
194
- def outputs(self, outputs: list[Feature]):
201
+ def outputs(self, outputs: list[Feature]) -> None:
195
202
  """input feature list"""
196
203
  self.spec.outputs = outputs
197
204
 
@@ -290,7 +297,7 @@ class ModelArtifact(Artifact):
290
297
  if not self.spec.model_file:
291
298
  raise ValueError("model_file attr must be specified")
292
299
 
293
- super(ModelArtifact, self).before_log()
300
+ super().before_log()
294
301
 
295
302
  if self.spec.framework:
296
303
  self.metadata.labels = self.metadata.labels or {}
@@ -396,144 +403,6 @@ class ModelArtifact(Artifact):
396
403
  return mlrun.get_dataitem(target_model_path).get()
397
404
 
398
405
 
399
- # TODO: remove in 1.7.0
400
- @deprecated(
401
- version="1.3.0",
402
- reason="'LegacyModelArtifact' will be removed in 1.7.0, use 'ModelArtifact' instead",
403
- category=FutureWarning,
404
- )
405
- class LegacyModelArtifact(LegacyArtifact):
406
- """ML Model artifact
407
-
408
- Store link to ML model file(s) along with the model metrics, parameters, schema, and stats
409
- """
410
-
411
- _dict_fields = LegacyArtifact._dict_fields + [
412
- "model_file",
413
- "metrics",
414
- "parameters",
415
- "inputs",
416
- "outputs",
417
- "framework",
418
- "algorithm",
419
- "extra_data",
420
- "feature_vector",
421
- "feature_weights",
422
- "feature_stats",
423
- "model_target_file",
424
- ]
425
- kind = "model"
426
- _store_prefix = StorePrefix.Model
427
-
428
- def __init__(
429
- self,
430
- key=None,
431
- body=None,
432
- format=None,
433
- model_file=None,
434
- metrics=None,
435
- target_path=None,
436
- parameters=None,
437
- inputs=None,
438
- outputs=None,
439
- framework=None,
440
- algorithm=None,
441
- feature_vector=None,
442
- feature_weights=None,
443
- extra_data=None,
444
- model_target_file=None,
445
- **kwargs,
446
- ):
447
- super().__init__(key, body, format=format, target_path=target_path, **kwargs)
448
- self._inputs: ObjectList = None
449
- self._outputs: ObjectList = None
450
-
451
- self.model_file = model_file
452
- self.parameters = parameters or {}
453
- self.metrics = metrics or {}
454
- self.inputs: list[Feature] = inputs or []
455
- self.outputs: list[Feature] = outputs or []
456
- self.extra_data = extra_data or {}
457
- self.framework = framework
458
- self.algorithm = algorithm
459
- self.feature_vector = feature_vector
460
- self.feature_weights = feature_weights
461
- self.feature_stats = None
462
- self.model_target_file = model_target_file
463
-
464
- @property
465
- def inputs(self) -> list[Feature]:
466
- """input feature list"""
467
- return self._inputs
468
-
469
- @inputs.setter
470
- def inputs(self, inputs: list[Feature]):
471
- self._inputs = ObjectList.from_list(Feature, inputs)
472
-
473
- @property
474
- def outputs(self) -> list[Feature]:
475
- """output feature list"""
476
- return self._outputs
477
-
478
- @outputs.setter
479
- def outputs(self, outputs: list[Feature]):
480
- self._outputs = ObjectList.from_list(Feature, outputs)
481
-
482
- def infer_from_df(self, df, label_columns=None, with_stats=True, num_bins=None):
483
- """infer inputs, outputs, and stats from provided df (training set)
484
-
485
- :param df: dataframe to infer from
486
- :param label_columns: name of the label (target) column
487
- :param with_stats: infer statistics (min, max, .. histogram)
488
- :param num_bins: number of bins for histogram
489
- """
490
- subset = df
491
- inferer = get_infer_interface(subset)
492
- if label_columns:
493
- if not isinstance(label_columns, list):
494
- label_columns = [label_columns]
495
- subset = df.drop(columns=label_columns)
496
- inferer.infer_schema(subset, self.inputs, {}, options=InferOptions.Features)
497
- if label_columns:
498
- inferer.infer_schema(
499
- df[label_columns], self.outputs, {}, options=InferOptions.Features
500
- )
501
- if with_stats:
502
- self.feature_stats = inferer.get_stats(
503
- df, options=InferOptions.Histogram, num_bins=num_bins
504
- )
505
-
506
- @property
507
- def is_dir(self):
508
- return True
509
-
510
- def before_log(self):
511
- if not self.model_file:
512
- raise ValueError("model_file attr must be specified")
513
-
514
- super(LegacyModelArtifact, self).before_log()
515
-
516
- if self.framework:
517
- self.labels = self.labels or {}
518
- self.labels["framework"] = self.framework
519
-
520
- def upload(self):
521
- target_model_path = path.join(self.target_path, self.model_file)
522
- body = self.get_body()
523
- if body:
524
- self._upload_body(body, target=target_model_path)
525
- else:
526
- src_model_path = _get_src_path(self, self.model_file)
527
- if not path.isfile(src_model_path):
528
- raise ValueError(f"model file {src_model_path} not found")
529
- self._upload_file(src_model_path, target=target_model_path)
530
-
531
- upload_extra_data(self, self.extra_data)
532
-
533
- spec_path = path.join(self.target_path, model_spec_filename)
534
- mlrun.datastore.store_manager.object(url=spec_path).put(self.to_yaml())
535
-
536
-
537
406
  def _get_src_path(model_spec: ModelArtifact, filename):
538
407
  if model_spec.src_path:
539
408
  return path.join(model_spec.src_path, filename)
@@ -552,9 +421,9 @@ def get_model(model_dir, suffix=""):
552
421
 
553
422
  example::
554
423
 
555
- model_file, model_artifact, extra_data = get_model(models_path, suffix='.pkl')
424
+ model_file, model_artifact, extra_data = get_model(models_path, suffix=".pkl")
556
425
  model = load(open(model_file, "rb"))
557
- categories = extra_data['categories'].as_df()
426
+ categories = extra_data["categories"].as_df()
558
427
 
559
428
  :param model_dir: model dir or artifact path (store://..) or DataItem
560
429
  :param suffix: model filename suffix (when using a dir)
@@ -640,7 +509,7 @@ def _get_extra(target, extra_data, is_dir=False):
640
509
  def _remove_tag_from_spec_yaml(model_spec):
641
510
  spec_dict = model_spec.to_dict()
642
511
  spec_dict["metadata"].pop("tag", None)
643
- return yaml.dump(spec_dict)
512
+ return yaml.safe_dump(spec_dict)
644
513
 
645
514
 
646
515
  def update_model(
@@ -663,8 +532,11 @@ def update_model(
663
532
 
664
533
  example::
665
534
 
666
- update_model(model_path, metrics={'speed': 100},
667
- extra_data={'my_data': b'some text', 'file': 's3://mybucket/..'})
535
+ update_model(
536
+ model_path,
537
+ metrics={"speed": 100},
538
+ extra_data={"my_data": b"some text", "file": "s3://mybucket/.."},
539
+ )
668
540
 
669
541
  :param model_artifact: model artifact object or path (store://..) or DataItem
670
542
  :param parameters: parameters dict