mlrun 1.10.0rc27__py3-none-any.whl → 1.10.0rc28__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.
mlrun/config.py CHANGED
@@ -255,7 +255,8 @@ default_config = {
255
255
  },
256
256
  "runtimes": {
257
257
  "dask": "600",
258
- "dask_cluster_start": "300",
258
+ # cluster start might take some time in case k8s needs to spin up new nodes
259
+ "dask_cluster_start": "600",
259
260
  },
260
261
  "push_notifications": "60",
261
262
  },
mlrun/db/httpdb.py CHANGED
@@ -5200,7 +5200,7 @@ class HTTPRunDB(RunDBInterface):
5200
5200
 
5201
5201
  :return: A ModelEndpointDriftValues object containing the drift counts over time.
5202
5202
  """
5203
- endpoint_path = f"projects/{project}/model-endpoints/drift-over-time"
5203
+ endpoint_path = f"projects/{project}/model-monitoring/drift-over-time"
5204
5204
  error_message = f"Failed retrieving drift data for {project}"
5205
5205
  response = self.api_call(
5206
5206
  method="GET",
@@ -1499,20 +1499,51 @@ class V3IOTSDBConnector(TSDBConnector):
1499
1499
  ) -> mm_schemas.ModelEndpointDriftValues:
1500
1500
  table = mm_schemas.V3IOTSDBTables.APP_RESULTS
1501
1501
  start, end, interval = self._prepare_aligned_start_end(start, end)
1502
-
1503
- # get per time-interval x endpoint_id combination the max result status
1504
1502
  df = self._get_records(
1505
1503
  table=table,
1506
1504
  start=start,
1507
1505
  end=end,
1508
- interval=interval,
1509
- sliding_window_step=interval,
1510
1506
  columns=[mm_schemas.ResultData.RESULT_STATUS],
1511
- agg_funcs=["max"],
1512
- group_by=mm_schemas.WriterEvent.ENDPOINT_ID,
1513
1507
  )
1508
+ df = self._aggregate_raw_drift_data(df, start, end, interval)
1514
1509
  if df.empty:
1515
1510
  return mm_schemas.ModelEndpointDriftValues(values=[])
1516
1511
  df = df[df[f"max({mm_schemas.ResultData.RESULT_STATUS})"] >= 1]
1517
- df = df.reset_index(names="_wstart")
1518
1512
  return self._df_to_drift_data(df)
1513
+
1514
+ @staticmethod
1515
+ def _aggregate_raw_drift_data(
1516
+ df: pd.DataFrame, start: datetime, end: datetime, interval: str
1517
+ ) -> pd.DataFrame:
1518
+ if df.empty:
1519
+ return df
1520
+ if not isinstance(df.index, pd.DatetimeIndex):
1521
+ raise TypeError("Expected a DatetimeIndex on the DataFrame (time index).")
1522
+ df[EventFieldType.ENDPOINT_ID] = (
1523
+ df[EventFieldType.ENDPOINT_ID].astype("string").str.strip()
1524
+ ) # remove extra data carried by the category dtype
1525
+ window = df.loc[
1526
+ (df.index >= start) & (df.index < end),
1527
+ [mm_schemas.ResultData.RESULT_STATUS, EventFieldType.ENDPOINT_ID],
1528
+ ]
1529
+ out = (
1530
+ window.groupby(
1531
+ [
1532
+ EventFieldType.ENDPOINT_ID,
1533
+ pd.Grouper(
1534
+ freq=interval, origin=start, label="left", closed="left"
1535
+ ),
1536
+ ]
1537
+ # align to start, [start, end) intervals
1538
+ )[mm_schemas.ResultData.RESULT_STATUS]
1539
+ .max()
1540
+ .reset_index()
1541
+ .rename(
1542
+ columns={
1543
+ mm_schemas.ResultData.RESULT_STATUS: f"max({mm_schemas.ResultData.RESULT_STATUS})"
1544
+ }
1545
+ )
1546
+ )
1547
+ return out.rename(
1548
+ columns={"time": "_wstart"}
1549
+ ) # rename datetime column to _wstart to align with the tdengine result
@@ -659,3 +659,26 @@ def get_start_end(
659
659
  )
660
660
 
661
661
  return start, end
662
+
663
+
664
+ def validate_time_range(
665
+ start: Optional[datetime.datetime] = None, end: Optional[datetime.datetime] = None
666
+ ) -> tuple[datetime.datetime, datetime.datetime]:
667
+ """
668
+ validate start and end parameters and set default values if needed.
669
+ :param start: Either None or datetime, None is handled as datetime.now(tz=timezone.utc) - timedelta(days=1)
670
+ :param end: Either None or datetime, None is handled as datetime.now(tz=timezone.utc)
671
+ :return: start datetime, end datetime
672
+ """
673
+ end = end or mlrun.utils.helpers.datetime_now()
674
+ start = start or (end - datetime.timedelta(days=1))
675
+ if start.tzinfo is None or end.tzinfo is None:
676
+ raise mlrun.errors.MLRunInvalidArgumentTypeError(
677
+ "Custom start and end times must contain the timezone."
678
+ )
679
+ if start > end:
680
+ raise mlrun.errors.MLRunInvalidArgumentError(
681
+ "The start time must be before the end time. Note that if end time is not provided, "
682
+ "the current time is used by default."
683
+ )
684
+ return start, end
mlrun/runtimes/base.py CHANGED
@@ -443,9 +443,11 @@ class BaseRuntime(ModelObj):
443
443
  :param runobj: Run context object (RunObject) with run metadata and status
444
444
  :return: Dictionary with all the variables that could be parsed
445
445
  """
