mlrun 1.7.0rc4__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 (200) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +25 -111
  3. mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +4 -3
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +38 -254
  8. mlrun/artifacts/dataset.py +9 -190
  9. mlrun/artifacts/manager.py +41 -47
  10. mlrun/artifacts/model.py +30 -158
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +68 -0
  13. mlrun/common/formatters/__init__.py +19 -0
  14. mlrun/{model_monitoring/stores/models/sqlite.py → common/formatters/artifact.py} +6 -8
  15. mlrun/common/formatters/base.py +78 -0
  16. mlrun/common/formatters/function.py +41 -0
  17. mlrun/common/formatters/pipeline.py +53 -0
  18. mlrun/common/formatters/project.py +51 -0
  19. mlrun/{runtimes → common/runtimes}/constants.py +32 -4
  20. mlrun/common/schemas/__init__.py +25 -4
  21. mlrun/common/schemas/alert.py +203 -0
  22. mlrun/common/schemas/api_gateway.py +148 -0
  23. mlrun/common/schemas/artifact.py +15 -5
  24. mlrun/common/schemas/auth.py +8 -2
  25. mlrun/common/schemas/client_spec.py +2 -0
  26. mlrun/common/schemas/frontend_spec.py +1 -0
  27. mlrun/common/schemas/function.py +4 -0
  28. mlrun/common/schemas/hub.py +7 -9
  29. mlrun/common/schemas/model_monitoring/__init__.py +19 -3
  30. mlrun/common/schemas/model_monitoring/constants.py +96 -26
  31. mlrun/common/schemas/model_monitoring/grafana.py +9 -5
  32. mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
  33. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  34. mlrun/common/schemas/pipeline.py +0 -9
  35. mlrun/common/schemas/project.py +22 -21
  36. mlrun/common/types.py +7 -1
  37. mlrun/config.py +87 -19
  38. mlrun/data_types/data_types.py +4 -0
  39. mlrun/data_types/to_pandas.py +9 -9
  40. mlrun/datastore/__init__.py +5 -8
  41. mlrun/datastore/alibaba_oss.py +130 -0
  42. mlrun/datastore/azure_blob.py +4 -5
  43. mlrun/datastore/base.py +69 -30
  44. mlrun/datastore/datastore.py +10 -2
  45. mlrun/datastore/datastore_profile.py +90 -6
  46. mlrun/datastore/google_cloud_storage.py +1 -1
  47. mlrun/datastore/hdfs.py +5 -0
  48. mlrun/datastore/inmem.py +2 -2
  49. mlrun/datastore/redis.py +2 -2
  50. mlrun/datastore/s3.py +5 -0
  51. mlrun/datastore/snowflake_utils.py +43 -0
  52. mlrun/datastore/sources.py +172 -44
  53. mlrun/datastore/store_resources.py +7 -7
  54. mlrun/datastore/targets.py +285 -41
  55. mlrun/datastore/utils.py +68 -5
  56. mlrun/datastore/v3io.py +27 -50
  57. mlrun/db/auth_utils.py +152 -0
  58. mlrun/db/base.py +149 -14
  59. mlrun/db/factory.py +1 -1
  60. mlrun/db/httpdb.py +608 -178
  61. mlrun/db/nopdb.py +191 -7
  62. mlrun/errors.py +11 -0
  63. mlrun/execution.py +37 -20
  64. mlrun/feature_store/__init__.py +0 -2
  65. mlrun/feature_store/api.py +21 -52
  66. mlrun/feature_store/feature_set.py +48 -23
  67. mlrun/feature_store/feature_vector.py +2 -1
  68. mlrun/feature_store/ingestion.py +7 -6
  69. mlrun/feature_store/retrieval/base.py +9 -4
  70. mlrun/feature_store/retrieval/conversion.py +9 -9
  71. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  72. mlrun/feature_store/retrieval/job.py +9 -3
  73. mlrun/feature_store/retrieval/local_merger.py +2 -0
  74. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  75. mlrun/feature_store/steps.py +30 -19
  76. mlrun/features.py +4 -13
  77. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
  78. mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
  79. mlrun/frameworks/lgbm/__init__.py +1 -1
  80. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  81. mlrun/frameworks/lgbm/model_handler.py +1 -1
  82. mlrun/frameworks/parallel_coordinates.py +2 -1
  83. mlrun/frameworks/pytorch/__init__.py +2 -2
  84. mlrun/frameworks/sklearn/__init__.py +1 -1
  85. mlrun/frameworks/tf_keras/__init__.py +5 -2
  86. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  87. mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
  88. mlrun/frameworks/xgboost/__init__.py +1 -1
  89. mlrun/k8s_utils.py +10 -11
  90. mlrun/launcher/__init__.py +1 -1
  91. mlrun/launcher/base.py +6 -5
  92. mlrun/launcher/client.py +8 -6
  93. mlrun/launcher/factory.py +1 -1
  94. mlrun/launcher/local.py +9 -3
  95. mlrun/launcher/remote.py +9 -3
  96. mlrun/lists.py +6 -2
  97. mlrun/model.py +58 -19
  98. mlrun/model_monitoring/__init__.py +1 -1
  99. mlrun/model_monitoring/api.py +127 -301
  100. mlrun/model_monitoring/application.py +5 -296
  101. mlrun/model_monitoring/applications/__init__.py +11 -0
  102. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  103. mlrun/model_monitoring/applications/base.py +282 -0
  104. mlrun/model_monitoring/applications/context.py +214 -0
  105. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  106. mlrun/model_monitoring/applications/histogram_data_drift.py +224 -93
  107. mlrun/model_monitoring/applications/results.py +99 -0
  108. mlrun/model_monitoring/controller.py +30 -36
  109. mlrun/model_monitoring/db/__init__.py +18 -0
  110. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  111. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  112. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +58 -32
  113. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  114. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  115. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  116. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  117. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  118. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  119. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  120. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +302 -155
  121. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  122. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  123. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  124. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  125. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  126. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  127. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  128. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  129. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  130. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  131. mlrun/model_monitoring/evidently_application.py +6 -118
  132. mlrun/model_monitoring/features_drift_table.py +34 -22
  133. mlrun/model_monitoring/helpers.py +100 -7
  134. mlrun/model_monitoring/model_endpoint.py +3 -2
  135. mlrun/model_monitoring/stream_processing.py +93 -228
  136. mlrun/model_monitoring/tracking_policy.py +7 -1
  137. mlrun/model_monitoring/writer.py +152 -124
  138. mlrun/package/packagers_manager.py +1 -0
  139. mlrun/package/utils/_formatter.py +2 -2
  140. mlrun/platforms/__init__.py +11 -10
  141. mlrun/platforms/iguazio.py +21 -202
  142. mlrun/projects/operations.py +30 -16
  143. mlrun/projects/pipelines.py +92 -99
  144. mlrun/projects/project.py +757 -268
  145. mlrun/render.py +15 -14
  146. mlrun/run.py +160 -162
  147. mlrun/runtimes/__init__.py +55 -3
  148. mlrun/runtimes/base.py +33 -19
  149. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  150. mlrun/runtimes/funcdoc.py +0 -28
  151. mlrun/runtimes/kubejob.py +28 -122
  152. mlrun/runtimes/local.py +5 -2
  153. mlrun/runtimes/mpijob/__init__.py +0 -20
  154. mlrun/runtimes/mpijob/abstract.py +8 -8
  155. mlrun/runtimes/mpijob/v1.py +1 -1
  156. mlrun/runtimes/nuclio/__init__.py +1 -0
  157. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  158. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  159. mlrun/runtimes/nuclio/application/application.py +523 -0
  160. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  161. mlrun/runtimes/nuclio/function.py +98 -58
  162. mlrun/runtimes/nuclio/serving.py +36 -42
  163. mlrun/runtimes/pod.py +196 -45
  164. mlrun/runtimes/remotesparkjob.py +1 -1
  165. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  166. mlrun/runtimes/utils.py +6 -73
  167. mlrun/secrets.py +6 -2
  168. mlrun/serving/remote.py +2 -3
  169. mlrun/serving/routers.py +7 -4
  170. mlrun/serving/server.py +7 -8
  171. mlrun/serving/states.py +73 -43
  172. mlrun/serving/v2_serving.py +8 -7
  173. mlrun/track/tracker.py +2 -1
  174. mlrun/utils/async_http.py +25 -5
  175. mlrun/utils/helpers.py +141 -75
  176. mlrun/utils/http.py +1 -1
  177. mlrun/utils/logger.py +39 -7
  178. mlrun/utils/notifications/notification/__init__.py +14 -9
  179. mlrun/utils/notifications/notification/base.py +12 -0
  180. mlrun/utils/notifications/notification/console.py +2 -0
  181. mlrun/utils/notifications/notification/git.py +3 -1
  182. mlrun/utils/notifications/notification/ipython.py +2 -0
  183. mlrun/utils/notifications/notification/slack.py +101 -21
  184. mlrun/utils/notifications/notification/webhook.py +11 -1
  185. mlrun/utils/notifications/notification_pusher.py +147 -16
  186. mlrun/utils/retryer.py +3 -2
  187. mlrun/utils/v3io_clients.py +0 -1
  188. mlrun/utils/version/version.json +2 -2
  189. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +33 -18
  190. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  191. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +1 -1
  192. mlrun/kfpops.py +0 -868
  193. mlrun/model_monitoring/batch.py +0 -974
  194. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  195. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
  196. mlrun/platforms/other.py +0 -305
  197. mlrun-1.7.0rc4.dist-info/RECORD +0 -321
  198. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  199. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  200. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
