mlrun 1.10.0rc35__py3-none-any.whl → 1.10.0rc37__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.

@@ -138,4 +138,4 @@ class HubCatalog(BaseModel):
138
138
 
139
139
  class HubModuleType(mlrun.common.types.StrEnum):
140
140
  generic = "generic"
141
- monitoring_app = "monitoring-app"
141
+ monitoring_app = "monitoring_application"
mlrun/config.py CHANGED
@@ -304,6 +304,7 @@ default_config = {
304
304
  "application": {
305
305
  "default_sidecar_internal_port": 8050,
306
306
  "default_authentication_mode": mlrun.common.schemas.APIGatewayAuthenticationMode.none,
307
+ "default_worker_number": 10000,
307
308
  },
308
309
  },
309
310
  # TODO: function defaults should be moved to the function spec config above
mlrun/db/base.py CHANGED
@@ -722,7 +722,9 @@ class RunDBInterface(ABC):
722
722
  tsdb_metrics: bool = False,
723
723
  metric_list: Optional[list[str]] = None,
724
724
  top_level: bool = False,
725
- modes: Optional[list[mm_constants.EndpointMode]] = None,
725
+ modes: Optional[
726
+ Union[mm_constants.EndpointMode, list[mm_constants.EndpointMode]]
727
+ ] = None,
726
728
  uids: Optional[list[str]] = None,
727
729
  latest_only: bool = False,
728
730
  ) -> mlrun.common.schemas.ModelEndpointList:
mlrun/db/httpdb.py CHANGED
@@ -3771,7 +3771,9 @@ class HTTPRunDB(RunDBInterface):
3771
3771
  tsdb_metrics: bool = False,
3772
3772
  metric_list: Optional[list[str]] = None,
3773
3773
  top_level: bool = False,
3774
- modes: Optional[list[mm_constants.EndpointMode]] = None,
3774
+ modes: Optional[
3775
+ Union[mm_constants.EndpointMode, list[mm_constants.EndpointMode]]
3776
+ ] = None,
3775
3777
  uids: Optional[list[str]] = None,
3776
3778
  latest_only: bool = False,
3777
3779
  ) -> mlrun.common.schemas.ModelEndpointList:
@@ -3802,8 +3804,13 @@ class HTTPRunDB(RunDBInterface):
3802
3804
  labels = self._parse_labels(labels)
3803
3805
  if names and isinstance(names, str):
3804
3806
  names = [names]
3805
- if isinstance(modes, mm_constants.EndpointMode):
3806
- modes = [modes]
3807
+ if modes:
3808
+ # Ensure backward compatibility with Python 3.9 clients by converting IntEnum modes to integer values
3809
+ modes = (
3810
+ [modes.value]
3811
+ if isinstance(modes, mm_constants.EndpointMode)
3812
+ else [mode.value for mode in modes]
3813
+ )
3807
3814
  response = self.api_call(
3808
3815
  method=mlrun.common.types.HTTPMethod.GET,
3809
3816
  path=path,
mlrun/db/nopdb.py CHANGED
@@ -626,7 +626,9 @@ class NopDB(RunDBInterface):
626
626
  tsdb_metrics: bool = False,
627
627
  metric_list: Optional[list[str]] = None,
628
628
  top_level: bool = False,
629
- modes: Optional[list[mm_constants.EndpointMode]] = None,
629
+ modes: Optional[
630
+ Union[mm_constants.EndpointMode, list[mm_constants.EndpointMode]]
631
+ ] = None,
630
632
  uids: Optional[list[str]] = None,
631
633
  latest_only: bool = False,
632
634
  ) -> mlrun.common.schemas.ModelEndpointList:
mlrun/hub/module.py CHANGED
@@ -26,6 +26,7 @@ from mlrun.common.schemas.hub import HubModuleType, HubSourceType
26
26
  from mlrun.run import function_to_module, get_object
27
27
  from mlrun.utils import logger
28
28
 
29
+ from ..errors import MLRunBadRequestError
29
30
  from ..model import ModelObj
30
31
  from ..utils import extend_hub_uri_if_needed
31
32
 
@@ -109,19 +110,33 @@ class HubModule(ModelObj):
109
110
  f.write(data)
110
111
 
111
112
  @staticmethod
112
- def verify_directory(path: str) -> Path:
113
- """Validate that the given path is an existing directory."""
113
+ def verify_directory(path: Optional[str] = None) -> Path:
114
+ """
115
+ Validate that the given path is an existing directory.
116
+ If no path has been provided, returns current working directory.
117
+ """
114
118
  if path:
115
119
  path = Path(path)
116
120
  if not path.exists():
117
121
  raise ValueError(f"Path does not exist: {path}")
118
122
  if not path.is_dir():
119
123
  raise ValueError(f"Path is not a directory: {path}")
120
- return path
124
+ return path
125
+ return Path(os.getcwd())
126
+
127
+ def get_module_file_path(self):
128
+ if not self.local_path:
129
+ raise MLRunBadRequestError(
130
+ "module files haven't been downloaded yet, try calling download_module_files() first"
131
+ )
132
+ return str(Path(self.local_path) / self.filename)
121
133
 
122
134
 
123
135
  def get_hub_module(
124
- url="", download_files=True, secrets=None, local_path=None
136
+ url: str = "",
137
+ download_files: Optional[bool] = True,
138
+ secrets: Optional[dict] = None,
139
+ local_path: Optional[str] = None,
125
140
  ) -> HubModule:
126
141
  """
127
142
  Get a hub-module object containing metadata of the requested module.
mlrun/model.py CHANGED
@@ -667,7 +667,7 @@ class ImageBuilder(ModelObj):
667
667
  """
668
668
  requirements = requirements or []
669
669
  self._verify_list(requirements, "requirements")
