mlrun 1.7.0rc7__py3-none-any.whl → 1.7.0rc11__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 (91) hide show
  1. mlrun/__init__.py +1 -0
  2. mlrun/__main__.py +2 -0
  3. mlrun/artifacts/model.py +29 -25
  4. mlrun/common/schemas/__init__.py +4 -0
  5. mlrun/common/schemas/alert.py +122 -0
  6. mlrun/common/schemas/api_gateway.py +8 -1
  7. mlrun/common/schemas/auth.py +4 -0
  8. mlrun/common/schemas/client_spec.py +1 -0
  9. mlrun/common/schemas/hub.py +7 -9
  10. mlrun/common/schemas/model_monitoring/constants.py +4 -2
  11. mlrun/{datastore/helpers.py → common/schemas/pagination.py} +11 -3
  12. mlrun/common/schemas/project.py +15 -10
  13. mlrun/config.py +35 -13
  14. mlrun/datastore/__init__.py +3 -7
  15. mlrun/datastore/base.py +6 -5
  16. mlrun/datastore/datastore_profile.py +19 -1
  17. mlrun/datastore/snowflake_utils.py +43 -0
  18. mlrun/datastore/sources.py +18 -30
  19. mlrun/datastore/targets.py +140 -12
  20. mlrun/datastore/utils.py +10 -5
  21. mlrun/datastore/v3io.py +27 -50
  22. mlrun/db/base.py +88 -2
  23. mlrun/db/httpdb.py +314 -41
  24. mlrun/db/nopdb.py +142 -0
  25. mlrun/execution.py +21 -14
  26. mlrun/feature_store/api.py +9 -5
  27. mlrun/feature_store/feature_set.py +39 -23
  28. mlrun/feature_store/feature_vector.py +2 -1
  29. mlrun/feature_store/retrieval/spark_merger.py +27 -23
  30. mlrun/feature_store/steps.py +30 -19
  31. mlrun/features.py +4 -13
  32. mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
  33. mlrun/frameworks/lgbm/__init__.py +1 -1
  34. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  35. mlrun/frameworks/lgbm/model_handler.py +1 -1
  36. mlrun/frameworks/pytorch/__init__.py +2 -2
  37. mlrun/frameworks/sklearn/__init__.py +1 -1
  38. mlrun/frameworks/tf_keras/__init__.py +1 -1
  39. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  40. mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
  41. mlrun/frameworks/xgboost/__init__.py +1 -1
  42. mlrun/kfpops.py +2 -5
  43. mlrun/launcher/base.py +1 -1
  44. mlrun/launcher/client.py +2 -2
  45. mlrun/model.py +2 -2
  46. mlrun/model_monitoring/application.py +11 -2
  47. mlrun/model_monitoring/applications/histogram_data_drift.py +3 -3
  48. mlrun/model_monitoring/controller.py +2 -3
  49. mlrun/model_monitoring/helpers.py +3 -1
  50. mlrun/model_monitoring/stream_processing.py +0 -1
  51. mlrun/model_monitoring/writer.py +32 -0
  52. mlrun/package/packagers_manager.py +1 -0
  53. mlrun/platforms/__init__.py +1 -1
  54. mlrun/platforms/other.py +1 -1
  55. mlrun/projects/operations.py +11 -4
  56. mlrun/projects/pipelines.py +1 -1
  57. mlrun/projects/project.py +180 -73
  58. mlrun/run.py +77 -41
  59. mlrun/runtimes/__init__.py +16 -0
  60. mlrun/runtimes/base.py +4 -1
  61. mlrun/runtimes/kubejob.py +26 -121
  62. mlrun/runtimes/mpijob/abstract.py +8 -8
  63. mlrun/runtimes/nuclio/api_gateway.py +58 -8
  64. mlrun/runtimes/nuclio/application/application.py +79 -1
  65. mlrun/runtimes/nuclio/application/reverse_proxy.go +9 -1
  66. mlrun/runtimes/nuclio/function.py +20 -13
  67. mlrun/runtimes/nuclio/serving.py +11 -10
  68. mlrun/runtimes/pod.py +148 -3
  69. mlrun/runtimes/utils.py +0 -28
  70. mlrun/secrets.py +6 -2
  71. mlrun/serving/remote.py +2 -3
  72. mlrun/serving/routers.py +7 -4
  73. mlrun/serving/server.py +1 -1
  74. mlrun/serving/states.py +14 -38
  75. mlrun/serving/v2_serving.py +8 -7
  76. mlrun/utils/helpers.py +1 -1
  77. mlrun/utils/http.py +1 -1
  78. mlrun/utils/notifications/notification/base.py +12 -0
  79. mlrun/utils/notifications/notification/console.py +2 -0
  80. mlrun/utils/notifications/notification/git.py +3 -1
  81. mlrun/utils/notifications/notification/ipython.py +2 -0
  82. mlrun/utils/notifications/notification/slack.py +41 -13
  83. mlrun/utils/notifications/notification/webhook.py +11 -1
  84. mlrun/utils/retryer.py +3 -2
  85. mlrun/utils/version/version.json +2 -2
  86. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/METADATA +15 -15
  87. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/RECORD +91 -89
  88. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/LICENSE +0 -0
  89. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/WHEEL +0 -0
  90. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/entry_points.txt +0 -0
  91. {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/top_level.txt +0 -0
@@ -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
@@ -85,7 +85,7 @@ def apply_mlrun(
85
85
 
86
86
  {
87
87
  "/.../custom_optimizer.py": "optimizer",
88
- "/.../custom_layers.py": ["layer1", "layer2"]
88
+ "/.../custom_layers.py": ["layer1", "layer2"],
89
89
  }
90
90
 
91
91
  All the paths will be accessed from the given 'custom_objects_directory',
@@ -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/kfpops.py CHANGED
@@ -103,7 +103,7 @@ def write_kfpmeta(struct):
103
103
  with open(path, "w") as fp:
104
104
  fp.write(str(val))
105
105
  except Exception as exc:
106
- logger.warning("Failed writing to temp file. Ignoring", exc=repr(exc))
106
+ logger.warning("Failed writing to temp file. Ignoring", exc=err_to_str(exc))
107
107
  pass
108
108
 
109
109
  text = "# Run Report\n"
@@ -112,10 +112,7 @@ def write_kfpmeta(struct):
112
112
 
113
113
  text += "## Metadata\n```yaml\n" + dict_to_yaml(struct) + "```\n"
114
114
 
115
- metadata = {
116
- "outputs": output_artifacts
117
- + [{"type": "markdown", "storage": "inline", "source": text}]
118
- }
115
+ metadata = {"outputs": [{"type": "markdown", "storage": "inline", "source": text}]}
119
116
  with open(os.path.join(KFPMETA_DIR, "mlpipeline-ui-metadata.json"), "w") as f:
120
117
  json.dump(metadata, f)
121
118
 
mlrun/launcher/base.py CHANGED
@@ -353,7 +353,7 @@ class BaseLauncher(abc.ABC):
353
353
  or {}
354
354
  )
355
355
  state_thresholds = (
356
- mlrun.config.config.function.spec.state_thresholds.default.to_dict()
356
+ mlrun.mlconf.function.spec.state_thresholds.default.to_dict()
357
357
  | state_thresholds
358
358
  )
359
359
  run.spec.state_thresholds = state_thresholds or run.spec.state_thresholds
mlrun/launcher/client.py CHANGED
@@ -47,7 +47,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
47
47
  If build is needed, set the image as the base_image for the build.
48
48
  If image is not given set the default one.
49
49
  """
50
- if runtime.kind in mlrun.runtimes.RuntimeKinds.nuclio_runtimes():
50
+ if runtime.kind in mlrun.runtimes.RuntimeKinds.pure_nuclio_deployed_runtimes():
51
51
  return
52
52
 
53
53
  require_build = runtime.requires_build()
@@ -129,7 +129,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
129
129
  logger.info("no returned result (job may still be in progress)")
130
130
  results_tbl.append(run.to_dict())
131
131
 
132
- if mlrun.utils.is_ipython and mlrun.config.config.ipython_widget:
132
+ if mlrun.utils.is_ipython and mlrun.mlconf.ipython_widget:
133
133
  results_tbl.show()
134
134
  print()
135
135
  ui_url = mlrun.utils.get_ui_url(project, uid)
mlrun/model.py CHANGED
@@ -931,7 +931,7 @@ class RunSpec(ModelObj):
931
931
 
932
932
  >>> run_spec.inputs = {
933
933
  ... "my_input": "...",
934
- ... "my_hinted_input : pandas.DataFrame": "..."
934
+ ... "my_hinted_input : pandas.DataFrame": "...",
935
935
  ... }
936
936
 
937
937
  :param inputs: The inputs to set.
@@ -1275,7 +1275,7 @@ class RunTemplate(ModelObj):
1275
1275
 
1276
1276
  example::
1277
1277
 
1278
- grid_params = {"p1": [2,4,1], "p2": [10,20]}
1278
+ grid_params = {"p1": [2, 4, 1], "p2": [10, 20]}
1279
1279
  task = mlrun.new_task("grid-search")
1280
1280
  task.with_hyper_params(grid_params, selector="max.accuracy")
1281
1281
  """
@@ -93,7 +93,11 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
93
93
  endpoint_id: str,
94
94
  output_stream_uri: str,
95
95
  ) -> ModelMonitoringApplicationResult:
96
- self.context.log_artifact(TableArtifact("sample_df_stats", df=self.dict_to_histogram(sample_df_stats)))
96
+ self.context.log_artifact(
97
+ TableArtifact(
98
+ "sample_df_stats", df=self.dict_to_histogram(sample_df_stats)
99
+ )
100
+ )
97
101
  return ModelMonitoringApplicationResult(
98
102
  name="data_drift_test",
99
103
  value=0.5,
@@ -101,6 +105,7 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
101
105
  status=mm_constant.ResultStatusApp.detected,
102
106
  )
103
107
 
108
+
104
109
  # mlrun: end-code
105
110
  """
106
111
 
@@ -203,7 +208,11 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
203
208
  json.loads(event[mm_constant.ApplicationEvent.FEATURE_STATS]),
204
209
  ParquetTarget(
205
210
  path=event[mm_constant.ApplicationEvent.SAMPLE_PARQUET_PATH]
206
- ).as_df(start_time=start_time, end_time=end_time, time_column="timestamp"),
211
+ ).as_df(
212
+ start_time=start_time,
213
+ end_time=end_time,
214
+ time_column=mm_constant.FeatureSetFeatures.time_stamp(),
215
+ ),
207
216
  start_time,
208
217
  end_time,
209
218
  pd.Timestamp(event[mm_constant.ApplicationEvent.LAST_REQUEST]),
@@ -22,8 +22,8 @@ import mlrun.artifacts
22
22
  import mlrun.common.model_monitoring.helpers
23
23
  import mlrun.model_monitoring.features_drift_table as mm_drift_table
24
24
  from mlrun.common.schemas.model_monitoring.constants import (
25
- MLRUN_HISTOGRAM_DATA_DRIFT_APP_NAME,
26
25
  EventFieldType,
26
+ HistogramDataDriftApplicationConstants,
27
27
  ResultKindApp,
28
28
  ResultStatusApp,
29
29
  )
@@ -94,7 +94,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBase):
94
94
  and the status is returned.
95
95
  """