@@ -363,7 +363,7 @@ class AutoMLRun:
363
363
 
364
364
  {
365
365
  "/.../custom_model.py": "MyModel",
366
- "/.../custom_objects.py": ["object1", "object2"]
366
+ "/.../custom_objects.py": ["object1", "object2"],
367
367
  }
368
368
 
369
369
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -464,7 +464,7 @@ class AutoMLRun:
464
464
 
465
465
  {
466
466
  "/.../custom_model.py": "MyModel",
467
- "/.../custom_objects.py": ["object1", "object2"]
467
+ "/.../custom_objects.py": ["object1", "object2"],
468
468
  }
469
469
 
470
470
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -241,7 +241,7 @@ def apply_mlrun(
241
241
 
242
242
  {
243
243
  "/.../custom_model.py": "MyModel",
244
- "/.../custom_objects.py": ["object1", "object2"]
244
+ "/.../custom_objects.py": ["object1", "object2"],
245
245
  }
246
246
 
247
247
  All the paths will be accessed from the given 'custom_objects_directory', meaning
@@ -63,11 +63,9 @@ class Callback(ABC):
63
63
  def on_train_end(self):
64
64
  print("{self.name}: Done training!")
65
65
 
66
+
66
67
  apply_mlrun()
67
- lgb.train(
68
- ...,
69
- callbacks=[ExampleCallback(name="Example")]
70
- )
68
+ lgb.train(..., callbacks=[ExampleCallback(name="Example")])
71
69
  """
72
70
 
73
71
  def __init__(self, order: int = 10, before_iteration: bool = False):
@@ -103,7 +103,7 @@ class LGBMModelHandler(MLModelHandler):
103
103
 
104
104
  {
105
105
  "/.../custom_model.py": "MyModel",
106
- "/.../custom_objects.py": ["object1", "object2"]
106
+ "/.../custom_objects.py": ["object1", "object2"],
107
107
  }
108
108
 
109
109
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -295,7 +295,7 @@ def compare_db_runs(
295
295
  iter=False,
296
296
  start_time_from: datetime = None,
297
297
  hide_identical: bool = True,
298
- exclude: list = [],
298
+ exclude: list = None,
299
299
  show=None,
300
300
  colorscale: str = "Blues",
301
301
  filename=None,
@@ -332,6 +332,7 @@ def compare_db_runs(
332
332
  **query_args,
333
333
  )
334
334
 
335
+ exclude = exclude or []
335
336
  runs_df = _runs_list_to_df(runs_list)
336
337
  plot_as_html = gen_pcp_plot(
337
338
  runs_df,
@@ -112,7 +112,7 @@ def train(
112
112
 
113
113
  {
114
114
  "/.../custom_optimizer.py": "optimizer",
115
- "/.../custom_layers.py": ["layer1", "layer2"]
115
+ "/.../custom_layers.py": ["layer1", "layer2"],
116
116
  }
117
117
 
118
118
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -264,7 +264,7 @@ def evaluate(
264
264
 
265
265
  {
266
266
  "/.../custom_optimizer.py": "optimizer",
267
- "/.../custom_layers.py": ["layer1", "layer2"]
267
+ "/.../custom_layers.py": ["layer1", "layer2"],
268
268
  }
269
269
 
270
270
  All the paths will be accessed from the given 'custom_objects_directory', meaning
@@ -92,7 +92,7 @@ def apply_mlrun(
92
92
 
93
93
  {
94
94
  "/.../custom_model.py": "MyModel",
95
- "/.../custom_objects.py": ["object1", "object2"]
95
+ "/.../custom_objects.py": ["object1", "object2"],
96
96
  }
97
97
 
98
98
  All the paths will be accessed from the given 'custom_objects_directory', meaning
@@ -18,6 +18,7 @@ from typing import Any, Union
18
18
  from tensorflow import keras
19
19
 
20
20
  import mlrun
21
+ import mlrun.common.constants as mlrun_constants
21
22
 
22
23
  from .callbacks import MLRunLoggingCallback, TensorboardLoggingCallback
23
24
  from .mlrun_interface import TFKerasMLRunInterface
@@ -85,7 +86,7 @@ def apply_mlrun(
85
86
 
86
87
  {
87
88
  "/.../custom_optimizer.py": "optimizer",
88
- "/.../custom_layers.py": ["layer1", "layer2"]
89
+ "/.../custom_layers.py": ["layer1", "layer2"],
89
90
  }
90
91
 
91
92
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -126,7 +127,9 @@ def apply_mlrun(
126
127
  # # Use horovod:
127
128
  if use_horovod is None:
128
129
  use_horovod = (
129
- context.labels.get("kind", "") == "mpijob" if context is not None else False
130
+ context.labels.get(mlrun_constants.MLRunInternalLabels.kind, "") == "mpijob"
131
+ if context is not None
132
+ else False
130
133
  )
131
134
 
132
135
  # Create a model handler:
@@ -17,7 +17,7 @@ from typing import Callable, Union
17
17
  import numpy as np
18
18
  import tensorflow as tf
19
19
  from tensorflow import Tensor, Variable
20
- from tensorflow.keras.callbacks import Callback
20
+ from tensorflow.python.keras.callbacks import Callback
21
21
 
22
22
  import mlrun
23
23
 
@@ -19,7 +19,8 @@ from typing import Union
19
19
 
20
20
  import tensorflow as tf
21
21
  from tensorflow import keras
22
- from tensorflow.keras.callbacks import (
22
+ from tensorflow.keras.optimizers import Optimizer
23
+ from tensorflow.python.keras.callbacks import (
23
24
  BaseLogger,
24
25
  Callback,
25
26
  CSVLogger,
@@ -27,7 +28,6 @@ from tensorflow.keras.callbacks import (
27
28
  ProgbarLogger,
28
29
  TensorBoard,
29
30
  )
30
- from tensorflow.keras.optimizers import Optimizer
31
31
 
32
32
  import mlrun
33
33
 
@@ -90,7 +90,7 @@ def apply_mlrun(
90
90
 
91
91
  {
92
92
  "/.../custom_model.py": "MyModel",
93
- "/.../custom_objects.py": ["object1", "object2"]
93
+ "/.../custom_objects.py": ["object1", "object2"],
94
94
  }
95
95
 
96
96
  All the paths will be accessed from the given 'custom_objects_directory', meaning
mlrun/k8s_utils.py CHANGED
@@ -141,17 +141,6 @@ def verify_label_key(key: str):
141
141
  if not key:
142
142
  raise mlrun.errors.MLRunInvalidArgumentError("label key cannot be empty")
143
143
 
144
- mlrun.utils.helpers.verify_field_regex(
145
- f"project.metadata.labels.'{key}'",
146
- key,
147
- mlrun.utils.regex.k8s_character_limit,
148
- )
149
-
150
- if key.startswith("k8s.io/") or key.startswith("kubernetes.io/"):
151
- raise mlrun.errors.MLRunInvalidArgumentError(
152
- "Labels cannot start with 'k8s.io/' or 'kubernetes.io/'"
153
- )
154
-
155
144
  parts = key.split("/")
156
145
  if len(parts) == 1:
157
146
  name = parts[0]
@@ -173,12 +162,22 @@ def verify_label_key(key: str):
173
162
  "Label key can only contain one '/'"
174
163
  )
175
164
 
165
+ mlrun.utils.helpers.verify_field_regex(
166
+ f"project.metadata.labels.'{key}'",
167
+ name,
168
+ mlrun.utils.regex.k8s_character_limit,
169
+ )
176
170
  mlrun.utils.helpers.verify_field_regex(
177
171
  f"project.metadata.labels.'{key}'",
178
172
  name,
179
173
  mlrun.utils.regex.qualified_name,
180
174
  )
181
175
 
176
+ if key.startswith("k8s.io/") or key.startswith("kubernetes.io/"):
177
+ raise mlrun.errors.MLRunInvalidArgumentError(
178
+ "Labels cannot start with 'k8s.io/' or 'kubernetes.io/'"
179
+ )
180
+
182
181
 
183
182
  def verify_label_value(value, label_key):
184
183
  mlrun.utils.helpers.verify_field_regex(
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
mlrun/launcher/base.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -18,10 +18,11 @@ import os
18
18
  import uuid
19
19
  from typing import Any, Callable, Optional, Union
20
20
 
21
+ import mlrun_pipelines.common.ops
22
+
21
23
  import mlrun.common.schemas
22
24
  import mlrun.config
23
25
  import mlrun.errors
24
- import mlrun.kfpops
25
26
  import mlrun.lists
26
27
  import mlrun.model
27
28
  import mlrun.runtimes
@@ -353,7 +354,7 @@ class BaseLauncher(abc.ABC):
353
354
  or {}
354
355
  )
355
356
  state_thresholds = (
356
- mlrun.config.config.function.spec.state_thresholds.default.to_dict()
357
+ mlrun.mlconf.function.spec.state_thresholds.default.to_dict()
357
358
  | state_thresholds
358
359
  )
359
360
  run.spec.state_thresholds = state_thresholds or run.spec.state_thresholds
@@ -390,7 +391,7 @@ class BaseLauncher(abc.ABC):
390
391
  return
391
392
 
392
393
  if result and runtime.kfp and err is None:
393
- mlrun.kfpops.write_kfpmeta(result)
394
+ mlrun_pipelines.common.ops.write_kfpmeta(result)
394
395
 
395
396
  self._log_track_results(runtime.is_child, result, run)
396
397
 
@@ -403,7 +404,7 @@ class BaseLauncher(abc.ABC):
403
404
  )
404
405
  if (
405
406
  run.status.state
406
- in mlrun.runtimes.constants.RunStates.error_and_abortion_states()
407
+ in mlrun.common.runtimes.constants.RunStates.error_and_abortion_states()
407
408
  ):
408
409
  if runtime._is_remote and not runtime.is_child:
409
410
  logger.error(
mlrun/launcher/client.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ from typing import Optional
16
16
 
17
17
  import IPython
18
18
 
19
+ import mlrun.common.constants as mlrun_constants
19
20
  import mlrun.errors
20
21
  import mlrun.launcher.base as launcher
21
22
  import mlrun.lists
@@ -47,7 +48,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
47
48
  If build is needed, set the image as the base_image for the build.
48
49
  If image is not given set the default one.
49
50
  """
50
- if runtime.kind in mlrun.runtimes.RuntimeKinds.nuclio_runtimes():
51
+ if runtime.kind in mlrun.runtimes.RuntimeKinds.pure_nuclio_deployed_runtimes():
51
52
  return
52
53
 
53
54
  require_build = runtime.requires_build()
@@ -69,13 +70,14 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
69
70
  def _store_function(
70
71
  runtime: "mlrun.runtimes.BaseRuntime", run: "mlrun.run.RunObject"
71
72
  ):
72
- run.metadata.labels["kind"] = runtime.kind
73
+ run.metadata.labels[mlrun_constants.MLRunInternalLabels.kind] = runtime.kind
73
74
  mlrun.runtimes.utils.enrich_run_labels(
74
- run.metadata.labels, [mlrun.runtimes.constants.RunLabels.owner]
75
+ run.metadata.labels, [mlrun.common.runtimes.constants.RunLabels.owner]
75
76
  )
76
77
  if run.spec.output_path:
77
78
  run.spec.output_path = run.spec.output_path.replace(
78
- "{{run.user}}", run.metadata.labels["owner"]
79
+ "{{run.user}}",
80
+ run.metadata.labels[mlrun_constants.MLRunInternalLabels.owner],
79
81
  )
80
82
  db = runtime._get_db()
81
83
  if db and runtime.kind != "handler":
@@ -129,7 +131,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
129
131
  logger.info("no returned result (job may still be in progress)")
130
132
  results_tbl.append(run.to_dict())
131
133
 
132
- if mlrun.utils.is_ipython and mlrun.config.config.ipython_widget:
134
+ if mlrun.utils.is_ipython and mlrun.mlconf.ipython_widget:
133
135
  results_tbl.show()
134
136
  print()
135
137
  ui_url = mlrun.utils.get_ui_url(project, uid)
mlrun/launcher/factory.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
mlrun/launcher/local.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@ import os
15
15
  import pathlib
16
16
  from typing import Callable, Optional, Union
17
17
 
18
+ import mlrun.common.constants as mlrun_constants
18
19
  import mlrun.common.schemas.schedule
19
20
  import mlrun.errors
20
21
  import mlrun.launcher.client as launcher
@@ -132,8 +133,13 @@ class ClientLocalLauncher(launcher.ClientBaseLauncher):
132
133
  runtime: "mlrun.runtimes.BaseRuntime",
133
134
  run: Optional[Union["mlrun.run.RunTemplate", "mlrun.run.RunObject"]] = None,
134
135
  ):