670
- resolved_requirements = self._resolve_requirements(
670
+ resolved_requirements = self.resolve_requirements(
671
671
  requirements, requirements_file
672
672
  )
673
673
  requirements = self.requirements or [] if not overwrite else []
@@ -680,7 +680,7 @@ class ImageBuilder(ModelObj):
680
680
  self.requirements = requirements
681
681
 
682
682
  @staticmethod
683
- def _resolve_requirements(requirements: list, requirements_file: str = "") -> list:
683
+ def resolve_requirements(requirements: list, requirements_file: str = "") -> list:
684
684
  requirements = requirements or []
685
685
  requirements_to_resolve = []
686
686
 
@@ -30,8 +30,9 @@ from mlrun.common.schemas.model_monitoring import (
30
30
  FunctionURI,
31
31
  )
32
32
  from mlrun.data_types.infer import InferOptions, get_df_stats
33
- from mlrun.utils import datetime_now, logger
33
+ from mlrun.utils import check_if_hub_uri, datetime_now, logger, merge_requirements
34
34
 
35
+ from ..common.schemas.hub import HubModuleType
35
36
  from .helpers import update_model_endpoint_last_request
36
37
 
37
38
  # A union of all supported dataset types:
@@ -548,8 +549,9 @@ def _create_model_monitoring_function_base(
548
549
  name: typing.Optional[str] = None,
549
550
  image: typing.Optional[str] = None,
550
551
  tag: typing.Optional[str] = None,
551
- requirements: typing.Union[str, list[str], None] = None,
552
+ requirements: typing.Union[list[str], None] = None,
552
553
  requirements_file: str = "",
554
+ local_path: typing.Optional[str] = None,
553
555
  **application_kwargs,
554
556
  ) -> mlrun.runtimes.ServingRuntime:
555
557
  """
@@ -567,6 +569,19 @@ def _create_model_monitoring_function_base(
567
569
  )
568
570
  if func is None:
569
571
  func = ""
572
+ if check_if_hub_uri(func):
573
+ hub_module = mlrun.get_hub_module(url=func, local_path=local_path)
574
+ if hub_module.kind != HubModuleType.monitoring_app:
575
+ raise mlrun.errors.MLRunInvalidArgumentError(
576
+ "The provided module is not a monitoring application"
577
+ )
578
+ requirements = mlrun.model.ImageBuilder.resolve_requirements(
579
+ requirements, requirements_file
580
+ )
581
+ requirements = merge_requirements(
582
+ reqs_priority=requirements, reqs_secondary=hub_module.requirements
583
+ )
584
+ func = hub_module.get_module_file_path()
570
585
  func_obj = typing.cast(
571
586
  mlrun.runtimes.ServingRuntime,
572
587
  mlrun.code_to_function(
@@ -233,7 +233,7 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
233
233
  try:
234
234
  yield endpoints_output, application_schedules.__enter__()
235
235
  finally:
236
- if write_output:
236
+ if write_output and any(endpoints_output.values()):
237
237
  logger.debug(
238
238
  "Pushing model monitoring application job data to the writer stream",
239
239
  passed_stream_profile=str(stream_profile),
@@ -344,7 +344,7 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
344
344
  return result
345
345
 
346
346
  if endpoints is not None:
347
- resolved_endpoints = self._validate_endpoints(
347
+ resolved_endpoints = self._normalize_and_validate_endpoints(
348
348
  project=project, endpoints=endpoints
349
349
  )
350
350
  if (
@@ -390,6 +390,16 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
390
390
  context.log_result(
391
391
  result_key, self._flatten_data_result(result)
392
392
  )
393
+ # Check if no result was produced for any endpoint (e.g., due to no data in all windows)
394
+ if not any(endpoints_output.values()):
395
+ context.logger.warning(
396
+ "No data was found for any of the specified endpoints. "
397
+ "No results were produced",
398
+ application_name=application_name,
399
+ endpoints=endpoints,
400
+ start=start,
401
+ end=end,
402
+ )
393
403
  else:
394
404
  result = call_do_tracking(
395
405
  mm_context.MonitoringApplicationContext._from_ml_ctx(
@@ -421,69 +431,97 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
421
431
  )
422
432
 
423
433
  @classmethod
424
- def _validate_endpoints(
434
+ def _normalize_and_validate_endpoints(
425
435
  cls,
426
436
  project: "mlrun.MlrunProject",
427
437
  endpoints: Union[
428
438
  list[tuple[str, str]], list[list[str]], list[str], Literal["all"]
429
439
  ],
430
- ) -> Union[list[tuple[str, str]], list[list[str]]]:
431
- if not endpoints:
432
- raise mlrun.errors.MLRunValueError(
433
- "The endpoints list cannot be empty. If you want to run on all the endpoints, "
434
- 'use `endpoints="all"`.'
435
- )
436
-
437
- if isinstance(endpoints, list) and isinstance(endpoints[0], (tuple, list)):
438
- return endpoints
439
-
440
- if not (isinstance(endpoints, list) and isinstance(endpoints[0], str)):
441
- if isinstance(endpoints, str):
442
- if endpoints != "all":
443
- raise mlrun.errors.MLRunValueError(
444
- 'A string input for `endpoints` can only be "all" for all the model endpoints in '
445
- "the project. If you want to select a single model endpoint with the given name, "
446
- f'use a list: `endpoints=["{endpoints}"]`.'
440
+ ) -> list[tuple[str, str]]:
441
+ if isinstance(endpoints, list):
442
+ if all(
443
+ isinstance(endpoint, (tuple, list)) and len(endpoint) == 2
444
+ for endpoint in endpoints
445
+ ):
446
+ # A list of [(name, uid), ...] / [[name, uid], ...] tuples/lists
447
+ endpoint_uids_to_names = {
448
+ endpoint[1]: endpoint[0] for endpoint in endpoints
449
+ }
450
+ endpoints_list = project.list_model_endpoints(
451
+ uids=list(endpoint_uids_to_names.keys()), latest_only=True
452
+ ).endpoints
453
+
454
+ # Check for missing endpoint uids or name/uid mismatches
455
+ for endpoint in endpoints_list:
456
+ if (
457
+ endpoint_uids_to_names[cast(str, endpoint.metadata.uid)]
458
+ != endpoint.metadata.name
459
+ ):
460
+ raise mlrun.errors.MLRunNotFoundError(
461
+ "Could not find model endpoint with name "
462
+ f"'{endpoint_uids_to_names[cast(str, endpoint.metadata.uid)]}' "
463
+ f"and uid '{endpoint.metadata.uid}'"
464
+ )
465
+ missing = set(endpoint_uids_to_names.keys()) - {
466
+ cast(str, endpoint.metadata.uid) for endpoint in endpoints_list
467
+ }
468
+ if missing:
469
+ raise mlrun.errors.MLRunNotFoundError(
470
+ "Could not find model endpoints with the following uids: "
471
+ f"{missing}"
447
472
  )
448
- else:
449
- raise mlrun.errors.MLRunValueError(
450
- f"Could not resolve endpoints as list of [(name, uid)], {endpoints=}"
451
- )
452
473
 
453
- if endpoints == "all":
454
- endpoint_names = None
455
- else:
456
- endpoint_names = endpoints
457
-
458
- endpoints_list = project.list_model_endpoints(
459
- names=endpoint_names, latest_only=True
460
- ).endpoints
474
+ elif all(isinstance(endpoint, str) for endpoint in endpoints):
475
+ # A list of [name, ...] strings
476
+ endpoint_names = cast(list[str], endpoints)
477
+ endpoints_list = project.list_model_endpoints(
478
+ names=endpoint_names, latest_only=True
479
+ ).endpoints
461
480
 
462
- cls._check_endpoints_first_request(endpoints_list)
463
-
464
- if endpoints_list:
465
- list_endpoints_result = [
466
- (endpoint.metadata.name, endpoint.metadata.uid)
467
- for endpoint in endpoints_list
468
- ]
469
- if endpoints != "all":
481
+ # Check for missing endpoint names
470
482
  missing = set(endpoints) - {
471
- endpoint[0] for endpoint in list_endpoints_result
483
+ endpoint.metadata.name for endpoint in endpoints_list
472
484
  }
473
485
  if missing:
474
486
  logger.warning(
475
487
  "Could not list all the required endpoints",
476
- missing_endpoint=missing,
477
- endpoints=list_endpoints_result,
488
+ missing_endpoints=missing,
489
+ endpoints_list=endpoints_list,
478
490
  )
479
- return list_endpoints_result
491
+ else:
492
+ raise mlrun.errors.MLRunValueError(
493
+ "Could not resolve the following list as a list of endpoints:\n"
494
+ f"{endpoints}\n"
495
+ "The list must be either a list of (name, uid) tuples/lists or a list of names."
496
+ )
497
+ elif endpoints == "all":
498
+ endpoints_list = project.list_model_endpoints(latest_only=True).endpoints
499
+ elif isinstance(endpoints, str):
500
+ raise mlrun.errors.MLRunValueError(
501
+ 'A string input for `endpoints` can only be "all" for all the model endpoints in '
502
+ "the project. If you want to select a single model endpoint with the given name, "
503
+ f'use a list: `endpoints=["{endpoints}"]`.'
504
+ )
480
505
  else:
481
- if endpoints != "all":
482
- err_msg_suffix = f" named '{endpoints}'"
506
+ raise mlrun.errors.MLRunValueError(
507
+ "Could not resolve the `endpoints` parameter. The parameter must be either:\n"
508
+ "- a list of (name, uid) tuples/lists\n"
509
+ "- a list of names\n"
510
+ '- the string "all" for all the model endpoints in the project.'
511
+ )
512
+
513
+ if not endpoints_list:
483
514
  raise mlrun.errors.MLRunNotFoundError(
484
- f"Did not find any model endpoints {err_msg_suffix}"
515
+ f"Did not find any model endpoints {endpoints=}"
485
516
  )
486
517
 
518
+ cls._check_endpoints_first_request(endpoints_list)
519
+
520
+ return [
521
+ (endpoint.metadata.name, cast(str, endpoint.metadata.uid))
522
+ for endpoint in endpoints_list
523
+ ]
524
+
487
525
  @staticmethod
488
526
  def _validate_and_get_window_length(
489
527
  *, base_period: int, start_dt: datetime, end_dt: datetime
mlrun/projects/project.py CHANGED
@@ -2386,8 +2386,9 @@ class MlrunProject(ModelObj):
2386
2386
  handler: Optional[str] = None,
2387
2387
  with_repo: Optional[bool] = None,
2388
2388
  tag: Optional[str] = None,
2389
- requirements: Optional[typing.Union[str, list[str]]] = None,
2389
+ requirements: Optional[list[str]] = None,
2390
2390
  requirements_file: str = "",
2391
+ local_path: Optional[str] = None,
2391
2392
  **application_kwargs,
2392
2393
  ) -> mlrun.runtimes.RemoteRuntime:
2393
2394
  """
@@ -2402,7 +2403,8 @@ class MlrunProject(ModelObj):
2402
2403
  )