96
96
 
97
- NAME: Final[str] = MLRUN_HISTOGRAM_DATA_DRIFT_APP_NAME
97
+ NAME: Final[str] = HistogramDataDriftApplicationConstants.NAME
98
98
  METRIC_KIND: Final[ResultKindApp] = ResultKindApp.data_drift
99
99
 
100
100
  _REQUIRED_METRICS = {HellingerDistance, TotalVarianceDistance}
@@ -148,7 +148,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBase):
148
148
  status = self._value_classifier.value_to_status(value)
149
149
  results.append(
150
150
  ModelMonitoringApplicationResult(
151
- name="general_drift",
151
+ name=HistogramDataDriftApplicationConstants.GENERAL_RESULT_NAME,
152
152
  value=value,
153
153
  kind=self.METRIC_KIND,
154
154
  status=status,
@@ -354,7 +354,7 @@ class MonitoringApplicationController:
354
354
  app.status.state == "ready"
355
355
  # workaround for the default app, as its `status.state` is `None`
356
356
  or app.metadata.name
357
- == mm_constants.MLRUN_HISTOGRAM_DATA_DRIFT_APP_NAME
357
+ == mm_constants.HistogramDataDriftApplicationConstants.NAME
358
358
  )
359
359
  }
360
360
  )
@@ -502,8 +502,7 @@ class MonitoringApplicationController:
502
502
 