135
- if "V3IO_USERNAME" in os.environ and "v3io_user" not in run.metadata.labels:
136
- run.metadata.labels["v3io_user"] = os.environ.get("V3IO_USERNAME")
136
+ if (
137
+ "V3IO_USERNAME" in os.environ
138
+ and mlrun_constants.MLRunInternalLabels.v3io_user not in run.metadata.labels
139
+ ):
140
+ run.metadata.labels[mlrun_constants.MLRunInternalLabels.v3io_user] = (
141
+ os.environ.get("V3IO_USERNAME")
142
+ )
137
143
 
138
144
  # store function object in db unless running from within a run pod
139
145
  if not runtime.is_child:
mlrun/launcher/remote.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023 MLRun Authors
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ from typing import Optional, Union
17
17
  import pandas as pd
18
18
  import requests
19
19
 
20
+ import mlrun.common.constants as mlrun_constants
20
21
  import mlrun.common.schemas.schedule
21
22
  import mlrun.db
22
23
  import mlrun.errors
@@ -100,8 +101,13 @@ class ClientRemoteLauncher(launcher.ClientBaseLauncher):
100
101
  if runtime.verbose:
101
102
  logger.info(f"runspec:\n{run.to_yaml()}")
102
103
 
103
- if "V3IO_USERNAME" in os.environ and "v3io_user" not in run.metadata.labels:
104
- run.metadata.labels["v3io_user"] = os.environ.get("V3IO_USERNAME")
104
+ if (
105
+ "V3IO_USERNAME" in os.environ
106
+ and mlrun_constants.MLRunInternalLabels.v3io_user not in run.metadata.labels
107
+ ):
108
+ run.metadata.labels[mlrun_constants.MLRunInternalLabels.v3io_user] = (
109
+ os.environ.get("V3IO_USERNAME")
110
+ )
105
111
 
