mlrun 1.8.0rc13__py3-none-any.whl → 1.8.0rc16__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.

@@ -66,3 +66,4 @@ class ClientSpec(pydantic.v1.BaseModel):
66
66
  packagers: typing.Optional[dict]
67
67
  external_platform_tracking: typing.Optional[dict]
68
68
  alerts_mode: typing.Optional[str]
69
+ system_id: typing.Optional[str]
@@ -75,6 +75,7 @@ class ModelEndpointCreationStrategy(MonitoringStrEnum):
75
75
  INPLACE = "inplace"
76
76
  ARCHIVE = "archive"
77
77
  OVERWRITE = "overwrite"
78
+ SKIP = "skip"
78
79
 
79
80
 
80
81
  class EventFieldType:
@@ -236,6 +237,7 @@ class ProjectSecretKeys:
236
237
  ACCESS_KEY = "MODEL_MONITORING_ACCESS_KEY"
237
238
  STREAM_PATH = "STREAM_PATH"
238
239
  TSDB_CONNECTION = "TSDB_CONNECTION"
240
+ TSDB_PROFILE_NAME = "TSDB_PROFILE_NAME"
239
241
 
240
242
  @classmethod
241
243
  def mandatory_secrets(cls):
mlrun/common/types.py CHANGED
@@ -31,6 +31,7 @@ class HTTPMethod(StrEnum):
31
31
  POST = "POST"
32
32
  DELETE = "DELETE"
33
33
  PATCH = "PATCH"
34
+ PUT = "PUT"
34
35
 
35
36
 
36
37
  class Operation(StrEnum):
mlrun/config.py CHANGED
@@ -83,7 +83,7 @@ default_config = {
83
83
  "images_to_enrich_registry": "^mlrun/*,python:3.9",
84
84
  "kfp_url": "",
85
85
  "kfp_ttl": "14400", # KFP ttl in sec, after that completed PODs will be deleted
86
- "kfp_image": "mlrun/mlrun", # image to use for KFP runner (defaults to mlrun/mlrun)
86
+ "kfp_image": "mlrun/mlrun-kfp", # image to use for KFP runner (defaults to mlrun/mlrun-kfp)
87
87
  "dask_kfp_image": "mlrun/ml-base", # image to use for dask KFP runner (defaults to mlrun/ml-base)
88
88
  "igz_version": "", # the version of the iguazio system the API is running on
89
89
  "iguazio_api_url": "", # the url to iguazio api
@@ -645,7 +645,7 @@ default_config = {
645
645
  "auto_add_project_secrets": True,
646
646
  "project_secret_name": "mlrun-project-secrets-{project}",
647
647
  "auth_secret_name": "mlrun-auth-secrets.{hashed_access_key}",
648
- "env_variable_prefix": "MLRUN_K8S_SECRET__",
648
+ "env_variable_prefix": "",
649
649
  "global_function_env_secret_name": None,
650
650
  },
651
651
  },
@@ -825,6 +825,7 @@ default_config = {
825
825
  "refresh_interval": "30",
826
826
  }
827
827
  },
828
+ "system_id": "",
828
829
  }
829
830
  _is_running_as_api = None
830
831
 
@@ -580,7 +580,7 @@ def datastore_profile_read(url, project_name="", secrets: typing.Optional[dict]
580
580
  )
581
581
  private_body = get_secret_or_env(project_ds_name_private, secret_provider=secrets)
582
582
  if not public_profile or not private_body:
583
- raise mlrun.errors.MLRunInvalidArgumentError(
583
+ raise mlrun.errors.MLRunNotFoundError(
584
584
  f"Unable to retrieve the datastore profile '{url}' from either the server or local environment. "
585
585
  "Make sure the profile is registered correctly, or if running in a local environment, "
586
586
  "use register_temporary_client_datastore_profile() to provide credentials locally."
mlrun/db/base.py CHANGED
@@ -908,6 +908,14 @@ class RunDBInterface(ABC):
908
908
  ):
909
909
  pass
910
910
 
911
+ def update_alert_activation(
912
+ self,
913
+ activation_id: int,
914
+ activation_time: datetime.datetime,
915
+ notifications_states,
916
+ ):
917
+ pass
918
+
911
919
  @abstractmethod
912
920
  def get_builder_status(
913
921
  self,
mlrun/db/httpdb.py CHANGED
@@ -580,6 +580,7 @@ class HTTPRunDB(RunDBInterface):
580
580
  or config.feature_store.default_targets
581
581
  )
582
582
  config.alerts.mode = server_cfg.get("alerts_mode") or config.alerts.mode
583
+ config.system_id = server_cfg.get("system_id") or config.system_id
583
584
 
584
585
  except Exception as exc:
585
586
  logger.warning(
@@ -773,7 +774,7 @@ class HTTPRunDB(RunDBInterface):
773
774
 
774
775
  response = self.api_call(
775
776
  "POST",
776
- path=f"projects/{project}/runs/{uid}/push_notifications",
777
+ path=f"projects/{project}/runs/{uid}/push-notifications",
777
778
  error="Failed push notifications",
778
779
  timeout=timeout,
779
780
  )
@@ -850,8 +851,9 @@ class HTTPRunDB(RunDBInterface):
850
851
  with_notifications: bool = False,
851
852
  ) -> RunList:
852
853
  """
853
- Retrieve a list of runs, filtered by various options.
854
- If no filter is provided, will return runs from the last week.
854
+ Retrieve a list of runs.
855
+ The default returns the runs from the last week, partitioned by project/name.
856
+ To override the default, specify any filter.
855
857
 
856
858
  Example::
857
859
 
@@ -3844,7 +3846,7 @@ class HTTPRunDB(RunDBInterface):
3844
3846
  """
3845
3847
  self.api_call(
3846
3848
  method=mlrun.common.types.HTTPMethod.PATCH,
3847
- path=f"projects/{project}/model-monitoring/model-monitoring-controller",
3849
+ path=f"projects/{project}/model-monitoring/controller",
3848
3850
  params={
3849
3851
  "base_period": base_period,
3850
3852
  "image": image,
@@ -3880,8 +3882,8 @@ class HTTPRunDB(RunDBInterface):
3880
3882
 
3881
3883
  """
3882
3884
  self.api_call(
3883
- method=mlrun.common.types.HTTPMethod.POST,
3884
- path=f"projects/{project}/model-monitoring/enable-model-monitoring",
3885
+ method=mlrun.common.types.HTTPMethod.PUT,
3886
+ path=f"projects/{project}/model-monitoring/",
3885
3887
  params={
3886
3888
  "base_period": base_period,
3887
3889
  "image": image,
@@ -3925,7 +3927,7 @@ class HTTPRunDB(RunDBInterface):
3925
3927
  """
3926
3928
  response = self.api_call(
3927
3929
  method=mlrun.common.types.HTTPMethod.DELETE,
3928
- path=f"projects/{project}/model-monitoring/disable-model-monitoring",
3930
+ path=f"projects/{project}/model-monitoring/",
3929
3931
  params={
3930
3932
  "delete_resources": delete_resources,
3931
3933
  "delete_stream_function": delete_stream_function,
@@ -4008,8 +4010,8 @@ class HTTPRunDB(RunDBInterface):
4008
4010
  :param image: The image on which the application will run.
4009
4011
  """
4010
4012
  self.api_call(
4011
- method=mlrun.common.types.HTTPMethod.POST,
4012
- path=f"projects/{project}/model-monitoring/deploy-histogram-data-drift-app",
4013
+ method=mlrun.common.types.HTTPMethod.PUT,
4014
+ path=f"projects/{project}/model-monitoring/histogram-data-drift-app",
4013
4015
  params={"image": image},
4014
4016
  )
4015
4017
 
@@ -4027,8 +4029,8 @@ class HTTPRunDB(RunDBInterface):
4027
4029
  :param replace_creds: If True, will override the existing credentials.
4028
4030
  """
4029
4031
  self.api_call(
4030
- method=mlrun.common.types.HTTPMethod.POST,
4031
- path=f"projects/{project}/model-monitoring/set-model-monitoring-credentials",
4032
+ method=mlrun.common.types.HTTPMethod.PUT,
4033
+ path=f"projects/{project}/model-monitoring/credentials",
4032
4034
  params={**credentials, "replace_creds": replace_creds},
4033
4035
  )
4034
4036
 
@@ -16,7 +16,9 @@ import enum
16
16
  import typing
17
17
 
18
18
  import mlrun.common.schemas.secret
19
+ import mlrun.datastore.datastore_profile
19
20
  import mlrun.errors
21
+ import mlrun.model_monitoring.helpers
20
22
 
21
23
  from .base import TSDBConnector
22
24
 
@@ -80,6 +82,13 @@ def get_tsdb_connector(
80
82
  or the provided TSDB connection is invalid.
81
83
  """
82
84
 
85
+ try:
86
+ profile = mlrun.model_monitoring.helpers._get_tsdb_profile(
87
+ project=project, secret_provider=secret_provider
88
+ )
89
+ except mlrun.errors.MLRunNotFoundError:
90
+ profile = None
91
+
83
92
  tsdb_connection_string = (
84
93
  tsdb_connection_string
85
94
  or mlrun.model_monitoring.helpers.get_tsdb_connection_string(
@@ -92,6 +101,9 @@ def get_tsdb_connector(
92
101
  kwargs["connection_string"] = tsdb_connection_string
93
102
  elif tsdb_connection_string and tsdb_connection_string == "v3io":
94
103
  tsdb_connector_type = mlrun.common.schemas.model_monitoring.TSDBTarget.V3IO_TSDB
104
+ elif isinstance(profile, mlrun.datastore.datastore_profile.DatastoreProfileV3io):
105
+ tsdb_connector_type = mlrun.common.schemas.model_monitoring.TSDBTarget.V3IO_TSDB
106
+ kwargs["v3io_access_key"] = profile.v3io_access_key
95
107
  else:
96
108
  raise mlrun.errors.MLRunInvalidMMStoreTypeError(
97
109
  "You must provide a valid tsdb store connection by using "
@@ -108,27 +108,6 @@ class TDEngineSchema:
108
108
  )
109
109
  return f"CREATE TABLE if NOT EXISTS {self.database}.{subtable} USING {self.super_table} TAGS ({tags});"
110
110
 
111
- @staticmethod
112
- def _insert_subtable_stmt(
113
- statement: taosws.TaosStmt,
114
- columns: dict[str, _TDEngineColumn],
115
- subtable: str,
116
- values: dict[str, Union[str, int, float, datetime.datetime]],
117
- ) -> taosws.TaosStmt:
118
- question_marks = ", ".join("?" * len(columns))
119
- statement.prepare(f"INSERT INTO ? VALUES ({question_marks});")
120
- statement.set_tbname(subtable)
121
-
122
- bind_params = []
123
-
124
- for col_name, col_type in columns.items():
125
- val = values[col_name]
126
- bind_params.append(values_to_column([val], col_type))
127
-
128
- statement.bind_param(bind_params)
129
- statement.add_batch()
130
- return statement
131
-
132
111
  def _delete_subtable_query(
133
112
  self,
134
113
  subtable: str,
@@ -26,7 +26,6 @@ import mlrun.common.schemas.model_monitoring as mm_schemas
26
26
  import mlrun.model_monitoring.db.tsdb.tdengine.schemas as tdengine_schemas
27
27
  import mlrun.model_monitoring.db.tsdb.tdengine.stream_graph_steps
28
28
  from mlrun.model_monitoring.db import TSDBConnector
29
- from mlrun.model_monitoring.db.tsdb.tdengine.schemas import TDEngineSchema
30
29
  from mlrun.model_monitoring.helpers import get_invocations_fqn
31
30
  from mlrun.utils import logger
32
31
 
@@ -147,8 +146,9 @@ class TDEngineConnector(TSDBConnector):
147
146
  create_table_sql = table._create_subtable_sql(subtable=table_name, values=event)
148
147
 
149
148
  insert_statement = Statement(
150
- TDEngineSchema._insert_subtable_stmt,
151
- dict(columns=table.columns, subtable=table_name, values=event),
149
+ columns=table.columns,
150
+ subtable=table_name,
151
+ values=event,
152
152
  )
153
153
 
154
154
  self.connection.run(
@@ -58,6 +58,7 @@ class V3IOTSDBConnector(TSDBConnector):
58
58
  project: str,
59
59
  container: str = _CONTAINER,
60
60
  v3io_framesd: Optional[str] = None,
61
+ v3io_access_key: str = "",
61
62
  create_table: bool = False,
62
63
  ) -> None:
63
64
  super().__init__(project=project)
@@ -65,6 +66,7 @@ class V3IOTSDBConnector(TSDBConnector):
65
66
  self.container = container
66
67
 
67
68
  self.v3io_framesd = v3io_framesd or mlrun.mlconf.v3io_framesd
69
+ self._v3io_access_key = v3io_access_key
68
70
  self._frames_client: Optional[v3io_frames.client.ClientBase] = None
69
71
  self._init_tables_path()
70
72
  self._create_table = create_table
@@ -72,7 +74,9 @@ class V3IOTSDBConnector(TSDBConnector):
72
74
  @property
73
75
  def frames_client(self) -> v3io_frames.client.ClientBase:
74
76
  if not self._frames_client:
75
- self._frames_client = self._get_v3io_frames_client(self.container)
77
+ self._frames_client = self._get_v3io_frames_client(
78
+ self.container, v3io_access_key=self._v3io_access_key
79
+ )
76
80
  if self._create_table:
77
81
  self.create_tables()
78
82
  return self._frames_client
@@ -564,10 +568,13 @@ class V3IOTSDBConnector(TSDBConnector):
564
568
  return source_directory
565
569
 
566
570
  @staticmethod
567
- def _get_v3io_frames_client(v3io_container: str) -> v3io_frames.client.ClientBase:
571
+ def _get_v3io_frames_client(
572
+ v3io_container: str, v3io_access_key: str = ""
573
+ ) -> v3io_frames.client.ClientBase:
568
574
  return mlrun.utils.v3io_clients.get_frames_client(
569
575
  address=mlrun.mlconf.v3io_framesd,
570
576
  container=v3io_container,
577
+ token=v3io_access_key,
571
578
  )
572
579
 
573
580
  def read_metrics_data(
@@ -32,6 +32,7 @@ import mlrun.artifacts
32
32
  import mlrun.common.model_monitoring.helpers
33
33
  import mlrun.common.schemas.model_monitoring.constants as mm_constants
34
34
  import mlrun.data_types.infer
35
+ import mlrun.datastore.datastore_profile
35
36
  import mlrun.model_monitoring
36
37
  import mlrun.utils.helpers
37
38
  from mlrun.common.schemas import ModelEndpoint
@@ -244,6 +245,29 @@ def get_tsdb_connection_string(
244
245
  )
245
246
 
246
247
 
248
+ def _get_tsdb_profile(
249
+ project: str = "",
250
+ secret_provider: typing.Optional[typing.Callable[[str], str]] = None,
251
+ ) -> mlrun.datastore.datastore_profile.DatastoreProfile:
252
+ """
253
+ Get TSDB datastore profile the project name and secret provider.
254
+
255
+ :param project: The project name. If not set, the default project name is used.
256
+ :param secret_provider: Optional secret provider to get the connection string secret.
257
+ If not set, the env vars are used.
258
+ :return: TSDB datastore profile.
259
+ """
260
+ profile_name = mlrun.get_secret_or_env(
261
+ key=mm_constants.ProjectSecretKeys.TSDB_PROFILE_NAME,
262
+ secret_provider=secret_provider,
263
+ )
264
+ if not profile_name:
265
+ raise mlrun.errors.MLRunNotFoundError("Not found TSDB profile name")
266
+ return mlrun.datastore.datastore_profile.datastore_profile_read(
267
+ url=f"ds://{profile_name}", project_name=project, secrets=secret_provider
268
+ )
269
+
270
+
247
271
  def batch_dict2timedelta(batch_dict: _BatchDict) -> datetime.timedelta:
248
272
  """
249
273
  Convert a batch dictionary to timedelta.
@@ -646,10 +646,14 @@ class _KFPRunner(_PipelineRunner):
646
646
  func_name=func.metadata.name,
647
647
  exc_info=err_to_str(exc),
648
648
  )
649
- project.notifiers.push_pipeline_start_message(
650
- project.metadata.name,
651
- context.uid,
652
- )
649
+
650
+ # TODO: we should check how can we get the run uid when we don't have the context (for example on
651
+ # mlrun.load_project() and later call directly to project.run)
652
+ if context:
653
+ project.notifiers.push_pipeline_start_message(
654
+ project.metadata.name,
655
+ context.uid,
656
+ )
653
657
  pipeline_context.clear()
654
658
  return _PipelineRunStatus(run_id, cls, project=project, workflow=workflow_spec)
655
659
 
mlrun/projects/project.py CHANGED
@@ -44,6 +44,7 @@ import mlrun.common.runtimes.constants
44
44
  import mlrun.common.schemas.alert
45
45
  import mlrun.common.schemas.artifact
46
46
  import mlrun.common.schemas.model_monitoring.constants as mm_constants
47
+ import mlrun.datastore.datastore_profile
47
48
  import mlrun.db
48
49
  import mlrun.errors
49
50
  import mlrun.k8s_utils
@@ -3579,8 +3580,6 @@ class MlrunProject(ModelObj):
3579
3580
  * None - will be set from the system configuration.
3580
3581
  * v3io - for v3io endpoint store, pass `v3io` and the system will generate the
3581
3582
  exact path.
3582
- * MySQL/SQLite - for SQL endpoint store, provide the full connection string,
3583
- for example: mysql+pymysql://<username>:<password>@<host>:<port>/<db_name>
3584
3583
  :param stream_path: Path to the model monitoring stream. By default, None. Options:
3585
3584
 
3586
3585
  * None - will be set from the system configuration.
@@ -3603,12 +3602,18 @@ class MlrunProject(ModelObj):
3603
3602
  & tracked model server.
3604
3603
  """
3605
3604
  db = mlrun.db.get_run_db(secrets=self._secrets)
3605
+ if tsdb_connection == "v3io":
3606
+ profile = mlrun.datastore.datastore_profile.DatastoreProfileV3io(
3607
+ name="mm-infra-tsdb"
3608
+ )
3609
+ self.register_datastore_profile(profile)
3606
3610
  db.set_model_monitoring_credentials(
3607
3611
  project=self.name,
3608
3612
  credentials={
3609
3613
  "access_key": access_key,
3610
3614
  "stream_path": stream_path,
3611
3615
  "tsdb_connection": tsdb_connection,
3616
+ "tsdb_profile_name": profile.name,
3612
3617
  },
3613
3618
  replace_creds=replace_creds,
3614
3619
  )
@@ -4519,7 +4524,9 @@ class MlrunProject(ModelObj):
4519
4524
  last_update_time_to: Optional[datetime.datetime] = None,
4520
4525
  **kwargs,
4521
4526
  ) -> mlrun.lists.RunList:
4522
- """Retrieve a list of runs, filtered by various options.
4527
+ """Retrieve a list of runs.
4528
+ The default returns the runs from the last week, partitioned by name.
4529
+ To override the default, specify any filter.
4523
4530
 
4524
4531
  The returned result is a `` (list of dict), use `.to_objects()` to convert it to a list of RunObjects,
4525
4532
  `.show()` to view graphically in Jupyter, `.to_df()` to convert to a DataFrame, and `compare()` to
mlrun/secrets.py CHANGED
@@ -151,7 +151,7 @@ def get_secret_or_env(
151
151
  secret_provider: Union[dict, SecretsStore, Callable, None] = None,
152
152
  default: Optional[str] = None,
153
153
  prefix: Optional[str] = None,
154
- ) -> str:
154
+ ) -> Optional[str]:
155
155
  """Retrieve value of a secret, either from a user-provided secret store, or from environment variables.
156
156
  The function will retrieve a secret value, attempting to find it according to the following order:
157
157
 
mlrun/serving/routers.py CHANGED
@@ -30,7 +30,6 @@ import mlrun.common.model_monitoring
30
30
  import mlrun.common.schemas.model_monitoring
31
31
  from mlrun.utils import logger, now_date
32
32
 
33
- from .server import GraphServer
34
33
  from .utils import RouterToDict, _extract_input_data, _update_result_body
35
34
  from .v2_serving import _ModelLogPusher
36
35
 
@@ -607,24 +606,24 @@ class VotingEnsemble(ParallelRun):
607
606
  self.prediction_col_name = prediction_col_name or "prediction"
608
607
  self.format_response_with_col_name_flag = format_response_with_col_name_flag
609
608
  self.model_endpoint_uid = None
609
+ self.model_endpoint = None
610
610
  self.shard_by_endpoint = shard_by_endpoint
611
611
 
612
612
  def post_init(self, mode="sync", **kwargs):
613
- server = getattr(self.context, "_server", None) or getattr(
614
- self.context, "server", None
615
- )
613
+ server: mlrun.serving.GraphServer = getattr(
614
+ self.context, "_server", None
615
+ ) or getattr(self.context, "server", None)
616
616
  if not server:
617
617
  logger.warn("GraphServer not initialized for VotingEnsemble instance")
618
618
  return
619
-
620
619
  if not self.context.is_mock or self.context.monitoring_mock:
621
- self.model_endpoint_uid = _init_endpoint_record(
622
- server,
623
- self,
624
- creation_strategy=kwargs.get("creation_strategy"),
625
- endpoint_type=kwargs.get("endpoint_type"),
620
+ self.model_endpoint = mlrun.get_run_db().get_model_endpoint(
621
+ project=server.project,
622
+ name=self.name,
623
+ function_name=server.function_name,
624
+ function_tag=server.function_tag or "latest",
626
625
  )
627
-
626
+ self.model_endpoint_uid = self.model_endpoint.metadata.uid
628
627
  self._update_weights(self.weights)
629
628
 
630
629
  def _resolve_route(self, body, urlpath):
@@ -1004,81 +1003,6 @@ class VotingEnsemble(ParallelRun):
1004
1003
  self._weights[model] = 0
1005
1004
 
1006
1005
 
1007
- def _init_endpoint_record(
1008
- graph_server: GraphServer,
1009
- voting_ensemble: VotingEnsemble,
1010
- creation_strategy: mlrun.common.schemas.ModelEndpointCreationStrategy,
1011
- endpoint_type: mlrun.common.schemas.EndpointType,
1012
- ) -> Union[str, None]:
1013
- """
1014
- Initialize model endpoint record and write it into the DB. In general, this method retrieve the unique model
1015
- endpoint ID which is generated according to the function uri and the model version. If the model endpoint is
1016
- already exist in the DB, we skip the creation process. Otherwise, it writes the new model endpoint record to the DB.
1017
-
1018
- :param graph_server: A GraphServer object which will be used for getting the function uri.
1019
- :param voting_ensemble: Voting ensemble serving class. It contains important details for the model endpoint record
1020
- such as model name, model path, model version, and the ids of the children model endpoints.
1021
- :param creation_strategy: Strategy for creating or updating the model endpoint:
1022
- * **overwrite**:
1023
- 1. If model endpoints with the same name exist, delete the `latest` one.
1024
- 2. Create a new model endpoint entry and set it as `latest`.
1025
- * **inplace** (default):
1026
- 1. If model endpoints with the same name exist, update the `latest` entry.
1027
- 2. Otherwise, create a new entry.
1028
- * **archive**:
1029
- 1. If model endpoints with the same name exist, preserve them.
1030
- 2. Create a new model endpoint with the same name and set it to `latest`.
1031
-
1032
- :param endpoint_type: model endpoint type
1033
- :return: Model endpoint unique ID.
1034
- """
1035
-
1036
- logger.info("Initializing endpoint records")
1037
- children_uids = []
1038
- children_names = []
1039
- for _, c in voting_ensemble.routes.items():
1040
- if hasattr(c, "endpoint_uid"):
1041
- children_uids.append(c.endpoint_uid)
1042
- children_names.append(c.name)
1043
- try:
1044
- logger.info(
1045
- "Creating Or Updating a new model endpoint record",
1046
- name=voting_ensemble.name,
1047
- project=graph_server.project,
1048
- function_name=graph_server.function_name,
1049
- function_tag=graph_server.function_tag or "latest",
1050
- model_class=voting_ensemble.__class__.__name__,
1051
- creation_strategy=creation_strategy,
1052
- )
1053
- model_endpoint = mlrun.common.schemas.ModelEndpoint(
1054
- metadata=mlrun.common.schemas.ModelEndpointMetadata(
1055
- project=graph_server.project,
1056
- name=voting_ensemble.name,
1057
- endpoint_type=endpoint_type,
1058
- ),
1059
- spec=mlrun.common.schemas.ModelEndpointSpec(
1060
- function_name=graph_server.function_name,
1061
- function_tag=graph_server.function_tag or "latest",
1062
- model_class=voting_ensemble.__class__.__name__,
1063
- children_uids=children_uids,
1064
- children=children_names,
1065
- ),
1066
- status=mlrun.common.schemas.ModelEndpointStatus(
1067
- monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled
1068
- if voting_ensemble.context.server.track_models
1069
- else mlrun.common.schemas.model_monitoring.ModelMonitoringMode.disabled,
1070
- ),
1071
- )
1072
- db = mlrun.get_run_db()
1073
- db.create_model_endpoint(
1074
- model_endpoint=model_endpoint, creation_strategy=creation_strategy
1075
- )
1076
- except mlrun.errors.MLRunInvalidArgumentError as e:
1077
- logger.info("Failed to create model endpoint record", error=e)
1078
- return None
1079
- return model_endpoint.metadata.uid
1080
-
1081
-
1082
1006
  class EnrichmentModelRouter(ModelRouter):
1083
1007
  """
1084
1008
  Model router with feature enrichment and imputing
mlrun/serving/states.py CHANGED
@@ -428,7 +428,7 @@ class TaskStep(BaseStep):
428
428
  result_path: Optional[str] = None,
429
429
  model_endpoint_creation_strategy: Optional[
430
430
  schemas.ModelEndpointCreationStrategy
431
- ] = schemas.ModelEndpointCreationStrategy.INPLACE,
431
+ ] = schemas.ModelEndpointCreationStrategy.SKIP,
432
432
  endpoint_type: Optional[schemas.EndpointType] = schemas.EndpointType.NODE_EP,
433
433
  ):
434
434
  super().__init__(name, after)
@@ -723,6 +723,11 @@ class RouterStep(TaskStep):
723
723
  self._routes: ObjectDict = None
724
724
  self.routes = routes
725
725
  self.endpoint_type = schemas.EndpointType.ROUTER
726
+ self.model_endpoint_creation_strategy = (
727
+ schemas.ModelEndpointCreationStrategy.INPLACE
728
+ if class_name and "serving.VotingEnsemble" in class_name
729
+ else schemas.ModelEndpointCreationStrategy.SKIP
730
+ )
726
731
 
727
732
  def get_children(self):
728
733
  """get child steps (routes)"""
@@ -15,7 +15,7 @@
15
15
  import threading
16
16
  import time
17
17
  import traceback
18
- from typing import Optional, Union
18
+ from typing import Optional
19
19
 
20
20
  import mlrun.artifacts
21
21
  import mlrun.common.model_monitoring.helpers
@@ -23,7 +23,6 @@ import mlrun.common.schemas.model_monitoring
23
23
  import mlrun.model_monitoring
24
24
  from mlrun.utils import logger, now_date
25
25
 
26
- from .server import GraphServer
27
26
  from .utils import StepToDict, _extract_input_data, _update_result_body
28
27
 
29
28
 
@@ -114,8 +113,8 @@ class V2ModelServer(StepToDict):
114
113
  if model:
115
114
  self.model = model
116
115
  self.ready = True
117
- self._versioned_model_name = None
118
116
  self.model_endpoint_uid = None
117
+ self.model_endpoint = None
119
118
  self.shard_by_endpoint = shard_by_endpoint
120
119
  self._model_logger = None
121
120
 
@@ -139,20 +138,23 @@ class V2ModelServer(StepToDict):
139
138
  else:
140
139
  self._load_and_update_state()
141
140
 
142
- server = getattr(self.context, "_server", None) or getattr(
143
- self.context, "server", None
144
- )
141
+ server: mlrun.serving.GraphServer = getattr(
142
+ self.context, "_server", None
143
+ ) or getattr(self.context, "server", None)
145
144
  if not server:
146
145
  logger.warn("GraphServer not initialized for VotingEnsemble instance")
147
146
  return
148
147
 
148
+ if not self.context.is_mock and not self.model_spec:
149
+ self.get_model()
149
150
  if not self.context.is_mock or self.context.monitoring_mock:
150
- self.model_endpoint_uid = _init_endpoint_record(
151
- graph_server=server,
152
- model=self,
153
- creation_strategy=kwargs.get("creation_strategy"),
154
- endpoint_type=kwargs.get("endpoint_type"),
151
+ self.model_endpoint = mlrun.get_run_db().get_model_endpoint(
152
+ project=server.project,
153
+ name=self.name,
154
+ function_name=server.function_name,
155
+ function_tag=server.function_tag or "latest",
155
156
  )
157
+ self.model_endpoint_uid = self.model_endpoint.metadata.uid
156
158
  self._model_logger = (
157
159
  _ModelLogPusher(self, self.context)
158
160
  if self.context and self.context.stream.enabled
@@ -233,23 +235,6 @@ class V2ModelServer(StepToDict):
233
235
  request = self.preprocess(event_body, op)
234
236
  return self.validate(request, op)
235
237
 
236
- @property
237
- def versioned_model_name(self):
238
- if self._versioned_model_name:
239
- return self._versioned_model_name
240
-
241
- # Generating version model value based on the model name and model version
242
- if self.model_path and self.model_path.startswith("store://"):
243
- # Enrich the model server with the model artifact metadata
244
- self.get_model()
245
- if not self.version:
246
- # Enrich the model version with the model artifact tag
247
- self.version = self.model_spec.tag
248
- self.labels = self.model_spec.labels
249
- version = self.version or "latest"
250
- self._versioned_model_name = f"{self.name}:{version}"
251
- return self._versioned_model_name
252
-
253
238
  def do_event(self, event, *args, **kwargs):
254
239
  """main model event handler method"""
255
240
  start = now_date()
@@ -553,95 +538,3 @@ class _ModelLogPusher:
553
538
  if getattr(self.model, "metrics", None):
554
539
  data["metrics"] = self.model.metrics
555
540
  self.output_stream.push([data], partition_key=partition_key)
556
-
557
-
558
- def _init_endpoint_record(
559
- graph_server: GraphServer,
560
- model: V2ModelServer,
561
- creation_strategy: mlrun.common.schemas.ModelEndpointCreationStrategy,
562
- endpoint_type: mlrun.common.schemas.EndpointType,
563
- ) -> Union[str, None]:
564
- """
565
- Initialize model endpoint record and write it into the DB. In general, this method retrieve the unique model
566
- endpoint ID which is generated according to the function uri and the model version. If the model endpoint is
567
- already exist in the DB, we skip the creation process. Otherwise, it writes the new model endpoint record to the DB.
568
-
569
- :param graph_server: A GraphServer object which will be used for getting the function uri.
570
- :param model: Base model serving class (v2). It contains important details for the model endpoint record
571
- such as model name, model path, and model version.
572
- :param creation_strategy: Strategy for creating or updating the model endpoint:
573
- * **overwrite**:
574
- 1. If model endpoints with the same name exist, delete the `latest` one.
575
- 2. Create a new model endpoint entry and set it as `latest`.
576
- * **inplace** (default):
577
- 1. If model endpoints with the same name exist, update the `latest` entry.
578
- 2. Otherwise, create a new entry.
579
- * **archive**:
580
- 1. If model endpoints with the same name exist, preserve them.
581
- 2. Create a new model endpoint with the same name and set it to `latest`.
582
- :param endpoint_type model endpoint type
583
-
584
- :return: Model endpoint unique ID.
585
- """
586
-
587
- logger.info("Initializing endpoint records")
588
- if not model.model_spec:
589
- model.get_model()
590
- if model.model_spec:
591
- model_name = model.model_spec.metadata.key
592
- model_db_key = model.model_spec.spec.db_key
593
- model_uid = model.model_spec.metadata.uid
594
- model_tag = model.model_spec.tag
595
- model_labels = model.model_spec.labels # todo : check if we still need this
596
- else:
597
- model_name = None
598
- model_db_key = None
599
- model_uid = None
600
- model_tag = None
601
- model_labels = {}
602
- logger.info(
603
- "Creating Or Updating a new model endpoint record",
604
- name=model.name,
605
- project=graph_server.project,
606
- function_name=graph_server.function_name,
607
- function_tag=graph_server.function_tag or "latest",
608
- model_name=model_name,
609
- model_tag=model_tag,
610
- model_db_key=model_db_key,
611
- model_uid=model_uid,
612
- model_class=model.__class__.__name__,
613
- creation_strategy=creation_strategy,
614
- endpoint_type=endpoint_type,
615
- )
616
- try:
617
- model_ep = mlrun.common.schemas.ModelEndpoint(
618
- metadata=mlrun.common.schemas.ModelEndpointMetadata(
619
- project=graph_server.project,
620
- labels=model_labels,
621
- name=model.name,
622
- endpoint_type=endpoint_type,
623
- ),
624
- spec=mlrun.common.schemas.ModelEndpointSpec(
625
- function_name=graph_server.function_name,
626
- function_tag=graph_server.function_tag or "latest",
627
- model_name=model_name,
628
- model_db_key=model_db_key,
629
- model_uid=model_uid,
630
- model_class=model.__class__.__name__,
631
- model_tag=model_tag,
632
- ),
633
- status=mlrun.common.schemas.ModelEndpointStatus(
634
- monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled
635
- if model.context.server.track_models
636
- else mlrun.common.schemas.model_monitoring.ModelMonitoringMode.disabled,
637
- ),
638
- )
639
- db = mlrun.get_run_db()
640
- model_ep = db.create_model_endpoint(
641
- model_endpoint=model_ep, creation_strategy=creation_strategy
642
- )
643
- except mlrun.errors.MLRunBadRequestError as e:
644
- logger.info("Failed to create model endpoint record", error=e)
645
- return None
646
-
647
- return model_ep.metadata.uid
mlrun/utils/helpers.py CHANGED
@@ -26,7 +26,7 @@ import sys
26
26
  import typing
27
27
  import uuid
28
28
  import warnings
29
- from datetime import datetime, timezone
29
+ from datetime import datetime, timedelta, timezone
30
30
  from importlib import import_module, reload
31
31
  from os import path
32
32
  from types import ModuleType
@@ -405,6 +405,28 @@ def now_date(tz: timezone = timezone.utc) -> datetime:
405
405
  return datetime.now(tz=tz)
406
406
 
407
407
 
408
+ def datetime_to_mysql_ts(datetime_object: datetime) -> datetime:
409
+ """
410
+ Convert a Python datetime object to a MySQL-compatible timestamp string,
411
+ rounded to the nearest millisecond.
412
+ Example: 2024-12-18T16:36:05.235687+00:00 -> 2024-12-18T16:36:05.236000
413
+
414
+ :param datetime_object: A Python datetime object.
415
+
416
+ :return: A MySQL-compatible timestamp string with millisecond precision.
417
+ """
418
+ if not datetime_object.tzinfo:
419
+ datetime_object = datetime_object.replace(tzinfo=timezone.utc)
420
+
421
+ # Round to the nearest millisecond
422
+ ms = round(datetime_object.microsecond / 1000) * 1000
423
+ if ms == 1000000:
424
+ datetime_object += timedelta(seconds=1)
425
+ ms = 0
426
+
427
+ return datetime_object.replace(microsecond=ms)
428
+
429
+
408
430
  def datetime_min(tz: timezone = timezone.utc) -> datetime:
409
431
  return datetime(1970, 1, 1, tzinfo=tz)
410
432
 
@@ -1,4 +1,4 @@
1
1
  {
2
- "git_commit": "6b23c9dc1a77d33bf56dd6e91623278630bb46c4",
3
- "version": "1.8.0-rc13"
2
+ "git_commit": "91e7d7fface3fc912eced8be04916b5e0628fda4",
3
+ "version": "1.8.0-rc16"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mlrun
3
- Version: 1.8.0rc13
3
+ Version: 1.8.0rc16
4
4
  Summary: Tracking and config of machine learning runs
5
5
  Home-page: https://github.com/mlrun/mlrun
6
6
  Author: Yaron Haviv
@@ -31,7 +31,7 @@ Requires-Dist: ipython~=8.10
31
31
  Requires-Dist: nuclio-jupyter~=0.11.1
32
32
  Requires-Dist: numpy<1.27.0,>=1.26.4
33
33
  Requires-Dist: pandas<2.2,>=1.2
34
- Requires-Dist: pyarrow<18,>=10.0
34
+ Requires-Dist: pyarrow<17,>=10.0
35
35
  Requires-Dist: pyyaml<7,>=6.0.2
36
36
  Requires-Dist: requests~=2.32
37
37
  Requires-Dist: tabulate~=0.8.6
@@ -51,10 +51,12 @@ Requires-Dist: setuptools>=75.2
51
51
  Requires-Dist: deprecated~=1.2
52
52
  Requires-Dist: jinja2>=3.1.3,~=3.1
53
53
  Requires-Dist: orjson<4,>=3.9.15
54
- Requires-Dist: mlrun-pipelines-kfp-common~=0.2.3
55
- Requires-Dist: mlrun-pipelines-kfp-v1-8~=0.2.3; python_version < "3.11"
54
+ Requires-Dist: mlrun-pipelines-kfp-common~=0.3.3
55
+ Requires-Dist: mlrun-pipelines-kfp-v1-8~=0.3.3; python_version < "3.11"
56
56
  Requires-Dist: docstring_parser~=0.16
57
57
  Requires-Dist: aiosmtplib~=3.0
58
+ Requires-Dist: grpcio-tools~=1.48.2; python_version < "3.11"
59
+ Requires-Dist: grpcio~=1.48.2; python_version < "3.11"
58
60
  Provides-Extra: s3
59
61
  Requires-Dist: boto3<1.36,>=1.28.0; extra == "s3"
60
62
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "s3"
@@ -86,9 +88,9 @@ Requires-Dist: avro~=1.11; extra == "kafka"
86
88
  Provides-Extra: redis
87
89
  Requires-Dist: redis~=4.3; extra == "redis"
88
90
  Provides-Extra: mlflow
89
- Requires-Dist: mlflow~=2.8; extra == "mlflow"
91
+ Requires-Dist: mlflow~=2.16; extra == "mlflow"
90
92
  Provides-Extra: databricks-sdk
91
- Requires-Dist: databricks-sdk~=0.13.0; extra == "databricks-sdk"
93
+ Requires-Dist: databricks-sdk~=0.20.0; extra == "databricks-sdk"
92
94
  Provides-Extra: sqlalchemy
93
95
  Requires-Dist: sqlalchemy~=1.4; extra == "sqlalchemy"
94
96
  Provides-Extra: dask
@@ -99,9 +101,11 @@ Requires-Dist: ossfs==2023.12.0; extra == "alibaba-oss"
99
101
  Requires-Dist: oss2==2.18.1; extra == "alibaba-oss"
100
102
  Provides-Extra: tdengine
101
103
  Requires-Dist: taos-ws-py==0.3.2; extra == "tdengine"
102
- Requires-Dist: taoswswrap~=0.2.0; extra == "tdengine"
104
+ Requires-Dist: taoswswrap~=0.3.0; extra == "tdengine"
103
105
  Provides-Extra: snowflake
104
106
  Requires-Dist: snowflake-connector-python~=3.7; extra == "snowflake"
107
+ Provides-Extra: kfp18
108
+ Requires-Dist: mlrun_pipelines_kfp_v1_8[kfp]>=0.3.2; python_version < "3.11" and extra == "kfp18"
105
109
  Provides-Extra: api
106
110
  Requires-Dist: uvicorn~=0.32.1; extra == "api"
107
111
  Requires-Dist: dask-kubernetes~=0.11.0; extra == "api"
@@ -116,6 +120,8 @@ Requires-Dist: alembic~=1.14; extra == "api"
116
120
  Requires-Dist: timelength~=1.1; extra == "api"
117
121
  Requires-Dist: memray~=1.12; sys_platform != "win32" and extra == "api"
118
122
  Requires-Dist: aiosmtplib~=3.0; extra == "api"
123
+ Requires-Dist: pydantic<2,>=1; extra == "api"
124
+ Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.3; python_version < "3.11" and extra == "api"
119
125
  Provides-Extra: all
120
126
  Requires-Dist: adlfs==2023.9.0; extra == "all"
121
127
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "all"
@@ -126,7 +132,7 @@ Requires-Dist: azure-keyvault-secrets~=4.2; extra == "all"
126
132
  Requires-Dist: bokeh>=2.4.2,~=2.4; extra == "all"
127
133
  Requires-Dist: boto3<1.36,>=1.28.0; extra == "all"
128
134
  Requires-Dist: dask~=2023.12.1; extra == "all"
129
- Requires-Dist: databricks-sdk~=0.13.0; extra == "all"
135
+ Requires-Dist: databricks-sdk~=0.20.0; extra == "all"
130
136
  Requires-Dist: distributed~=2023.12.1; extra == "all"
131
137
  Requires-Dist: gcsfs<2024.7,>=2023.9.2; extra == "all"
132
138
  Requires-Dist: google-cloud-bigquery-storage~=2.17; extra == "all"
@@ -135,7 +141,7 @@ Requires-Dist: google-cloud-storage==2.14.0; extra == "all"
135
141
  Requires-Dist: google-cloud==0.34; extra == "all"
136
142
  Requires-Dist: graphviz~=0.20.0; extra == "all"
137
143
  Requires-Dist: kafka-python~=2.0; extra == "all"
138
- Requires-Dist: mlflow~=2.8; extra == "all"
144
+ Requires-Dist: mlflow~=2.16; extra == "all"
139
145
  Requires-Dist: msrest~=0.6.21; extra == "all"
140
146
  Requires-Dist: oss2==2.18.1; extra == "all"
141
147
  Requires-Dist: ossfs==2023.12.0; extra == "all"
@@ -146,7 +152,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "all"
146
152
  Requires-Dist: snowflake-connector-python~=3.7; extra == "all"
147
153
  Requires-Dist: sqlalchemy~=1.4; extra == "all"
148
154
  Requires-Dist: taos-ws-py==0.3.2; extra == "all"
149
- Requires-Dist: taoswswrap~=0.2.0; extra == "all"
155
+ Requires-Dist: taoswswrap~=0.3.0; extra == "all"
150
156
  Provides-Extra: complete
151
157
  Requires-Dist: adlfs==2023.9.0; extra == "complete"
152
158
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "complete"
@@ -156,7 +162,7 @@ Requires-Dist: azure-identity~=1.5; extra == "complete"
156
162
  Requires-Dist: azure-keyvault-secrets~=4.2; extra == "complete"
157
163
  Requires-Dist: boto3<1.36,>=1.28.0; extra == "complete"
158
164
  Requires-Dist: dask~=2023.12.1; extra == "complete"
159
- Requires-Dist: databricks-sdk~=0.13.0; extra == "complete"
165
+ Requires-Dist: databricks-sdk~=0.20.0; extra == "complete"
160
166
  Requires-Dist: distributed~=2023.12.1; extra == "complete"
161
167
  Requires-Dist: gcsfs<2024.7,>=2023.9.2; extra == "complete"
162
168
  Requires-Dist: google-cloud-bigquery-storage~=2.17; extra == "complete"
@@ -165,7 +171,7 @@ Requires-Dist: google-cloud-storage==2.14.0; extra == "complete"
165
171
  Requires-Dist: google-cloud==0.34; extra == "complete"
166
172
  Requires-Dist: graphviz~=0.20.0; extra == "complete"
167
173
  Requires-Dist: kafka-python~=2.0; extra == "complete"
168
- Requires-Dist: mlflow~=2.8; extra == "complete"
174
+ Requires-Dist: mlflow~=2.16; extra == "complete"
169
175
  Requires-Dist: msrest~=0.6.21; extra == "complete"
170
176
  Requires-Dist: oss2==2.18.1; extra == "complete"
171
177
  Requires-Dist: ossfs==2023.12.0; extra == "complete"
@@ -176,7 +182,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "complete"
176
182
  Requires-Dist: snowflake-connector-python~=3.7; extra == "complete"
177
183
  Requires-Dist: sqlalchemy~=1.4; extra == "complete"
178
184
  Requires-Dist: taos-ws-py==0.3.2; extra == "complete"
179
- Requires-Dist: taoswswrap~=0.2.0; extra == "complete"
185
+ Requires-Dist: taoswswrap~=0.3.0; extra == "complete"
180
186
  Provides-Extra: complete-api
181
187
  Requires-Dist: adlfs==2023.9.0; extra == "complete-api"
182
188
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "complete-api"
@@ -190,7 +196,7 @@ Requires-Dist: azure-keyvault-secrets~=4.2; extra == "complete-api"
190
196
  Requires-Dist: boto3<1.36,>=1.28.0; extra == "complete-api"
191
197
  Requires-Dist: dask-kubernetes~=0.11.0; extra == "complete-api"
192
198
  Requires-Dist: dask~=2023.12.1; extra == "complete-api"
193
- Requires-Dist: databricks-sdk~=0.13.0; extra == "complete-api"
199
+ Requires-Dist: databricks-sdk~=0.20.0; extra == "complete-api"
194
200
  Requires-Dist: distributed~=2023.12.1; extra == "complete-api"
195
201
  Requires-Dist: fastapi~=0.115.6; extra == "complete-api"
196
202
  Requires-Dist: gcsfs<2024.7,>=2023.9.2; extra == "complete-api"
@@ -203,12 +209,14 @@ Requires-Dist: humanfriendly~=10.0; extra == "complete-api"
203
209
  Requires-Dist: igz-mgmt~=0.4.1; extra == "complete-api"
204
210
  Requires-Dist: kafka-python~=2.0; extra == "complete-api"
205
211
  Requires-Dist: memray~=1.12; sys_platform != "win32" and extra == "complete-api"
206
- Requires-Dist: mlflow~=2.8; extra == "complete-api"
212
+ Requires-Dist: mlflow~=2.16; extra == "complete-api"
213
+ Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.3; python_version < "3.11" and extra == "complete-api"
207
214
  Requires-Dist: msrest~=0.6.21; extra == "complete-api"
208
215
  Requires-Dist: objgraph~=3.6; extra == "complete-api"
209
216
  Requires-Dist: oss2==2.18.1; extra == "complete-api"
210
217
  Requires-Dist: ossfs==2023.12.0; extra == "complete-api"
211
218
  Requires-Dist: plotly~=5.23; extra == "complete-api"
219
+ Requires-Dist: pydantic<2,>=1; extra == "complete-api"
212
220
  Requires-Dist: pymysql~=1.1; extra == "complete-api"
213
221
  Requires-Dist: pyopenssl>=23; extra == "complete-api"
214
222
  Requires-Dist: redis~=4.3; extra == "complete-api"
@@ -216,7 +224,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "complete-api"
216
224
  Requires-Dist: snowflake-connector-python~=3.7; extra == "complete-api"
217
225
  Requires-Dist: sqlalchemy~=1.4; extra == "complete-api"
218
226
  Requires-Dist: taos-ws-py==0.3.2; extra == "complete-api"
219
- Requires-Dist: taoswswrap~=0.2.0; extra == "complete-api"
227
+ Requires-Dist: taoswswrap~=0.3.0; extra == "complete-api"
220
228
  Requires-Dist: timelength~=1.1; extra == "complete-api"
221
229
  Requires-Dist: uvicorn~=0.32.1; extra == "complete-api"
222
230
 
@@ -1,6 +1,6 @@
1
1
  mlrun/__init__.py,sha256=7vuMpUiigXXDrghLRq680LKWy1faC0kQyGCZb_7cwyE,7473
2
2
  mlrun/__main__.py,sha256=o65gXHhmFA9GV_n2mqmAO80nW3MAwo_s7j80IKgCzRE,45949
3
- mlrun/config.py,sha256=HFQv1Qx3swxEW-QDITkakMrx6IcEEwApmkd1o38PDAI,70992
3
+ mlrun/config.py,sha256=cN_o0nSf7SJLi8xxg4kQ-_Kg5ZasUxA8IP6b-pyJJCc,71003
4
4
  mlrun/errors.py,sha256=5raKb1PXQpTcIvWQ4sr1qn2IS7P_GT_FydBJ0dXkVuc,8097
5
5
  mlrun/execution.py,sha256=sg3R6m5Vpg5VYMD-1B6-mpxW0ck6m9dmxN2fcGdJ3c8,48713
6
6
  mlrun/features.py,sha256=ReBaNGsBYXqcbgI012n-SO_j6oHIbk_Vpv0CGPXbUmo,15842
@@ -9,7 +9,7 @@ mlrun/lists.py,sha256=1hFv3Iyu5DVX1kdBGJmwUoY0CqrzauhKdSq9g3piHb4,8442
9
9
  mlrun/model.py,sha256=Qmj0UH5H0GKd6ZwxugxCvoqSP3O5q0LV0wSlHIzkyIM,85312
10
10
  mlrun/render.py,sha256=940H9fBBFeghH4dlifbURvtjlvw4GlWdAXezN6ky4rI,13275
11
11
  mlrun/run.py,sha256=ht5tg-Sge_IYHILd55ym_HJTSmimu6sjBvSc5JzVqJc,45151
12
- mlrun/secrets.py,sha256=ibtCK79u7JVBZF6F0SP1-xXXF5MyrLEUs_TCWiJAnlc,7798
12
+ mlrun/secrets.py,sha256=2WZEYp11tZkvcvD888vnSIbRMRttfNfYKLnCbiRvEaU,7808
13
13
  mlrun/alerts/__init__.py,sha256=0gtG1BG0DXxFrXegIkjbM1XEN4sP9ODo0ucXrNld1hU,601
14
14
  mlrun/alerts/alert.py,sha256=mTROlDXzQw5gyWBFaUnykai3wpvjmgRmo28p0ytbzIU,15930
15
15
  mlrun/api/schemas/__init__.py,sha256=fEWH4I8hr5AdRJ7yoW44RlFB6NHkYDxyomP5J6ct1z4,14248
@@ -24,7 +24,7 @@ mlrun/common/__init__.py,sha256=xY3wHC4TEJgez7qtnn1pQvHosi8-5UJOCtyGBS7FcGE,571
24
24
  mlrun/common/constants.py,sha256=14xMUX9C5BB-LxsTlMTJQf_Xz2DyRjaK9yeR5dadcDU,3426
25
25
  mlrun/common/helpers.py,sha256=DIdqs_eN3gO5bZ8iFobIvx8cEiOxYxhFIyut6-O69T0,1385
26
26
  mlrun/common/secrets.py,sha256=vc8WV82EZsCB5ENjUkObFOzZP59aZ1w8F82PTnqwBnc,5181
27
- mlrun/common/types.py,sha256=APVFvumnHpCG-yXlt6OSioMfkyT-DADPiW3dGG3dUFQ,1057
27
+ mlrun/common/types.py,sha256=1gxThbmC0Vd0U1ffIkEwz4T4S7JOgHt70rvw8TCO21c,1073
28
28
  mlrun/common/db/__init__.py,sha256=xY3wHC4TEJgez7qtnn1pQvHosi8-5UJOCtyGBS7FcGE,571
29
29
  mlrun/common/db/sql_session.py,sha256=J6b-0xrnFb-8n_xdksPXeA8kArSMfAiSDN4n7iOhtus,2708
30
30
  mlrun/common/formatters/__init__.py,sha256=lHcGFKKXx4vcCgJ0n2KHYD5sY5p5MvPz3DO9RbUoEOM,891
@@ -45,7 +45,7 @@ mlrun/common/schemas/api_gateway.py,sha256=3a0QxECLmoDkD5IiOKtXJL-uiWB26Hg55WMA3
45
45
  mlrun/common/schemas/artifact.py,sha256=i29BeZ4MoOLMST3WlApX1Nli0vy-M7Zj_oTm8jySlw4,3805
46
46
  mlrun/common/schemas/auth.py,sha256=AGbBNvQq_vcvhX_NLqbT-QPHL4BAJMB3xwBXW7cFvpo,6761
47
47
  mlrun/common/schemas/background_task.py,sha256=ofWRAQGGEkXEu79Dbw7tT_5GPolR09Lc3Ebg2r0fT24,1728
48
- mlrun/common/schemas/client_spec.py,sha256=j75fSEOm2bg4XYMKMzKpFVCcNBSv2ndY2J08jfMHerM,2820
48
+ mlrun/common/schemas/client_spec.py,sha256=CCdAMwRS2DFKddxNSulWcRDwp3mrE7dDdKeAD6djxLo,2856
49
49
  mlrun/common/schemas/clusterization_spec.py,sha256=LAWOL6V3E5hAt8tKmnP3DOJcKG1FQqp8Z-x8szPkf1I,894
50
50
  mlrun/common/schemas/common.py,sha256=3GcfkT7yOWmrieCSrjOJ_4aXkiUWwLd_kxqMDP1-_hw,3540
51
51
  mlrun/common/schemas/constants.py,sha256=LfoSq8d2n7TMrM0IvxGylOtVEJGvvDVlK2-Yau-Tt30,7245
@@ -72,7 +72,7 @@ mlrun/common/schemas/secret.py,sha256=CCxFYiPwJtDxwg2VVJH9nUG9cAZ2a34IjeuaWv-BYl
72
72
  mlrun/common/schemas/tag.py,sha256=HRZi5QZ4vVGaCr2AMk9eJgcNiAIXmH4YDc8a4fvF770,893
73
73
  mlrun/common/schemas/workflow.py,sha256=rwYzDJYxpE9k4kC88j_eUCmqK4ZsWV_h-_nli7Fs7Ow,2078
74
74
  mlrun/common/schemas/model_monitoring/__init__.py,sha256=noj7DPPia59PBWORsQZO20Ym0yhUwyoNJ3EeG8gVxlQ,1875
75
- mlrun/common/schemas/model_monitoring/constants.py,sha256=j0b5FhEOIcaq-0UCiMlWQXUrL7QlDP9jWMGuu7_eKkk,11433
75
+ mlrun/common/schemas/model_monitoring/constants.py,sha256=2U9TvO5vSJJYjzAaUys8PbdFOxhjwXZCdZ5oPuS3be0,11495
76
76
  mlrun/common/schemas/model_monitoring/grafana.py,sha256=Rq10KKOyyUYr7qOQFZfwGZtUim0LY9O0LQ5uc9jmIVQ,1562
77
77
  mlrun/common/schemas/model_monitoring/model_endpoints.py,sha256=GVWePSdaKyJm7-QdBiAQdMymlp2QgZIJwXO9EA6Q7AI,11727
78
78
  mlrun/data_types/__init__.py,sha256=unRo9GGwCmj0hBKBRsXJ2P4BzpQaddlQTvIrVQaKluI,984
@@ -85,7 +85,7 @@ mlrun/datastore/alibaba_oss.py,sha256=k-OHVe08HjMewlkpsT657CbOiVFAfSq9_EqhCE-k86
85
85
  mlrun/datastore/azure_blob.py,sha256=SzAcHYSXkm8Zpopz2Ea-rWVClH0URocUazcNK04S9W0,12776
86
86
  mlrun/datastore/base.py,sha256=Dqg8PqX0TFKHZg27Dgguc3RnQ1GABZiLf87p5ErTqJs,26448
87
87
  mlrun/datastore/datastore.py,sha256=frUYYP4i8ZmnY8GNXSgN_3x_exRgRPfxrCtAGEUifEU,9478
88
- mlrun/datastore/datastore_profile.py,sha256=DOCiN90li7G3kIe6z3vfHxf8iQKS6V_UNai_woeFR80,20884
88
+ mlrun/datastore/datastore_profile.py,sha256=7spsLLmlbilDurHqQoSmK7NxFWGshAc-D5v_KwwbStY,20877
89
89
  mlrun/datastore/dbfs_store.py,sha256=QkDRzwFnvm7CgEg4NuGxes6tBgKDyhX0CiBUvK8c9pk,6568
90
90
  mlrun/datastore/filestore.py,sha256=OcykjzhbUAZ6_Cb9bGAXRL2ngsOpxXSb4rR0lyogZtM,3773
91
91
  mlrun/datastore/google_cloud_storage.py,sha256=MnToY6irdhBZ8Wcapqnr1Yq2724LAh2uPO7MAtdWfUY,8716
@@ -107,9 +107,9 @@ mlrun/datastore/wasbfs/__init__.py,sha256=s5Ul-0kAhYqFjKDR2X0O2vDGDbLQQduElb32Ev
107
107
  mlrun/datastore/wasbfs/fs.py,sha256=ge8NK__5vTcFT-krI155_8RDUywQw4SIRX6BWATXy9Q,6299
108
108
  mlrun/db/__init__.py,sha256=WqJ4x8lqJ7ZoKbhEyFqkYADd9P6E3citckx9e9ZLcIU,1163
109
109
  mlrun/db/auth_utils.py,sha256=hpg8D2r82oN0BWabuWN04BTNZ7jYMAF242YSUpK7LFM,5211
110
- mlrun/db/base.py,sha256=pedRSSq-_m5c6grWHpMT_MiukmWxc1YVSFwswf63YQY,29675
110
+ mlrun/db/base.py,sha256=dzYvS8mUBShit9UBqgKuu4AJZHx8dQiD8ys7x7jAW90,29845
111
111
  mlrun/db/factory.py,sha256=yP2vVmveUE7LYTCHbS6lQIxP9rW--zdISWuPd_I3d_4,2111
112
- mlrun/db/httpdb.py,sha256=266EE-_ZMebs3EJKJLoi6e9slCDpo4IGhizMlj7doK4,226108
112
+ mlrun/db/httpdb.py,sha256=MR-GOZGTpTf8jZ28DGvfDuarQ09nmgd2voaER8CuXpg,226131
113
113
  mlrun/db/nopdb.py,sha256=CUIhRHxfoSXSgBksOWki0piC-fWNgtQvtZdnmCvH46Y,26663
114
114
  mlrun/feature_store/__init__.py,sha256=AVnY2AFUNc2dKxLLUMx2K3Wo1eGviv0brDcYlDnmtf4,1506
115
115
  mlrun/feature_store/api.py,sha256=qkojZpzqGAn3r9ww0ynBRKOs8ji8URaK4DSYD4SE-CE,50395
@@ -219,7 +219,7 @@ mlrun/model_monitoring/__init__.py,sha256=RgXjrQSN7gZwo-URei3FNo3fE9wWlo1-wNhSVt
219
219
  mlrun/model_monitoring/api.py,sha256=nH5aEUkmUEJF0CurrWJxmxVv1tQed2yzCLhQByG1L00,28561
220
220
  mlrun/model_monitoring/controller.py,sha256=dBfZQswF67vqeUFnmgsm9jU_5sOs9dLwMPEiYHG-Kk8,19786
221
221
  mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
222
- mlrun/model_monitoring/helpers.py,sha256=cGK8ZQgzqW8-TAgpBF30HyHfDmeeSlogskHGxnE_Em8,16091
222
+ mlrun/model_monitoring/helpers.py,sha256=L92YEzfKRWxoO8-qOsUK0Jrs86Wr8XDYfNnoeqnOZok,17106
223
223
  mlrun/model_monitoring/stream_processing.py,sha256=ltCVgo_b3yay16CUbqeGkRfzCHZSn14lVeBng5m9keY,31738
224
224
  mlrun/model_monitoring/tracking_policy.py,sha256=PBIGrUYWrwcE5gwXupBIVzOb0QRRwPJsgQm_yLGQxB4,5595
225
225
  mlrun/model_monitoring/writer.py,sha256=-47Z7oMr6q2ieJunZgkMK8d0IHZJhC3jxTBIxHgtSOk,10490
@@ -233,16 +233,16 @@ mlrun/model_monitoring/applications/results.py,sha256=oh1z9oacWWP4azVXm_Fx7j8uXS
233
233
  mlrun/model_monitoring/db/__init__.py,sha256=r47xPGZpIfMuv8J3PQCZTSqVPMhUta4sSJCZFKcS7FM,644
234
234
  mlrun/model_monitoring/db/_schedules.py,sha256=NTO1rbSyhW1JidpBDSN39ZBD0ctp5pbJFYQwxKRIRrs,5821
235
235
  mlrun/model_monitoring/db/_stats.py,sha256=VVMWLMqG3Us3ozBkLaokJF22Ewv8WKmVE1-OvS_g9vA,6943
236
- mlrun/model_monitoring/db/tsdb/__init__.py,sha256=Zqh_27I2YAEHk9nl0Z6lUxP7VEfrgrpnwhmHsbi4jnA,4055
236
+ mlrun/model_monitoring/db/tsdb/__init__.py,sha256=_ejhGA-bi5-6kEMEVYUN5TLxND8hTj4gMG7WrYIkpxM,4585
237
237
  mlrun/model_monitoring/db/tsdb/base.py,sha256=EWm-56AzuLSH1JV6DAhSRu9sUel5YD6Ch1n5tgUHODo,20983
238
238
  mlrun/model_monitoring/db/tsdb/helpers.py,sha256=0oUXc4aUkYtP2SGP6jTb3uPPKImIUsVsrb9otX9a7O4,1189
239
239
  mlrun/model_monitoring/db/tsdb/tdengine/__init__.py,sha256=vgBdsKaXUURKqIf3M0y4sRatmSVA4CQiJs7J5dcVBkQ,620
240
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py,sha256=5otz6VXRYNMc55hq9SdTQoglywdr2Ylh-ApL1dCyqls,13169
240
+ mlrun/model_monitoring/db/tsdb/tdengine/schemas.py,sha256=6de8P0CJMqe7PGttoZNt9UtrbBcJnpIp82hk_MbtepA,12477
241
241
  mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py,sha256=Uadj0UvAmln2MxDWod-kAzau1uNlqZh981rPhbUH_5M,2857
242
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=a2AjI7_jTnbJ8as1Bt0AMQcwsPgFsR0tvyxlKp3uZrs,29706
242
+ mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=Vbx5u4Y2ZbzbRQDwMIyz-9S0OgkGKw_gZTvWvF8Jp7I,29599
243
243
  mlrun/model_monitoring/db/tsdb/v3io/__init__.py,sha256=aL3bfmQsUQ-sbvKGdNihFj8gLCK3mSys0qDcXtYOwgc,616
244
244
  mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py,sha256=_-zo9relCDtjGgievxAcAP9gVN9nDWs8BzGtFwTjb9M,6284
245
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=_9n837rmlmxeEzqKjc5LerXRxNqKAgjMMzU-sKz4uyo,35668
245
+ mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=rZGakT22t3vNO7K9Ez1Au1UM5-E8c2Fuw4B6wuIIWPM,35896
246
246
  mlrun/model_monitoring/metrics/__init__.py,sha256=6CsTXAxeLbbf8yfCADTaxmiavqwrLEdYFJ-qc5kgDAY,569
247
247
  mlrun/model_monitoring/metrics/histogram_distance.py,sha256=E9_WIl2vd6qNvoHVHoFcnuQk3ekbFWOdi8aU7sHrfk4,4724
248
248
  mlrun/package/__init__.py,sha256=v7VDyK9kDOOuDvFo4oiGV2fx-vM1KL7fdN9pGLakhUQ,7008
@@ -266,8 +266,8 @@ mlrun/platforms/__init__.py,sha256=ZuyeHCHHUxYEoZRmaJqzFSfwhaTyUdBZXMeVp75ql1w,3
266
266
  mlrun/platforms/iguazio.py,sha256=6VBTq8eQ3mzT96tzjYhAtcMQ2VjF4x8LpIPW5DAcX2Q,13749
267
267
  mlrun/projects/__init__.py,sha256=0Krf0WIKfnZa71WthYOg0SoaTodGg3sV_hK3f_OlTPI,1220
268
268
  mlrun/projects/operations.py,sha256=VXUlMrouFTls-I-bMhdN5pPfQ34TR7bFQ-NUSWNvl84,20029
269
- mlrun/projects/pipelines.py,sha256=NCl48J6nTjlLobmzQnVB8MTMvnLg0_OTmJ7Fk7UefU8,47128
270
- mlrun/projects/project.py,sha256=D4kHK6k8inMrhYjRUGUbqU7dMQyNkDUnDh5DndxFe0o,227255
269
+ mlrun/projects/pipelines.py,sha256=SOlwMyyPO4jhV61Ja_4yco3OYzhijNQwyoq8g41fTe8,47343
270
+ mlrun/projects/project.py,sha256=i_LukfblPoqylLcq73Uw02HDTqM_-npVVMq8Qv5_MWg,227431
271
271
  mlrun/runtimes/__init__.py,sha256=J9Sy2HiyMlztNv6VUurMzF5H2XzttNil8nRsWDsqLyg,8923
272
272
  mlrun/runtimes/base.py,sha256=Yt2l7srrXjK783cunBEKH0yQxQZRH8lkedXNOXuLbbo,37841
273
273
  mlrun/runtimes/daskjob.py,sha256=JwuGvOiPsxEDHHMMUS4Oie4hLlYYIZwihAl6DjroTY0,19521
@@ -300,13 +300,13 @@ mlrun/runtimes/sparkjob/spark3job.py,sha256=0ipkgAjDYDJDlcuvt379zonjhepCspsQQXMr
300
300
  mlrun/serving/__init__.py,sha256=FhOlOCnBC5HFXOHzSDe4NHBs6mNUDP_Qqy6WMNsCwws,1307
301
301
  mlrun/serving/merger.py,sha256=qtPJacx94Tsz_-8L3J_-aS2NEsTdechZkQzJmyHjmig,6195
302
302
  mlrun/serving/remote.py,sha256=gxJkj_J3j-sZcVUbUzbAmJafP6t6y4NVFsu0kWmYngA,18818
303
- mlrun/serving/routers.py,sha256=GK8IglQZo7vYTtK4xlnR5hLRQUbUhF2IwUbquGK9zrE,54395
303
+ mlrun/serving/routers.py,sha256=A_R34_N6uYw2veK58WpffEp1NsFwq0XbNU9is2Nd7s8,50901
304
304
  mlrun/serving/server.py,sha256=xP88X7_C4mHIk0R7TJBCl-jSl-VomctblipiYepQTaQ,22512
305
305
  mlrun/serving/serving_wrapper.py,sha256=R670-S6PX_d5ER6jiHtRvacuPyFzQH0mEf2K0sBIIOM,836
306
- mlrun/serving/states.py,sha256=FXTiHsM8H9mwpg0_mYooMxF7Z3QvMHnUeZDiQXN2ohg,67142
306
+ mlrun/serving/states.py,sha256=VjcP7GToyjH1PDGa1ASANKI1LWu-dgo_rXEVr5zsHxw,67386
307
307
  mlrun/serving/utils.py,sha256=k2EIYDWHUGkE-IBI6T0UNT32fw-KySsccIJM_LObI00,4171
308
308
  mlrun/serving/v1_serving.py,sha256=c6J_MtpE-Tqu00-6r4eJOCO6rUasHDal9W2eBIcrl50,11853
309
- mlrun/serving/v2_serving.py,sha256=-YXyo01rwW7VWi_T7Sv_k_trVbxDAgxVKjg0-bSK5fs,26456
309
+ mlrun/serving/v2_serving.py,sha256=ViPRigBwb58M6eeRvKa3JyVLd_OVEEtjPVSMRFZ1aPs,21861
310
310
  mlrun/track/__init__.py,sha256=yVXbT52fXvGKRlc_ByHqIVt7-9L3DRE634RSeQwgXtU,665
311
311
  mlrun/track/tracker.py,sha256=CyTU6Qd3_5GGEJ_hpocOj71wvV65EuFYUjaYEUKAL6Q,3575
312
312
  mlrun/track/tracker_manager.py,sha256=IYBl99I62IC6VCCmG1yt6JoHNOQXa53C4DURJ2sWgio,5726
@@ -318,7 +318,7 @@ mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,34
318
318
  mlrun/utils/clones.py,sha256=y3zC9QS7z5mLuvyQ6vFd6sJnikbgtDwrBvieQq0sovY,7359
319
319
  mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
320
320
  mlrun/utils/db.py,sha256=blQgkWMfFH9lcN4sgJQcPQgEETz2Dl_zwbVA0SslpFg,2186
321
- mlrun/utils/helpers.py,sha256=g9weVIuAoR_QuplJvVWpEmUhsyz78x2Jag9SP-8iPNQ,63476
321
+ mlrun/utils/helpers.py,sha256=3E7cQFcvcKdXmMnjsFY5r6cY6S0LxoFOrAkN6_jYw1s,64237
322
322
  mlrun/utils/http.py,sha256=t6FrXQstZm9xVVjxqIGiLzrwZNCR4CSienSOuVgNIcI,8706
323
323
  mlrun/utils/logger.py,sha256=_v4UTv1-STzC2c6aAWAa0NNl9STQoBYbR3OHgAiL41s,14606
324
324
  mlrun/utils/regex.py,sha256=IQqwPna6Z8J31xkTUduYbGk48GkQBUJFZSuxAWm1pzU,5162
@@ -337,11 +337,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
337
337
  mlrun/utils/notifications/notification/slack.py,sha256=NKV4RFiY3gLsS8uPppgniPLyag8zJ9O1VhixoXkM7kw,7108
338
338
  mlrun/utils/notifications/notification/webhook.py,sha256=M-pSBM2VTKVUPRERocjORlH6mKqo1K9ihVL5Qrn2GyM,4789
339
339
  mlrun/utils/version/__init__.py,sha256=7kkrB7hEZ3cLXoWj1kPoDwo4MaswsI2JVOBpbKgPAgc,614
340
- mlrun/utils/version/version.json,sha256=NRcojevxzB3LkRGh9XYHV-DuGk-SpwErl7ELG1QmJow,89
340
+ mlrun/utils/version/version.json,sha256=6DN2cKENaaROp7hH2NZfzZAwPDExF5JEb1N0SAOWCvE,89
341
341
  mlrun/utils/version/version.py,sha256=eEW0tqIAkU9Xifxv8Z9_qsYnNhn3YH7NRAfM-pPLt1g,1878
342
- mlrun-1.8.0rc13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
343
- mlrun-1.8.0rc13.dist-info/METADATA,sha256=NlZ2jzioUd_eB5WJ23rKuFaCY8iAI7kkmGuOZK9jJwg,24459
344
- mlrun-1.8.0rc13.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
345
- mlrun-1.8.0rc13.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
346
- mlrun-1.8.0rc13.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
347
- mlrun-1.8.0rc13.dist-info/RECORD,,
342
+ mlrun-1.8.0rc16.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
343
+ mlrun-1.8.0rc16.dist-info/METADATA,sha256=L98gsrwODKowDqownhVjnIigGdHJPUF77HNjpzOj4oc,25001
344
+ mlrun-1.8.0rc16.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
345
+ mlrun-1.8.0rc16.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
346
+ mlrun-1.8.0rc16.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
347
+ mlrun-1.8.0rc16.dist-info/RECORD,,