446
+ active_project = self.metadata.project or config.active_project
446
447
  runtime_env = {
447
- mlrun_constants.MLRUN_ACTIVE_PROJECT: self.metadata.project
448
- or config.active_project
448
+ mlrun_constants.MLRUN_ACTIVE_PROJECT: active_project,
449
+ # TODO: Remove this in 1.12.0 as MLRUN_DEFAULT_PROJECT is deprecated and should not be injected anymore
450
+ "MLRUN_DEFAULT_PROJECT": active_project,
449
451
  }
450
452
  if runobj:
451
453
  runtime_env["MLRUN_EXEC_CONFIG"] = runobj.to_json(
mlrun/utils/helpers.py CHANGED
@@ -45,6 +45,7 @@ import pytz
45
45
  import semver
46
46
  import yaml
47
47
  from dateutil import parser
48
+ from orjson import orjson
48
49
  from pandas import Timedelta, Timestamp
49
50
  from yaml.representer import RepresenterError
50
51
 
@@ -1214,52 +1215,58 @@ def get_workflow_url(
1214
1215
 
1215
1216
 
1216
1217
  def get_kfp_list_runs_filter(
1217
- project_name: Optional[str] = None,
1218
- end_date: Optional[str] = None,
1219
1218
  start_date: Optional[str] = None,
1219
+ end_date: Optional[str] = None,
1220
+ filter_: Optional[str] = None,
1221
+ experiment_ids: Optional[list[str]] = None,
1220
1222
  ) -> str:
1221
1223
  """
1222
- Generates a filter for listing Kubeflow Pipelines (KFP) runs.
1223
-
1224
- :param project_name: The name of the project. If "*", it won't filter by project.
1225
- :param end_date: The latest creation date for filtering runs (ISO 8601 format).
1226
- :param start_date: The earliest creation date for filtering runs (ISO 8601 format).
1227
- :return: A JSON-formatted filter string for KFP.
1224
+ Generate a filter for KFP runs based on start and end dates, and experiment IDs.
1228
1225
  """
1226
+ existing_filter_object = json.loads(filter_) if filter_ else {"predicates": []}
1227
+ preserved_predicates = [
1228
+ predicate
1229
+ for predicate in existing_filter_object.get("predicates", [])
1230
+ if predicate.get("key") != "name"
1231
+ ]
1229
1232
 
1230
- # KFP filter operation codes
1231
- kfp_less_than_or_equal_op = 7 # '<='
1232
- kfp_greater_than_or_equal_op = 5 # '>='
1233
- kfp_substring_op = 9 # Substring match
1234
-
1235
- filters = {"predicates": []}
1236
-
1233
+ new_predicates = []
1237
1234
  if end_date:
1238
- filters["predicates"].append(
1235
+ new_predicates.append(
1239
1236
  {
1240
- "key": "created_at",
1241
- "op": kfp_less_than_or_equal_op,
1237
+ "key": mlrun_pipelines.models.FilterFields.CREATED_AT,
1238
+ "op": mlrun_pipelines.models.FilterOperations.LESS_THAN_EQUALS.value,
1242
1239
  "timestamp_value": end_date,
1243
1240
  }
1244
1241
  )
1245
1242
 
1246
- if project_name and project_name != "*":
1247
- filters["predicates"].append(
1243
+ if start_date:
1244
+ new_predicates.append(
1248
1245
  {
1249
- "key": "name",
1250
- "op": kfp_substring_op,
1251
- "string_value": project_name,
1246
+ "key": mlrun_pipelines.models.FilterFields.CREATED_AT,
1247
+ "op": mlrun_pipelines.models.FilterOperations.GREATER_THAN_EQUALS.value,
1248
+ "timestamp_value": start_date,
1252
1249
  }
1253
1250
  )
1254
- if start_date:
1255
- filters["predicates"].append(
1251
+
1252
+ if experiment_ids and all(experiment_ids):
1253
+ new_predicates.append(
1256
1254
  {
1257
- "key": "created_at",
1258
- "op": kfp_greater_than_or_equal_op,
1259
- "timestamp_value": start_date,
1255
+ "key": mlrun_pipelines.models.FilterFields.EXPERIMENT_ID,
1256
+ "op": mlrun_pipelines.models.FilterOperations.IN.value,
1257
+ "string_values": {"values": experiment_ids},
1260
1258
  }
1261
1259
  )
1262
- return json.dumps(filters)
1260
+
1261
+ final_filter_object = {"predicates": preserved_predicates + new_predicates}
1262
+ if not final_filter_object["predicates"]:
1263
+ return ""
1264
+
1265
+ logger.debug(
1266
+ "Generated KFP runs filter",
1267
+ filter_object_with_predicates=final_filter_object,
1268
+ )
1269
+ return orjson.dumps(final_filter_object).decode()
1263
1270
 
1264
1271
 
1265
1272
  def validate_and_convert_date(date_input: str) -> str:
@@ -1,4 +1,4 @@
1
1
  {
2
- "git_commit": "8b5d7492c858f675bcf8fce28d536c9af13a8d86",
3
- "version": "1.10.0-rc27"
2
+ "git_commit": "ec44cbf076b74e7961c4597ce7b9d92dcaf87f90",
3
+ "version": "1.10.0-rc28"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mlrun
3
- Version: 1.10.0rc27
3
+ Version: 1.10.0rc28
4
4
  Summary: Tracking and config of machine learning runs
5
5
  Home-page: https://github.com/mlrun/mlrun
6
6
  Author: Yaron Haviv
@@ -1,6 +1,6 @@
1
1
  mlrun/__init__.py,sha256=JYy9uteFFNPbPoC0geDEPhaLrfiqTijxUhLZSToAky4,8029
2
2
  mlrun/__main__.py,sha256=wQNaxW7QsqFBtWffnPkw-497fnpsrQzUnscBQQAP_UM,48364
3
- mlrun/config.py,sha256=3FWf5jbJDJrwfipSXoiNWOQ5A2Vy4FcZl7Ai8Pv4yIg,73057
3
+ mlrun/config.py,sha256=F1PDI88t2cFujGnDr4YslEBzG6SckBKjUSdkxFX3zUE,73149
4
4
  mlrun/errors.py,sha256=bAk0t_qmCxQSPNK0TugOAfA5R6f0G6OYvEvXUWSJ_5U,9062
5
5
  mlrun/execution.py,sha256=wkmT1k0QROgGJFMBIsYUsJaqEF2bkqaYVzp_ZQb527Q,58814
6
6
  mlrun/features.py,sha256=jMEXo6NB36A6iaxNEJWzdtYwUmglYD90OIKTIEeWhE8,15841
@@ -118,7 +118,7 @@ mlrun/db/__init__.py,sha256=WqJ4x8lqJ7ZoKbhEyFqkYADd9P6E3citckx9e9ZLcIU,1163
118
118
  mlrun/db/auth_utils.py,sha256=hpg8D2r82oN0BWabuWN04BTNZ7jYMAF242YSUpK7LFM,5211
119
119
  mlrun/db/base.py,sha256=D4P8jhsp4j3ZPg2tKRTgFgm4hrGAx7kVnmio9qfJZDI,32295
120
120
  mlrun/db/factory.py,sha256=yP2vVmveUE7LYTCHbS6lQIxP9rW--zdISWuPd_I3d_4,2111
121
- mlrun/db/httpdb.py,sha256=-Jl7WsZDFcTSpiSmBrutLoMPGALDjpDYI899i3F9hcw,238788
121
+ mlrun/db/httpdb.py,sha256=q0AggpqHdG5oLukZQUsUOXG26eeXlrvdcTacueNbabY,238789
122
122
  mlrun/db/nopdb.py,sha256=SZqCaCnaijT8-vivdVjj0VvZcZyqzat4YFFhOJlrTtI,28661
123
123
  mlrun/feature_store/__init__.py,sha256=SlI845bWt6xX34SXunHHqhmFAR9-5v2ak8N-qpcAPGo,1328
124
124
  mlrun/feature_store/api.py,sha256=qKj5Tk6prTab6XWatWhBuPRVp0eJEctoxRMN2wz48vA,32168
@@ -229,7 +229,7 @@ mlrun/model_monitoring/__init__.py,sha256=qDQnncjya9XPTlfvGyfWsZWiXc-glGZrrNja-5
229
229
  mlrun/model_monitoring/api.py,sha256=k0eOm-vW8z2u05PwMK2PI2mSAplK0xGIrUe_XWk7mRM,27000
230
230
  mlrun/model_monitoring/controller.py,sha256=2XOkOZRB03K9ph6TH-ICspHga-GQOURL0C8-0GTHaTY,43961
231
231
  mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
232
- mlrun/model_monitoring/helpers.py,sha256=VQ_afyhqzFMOqPdqpkpX3md_afjlkFtsUWIg28zxp5g,23596
232
+ mlrun/model_monitoring/helpers.py,sha256=50oFqgIc5xFHYPIVgq3M-Gbr7epqAI5NgHmvOeMy52U,24667
233
233
  mlrun/model_monitoring/stream_processing.py,sha256=bryYO3D0cC10MAQ-liHxUZ79MrL-VFXCb7KNyj6bl-8,34655
234
234
  mlrun/model_monitoring/writer.py,sha256=rGRFzSOkqZWvD3Y6sVk2H1Gepfnkzkp9ce00PsApTLo,8288
235
235
  mlrun/model_monitoring/applications/__init__.py,sha256=BwlmRELlFJf2b2YMyv5kUSHNe8--OyqWhDgRlT8a_8g,779
@@ -253,7 +253,7 @@ mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py,sha256=dtkaHaWKWE
253
253
  mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=Vj8eWZ6jxXs9nTlo5Du1jJjYutwSNp4ZtztvKsnrr4M,51333
254
254
  mlrun/model_monitoring/db/tsdb/v3io/__init__.py,sha256=aL3bfmQsUQ-sbvKGdNihFj8gLCK3mSys0qDcXtYOwgc,616
255
255
  mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py,sha256=sNQFj6qyJx5eSBKRC3gyTc1cfh1l2IkRpPtuZwtzCW0,6844
256
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=fLzZrtZvJQk22eBT-zUzJfvbrlFwyBB3FbTSgivdLNQ,60242
256
+ mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=3GNMudOpedhu_OId4Gp-r9nj1gtqh_353yn2gWta-BY,61459
257
257
  mlrun/model_monitoring/metrics/__init__.py,sha256=6CsTXAxeLbbf8yfCADTaxmiavqwrLEdYFJ-qc5kgDAY,569
258
258
  mlrun/model_monitoring/metrics/histogram_distance.py,sha256=E9_WIl2vd6qNvoHVHoFcnuQk3ekbFWOdi8aU7sHrfk4,4724
259
259
  mlrun/package/__init__.py,sha256=v7VDyK9kDOOuDvFo4oiGV2fx-vM1KL7fdN9pGLakhUQ,7008
@@ -280,7 +280,7 @@ mlrun/projects/operations.py,sha256=Rc__P5ucNAY2G-lHc2LrnZs15PUbNFt8-NqNNT2Bjpk,
280
280
  mlrun/projects/pipelines.py,sha256=ZOfuIEHOXfuc4qAkuWvbWhCjP6kqpLkv-yBBaY9RXhg,52219
281
281
  mlrun/projects/project.py,sha256=xbh6qXfU9ckkDSTcd-LyPWxHtHzz6gsqDI63ZZQPuhs,256413
282
282
  mlrun/runtimes/__init__.py,sha256=8cqrYKy1a0_87XG7V_p96untQ4t8RocadM4LVEEN1JM,9029
283
- mlrun/runtimes/base.py,sha256=8AMJcTnm9_LSEKLlmmbEzGSCRAoCh3vAQudKzuIVXhY,38285
283
+ mlrun/runtimes/base.py,sha256=LyrF2SmyNN2uBRL-5bUzFxTm186pXywjnFmu5mhtNtA,38483
284
284
  mlrun/runtimes/daskjob.py,sha256=IN6gKKrmCIjWooj5FgFm-pAb2i7ra1ERRzClfu_rYGI,20102
285
285
  mlrun/runtimes/funcdoc.py,sha256=zRFHrJsV8rhDLJwoUhcfZ7Cs0j-tQ76DxwUqdXV_Wyc,9810
286
286
  mlrun/runtimes/function_reference.py,sha256=fnMKUEieKgy4JyVLhFpDtr6JvKgOaQP8F_K2H3-Pk9U,5030
@@ -329,7 +329,7 @@ mlrun/utils/async_http.py,sha256=8Olx8TNNeXB07nEGwlqhEgFgnFAD71vBU_bqaA9JW-w,122
329
329
  mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,3450
330
330
  mlrun/utils/clones.py,sha256=qbAGyEbSvlewn3Tw_DpQZP9z6MGzFhSaZfI1CblX8Fg,7515
331
331
  mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
332
- mlrun/utils/helpers.py,sha256=cN_cVAaJh5T2xE_KgiXTWlXDLM_waIi8PDV3NBj6ioE,83104
332
+ mlrun/utils/helpers.py,sha256=dCISzUwBjGztqsl27-WrznT485nZa7ZliLF_WXw2i_4,83457
333
333
  mlrun/utils/http.py,sha256=5ZU2VpokaUM_DT3HBSqTm8xjUqTPjZN5fKkSIvKlTl0,8704
334
334
  mlrun/utils/logger.py,sha256=uaCgI_ezzaXf7nJDCy-1Nrjds8vSXqDbzmjmb3IyCQo,14864
335
335
  mlrun/utils/regex.py,sha256=FcRwWD8x9X3HLhCCU2F0AVKTFah784Pr7ZAe3a02jw8,5199
@@ -348,11 +348,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
348
348
  mlrun/utils/notifications/notification/slack.py,sha256=wSu_7W0EnGLBNwIgWCYEeTP8j9SPAMPDBnfUcPnVZYA,7299
349
349
  mlrun/utils/notifications/notification/webhook.py,sha256=FM5-LQAKAVJKp37MRzR3SsejalcnpM6r_9Oe7znxZEA,5313
350
350
  mlrun/utils/version/__init__.py,sha256=YnzE6tlf24uOQ8y7Z7l96QLAI6-QEii7-77g8ynmzy0,613
351
- mlrun/utils/version/version.json,sha256=4XxnjcO5M_JMzeQSt05p2f7kyBOjoyz8_C6-mXrlqUs,90
351
+ mlrun/utils/version/version.json,sha256=8LqPKs3owy8BezmiKv4mJzJ7Q6092ElXwEN7UTAst3U,90
352
352
  mlrun/utils/version/version.py,sha256=M2hVhRrgkN3SxacZHs3ZqaOsqAA7B6a22ne324IQ1HE,1877
353
- mlrun-1.10.0rc27.dist-info/licenses/LICENSE,sha256=zTiv1CxWNkOk1q8eJS1G_8oD4gWpWLwWxj_Agcsi8Os,11337
354
- mlrun-1.10.0rc27.dist-info/METADATA,sha256=2-9lgsReCFdnK-z8X5FCT2rdbRvTrkUGErsiib9H1To,26017
355
- mlrun-1.10.0rc27.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
356
- mlrun-1.10.0rc27.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
357
- mlrun-1.10.0rc27.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
358
- mlrun-1.10.0rc27.dist-info/RECORD,,
353
+ mlrun-1.10.0rc28.dist-info/licenses/LICENSE,sha256=zTiv1CxWNkOk1q8eJS1G_8oD4gWpWLwWxj_Agcsi8Os,11337
354
+ mlrun-1.10.0rc28.dist-info/METADATA,sha256=whhfF5YIKLUim-iWuo6lB4V9mzSCh99eaYisXKLAnEI,26017
355
+ mlrun-1.10.0rc28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
356
+ mlrun-1.10.0rc28.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
357
+ mlrun-1.10.0rc28.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
358
+ mlrun-1.10.0rc28.dist-info/RECORD,,