106
112
  logger.info(
107
113
  "Storing function",
mlrun/lists.py CHANGED
@@ -21,7 +21,7 @@ import mlrun.frameworks
21
21
  from .artifacts import Artifact, dict_to_artifact
22
22
  from .config import config
23
23
  from .render import artifacts_to_html, runs_to_html
24
- from .utils import flatten, get_artifact_target, get_in, is_legacy_artifact
24
+ from .utils import flatten, get_artifact_target, get_in
25
25
 
26
26
  list_header = [
27
27
  "project",
@@ -29,12 +29,14 @@ list_header = [
29
29
  "iter",
30
30
  "start",
31
31
  "state",
32
+ "kind",
32
33
  "name",
33
34
  "labels",
34
35
  "inputs",
35
36
  "parameters",
36
37
  "results",
37
38
  "artifacts",
39
+ "artifact_uris",
38
40
  "error",
39
41
  ]
40
42
 
@@ -56,12 +58,14 @@ class RunList(list):
56
58
  get_in(run, "metadata.iteration", ""),
57
59
  get_in(run, "status.start_time", ""),
58
60
  get_in(run, "status.state", ""),
61
+ get_in(run, "step_kind", get_in(run, "kind", "")),
59
62
  get_in(run, "metadata.name", ""),
60
63
  get_in(run, "metadata.labels", ""),
61
64
  get_in(run, "spec.inputs", ""),
62
65
  get_in(run, "spec.parameters", ""),
63
66
  get_in(run, "status.results", ""),
64
67
  get_in(run, "status.artifacts", []),
68
+ get_in(run, "status.artifact_uris", {}),
65
69
  get_in(run, "status.error", ""),
66
70
  ]
67
71
  if extend_iterations and iterations:
@@ -184,7 +188,7 @@ class ArtifactList(list):
184
188
  "uri": ["uri", "uri"],
185
189
  }