503
503
  # Get the current stats:
504
504
  current_stats = calculate_inputs_statistics(
505
- sample_set_statistics=feature_stats,
506
- inputs=df,
505
+ sample_set_statistics=feature_stats, inputs=df
507
506
  )
508
507
 
509
508
  cls._push_to_applications(
@@ -42,7 +42,7 @@ class _BatchDict(typing.TypedDict):
42
42
  def get_stream_path(
43
43
  project: str = None,
44
44
  function_name: str = mm_constants.MonitoringFunctionNames.STREAM,
45
- ):
45
+ ) -> str:
46
46
  """
47
47
  Get stream path from the project secret. If wasn't set, take it from the system configurations
48
48
 
@@ -61,6 +61,8 @@ def get_stream_path(
61
61
  function_name=function_name,
62
62
  )
63
63
 
64
+ if isinstance(stream_uri, list): # ML-6043 - user side gets only the new stream uri
65
+ stream_uri = stream_uri[1] # get new stream path, under projects
64
66
  return mlrun.common.model_monitoring.helpers.parse_monitoring_stream_path(
65
67
  stream_uri=stream_uri, project=project, function_name=function_name
66
68
  )
@@ -352,7 +352,6 @@ class EventStreamProcessor:
352
352
  rate="10/m",
353
353
  time_col=EventFieldType.TIMESTAMP,
354
354
  container=self.tsdb_container,
355
- access_key=self.v3io_access_key,
356
355
  v3io_frames=self.v3io_framesd,
357
356
  infer_columns_from_data=True,
358
357
  index_cols=[
@@ -23,6 +23,7 @@ from v3io_frames.errors import Error as V3IOFramesError
23
23
  from v3io_frames.frames_pb2 import IGNORE
24
24
 
25
25
  import mlrun.common.model_monitoring
26
+ import mlrun.common.schemas.alert as alert_constants
26
27
  import mlrun.model_monitoring
27
28
  import mlrun.model_monitoring.db.stores
28
29
  import mlrun.utils.v3io_clients
@@ -171,6 +172,29 @@ class ModelMonitoringWriter(StepToDict):
171
172
  event=event,
172
173
  )
173
174
 
175
+ @staticmethod
176
+ def _generate_event_on_drift(
177
+ uid: str, drift_status: str, drift_value: float, project_name: str
178
+ ):
179
+ if (
180
+ drift_status == ResultStatusApp.detected
181
+ or drift_status == ResultStatusApp.potential_detection
182
+ ):
183
+ entity = {
184
+ "kind": alert_constants.EventEntityKind.MODEL,
185
+ "project": project_name,
186
+ "id": uid,
187
+ }
188
+ event_kind = (
189
+ alert_constants.EventKind.DRIFT_DETECTED
190
+ if drift_status == ResultStatusApp.detected
191
+ else alert_constants.EventKind.DRIFT_SUSPECTED
192
+ )
193
+ event_data = mlrun.common.schemas.Event(
194
+ kind=event_kind, entity=entity, value=drift_value
195
+ )
196
+ mlrun.get_run_db().generate_event(event_kind, event_data)
197
+
174
198
  @staticmethod
175
199
  def _reconstruct_event(event: _RawEvent) -> _AppResultEvent:
176
200
  """