2403
2404
 
2404
2405
  :param func: Remote function object or spec/code URL. :code:`None` refers to the current
2405
- notebook.
2406
+ notebook. May also be a hub URL of a module of kind model-monitoring-app in the
2407
+ format: hub://[{source}/]{name}[:{tag}].
2406
2408
  :param name: Name of the function (under the project), can be specified with a tag to support
2407
2409
  versions (e.g. myfunc:v1).
2408
2410
  :param image: Docker image to be used, can also be specified in
@@ -2417,6 +2419,8 @@ class MlrunProject(ModelObj):
2417
2419
  :param application_class: Name or an Instance of a class that implements the monitoring application.
2418
2420
  :param application_kwargs: Additional keyword arguments to be passed to the
2419
2421
  monitoring application's constructor.
2422
+ :param local_path: Path to a local directory to save the downloaded monitoring-app code files in,
2423
+ in case 'func' is a hub URL (defaults to current working directory).
2420
2424
  :returns: The model monitoring remote function object.
2421
2425
  """
2422
2426
  (
@@ -2433,6 +2437,7 @@ class MlrunProject(ModelObj):
2433
2437
  tag,
2434
2438
  requirements,
2435
2439
  requirements_file,
2440
+ local_path,
2436
2441
  **application_kwargs,
2437
2442
  )
2438
2443
  # save to project spec
@@ -2511,8 +2516,9 @@ class MlrunProject(ModelObj):
2511
2516
  handler: typing.Optional[str] = None,
2512
2517
  with_repo: typing.Optional[bool] = None,
2513
2518
  tag: typing.Optional[str] = None,
2514
- requirements: typing.Union[str, list[str], None] = None,
2519
+ requirements: typing.Union[list[str], None] = None,
2515
2520
  requirements_file: str = "",
2521
+ local_path: typing.Optional[str] = None,
2516
2522
  **application_kwargs,
2517
2523
  ) -> tuple[str, mlrun.runtimes.RemoteRuntime, dict]:
2518
2524
  import mlrun.model_monitoring.api
@@ -2529,6 +2535,7 @@ class MlrunProject(ModelObj):
2529
2535
  tag=tag,
2530
2536
  requirements=requirements,
2531
2537
  requirements_file=requirements_file,
2538
+ local_path=local_path,
2532
2539
  **application_kwargs,
2533
2540
  )
2534
2541
  elif isinstance(func, str) and isinstance(handler, str):
mlrun/run.py CHANGED
@@ -609,7 +609,7 @@ def code_to_function(
609
609
  code_output: Optional[str] = "",
610
610
  embed_code: bool = True,
611
611
  description: Optional[str] = "",
612
- requirements: Optional[Union[str, list[str]]] = None,
612
+ requirements: Optional[list[str]] = None,
613
613
  categories: Optional[list[str]] = None,
614
614
  labels: Optional[dict[str, str]] = None,
615
615
  with_doc: Optional[bool] = True,
@@ -413,8 +413,7 @@ class ApplicationRuntime(RemoteRuntime):
413
413
  show_on_failure=show_on_failure,
414
414
  )
415
415
 
416
- # This is a class method that accepts a function instance, so we pass self as the function instance
417
- self._ensure_reverse_proxy_configurations(self)
416
+ self._ensure_reverse_proxy_configurations()
418
417
  self._configure_application_sidecar()
419
418
 
420
419
  # We only allow accessing the application via the API Gateway
@@ -799,27 +798,42 @@ class ApplicationRuntime(RemoteRuntime):
799
798
  with_mlrun=with_mlrun,
800
799
  )
801
800
 
802
- @staticmethod
803
- def _ensure_reverse_proxy_configurations(function: RemoteRuntime):
804
- if function.spec.build.functionSourceCode or function.status.container_image:
801
+ def _ensure_reverse_proxy_configurations(self):
802
+ # If an HTTP trigger already exists in the spec,
803
+ # it means the user explicitly defined a custom configuration,
804
+ # so, skip automatic creation.
805
+ skip_http_trigger_creation = False
806
+ for key, value in self.spec.config.items():
807
+ if key.startswith("spec.triggers"):
808
+ if isinstance(value, dict):
809
+ if value.get("kind") == "http":
810
+ skip_http_trigger_creation = True
811
+ break
812
+ if not skip_http_trigger_creation:
813
+ self.with_http(
814
+ workers=mlrun.mlconf.function.application.default_worker_number,
815
+ trigger_name="application-http",
816
+ )
817
+
818
+ if self.spec.build.functionSourceCode or self.status.container_image:
805
819
  return
806
820
 
807
821
  filename, handler = ApplicationRuntime.get_filename_and_handler()
808
822
  name, spec, code = nuclio.build_file(
809
823
  filename,
810
- name=function.metadata.name,
824
+ name=self.metadata.name,
811
825
  handler=handler,
812
826
  )
813
- function.spec.function_handler = mlrun.utils.get_in(spec, "spec.handler")
814
- function.spec.build.functionSourceCode = mlrun.utils.get_in(
827
+ self.spec.function_handler = mlrun.utils.get_in(spec, "spec.handler")
828
+ self.spec.build.functionSourceCode = mlrun.utils.get_in(
815
829
  spec, "spec.build.functionSourceCode"
816
830
  )
817
- function.spec.nuclio_runtime = mlrun.utils.get_in(spec, "spec.runtime")
831
+ self.spec.nuclio_runtime = mlrun.utils.get_in(spec, "spec.runtime")
818
832
 
819
833
  # default the reverse proxy logger level to info
820
834
  logger_sinks_key = "spec.loggerSinks"
821
- if not function.spec.config.get(logger_sinks_key):
822
- function.set_config(
835
+ if not self.spec.config.get(logger_sinks_key):
836
+ self.set_config(
823
837
  logger_sinks_key, [{"level": "info", "sink": "myStdoutLoggerSink"}]
824
838
  )
825
839
 
@@ -1224,11 +1224,6 @@ class RemoteRuntime(KubeResource):
1224
1224
  # try to infer the invocation url from the internal and if not exists, use external.
1225
1225
  # $$$$ we do not want to use the external invocation url (e.g.: ingress, nodePort, etc.)
1226
1226
 
1227
- # check function state before invocation
1228
- state, _, _ = self._get_state()
1229
- if state not in ["ready", "scaledToZero"]:
1230
- logger.warning(f"Function is in the {state} state")
1231
-
1232
1227
  # prefer internal invocation url if running inside k8s cluster
1233
1228
  if (
1234
1229
  not force_external_address
@@ -679,9 +679,13 @@ class ServingRuntime(RemoteRuntime):
679
679
  f"function {function} is used in steps and is not defined, "
680
680
  "use the .add_child_function() to specify child function attributes"
681
681
  )
682
- if isinstance(self.spec.graph, RootFlowStep) and any(
683
- isinstance(step_type, mlrun.serving.states.ModelRunnerStep)
684
- for step_type in self.spec.graph.steps.values()
682
+ if (
683
+ isinstance(self.spec.graph, RootFlowStep)
684
+ and any(
685
+ isinstance(step_type, mlrun.serving.states.ModelRunnerStep)
686
+ for step_type in self.spec.graph.steps.values()
687
+ )
688
+ and self.spec.build.functionSourceCode
685
689
  ):
686
690
  # Add import for LLModel
687
691
  decoded_code = b64decode(self.spec.build.functionSourceCode).decode("utf-8")
mlrun/secrets.py CHANGED
@@ -11,9 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
14
+ import json
15
15
  from ast import literal_eval
16
- from os import environ, getenv
16
+ from os import environ
17
17
  from typing import Callable, Optional, Union
18
18
 
19
19
  from .utils import AzureVaultStore, list2dict
@@ -161,6 +161,9 @@ def get_secret_or_env(
161
161
  4. An MLRun-generated env. variable, mounted from a project secret (to be used in MLRun runtimes)
162
162
  5. The default value
163
163
 
164
+ Also supports discovering the value inside any environment variable that contains a JSON-encoded list
165
+ of dicts with fields: {'name': 'KEY', 'value': 'VAL', 'value_from': ...}. This fallback is applied
166
+ after checking normal environment variables and before returning the default.
164
167
  Example::
165
168
 
166
169
  secrets = {"KEY1": "VALUE1"}
@@ -187,18 +190,56 @@ def get_secret_or_env(
187
190
  if prefix:
188
191
  key = f"{prefix}_{key}"
189
192
 
190
- value = None
191
193
  if secret_provider:
192
194
  if isinstance(secret_provider, (dict, SecretsStore)):
193
- value = secret_provider.get(key)
195
+ secret_value = secret_provider.get(key)
194
196
  else:
195
- value = secret_provider(key)
196
- if value:
197
- return value
197
+ secret_value = secret_provider(key)
198
+ if secret_value:
199
+ return secret_value
200
+
201
+ direct_environment_value = environ.get(key)
202
+ if direct_environment_value:
203
+ return direct_environment_value
204
+
205
+ json_list_value = _find_value_in_json_env_lists(key)
206
+ if json_list_value is not None:
207
+ return json_list_value
208
+
209
+ mlrun_env_key = SecretsStore.k8s_env_variable_name_for_secret(key)
210
+ mlrun_env_value = environ.get(mlrun_env_key)
211
+ if mlrun_env_value:
212
+ return mlrun_env_value
198
213
 
199
- return (
200
- value
201
- or getenv(key)
202
- or getenv(SecretsStore.k8s_env_variable_name_for_secret(key))
203
- or default
204
- )
214
+ return default
215
+
216
+
217
+ def _find_value_in_json_env_lists(
218
+ secret_name: str,
219
+ ) -> Optional[str]:
220
+ """
221
+ Scan all environment variables. If any env var contains a JSON-encoded list
222
+ of dicts shaped like {'name': str, 'value': str|None, 'value_from': ...},
223
+ return the 'value' for the entry whose 'name' matches secret_name.
224
+ """
225
+ for environment_variable_value in environ.values():
226
+ if not environment_variable_value or not isinstance(
227
+ environment_variable_value, str
228
+ ):
229
+ continue
230
+ # Fast precheck to skip obvious non-JSON strings
231
+ first_char = environment_variable_value.lstrip()[:1]
232
+ if first_char not in ("[", "{"):
233
+ continue
234
+ try:
235
+ parsed_value = json.loads(environment_variable_value)
236
+ except ValueError:
237
+ continue
238
+ if isinstance(parsed_value, list):
239
+ for entry in parsed_value:
240
+ if isinstance(entry, dict) and entry.get("name") == secret_name:
241
+ value_in_entry = entry.get("value")
242
+ # Match original semantics: empty string is treated as "not found"
243
+ if value_in_entry:
244
+ return value_in_entry
245
+ return None
mlrun/serving/server.py CHANGED
@@ -584,6 +584,16 @@ async def async_execute_graph(
584
584
  read_as_lists: bool,
585
585
  nest_under_inputs: bool,
586
586
  ) -> list[Any]:
587
+ # Validate that data parameter is a DataItem and not passed via params
588
+ if not isinstance(data, DataItem):
589
+ raise MLRunInvalidArgumentError(
590
+ f"Parameter 'data' has type hint 'DataItem' but got {type(data).__name__} instead. "
591
+ f"Data files and artifacts must be passed via the 'inputs' parameter, not 'params'. "
592
+ f"The 'params' parameter is for simple configuration values (strings, numbers, booleans), "
593
+ f"while 'inputs' is for data files that need to be loaded. "
594
+ f"Example: run_function(..., inputs={{'data': 'path/to/data.csv'}}, params={{other_config: value}})"
595
+ )
596
+
587
597
  spec = mlrun.utils.get_serving_spec()
588
598
  modname = None
589
599
  code = os.getenv("MLRUN_EXEC_CODE")
@@ -257,9 +257,10 @@ class MonitoringPreProcessor(storey.MapClass):
257
257
  ].get(
258
258
  mlrun.common.schemas.MonitoringData.MODEL_ENDPOINT_UID
259
259
  ),
260
- mm_schemas.StreamProcessingEvent.LABELS: monitoring_data[
260
+ mm_schemas.StreamProcessingEvent.LABELS: event.body[
261
261
  model
262
- ].get(mlrun.common.schemas.MonitoringData.OUTPUTS),
262
+ ].get("labels")
263
+ or {},
263
264
  mm_schemas.StreamProcessingEvent.FUNCTION_URI: self.server.function_uri
264
265
  if self.server
265
266
  else None,
@@ -301,19 +302,16 @@ class MonitoringPreProcessor(storey.MapClass):
301
302
  mm_schemas.StreamProcessingEvent.ENDPOINT_ID: monitoring_data[
302
303
  model
303
304
  ].get(mlrun.common.schemas.MonitoringData.MODEL_ENDPOINT_UID),
304
- mm_schemas.StreamProcessingEvent.LABELS: monitoring_data[model].get(
305
- mlrun.common.schemas.MonitoringData.OUTPUTS
306
- ),
305
+ mm_schemas.StreamProcessingEvent.LABELS: event.body.get("labels")
306
+ or {},
307
307
  mm_schemas.StreamProcessingEvent.FUNCTION_URI: self.server.function_uri
308
308
  if self.server
309
309
  else None,
310
310
  mm_schemas.StreamProcessingEvent.REQUEST: request,
311
311
  mm_schemas.StreamProcessingEvent.RESPONSE: resp,
312
- mm_schemas.StreamProcessingEvent.ERROR: event.body[
312
+ mm_schemas.StreamProcessingEvent.ERROR: event.body.get(
313
313
  mm_schemas.StreamProcessingEvent.ERROR
314
- ]
315
- if mm_schemas.StreamProcessingEvent.ERROR in event.body
316
- else None,
314
+ ),
317
315
  mm_schemas.StreamProcessingEvent.METRICS: event.body[
318
316
  mm_schemas.StreamProcessingEvent.METRICS
319
317
  ]
mlrun/utils/helpers.py CHANGED
@@ -46,6 +46,8 @@ import pytz
46
46
  import semver
47
47
  import yaml
48
48
  from dateutil import parser
49
+ from packaging.requirements import Requirement
50
+ from packaging.utils import canonicalize_name
49
51
  from pandas import Timedelta, Timestamp
50
52
  from yaml.representer import RepresenterError
51
53
 
@@ -808,6 +810,10 @@ def remove_tag_from_artifact_uri(uri: str) -> Optional[str]:
808
810
  return uri if not add_store else DB_SCHEMA + "://" + uri
809
811
 
810
812
 
813
+ def check_if_hub_uri(uri: str) -> bool:
814
+ return uri.startswith(hub_prefix)
815
+
816
+
811
817
  def extend_hub_uri_if_needed(
812
818
  uri: str,
813
819
  asset_type: HubSourceType = HubSourceType.functions,
@@ -824,7 +830,7 @@ def extend_hub_uri_if_needed(
824
830
  [0] = Extended URI of item
825
831
  [1] = Is hub item (bool)
826
832
  """