186
190
  for artifact in self:
187
- fields_index = 0 if is_legacy_artifact(artifact) else 1
191
+ fields_index = 1
188
192
  row = [get_in(artifact, v[fields_index], "") for k, v in head.items()]
189
193
  artifact_uri = dict_to_artifact(artifact).uri
190
194
  last_index = len(row) - 1
mlrun/model.py CHANGED
@@ -27,13 +27,13 @@ from typing import Any, Optional, Union
27
27
  import pydantic.error_wrappers
28
28
 
29
29
  import mlrun
30
+ import mlrun.common.constants as mlrun_constants
30
31
  import mlrun.common.schemas.notification
31
32
 
32
33
  from .utils import (
33
34
  dict_to_json,
34
35
  dict_to_yaml,
35
36
  get_artifact_target,
36
- is_legacy_artifact,
37
37
  logger,
38
38
  template_artifact_path,
39
39
  )
@@ -71,6 +71,7 @@ class ModelObj:
71
71
  return new_type.from_dict(param)
72
72
  return param
73
73
 
74
+ @mlrun.utils.filter_warnings("ignore", FutureWarning)
74
75
  def to_dict(
75
76
  self, fields: list = None, exclude: list = None, strip: bool = False
76
77
  ) -> dict:
@@ -681,10 +682,14 @@ class Notification(ModelObj):
681
682
 