@@ -201,4 +225,12 @@ class ModelMonitoringWriter(StepToDict):
201
225
  self._update_tsdb(event)
202
226
  self._update_kv_db(event)
203
227
  _Notifier(event=event, notification_pusher=self._custom_notifier).notify()
228
+
229
+ if mlrun.mlconf.alerts.mode == mlrun.common.schemas.alert.AlertsModes.enabled:
230
+ self._generate_event_on_drift(
231
+ event[WriterEvent.ENDPOINT_ID],
232
+ event[WriterEvent.RESULT_STATUS],
233
+ event[WriterEvent.RESULT_VALUE],
234
+ self.project,
235
+ )
204
236
  logger.info("Completed event DB writes")
@@ -92,6 +92,7 @@ class PackagersManager:
92
92
  from mlrun import Packager
93
93
  from x import XPackager
94
94
 
95
+
95
96
  class YPackager(Packager):
96
97
  pass
97
98
 
@@ -48,7 +48,7 @@ def watch_stream(
48
48
 
49
49
  example::
50
50
 
51
- watch_stream('v3io:///users/admin/mystream')
51
+ watch_stream("v3io:///users/admin/mystream")
52
52
 
53
53
  :param url: stream url
54
54
  :param shard_ids: range or list of shard IDs
mlrun/platforms/other.py CHANGED
@@ -33,7 +33,7 @@ def mount_pvc(pvc_name=None, volume_name="pipeline", volume_mount_path="/mnt/pip
33
33
  Usage::
34
34
 
35
35
  train = train_op(...)
36
- train.apply(mount_pvc('claim-name', 'pipeline', '/mnt/pipeline'))
36
+ train.apply(mount_pvc("claim-name", "pipeline", "/mnt/pipeline"))
37
37
  """
38
38
  if "MLRUN_PVC_MOUNT" in os.environ:
39
39
  mount = os.environ.get("MLRUN_PVC_MOUNT")
@@ -95,8 +95,11 @@ def run_function(
95
95
  MODEL_CLASS = "sklearn.ensemble.RandomForestClassifier"
96
96
  DATA_PATH = "s3://bigdata/data.parquet"
97
97
  function = mlrun.import_function("hub://auto-trainer")
98
- run1 = run_function(function, params={"label_columns": LABELS, "model_class": MODEL_CLASS},
99
- inputs={"dataset": DATA_PATH})
98
+ run1 = run_function(
99
+ function,
100
+ params={"label_columns": LABELS, "model_class": MODEL_CLASS},
101
+ inputs={"dataset": DATA_PATH},
102
+ )
100
103
 
101
104
  example (use with project)::
102
105
 
@@ -115,8 +118,12 @@ def run_function(
115
118
  @dsl.pipeline(name="test pipeline", description="test")
116
119
  def my_pipe(url=""):
117
120
  run1 = run_function("loaddata", params={"url": url}, outputs=["data"])
118
- run2 = run_function("train", params={"label_columns": LABELS, "model_class": MODEL_CLASS},
119
- inputs={"dataset": run1.outputs["data"]})
121
+ run2 = run_function(
122
+ "train",
123
+ params={"label_columns": LABELS, "model_class": MODEL_CLASS},
124
+ inputs={"dataset": run1.outputs["data"]},
125
+ )
126
+
120
127
 
121
128
  project.run(workflow_handler=my_pipe, arguments={"param1": 7})
122
129
 
@@ -1071,7 +1071,7 @@ def load_and_run(
1071
1071
  )
1072
1072
 
1073
1073
  except Exception as exc:
1074
- logger.error("Failed to send slack notification", exc=exc)
1074
+ logger.error("Failed to send slack notification", exc=err_to_str(exc))
1075
1075
 
1076
1076
  raise error
1077
1077