827
- is_hub_uri = uri.startswith(hub_prefix)
833
+ is_hub_uri = check_if_hub_uri(uri)
828
834
  if not is_hub_uri:
829
835
  return uri, is_hub_uri
830
836
 
@@ -2423,6 +2429,41 @@ def set_data_by_path(
2423
2429
  )
2424
2430
 
2425
2431
 
2432
+ def _normalize_requirements(reqs: typing.Union[str, list[str], None]) -> list[str]:
2433
+ if reqs is None:
2434
+ return []
2435
+ if isinstance(reqs, str):
2436
+ s = reqs.strip()
2437
+ return [s] if s else []
2438
+ return [s.strip() for s in reqs if s and s.strip()]
2439
+
2440
+
2441
+ def merge_requirements(
2442
+ reqs_priority: typing.Union[str, list[str], None],
2443
+ reqs_secondary: typing.Union[str, list[str], None],
2444
+ ) -> list[str]:
2445
+ """
2446
+ Merge two requirement collections into a union. If the same package
2447
+ appears in both, the specifier from reqs_priority wins.
2448
+
2449
+ Args:
2450
+ reqs_priority: str | list[str] | None (priority input)
2451
+ reqs_secondary: str | list[str] | None
2452
+
2453
+ Returns:
2454
+ list[str]: pip-style requirements.
2455
+ """
2456
+ merged: dict[str, Requirement] = {}
2457
+
2458
+ for r in _normalize_requirements(reqs_secondary) + _normalize_requirements(
2459
+ reqs_priority
2460
+ ):
2461
+ req = Requirement(r)
2462
+ merged[canonicalize_name(req.name)] = req
2463
+
2464
+ return [str(req) for req in merged.values()]
2465
+
2466
+
2426
2467
  def get_module_name_from_path(source_file_path: str) -> str:
2427
2468
  source_file_path_object = pathlib.Path(source_file_path).resolve()
2428
2469
  current_dir_path_object = pathlib.Path(".").resolve()
@@ -1,4 +1,4 @@
1
1
  {
2
- "git_commit": "6ab7c319ab2182ce9f0594c1a6c0be3c98175ebe",
3
- "version": "1.10.0-rc35"
2
+ "git_commit": "5c0bf44084e089850e98e6255745822c5107d001",
3
+ "version": "1.10.0-rc37"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mlrun
3
- Version: 1.10.0rc35
3
+ Version: 1.10.0rc37
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,15 +1,15 @@
1
1
  mlrun/__init__.py,sha256=acM2jRv7RCvBROwucuC01Rf_HdvV3xUPtJlQtX_01MY,8076
2
2
  mlrun/__main__.py,sha256=wQNaxW7QsqFBtWffnPkw-497fnpsrQzUnscBQQAP_UM,48364
3
- mlrun/config.py,sha256=edvnwbZ2xlHwuRxy32SqzJyJE517zsWoduGYLO0zgGs,73433
3
+ mlrun/config.py,sha256=7t7F5jsPI1rO78-VzZv3q6QvzTIV6CZPZEQAJTmKwtM,73477
4
4
  mlrun/errors.py,sha256=bAk0t_qmCxQSPNK0TugOAfA5R6f0G6OYvEvXUWSJ_5U,9062
5
5
  mlrun/execution.py,sha256=Ozu8SjO-nQ6l5vHwqrTQjmP6koMpUqNQpp6qn6jvhVE,58802
6
6
  mlrun/features.py,sha256=jMEXo6NB36A6iaxNEJWzdtYwUmglYD90OIKTIEeWhE8,15841
7
7
  mlrun/k8s_utils.py,sha256=zIacVyvsXrXVO-DdxAoGQOGEDWOGJEFJzYPhPVnn3z8,24548
8
8
  mlrun/lists.py,sha256=OlaV2QIFUzmenad9kxNJ3k4whlDyxI3zFbGwr6vpC5Y,8561
9
- mlrun/model.py,sha256=wHtM8LylSOEFk6Hxl95CVm8DOPhofjsANYdIvKHH6dw,88956
9
+ mlrun/model.py,sha256=JxYWYfMvRMloVEsxfghjH8gq5vsVCVk-OJmHGhbPJuU,88954
10
10
  mlrun/render.py,sha256=5DlhD6JtzHgmj5RVlpaYiHGhX84Q7qdi4RCEUj2UMgw,13195
11
- mlrun/run.py,sha256=6ginzm5WUbfHlPurgfyE1qJchTDm8PymiBgiNysZWUE,48960
12
- mlrun/secrets.py,sha256=dZPdkc_zzfscVQepOHUwmzFqnBavDCBXV9DQoH_eIYM,7800
11
+ mlrun/run.py,sha256=eXmu2C2Z-iWWRkyraYjOoM22lRfnyavOnskylHwPeV8,48948
12
+ mlrun/secrets.py,sha256=VFETVDJFZ0AGDivYjhYscO_YHnzeBnAebxlio7Svkq0,9633
13
13
  mlrun/alerts/__init__.py,sha256=0gtG1BG0DXxFrXegIkjbM1XEN4sP9ODo0ucXrNld1hU,601
14
14
  mlrun/alerts/alert.py,sha256=QQFZGydQbx9RvAaSiaH-ALQZVcDKQX5lgizqj_rXW2k,15948
15
15
  mlrun/artifacts/__init__.py,sha256=ZrEUNto7tGdnBGteCp9zOyO8b78z7O3xgcpzUt9UHE4,1240
@@ -56,7 +56,7 @@ mlrun/common/schemas/feature_store.py,sha256=Kz7AWQ1RCPA8sTL9cGRZnfUBhWf4MX_5yyY
56
56
  mlrun/common/schemas/frontend_spec.py,sha256=tR8k78cppYK-X8kCWe0mz1gk8yqpsn2IxM3QmBdTJs8,2622
57
57
  mlrun/common/schemas/function.py,sha256=BUHenAK6r_mWtDrBWE42xPJU8zh8ng5Usj7GmB_SAcU,5108
58
58
  mlrun/common/schemas/http.py,sha256=KozLgGV1vpNXQ8Qptr_Zm6BEbc2VcU42hSphe_ffe_A,704
59
- mlrun/common/schemas/hub.py,sha256=K_9AyyYF-qnwjvkGWYFEke-jG58pS3Klv1IKAkdWOxA,4267
59
+ mlrun/common/schemas/hub.py,sha256=K6Z9RHeCFXRWDyhtmc2UF4SNl2uwmJk0Pe4BqrZgLVw,4275
60
60
  mlrun/common/schemas/k8s.py,sha256=YgyDK7KNt29GHCOxd1vw-jnl_757cIPLzViCTNT1Zcc,1403
61
61
  mlrun/common/schemas/memory_reports.py,sha256=Q6w7xofQlMD-iqjE8uK9yU5ijLPkht_EsXJCMad_TQo,899
62
62
  mlrun/common/schemas/notification.py,sha256=Q-tBaU_V7YZiuj3ankuACf3_-hb874_osxq0eaW90Ww,5549
@@ -116,10 +116,10 @@ mlrun/datastore/wasbfs/__init__.py,sha256=s5Ul-0kAhYqFjKDR2X0O2vDGDbLQQduElb32Ev
116
116
  mlrun/datastore/wasbfs/fs.py,sha256=ge8NK__5vTcFT-krI155_8RDUywQw4SIRX6BWATXy9Q,6299
117
117
  mlrun/db/__init__.py,sha256=WqJ4x8lqJ7ZoKbhEyFqkYADd9P6E3citckx9e9ZLcIU,1163
118
118
  mlrun/db/auth_utils.py,sha256=hpg8D2r82oN0BWabuWN04BTNZ7jYMAF242YSUpK7LFM,5211
119
- mlrun/db/base.py,sha256=QNqL29xYs2yL4JKHfvljpf-UsIoUeMxun-eL33msJmc,32405
119
+ mlrun/db/base.py,sha256=8K0KlVfsGce1LgoB7pVOQCmQ2ceBnDz13PJlba1xuSw,32461
120
120
  mlrun/db/factory.py,sha256=yP2vVmveUE7LYTCHbS6lQIxP9rW--zdISWuPd_I3d_4,2111
121
- mlrun/db/httpdb.py,sha256=1XEWpfZm2wW3d6eUqsE-13Nk4Zm2lLKg18J53E5vE10,238986
122
- mlrun/db/nopdb.py,sha256=iClAugTqMPPQRkXb3uzf_vFhmnfuIKCLpK5M6QKHT4Y,28771
121
+ mlrun/db/httpdb.py,sha256=QLQDhzALh6NQdpzTSw9H9XfQR9NFvnG1qct9N2dLtsk,239271
122
+ mlrun/db/nopdb.py,sha256=gi6O0ZSxC3PhRBeIjTTL1rIDVHp4GhJLlD1PM1I17Gs,28827
123
123
  mlrun/feature_store/__init__.py,sha256=SlI845bWt6xX34SXunHHqhmFAR9-5v2ak8N-qpcAPGo,1328
124
124
  mlrun/feature_store/api.py,sha256=qKj5Tk6prTab6XWatWhBuPRVp0eJEctoxRMN2wz48vA,32168
125
125
  mlrun/feature_store/common.py,sha256=JlQA7XWkg9fLuw7cXFmWpUneQqM3NBhwv7DU_xlenWI,12819
@@ -220,7 +220,7 @@ mlrun/frameworks/xgboost/mlrun_interface.py,sha256=KINOf0udbY75raTewjEFGNlIRyE0e
220
220
  mlrun/frameworks/xgboost/model_handler.py,sha256=bJq4D1VK3rzhALovqIV5mS0LvGiTlsgAkHanD25pU2c,11663
221
221
  mlrun/frameworks/xgboost/utils.py,sha256=4rShiFChzDbWJ4HoTo4qV_lj-Z89pHBAp6Z1yHmU8wA,1068
222
222
  mlrun/hub/__init__.py,sha256=50cXcEk8i5G8KQ-nzF6iZDkMbXd-zMNd8nQZ7y7KTVI,620
223
- mlrun/hub/module.py,sha256=EDdQ2nFfH-i_S1WAHgtxh8CYK-P1ByD95Eow74tdzOY,6726
223
+ mlrun/hub/module.py,sha256=ZVZB8hsd5tEaRLM-mMsnw1yZx6acNrpTyGBl8EJ4nhU,7269
224
224
  mlrun/launcher/__init__.py,sha256=JL8qkT1lLr1YvW6iP0hmwDTaSR2RfrMDx0-1gWRhTOE,571
225
225
  mlrun/launcher/base.py,sha256=IgBE-ZS1ZiGzucg5SElGtO4qOB0cqYQfGtZTcRc2S3Y,17378
226
226
  mlrun/launcher/client.py,sha256=cl40ZdF2fU1QbUKdl4Xnucb1u2h-8_dn095qIUyxbuM,6402
@@ -228,7 +228,7 @@ mlrun/launcher/factory.py,sha256=RW7mfzEFi8fR0M-4W1JQg1iq3_muUU6OTqT_3l4Ubrk,233
228
228
  mlrun/launcher/local.py,sha256=3gv-IQYoIChSmRaZ0vLUh0Tu26oLMCx9GbBYh4fWygQ,12161
229
229
  mlrun/launcher/remote.py,sha256=zFXE52Cq_7EkC8lfNKT0ceIbye0CfFiundF7O1YU4Xw,7810
230
230
  mlrun/model_monitoring/__init__.py,sha256=qDQnncjya9XPTlfvGyfWsZWiXc-glGZrrNja-5QmCZk,782
231
- mlrun/model_monitoring/api.py,sha256=k0eOm-vW8z2u05PwMK2PI2mSAplK0xGIrUe_XWk7mRM,27000
231
+ mlrun/model_monitoring/api.py,sha256=g9st30YgcApT42ZU-aSlnLiLdDwATkujXg_5UrAFt1M,27738
232
232
  mlrun/model_monitoring/controller.py,sha256=2XOkOZRB03K9ph6TH-ICspHga-GQOURL0C8-0GTHaTY,43961
233
233
  mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
234
234
  mlrun/model_monitoring/helpers.py,sha256=50oFqgIc5xFHYPIVgq3M-Gbr7epqAI5NgHmvOeMy52U,24667
@@ -236,7 +236,7 @@ mlrun/model_monitoring/stream_processing.py,sha256=bryYO3D0cC10MAQ-liHxUZ79MrL-V
236
236
  mlrun/model_monitoring/writer.py,sha256=l2D_5Ms5Wq5jfyQRVJbGBBRTMLjMmIAxwPeHWmrc9Kg,16382
237
237
  mlrun/model_monitoring/applications/__init__.py,sha256=BwlmRELlFJf2b2YMyv5kUSHNe8--OyqWhDgRlT8a_8g,779
238
238
  mlrun/model_monitoring/applications/_application_steps.py,sha256=t9LDIqQUGE10cyjyhlg0QqN1yVx0apD1HpERYLJfm8U,7409
239
- mlrun/model_monitoring/applications/base.py,sha256=kvfYiFUsStjZwPIqeibUW6auCXRFcovyh-pih_pZ6Rs,49139
239
+ mlrun/model_monitoring/applications/base.py,sha256=f3WWMoXinsqzWtYebQnsMCGhi7M50E8LdeYmQl5QXjg,51339
240
240
  mlrun/model_monitoring/applications/context.py,sha256=3W3AW4oyJgx_nW_5mDsV59Iy5D3frkfYMQSc6DgBc4c,17004
241
241
  mlrun/model_monitoring/applications/histogram_data_drift.py,sha256=2qgfFmrpHf-x0_EaHD-0T28piwSQzw-HH71aV1GwbZs,15389
242
242
  mlrun/model_monitoring/applications/results.py,sha256=LfBQOmkpKGvVGNrcj5QiXsRIG2IRgcv_Xqe4QJBmauk,5699
@@ -281,7 +281,7 @@ mlrun/platforms/iguazio.py,sha256=32_o95Ntx9z3ciowt2NcnX7tAiLBwX3VB0mbTQ-KrIQ,13
281
281
  mlrun/projects/__init__.py,sha256=hdCOA6_fp8X4qGGGT7Bj7sPbkM1PayWuaVZL0DkpuZw,1240
282
282
  mlrun/projects/operations.py,sha256=Oo7h0TMztI_RVmj0rQxNS1igS_c94HpQZwMIFjiWt0E,21038
283
283
  mlrun/projects/pipelines.py,sha256=ZOfuIEHOXfuc4qAkuWvbWhCjP6kqpLkv-yBBaY9RXhg,52219
284
- mlrun/projects/project.py,sha256=DFyiEutH-Jy5lPp5uKP1P3EGpQAAOj78Ho9NEsE2EN8,257186
284
+ mlrun/projects/project.py,sha256=jSJ65upJ6zYRHly6aOQxBR6414Ypueg2iXE6XBjc-uQ,257695
285
285
  mlrun/runtimes/__init__.py,sha256=8cqrYKy1a0_87XG7V_p96untQ4t8RocadM4LVEEN1JM,9029
286
286
  mlrun/runtimes/base.py,sha256=txynS-hiNLR97PBd49mc5q9ZX3gMf3VdJ2rJ-fz5bZU,38913
287
287
  mlrun/runtimes/daskjob.py,sha256=IN6gKKrmCIjWooj5FgFm-pAb2i7ra1ERRzClfu_rYGI,20102
@@ -303,11 +303,11 @@ mlrun/runtimes/mpijob/abstract.py,sha256=QjAG4OZ6JEQ58w5-qYNd6hUGwvaW8ynLtlr9jNf
303
303
  mlrun/runtimes/mpijob/v1.py,sha256=zSlRkiWHz4B3yht66sVf4mlfDs8YT9EnP9DfBLn5VNs,3372
304
304
  mlrun/runtimes/nuclio/__init__.py,sha256=osOVMN9paIOuUoOTizmkxMb_OXRP-SlPwXHJSSYK_wk,834
305
305
  mlrun/runtimes/nuclio/api_gateway.py,sha256=vH9ClKVP4Mb24rvA67xPuAvAhX-gAv6vVtjVxyplhdc,26969
306
- mlrun/runtimes/nuclio/function.py,sha256=VjJtfteEX2I8gYCwbBdqWwIK6ZOCVOu8lQGlX4i3nwU,55693
306
+ mlrun/runtimes/nuclio/function.py,sha256=6o9SndAkd-k4FyVr4ms_oWL6MuAWMnsrtrEd_fWfnDw,55488
307
307
  mlrun/runtimes/nuclio/nuclio.py,sha256=sLK8KdGO1LbftlL3HqPZlFOFTAAuxJACZCVl1c0Ha6E,2942
308
- mlrun/runtimes/nuclio/serving.py,sha256=NF0f7a6KV8GIb4QBUKiJa_L_5oqCsG7UHPs8Uo3K_Eo,36330
308
+ mlrun/runtimes/nuclio/serving.py,sha256=eXffwn6xTvEwC-HEk42DRxywOrin7RMUze3JWjeBxzA,36429
309
309
  mlrun/runtimes/nuclio/application/__init__.py,sha256=rRs5vasy_G9IyoTpYIjYDafGoL6ifFBKgBtsXn31Atw,614
310
- mlrun/runtimes/nuclio/application/application.py,sha256=q5vBuHnWTGciokEODlSM3nfopuPwJ9RqKZNZe6C86l4,33464
310
+ mlrun/runtimes/nuclio/application/application.py,sha256=usovOWonpzHQ1B_El7l60y-jpUXyYwppjmrHlP5RMW8,33993
311
311
  mlrun/runtimes/nuclio/application/reverse_proxy.go,sha256=lEHH74vr2PridIHp1Jkc_NjkrWb5b6zawRrNxHQhwGU,2913
312
312
  mlrun/runtimes/sparkjob/__init__.py,sha256=GPP_ekItxiU9Ydn3mJa4Obph02Bg6DO-JYs791_MV58,607
313
313
  mlrun/runtimes/sparkjob/spark3job.py,sha256=3dW7RG2T58F2dsUw0TsRvE3SIFcekx3CerLdcaG1f50,41458
@@ -315,11 +315,11 @@ mlrun/serving/__init__.py,sha256=nriJAcVn5aatwU03T7SsE6ngJEGTxr3wIGt4WuvCCzY,139
315
315
  mlrun/serving/merger.py,sha256=pfOQoozUyObCTpqXAMk94PmhZefn4bBrKufO3MKnkAc,6193
316
316
  mlrun/serving/remote.py,sha256=p29CBtKwbW_l8BzmNg3Uy__0eMf7_OubTMzga_S3EOA,22089
317
317
  mlrun/serving/routers.py,sha256=pu5jlSLI4Ml68YP_FMFDhhwPfLcT6lRu5yL5QDgXPHQ,52889
318
- mlrun/serving/server.py,sha256=voN7s7WT3S-7gt14F1lXd5OMxz6tMNZX8ORP-blq2Hg,40342
318
+ mlrun/serving/server.py,sha256=7RiXZ1Nf6I_rwZUyTNqVaNEzQmYUTqKLjXXZEM1OwEc,40993
319
319
  mlrun/serving/serving_wrapper.py,sha256=UL9hhWCfMPcTJO_XrkvNaFvck1U1E7oS8trTZyak0cA,835
320
320
  mlrun/serving/states.py,sha256=Q2Q7o0eJCvnonXd2-sfiv7zhCiyC6xthfW25nzf61KM,138976
321
321
  mlrun/serving/steps.py,sha256=zbMgJnu-m4n7vhFRgZkCMMifIsCya-TzAj3Gjc-Fgnc,2193
322
- mlrun/serving/system_steps.py,sha256=ZvGkUqiiYOrUlsDnsvzf9u9554mzyFwlKVrybqB7xao,20200
322
+ mlrun/serving/system_steps.py,sha256=BDCJn73h7cUT5AoSSm25Fjg4WwzcEpMQp-ZjMw9ogEc,20025
323
323
  mlrun/serving/utils.py,sha256=Zbfqm8TKNcTE8zRBezVBzpvR2WKeKeIRN7otNIaiYEc,4170
324
324
  mlrun/serving/v1_serving.py,sha256=c6J_MtpE-Tqu00-6r4eJOCO6rUasHDal9W2eBIcrl50,11853
325
325
  mlrun/serving/v2_serving.py,sha256=FbN5QAurWL_KoKMUgRLV7b227PpnvntY5tPNE36J42E,25270
@@ -333,7 +333,7 @@ mlrun/utils/async_http.py,sha256=8Olx8TNNeXB07nEGwlqhEgFgnFAD71vBU_bqaA9JW-w,122
333
333
  mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,3450
334
334
  mlrun/utils/clones.py,sha256=qbAGyEbSvlewn3Tw_DpQZP9z6MGzFhSaZfI1CblX8Fg,7515
335
335
  mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
336
- mlrun/utils/helpers.py,sha256=5zlzE8ueXulk8jezi1cutYcLcVMEhI8B09LU0SRK_x0,83174
336
+ mlrun/utils/helpers.py,sha256=Cz3VR5aq3N6DinKd16HI9HGZSLqSmN9h4-EmnNyYGqQ,84369
337
337
  mlrun/utils/http.py,sha256=5ZU2VpokaUM_DT3HBSqTm8xjUqTPjZN5fKkSIvKlTl0,8704
338
338
  mlrun/utils/logger.py,sha256=uaCgI_ezzaXf7nJDCy-1Nrjds8vSXqDbzmjmb3IyCQo,14864
339
339
  mlrun/utils/regex.py,sha256=FcRwWD8x9X3HLhCCU2F0AVKTFah784Pr7ZAe3a02jw8,5199
@@ -352,11 +352,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
352
352
  mlrun/utils/notifications/notification/slack.py,sha256=wSu_7W0EnGLBNwIgWCYEeTP8j9SPAMPDBnfUcPnVZYA,7299
353
353
  mlrun/utils/notifications/notification/webhook.py,sha256=FM5-LQAKAVJKp37MRzR3SsejalcnpM6r_9Oe7znxZEA,5313
354
354
  mlrun/utils/version/__init__.py,sha256=YnzE6tlf24uOQ8y7Z7l96QLAI6-QEii7-77g8ynmzy0,613
355
- mlrun/utils/version/version.json,sha256=pCkizZFO7606nn8mstxD5U8Su__8IGZsvegPQ4lFcD0,90
355
+ mlrun/utils/version/version.json,sha256=XVTb8THn_xGwKwbjV7Mu2mVTg-z6fmV6gXnUhrvfT6s,90
356
356
  mlrun/utils/version/version.py,sha256=M2hVhRrgkN3SxacZHs3ZqaOsqAA7B6a22ne324IQ1HE,1877
357
- mlrun-1.10.0rc35.dist-info/licenses/LICENSE,sha256=zTiv1CxWNkOk1q8eJS1G_8oD4gWpWLwWxj_Agcsi8Os,11337
358
- mlrun-1.10.0rc35.dist-info/METADATA,sha256=Z0CoYAAIxgiUb02QdTHV3Jzvx6fQ__svH209vXs7O9s,26104
359
- mlrun-1.10.0rc35.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
360
- mlrun-1.10.0rc35.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
361
- mlrun-1.10.0rc35.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
362
- mlrun-1.10.0rc35.dist-info/RECORD,,
357
+ mlrun-1.10.0rc37.dist-info/licenses/LICENSE,sha256=zTiv1CxWNkOk1q8eJS1G_8oD4gWpWLwWxj_Agcsi8Os,11337
358
+ mlrun-1.10.0rc37.dist-info/METADATA,sha256=mZhr0TYnjpEVjpPTy6JYYXqs4dnp0q4X7Hu7TPQ5R8M,26104
359
+ mlrun-1.10.0rc37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
360
+ mlrun-1.10.0rc37.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
361
+ mlrun-1.10.0rc37.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
362
+ mlrun-1.10.0rc37.dist-info/RECORD,,