682
683
  def __init__(
683
684
  self,
684
- kind=None,
685
+ kind: mlrun.common.schemas.notification.NotificationKind = (
686
+ mlrun.common.schemas.notification.NotificationKind.slack
687
+ ),
685
688
  name=None,
686
689
  message=None,
687
- severity=None,
690
+ severity: mlrun.common.schemas.notification.NotificationSeverity = (
691
+ mlrun.common.schemas.notification.NotificationSeverity.INFO
692
+ ),
688
693
  when=None,
689
694
  condition=None,
690
695
  secret_params=None,
@@ -693,12 +698,10 @@ class Notification(ModelObj):
693
698
  sent_time=None,
694
699
  reason=None,
695
700
  ):
696
- self.kind = kind or mlrun.common.schemas.notification.NotificationKind.slack
701
+ self.kind = kind
697
702
  self.name = name or ""
698
703
  self.message = message or ""
699
- self.severity = (
700
- severity or mlrun.common.schemas.notification.NotificationSeverity.INFO
701
- )
704
+ self.severity = severity
702
705
  self.when = when or ["completed"]
703
706
  self.condition = condition or ""
704
707
  self.secret_params = secret_params or {}
@@ -765,6 +768,14 @@ class RunMetadata(ModelObj):
765
768
  def iteration(self, iteration):
766
769
  self._iteration = iteration
767
770
 
771
+ def is_workflow_runner(self):
772
+ if not self.labels:
773
+ return False
774
+ return (
775
+ self.labels.get(mlrun_constants.MLRunInternalLabels.job_type, "")
776
+ == "workflow-runner"
777
+ )
778
+
768
779
 
769
780
  class HyperParamStrategies:
770
781
  grid = "grid"
@@ -930,7 +941,7 @@ class RunSpec(ModelObj):
930
941
 
931
942
  >>> run_spec.inputs = {
932
943
  ... "my_input": "...",
933
- ... "my_hinted_input : pandas.DataFrame": "..."
944
+ ... "my_hinted_input : pandas.DataFrame": "...",
934
945
  ... }
935
946
 
936
947
  :param inputs: The inputs to set.
@@ -1202,6 +1213,7 @@ class RunStatus(ModelObj):
1202
1213
  ui_url=None,
1203
1214
  reason: str = None,
1204
1215
  notifications: dict[str, Notification] = None,
1216
+ artifact_uris: dict[str, str] = None,
1205
1217
  ):
1206
1218
  self.state = state or "created"
1207
1219
  self.status_text = status_text
@@ -1216,6 +1228,21 @@ class RunStatus(ModelObj):
1216
1228
  self.ui_url = ui_url
1217
1229
  self.reason = reason
1218
1230
  self.notifications = notifications or {}
1231
+ # Artifact key -> URI mapping, since the full artifacts are not stored in the runs DB table
1232
+ self.artifact_uris = artifact_uris or {}
1233
+
1234
+ def is_failed(self) -> Optional[bool]:
1235
+ """
1236
+ This method returns whether a run has failed.
1237
+ Returns none if state has yet to be defined. callee is responsible for handling None.
1238
+ (e.g wait for state to be defined)
1239
+ """
1240
+ if not self.state:
1241
+ return None
1242
+ return self.state.casefold() in [
1243
+ mlrun.run.RunStatuses.failed.casefold(),
1244
+ mlrun.run.RunStatuses.error.casefold(),
1245
+ ]
1219
1246
 
1220
1247
 
1221
1248
  class RunTemplate(ModelObj):
@@ -1274,7 +1301,7 @@ class RunTemplate(ModelObj):
1274
1301
 
1275
1302
  example::
1276
1303
 
1277
- grid_params = {"p1": [2,4,1], "p2": [10,20]}
1304
+ grid_params = {"p1": [2, 4, 1], "p2": [10, 20]}
1278
1305
  task = mlrun.new_task("grid-search")
1279
1306
  task.with_hyper_params(grid_params, selector="max.accuracy")
1280
1307
  """
@@ -1416,11 +1443,14 @@ class RunObject(RunTemplate):
1416
1443
  unknown_error = ""
1417
1444
  if (
1418
1445
  self.status.state
1419
- in mlrun.runtimes.constants.RunStates.abortion_states()
1446
+ in mlrun.common.runtimes.constants.RunStates.abortion_states()
1420
1447
  ):
1421
1448
  unknown_error = "Run was aborted"
1422
1449
 
1423
- elif self.status.state in mlrun.runtimes.constants.RunStates.error_states():
1450
+ elif (
1451
+ self.status.state
1452
+ in mlrun.common.runtimes.constants.RunStates.error_states()
1453
+ ):
1424
1454
  unknown_error = "Unknown error"
1425
1455
 
1426
1456
  return (
@@ -1458,7 +1488,7 @@ class RunObject(RunTemplate):
1458
1488
  outputs = {k: v for k, v in self.status.results.items()}
1459
1489
  if self.status.artifacts:
1460
1490
  for a in self.status.artifacts:
1461
- key = a["key"] if is_legacy_artifact(a) else a["metadata"]["key"]
1491
+ key = a["metadata"]["key"]
1462
1492
  outputs[key] = get_artifact_target(a, self.metadata.project)
1463
1493
  return outputs
1464
1494
 
@@ -1501,7 +1531,10 @@ class RunObject(RunTemplate):
1501
1531
 
1502
1532
  def state(self):
1503
1533
  """current run state"""
1504
- if self.status.state in mlrun.runtimes.constants.RunStates.terminal_states():
1534
+ if (
1535
+ self.status.state
1536
+ in mlrun.common.runtimes.constants.RunStates.terminal_states()
1537
+ ):
1505
1538
  return self.status.state
1506
1539
  self.refresh()
1507
1540
  return self.status.state or "unknown"
@@ -1515,8 +1548,10 @@ class RunObject(RunTemplate):
1515
1548
  iter=self.metadata.iteration,
1516
1549
  )
1517
1550
  if run:
1518
- self.status = RunStatus.from_dict(run.get("status", {}))
1519
- self.status.from_dict(run.get("status", {}))
1551
+ run_status = run.get("status", {})
1552
+ # Artifacts are not stored in the DB, so we need to preserve them here
1553
+ run_status["artifacts"] = self.status.artifacts
1554
+ self.status = RunStatus.from_dict(run_status)
1520
1555
  return self
1521
1556
 
1522
1557
  def show(self):
@@ -1563,7 +1598,7 @@ class RunObject(RunTemplate):
1563
1598
  last_pull_log_time = None
1564
1599
  logs_enabled = show_logs is not False
1565
1600
  state = self.state()
1566
- if state not in mlrun.runtimes.constants.RunStates.terminal_states():
1601
+ if state not in mlrun.common.runtimes.constants.RunStates.terminal_states():
1567
1602
  logger.info(
1568
1603
  f"run {self.metadata.name} is not completed yet, waiting for it to complete",
1569
1604
  current_state=state,
@@ -1573,7 +1608,8 @@ class RunObject(RunTemplate):
1573
1608
  if (
1574
1609
  logs_enabled
1575
1610
  and logs_interval
1576
- and state not in mlrun.runtimes.constants.RunStates.terminal_states()
1611
+ and state
1612
+ not in mlrun.common.runtimes.constants.RunStates.terminal_states()
1577
1613
  and (
1578
1614
  last_pull_log_time is None
1579
1615
  or (datetime.now() - last_pull_log_time).seconds > logs_interval
@@ -1582,7 +1618,7 @@ class RunObject(RunTemplate):
1582
1618
  last_pull_log_time = datetime.now()
1583
1619
  state, offset = self.logs(watch=False, offset=offset)
1584
1620
 
1585
- if state in mlrun.runtimes.constants.RunStates.terminal_states():
1621
+ if state in mlrun.common.runtimes.constants.RunStates.terminal_states():
1586
1622
  if logs_enabled and logs_interval:
1587
1623
  self.logs(watch=False, offset=offset)
1588
1624
  break
@@ -1594,7 +1630,10 @@ class RunObject(RunTemplate):
1594
1630
  )
1595
1631
  if logs_enabled and not logs_interval:
1596
1632
  self.logs(watch=False)
1597
- if raise_on_failure and state != mlrun.runtimes.constants.RunStates.completed:
1633
+ if (
1634
+ raise_on_failure
1635
+ and state != mlrun.common.runtimes.constants.RunStates.completed
1636
+ ):
1598
1637
  raise mlrun.errors.MLRunRuntimeError(
1599
1638
  f"Task {self.metadata.name} did not complete (state={state})"
1600
1639
  )
@@ -15,7 +15,7 @@
15
15
  # flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
16
16
  # for backwards compatibility
17
17
 
18
+ from .db import get_store_object, get_tsdb_connector
18
19
  from .helpers import get_stream_path
19
20
  from .model_endpoint import ModelEndpoint
20
- from .stores import ModelEndpointStore, ModelEndpointStoreType, get_model_endpoint_store
21
21
  from .tracking_policy import TrackingPolicy