mlrun 1.10.0rc42__py3-none-any.whl → 1.10.1rc4__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.

mlrun/projects/project.py CHANGED
@@ -167,7 +167,7 @@ def new_project(
167
167
  in the project root dir, it will be executed upon project creation or loading.
168
168
 
169
169
 
170
- example::
170
+ Example::
171
171
 
172
172
  # create a project with local and hub functions, a workflow, and an artifact
173
173
  project = mlrun.new_project(
@@ -184,7 +184,7 @@ def new_project(
184
184
  # run the "main" workflow (watch=True to wait for run completion)
185
185
  project.run("main", watch=True)
186
186
 
187
- example (load from template)::
187
+ Example (load from template)::
188
188
 
189
189
  # create a new project from a zip template (can also use yaml/git templates)
190
190
  # initialize a local git, and register the git remote path
@@ -198,7 +198,7 @@ def new_project(
198
198
  project.run("main", watch=True)
199
199
 
200
200
 
201
- example using project_setup.py to init the project objects::
201
+ Example using project_setup.py to init the project objects::
202
202
 
203
203
  def setup(project):
204
204
  project.set_function(
@@ -1282,7 +1282,7 @@ class MlrunProject(ModelObj):
1282
1282
  ) -> str:
1283
1283
  """return the project artifact uri (store://..) from the artifact key
1284
1284
 
1285
- example::
1285
+ Example::
1286
1286
 
1287
1287
  uri = project.get_artifact_uri("my_model", category="model", tag="prod", iter=0)
1288
1288
 
@@ -1460,7 +1460,7 @@ class MlrunProject(ModelObj):
1460
1460
  ):
1461
1461
  """add/set an artifact in the project spec (will be registered on load)
1462
1462
 
1463
- example::
1463
+ Example::
1464
1464
 
1465
1465
  # register a simple file artifact
1466
1466
  project.set_artifact("data", target_path=data_url)
@@ -1611,7 +1611,7 @@ class MlrunProject(ModelObj):
1611
1611
 
1612
1612
  If the artifact already exists with the same key and tag, it will be overwritten.
1613
1613
 
1614
- example::
1614
+ Example::
1615
1615
 
1616
1616
  project.log_artifact(
1617
1617
  "some-data",
@@ -1715,7 +1715,7 @@ class MlrunProject(ModelObj):
1715
1715
 
1716
1716
  If the dataset already exists with the same key and tag, it will be overwritten.
1717
1717
 
1718
- example::
1718
+ Example::
1719
1719
 
1720
1720
  raw_data = {
1721
1721
  "first_name": ["Jason", "Molly", "Tina", "Jake", "Amy"],
@@ -1802,7 +1802,7 @@ class MlrunProject(ModelObj):
1802
1802
 
1803
1803
  If the model already exists with the same key and tag, it will be overwritten.
1804
1804
 
1805
- example::
1805
+ Example::
1806
1806
 
1807
1807
  project.log_model(
1808
1808
  "model",
@@ -2044,11 +2044,12 @@ class MlrunProject(ModelObj):
2044
2044
  This wrapper provides both access to the original vector
2045
2045
  store's capabilities and additional MLRun functionality.
2046
2046
 
2047
- Example:
2048
- >>> vector_store = Chroma(embedding_function=embeddings)
2049
- >>> collection = project.get_vector_store_collection(
2050
- ... vector_store, collection_name="my_collection"
2051
- ... )
2047
+ Example::
2048
+
2049
+ vector_store = Chroma(embedding_function=embeddings)
2050
+ collection = project.get_vector_store_collection(
2051
+ vector_store, collection_name="my_collection"
2052
+ )
2052
2053
  """
2053
2054
  return VectorStoreCollection(
2054
2055
  self,
@@ -2099,16 +2100,17 @@ class MlrunProject(ModelObj):
2099
2100
  :param kwargs: Additional keyword arguments
2100
2101
  :return: DocumentArtifact object
2101
2102
 
2102
- Example:
2103
- >>> # Log a PDF document with custom loader
2104
- >>> project.log_document(
2105
- ... local_path="path/to/doc.pdf",
2106
- ... document_loader=DocumentLoaderSpec(
2107
- ... loader_class_name="langchain_community.document_loaders.PDFLoader",
2108
- ... src_name="file_path",
2109
- ... kwargs={"extract_images": True},
2110
- ... ),
2111
- ... )
2103
+ Example::
2104
+
2105
+ # Log a PDF document with custom loader
2106
+ project.log_document(
2107
+ local_path="path/to/doc.pdf",
2108
+ document_loader=DocumentLoaderSpec(
2109
+ loader_class_name="langchain_community.document_loaders.PDFLoader",
2110
+ src_name="file_path",
2111
+ kwargs={"extract_images": True},
2112
+ ),
2113
+ )
2112
2114
 
2113
2115
  """
2114
2116
  if not key and not local_path and not target_path:
@@ -2765,9 +2767,9 @@ class MlrunProject(ModelObj):
2765
2767
 
2766
2768
  Supported URL prefixes:
2767
2769
 
2768
- - Object: s3://, v3io://, etc.
2769
- - MLRun DB: e.g db://project/func:ver
2770
- - Function hub/market: e.g. hub://auto-trainer:master
2770
+ | Object (s3://, v3io://, ..)
2771
+ | MLRun DB e.g. db://project/func:ver
2772
+ | Hub/market: e.g. hub://auto-trainer:master
2771
2773
 
2772
2774
  Examples::
2773
2775
 
@@ -3485,7 +3487,7 @@ class MlrunProject(ModelObj):
3485
3487
  when using a secrets file it should have lines in the form KEY=VALUE, comment line start with "#"
3486
3488
  V3IO paths/credentials and MLrun service API address are dropped from the secrets
3487
3489
 
3488
- example secrets file:
3490
+ Example secrets file:
3489
3491
 
3490
3492
  .. code-block:: shell
3491
3493
 
@@ -4071,7 +4073,7 @@ class MlrunProject(ModelObj):
4071
4073
  ) -> typing.Union[mlrun.model.RunObject, PipelineNodeWrapper]:
4072
4074
  """Run a local or remote task as part of a local/kubeflow pipeline
4073
4075
 
4074
- example (use with project)::
4076
+ Example (use with project)::
4075
4077
 
4076
4078
  # create a project with two functions (local and from hub)
4077
4079
  project = mlrun.new_project(project_name, "./proj")
@@ -4910,7 +4912,7 @@ class MlrunProject(ModelObj):
4910
4912
  ):
4911
4913
  """Retrieve a list of functions, filtered by specific criteria.
4912
4914
 
4913
- example::
4915
+ Example::
4914
4916
 
4915
4917
  functions = project.list_functions(tag="latest")
4916
4918
 
@@ -5049,12 +5051,14 @@ class MlrunProject(ModelObj):
5049
5051
  include_infra: bool = True,
5050
5052
  ) -> list[mlrun.common.schemas.model_monitoring.FunctionSummary]:
5051
5053
  """Get monitoring function summaries for the specified project.
5054
+
5052
5055
  :param start: Start time for filtering the results (optional).
5053
5056
  :param end: End time for filtering the results (optional).
5054
5057
  :param names: List of function names to filter by (optional).
5055
5058
  :param labels: Labels to filter by (optional).
5056
5059
  :param include_stats: Whether to include statistics in the response (default is False).
5057
5060
  :param include_infra: whether to include model monitoring infrastructure functions (default is True).
5061
+
5058
5062
  :return: A list of FunctionSummary objects containing information about the monitoring functions.
5059
5063
  """
5060
5064
 
@@ -5083,6 +5087,7 @@ class MlrunProject(ModelObj):
5083
5087
  include_latest_metrics: bool = False,
5084
5088
  ) -> mlrun.common.schemas.model_monitoring.FunctionSummary:
5085
5089
  """Get a monitoring function summary for the specified project and function name.
5090
+
5086
5091
  :param name: Name of the monitoring function to retrieve the summary for.
5087
5092
  :param start: Start time for filtering the results (optional).
5088
5093
  :param end: End time for filtering the results (optional).
mlrun/run.py CHANGED
@@ -345,7 +345,7 @@ def get_or_create_ctx(
345
345
  def import_function(url="", secrets=None, db="", project=None, new_name=None):
346
346
  """Create function object from DB or local/remote YAML file
347
347
 
348
- Functions can be imported from function repositories (mlrun Function Hub (formerly Marketplace) or local db),
348
+ Functions can be imported from function repositories (MLRun Hub) or local db),
349
349
  or be read from a remote URL (http(s), s3, git, v3io, ..) containing the function YAML
350
350
 
351
351
  special URLs::
@@ -361,7 +361,7 @@ def import_function(url="", secrets=None, db="", project=None, new_name=None):
361
361
  "https://raw.githubusercontent.com/org/repo/func.yaml"
362
362
  )
363
363
 
364
- :param url: path/url to Function Hub, db or function YAML file
364
+ :param url: path/url to MLRun Hub, db or function YAML file
365
365
  :param secrets: optional, credentials dict for DB or URL (s3, v3io, ...)
366
366
  :param db: optional, mlrun api/db path
367
367
  :param project: optional, target project for the function
@@ -692,7 +692,7 @@ def code_to_function(
692
692
  :param description: short function description, defaults to ''
693
693
  :param requirements: a list of python packages
694
694
  :param requirements_file: path to a python requirements file
695
- :param categories: list of categories for mlrun Function Hub, defaults to None
695
+ :param categories: list of categories for MLRun Hub, defaults to None
696
696
  :param labels: name/value pairs dict to tag the function with useful metadata, defaults to None
697
697
  :param with_doc: indicates whether to document the function parameters, defaults to True
698
698
  :param ignored_tags: notebook cells to ignore when converting notebooks to py code (separated by ';')
@@ -843,9 +843,11 @@ class RemoteRuntime(KubeResource):
843
843
 
844
844
  def _get_runtime_env(self):
845
845
  # for runtime specific env var enrichment (before deploy)
846
+ active_project = self.metadata.project or mlconf.active_project
846
847
  runtime_env = {
847
- mlrun.common.constants.MLRUN_ACTIVE_PROJECT: self.metadata.project
848
- or mlconf.active_project,
848
+ mlrun.common.constants.MLRUN_ACTIVE_PROJECT: active_project,
849
+ # TODO: Remove this in 1.12.0 as MLRUN_DEFAULT_PROJECT is deprecated and should not be injected anymore
850
+ "MLRUN_DEFAULT_PROJECT": active_project,
849
851
  }
850
852
  if mlconf.httpdb.api_url:
851
853
  runtime_env["MLRUN_DBPATH"] = mlconf.httpdb.api_url
@@ -283,7 +283,7 @@ class ServingRuntime(RemoteRuntime):
283
283
  :param exist_ok: - allow overriding existing topology
284
284
  :param class_args: - optional, router/flow class init args
285
285
 
286
- :return graph object (fn.spec.graph)
286
+ :return: graph object (fn.spec.graph)
287
287
  """
288
288
  topology = topology or StepKinds.router
289
289
  if self.spec.graph and not exist_ok:
@@ -396,7 +396,7 @@ class ServingRuntime(RemoteRuntime):
396
396
  outputs: Optional[list[str]] = None,
397
397
  **class_args,
398
398
  ):
399
- """add ml model and/or route to the function.
399
+ """Add ml model and/or route to the function.
400
400
 
401
401
  Example, create a function (from the notebook), add a model class, and deploy::
402
402
 
@@ -404,7 +404,7 @@ class ServingRuntime(RemoteRuntime):
404
404
  fn.add_model("boost", model_path, model_class="MyClass", my_arg=5)
405
405
  fn.deploy()
406
406
 
407
- only works with router topology, for nested topologies (model under router under flow)
407
+ Only works with router topology. For nested topologies (model under router under flow)
408
408
  need to add router to flow and use router.add_route()
409
409
 
410
410
  :param key: model api key (or name:version), will determine the relative url/path
@@ -417,18 +417,19 @@ class ServingRuntime(RemoteRuntime):
417
417
  with multiple router steps)
418
418
  :param child_function: child function name, when the model runs in a child function
419
419
  :param creation_strategy: Strategy for creating or updating the model endpoint:
420
- * **overwrite**:
421
- 1. If model endpoints with the same name exist, delete the `latest` one.
422
- 2. Create a new model endpoint entry and set it as `latest`.
423
- * **inplace** (default):
424
- 1. If model endpoints with the same name exist, update the `latest` entry.
425
- 2. Otherwise, create a new entry.
426
- * **archive**:
427
- 1. If model endpoints with the same name exist, preserve them.
428
- 2. Create a new model endpoint with the same name and set it to `latest`.
429
- :param outputs: list of the model outputs (e.g. labels) ,if provided will override the outputs that been
430
- configured in the model artifact, please note that those outputs need to be equal to the
431
- model serving function outputs (length, and order)
420
+
421
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest`
422
+ one. Create a new model endpoint entry and set it as `latest`.
423
+
424
+ * **inplace** (default): If model endpoints with the same name exist, update the
425
+ `latest` entry. Otherwise, create a new entry.
426
+
427
+ * **archive**: If model endpoints with the same name exist, preserve them.
428
+ Create a new model endpoint with the same name and set it to `latest`.
429
+
430
+ :param outputs: list of the model outputs (e.g. labels), if provided will override the outputs that were
431
+ configured in the model artifact. Note that those outputs need to be equal to the
432
+ model serving function outputs (length, and order).
432
433
  :param class_args: extra kwargs to pass to the model serving class __init__
433
434
  (can be read in the model using .get_param(key) method)
434
435
  """
@@ -521,7 +522,7 @@ class ServingRuntime(RemoteRuntime):
521
522
  :param requirements: py package requirements file path OR list of packages
522
523
  :param kind: mlrun function/runtime kind
523
524
 
524
- :return function object
525
+ :return: function object
525
526
  """
526
527
  function_reference = FunctionReference(
527
528
  url,
mlrun/serving/server.py CHANGED
@@ -649,7 +649,7 @@ async def async_execute_graph(
649
649
 
650
650
  if df.empty:
651
651
  context.logger.warn("Job terminated due to empty inputs (0 rows)")
652
- return []
652
+ return
653
653
 
654
654
  track_models = spec.get("track_models")
655
655
 
@@ -779,30 +779,49 @@ async def async_execute_graph(
779
779
  model_endpoint_uids=model_endpoint_uids,
780
780
  )
781
781
 
782
- # log the results as artifacts
783
- num_of_meps_in_the_graph = len(server.graph.model_endpoints_names)
784
- artifact_path = None
785
- if (
786
- "{{run.uid}}" not in context.artifact_path
787
- ): # TODO: delete when IG-22841 is resolved
788
- artifact_path = "+/{{run.uid}}" # will be concatenated to the context's path in extend_artifact_path
789
- if num_of_meps_in_the_graph <= 1:
782
+ has_responder = False
783
+ for step in server.graph.steps.values():
784
+ if getattr(step, "responder", False):
785
+ has_responder = True
786
+ break
787
+
788
+ if has_responder:
789
+ # log the results as a dataset artifact
790
+ artifact_path = None
791
+ if (
792
+ "{{run.uid}}" not in context.artifact_path
793
+ ): # TODO: delete when IG-22841 is resolved
794
+ artifact_path = "+/{{run.uid}}" # will be concatenated to the context's path in extend_artifact_path
790
795
  context.log_dataset(
791
796
  "prediction", df=pd.DataFrame(responses), artifact_path=artifact_path
792
797
  )
793
- else:
794
- # turn this list of samples into a dict of lists, one per model endpoint
795
- grouped = defaultdict(list)
796
- for sample in responses:
797
- for model_name, features in sample.items():
798
- grouped[model_name].append(features)
799
- # create a dataframe per model endpoint and log it
800
- for model_name, features in grouped.items():
801
- context.log_dataset(
802
- f"prediction_{model_name}",
803
- df=pd.DataFrame(features),
804
- artifact_path=artifact_path,
805
- )
798
+
799
+ # if we got responses that appear to be in the right format, try to log per-model datasets too
800
+ if (
801
+ responses
802
+ and responses[0]
803
+ and isinstance(responses[0], dict)
804
+ and isinstance(next(iter(responses[0].values())), (dict, list))
805
+ ):
806
+ try:
807
+ # turn this list of samples into a dict of lists, one per model endpoint
808
+ grouped = defaultdict(list)
809
+ for sample in responses:
810
+ for model_name, features in sample.items():
811
+ grouped[model_name].append(features)
812
+ # create a dataframe per model endpoint and log it
813
+ for model_name, features in grouped.items():
814
+ context.log_dataset(
815
+ f"prediction_{model_name}",
816
+ df=pd.DataFrame(features),
817
+ artifact_path=artifact_path,
818
+ )
819
+ except Exception as e:
820
+ context.logger.warning(
821
+ "Failed to log per-model prediction datasets",
822
+ error=err_to_str(e),
823
+ )
824
+
806
825
  context.log_result("num_rows", run_call_count)
807
826
 
808
827
 
mlrun/serving/states.py CHANGED
@@ -377,20 +377,14 @@ class BaseStep(ModelObj):
377
377
  to event["y"] resulting in {"x": 5, "y": <result>}
378
378
  :param model_endpoint_creation_strategy: Strategy for creating or updating the model endpoint:
379
379
 
380
- * **overwrite**:
380
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest` one;
381
+ create a new model endpoint entry and set it as `latest`.
381
382
 
382
- 1. If model endpoints with the same name exist, delete the `latest` one.
383
- 2. Create a new model endpoint entry and set it as `latest`.
383
+ * **inplace** (default): If model endpoints with the same name exist, update the `latest`
384
+ entry; otherwise, create a new entry.
384
385
 
385
- * **inplace** (default):
386
-
387
- 1. If model endpoints with the same name exist, update the `latest` entry.
388
- 2. Otherwise, create a new entry.
389
-
390
- * **archive**:
391
-
392
- 1. If model endpoints with the same name exist, preserve them.
393
- 2. Create a new model endpoint with the same name and set it to `latest`.
386
+ * **archive**: If model endpoints with the same name exist, preserve them;
387
+ create a new model endpoint with the same name and set it to `latest`.
394
388
 
395
389
  :param class_args: class init arguments
396
390
  """
@@ -1042,20 +1036,14 @@ class RouterStep(TaskStep):
1042
1036
  :param function: function this step should run in
1043
1037
  :param creation_strategy: Strategy for creating or updating the model endpoint:
1044
1038
 
1045
- * **overwrite**:
1046
-
1047
- 1. If model endpoints with the same name exist, delete the `latest` one.
1048
- 2. Create a new model endpoint entry and set it as `latest`.
1049
-
1050
- * **inplace** (default):
1039
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest` one;
1040
+ create a new model endpoint entry and set it as `latest`.
1051
1041
 
1052
- 1. If model endpoints with the same name exist, update the `latest` entry.
1053
- 2. Otherwise, create a new entry.
1042
+ * **inplace** (default): If model endpoints with the same name exist, update the `latest`
1043
+ entry;otherwise, create a new entry.
1054
1044
 
1055
- * **archive**:
1056
-
1057
- 1. If model endpoints with the same name exist, preserve them.
1058
- 2. Create a new model endpoint with the same name and set it to `latest`.
1045
+ * **archive**: If model endpoints with the same name exist, preserve them;
1046
+ create a new model endpoint with the same name and set it to `latest`.
1059
1047
 
1060
1048
  """
1061
1049
  if len(self.routes.keys()) >= MAX_MODELS_PER_ROUTER and key not in self.routes:
@@ -1663,17 +1651,17 @@ class ModelRunnerStep(MonitoredStep):
1663
1651
 
1664
1652
  Note ModelRunnerStep can only be added to a graph that has the flow topology and running with async engine.
1665
1653
 
1666
- Note see config_pool_resource method documentation for default number of max threads and max processes.
1654
+ Note see configure_pool_resource method documentation for default number of max threads and max processes.
1667
1655
 
1668
1656
  :param model_selector: ModelSelector instance whose select() method will be used to select models to run on each
1669
1657
  event. Optional. If not passed, all models will be run.
1670
1658
  :param raise_exception: If True, an error will be raised when model selection fails or if one of the models raised
1671
1659
  an error. If False, the error will appear in the output event.
1672
1660
 
1673
- :raise ModelRunnerError - when a model raise an error the ModelRunnerStep will handle it, collect errors and outputs
1674
- from added models, If raise_exception is True will raise ModelRunnerError Else will add
1675
- the error msg as part of the event body mapped by model name if more than one model was
1676
- added to the ModelRunnerStep
1661
+ :raise ModelRunnerError: when a model raises an error the ModelRunnerStep will handle it, collect errors and
1662
+ outputs from added models. If raise_exception is True will raise ModelRunnerError. Else
1663
+ will add the error msg as part of the event body mapped by model name if more than
1664
+ one model was added to the ModelRunnerStep
1677
1665
  """
1678
1666
 
1679
1667
  kind = "model_runner"
@@ -1747,15 +1735,15 @@ class ModelRunnerStep(MonitoredStep):
1747
1735
  :param shared_model_name: str, the name of the shared model that is already defined within the graph
1748
1736
  :param labels: model endpoint labels, should be list of str or mapping of str:str
1749
1737
  :param model_endpoint_creation_strategy: Strategy for creating or updating the model endpoint:
1750
- * **overwrite**:
1751
- 1. If model endpoints with the same name exist, delete the `latest` one.
1752
- 2. Create a new model endpoint entry and set it as `latest`.
1753
- * **inplace** (default):
1754
- 1. If model endpoints with the same name exist, update the `latest` entry.
1755
- 2. Otherwise, create a new entry.
1756
- * **archive**:
1757
- 1. If model endpoints with the same name exist, preserve them.
1758
- 2. Create a new model endpoint with the same name and set it to `latest`.
1738
+
1739
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest` one;
1740
+ create a new model endpoint entry and set it as `latest`.
1741
+
1742
+ * **inplace** (default): If model endpoints with the same name exist, update the `latest` entry;
1743
+ otherwise, create a new entry.
1744
+
1745
+ * **archive**: If model endpoints with the same name exist, preserve them;
1746
+ create a new model endpoint with the same name and set it to `latest`.
1759
1747
 
1760
1748
  :param override: bool allow override existing model on the current ModelRunnerStep.
1761
1749
  :raise GraphError: when the shared model is not found in the root flow step shared models.
@@ -1867,6 +1855,7 @@ class ModelRunnerStep(MonitoredStep):
1867
1855
  (either by name `LLModel` or by its full path, e.g. mlrun.serving.states.LLModel),
1868
1856
  outputs will be overridden with UsageResponseKeys fields.
1869
1857
  :param execution_mechanism: Parallel execution mechanism to be used to execute this model. Must be one of:
1858
+
1870
1859
  * "process_pool" – To run in a separate process from a process pool. This is appropriate for CPU or GPU
1871
1860
  intensive tasks as they would otherwise block the main process by holding Python's Global Interpreter
1872
1861
  Lock (GIL).
@@ -1879,29 +1868,29 @@ class ModelRunnerStep(MonitoredStep):
1879
1868
  * "naive" – To run in the main event loop. This is appropriate only for trivial computation and/or file I/O.
1880
1869
  It means that the runnable will not actually be run in parallel to anything else.
1881
1870
 
1882
- :param model_artifact: model artifact or mlrun model artifact uri
1883
- :param labels: model endpoint labels, should be list of str or mapping of str:str
1884
- :param model_endpoint_creation_strategy: Strategy for creating or updating the model endpoint:
1885
- * **overwrite**:
1886
- 1. If model endpoints with the same name exist, delete the `latest` one.
1887
- 2. Create a new model endpoint entry and set it as `latest`.
1888
- * **inplace** (default):
1889
- 1. If model endpoints with the same name exist, update the `latest` entry.
1890
- 2. Otherwise, create a new entry.
1891
- * **archive**:
1892
- 1. If model endpoints with the same name exist, preserve them.
1893
- 2. Create a new model endpoint with the same name and set it to `latest`.
1894
-
1895
- :param inputs: list of the model inputs (e.g. features) ,if provided will override the inputs
1871
+ :param model_artifact: model artifact or mlrun model artifact uri
1872
+ :param labels: model endpoint labels, should be list of str or mapping of str:str
1873
+ :param model_endpoint_creation_strategy: Strategy for creating or updating the model endpoint:
1874
+
1875
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest` one;
1876
+ create a new model endpoint entry and set it as `latest`.
1877
+
1878
+ * **inplace** (default): If model endpoints with the same name exist, update the `latest`
1879
+ entry; otherwise, create a new entry.
1880
+
1881
+ * **archive**: If model endpoints with the same name exist, preserve them;
1882
+ create a new model endpoint with the same name and set it to `latest`.
1883
+
1884
+ :param inputs: list of the model inputs (e.g. features) ,if provided will override the inputs
1896
1885
  that been configured in the model artifact, please note that those inputs need to
1897
1886
  be equal in length and order to the inputs that model_class predict method expects
1898
- :param outputs: list of the model outputs (e.g. labels) ,if provided will override the outputs
1887
+ :param outputs: list of the model outputs (e.g. labels) ,if provided will override the outputs
1899
1888
  that been configured in the model artifact, please note that those outputs need to
1900
1889
  be equal to the model_class predict method outputs (length, and order)
1901
1890
 
1902
1891
  When using LLModel, the output will be overridden with UsageResponseKeys.fields().
1903
1892
 
1904
- :param input_path: when specified selects the key/path in the event to use as model monitoring inputs
1893
+ :param input_path: when specified selects the key/path in the event to use as model monitoring inputs
1905
1894
  this require that the event body will behave like a dict, expects scopes to be
1906
1895
  defined by dot notation (e.g "data.d").
1907
1896
  examples: input_path="data.b"
@@ -1911,7 +1900,7 @@ class ModelRunnerStep(MonitoredStep):
1911
1900
  be {"f0": [1, 2]}.
1912
1901
  if a ``list`` or ``list of lists`` is provided, it must follow the order and
1913
1902
  size defined by the input schema.
1914
- :param result_path: when specified selects the key/path in the output event to use as model monitoring
1903
+ :param result_path: when specified selects the key/path in the output event to use as model monitoring
1915
1904
  outputs this require that the output event body will behave like a dict,
1916
1905
  expects scopes to be defined by dot notation (e.g "data.d").
1917
1906
  examples: result_path="out.b"
@@ -1922,8 +1911,8 @@ class ModelRunnerStep(MonitoredStep):
1922
1911
  if a ``list`` or ``list of lists`` is provided, it must follow the order and
1923
1912
  size defined by the output schema.
1924
1913
 
1925
- :param override: bool allow override existing model on the current ModelRunnerStep.
1926
- :param model_parameters: Parameters for model instantiation
1914
+ :param override: bool allow override existing model on the current ModelRunnerStep.
1915
+ :param model_parameters: Parameters for model instantiation
1927
1916
  """
1928
1917
  if isinstance(model_class, Model) and model_parameters:
1929
1918
  raise mlrun.errors.MLRunInvalidArgumentError(
@@ -2384,20 +2373,14 @@ class FlowStep(BaseStep):
2384
2373
  to event["y"] resulting in {"x": 5, "y": <result>}
2385
2374
  :param model_endpoint_creation_strategy: Strategy for creating or updating the model endpoint:
2386
2375
 
2387
- * **overwrite**:
2388
-
2389
- 1. If model endpoints with the same name exist, delete the `latest` one.
2390
- 2. Create a new model endpoint entry and set it as `latest`.
2376
+ * **overwrite**: If model endpoints with the same name exist, delete the `latest` one;
2377
+ create a new model endpoint entry and set it as `latest`.
2391
2378
 
2392
- * **inplace** (default):
2379
+ * **inplace** (default): If model endpoints with the same name exist, update the `latest`
2380
+ entry; otherwise, create a new entry.
2393
2381
 
2394
- 1. If model endpoints with the same name exist, update the `latest` entry.
2395
- 2. Otherwise, create a new entry.
2396
-
2397
- * **archive**:
2398
-
2399
- 1. If model endpoints with the same name exist, preserve them.
2400
- 2. Create a new model endpoint with the same name and set it to `latest`.
2382
+ * **archive**: If model endpoints with the same name exist, preserve them;
2383
+ create a new model endpoint with the same name and set it to `latest`.
2401
2384
 
2402
2385
  :param class_args: class init arguments
2403
2386
  """
@@ -2906,25 +2889,35 @@ class RootFlowStep(FlowStep):
2906
2889
  (either by name `LLModel` or by its full path, e.g. mlrun.serving.states.LLModel),
2907
2890
  outputs will be overridden with UsageResponseKeys fields.
2908
2891
  :param execution_mechanism: Parallel execution mechanism to be used to execute this model. Must be one of:
2909
- * "process_pool" – To run in a separate process from a process pool. This is appropriate for CPU or GPU
2892
+
2893
+ * **process_pool**: To run in a separate process from a process pool. This is appropriate for CPU or GPU
2910
2894
  intensive tasks as they would otherwise block the main process by holding Python's Global Interpreter
2911
2895
  Lock (GIL).
2912
- * "dedicated_process" – To run in a separate dedicated process. This is appropriate for CPU or GPU intensive
2913
- tasks that also require significant Runnable-specific initialization (e.g. a large model).
2914
- * "thread_pool" To run in a separate thread. This is appropriate for blocking I/O tasks, as they would
2896
+
2897
+ * **dedicated_process**: To run in a separate dedicated process. This is appropriate for CPU or GPU
2898
+ intensive tasks that also require significant Runnable-specific initialization (e.g. a large model).
2899
+
2900
+ * **thread_pool**: To run in a separate thread. This is appropriate for blocking I/O tasks, as they would
2915
2901
  otherwise block the main event loop thread.
2916
- * "asyncio" – To run in an asyncio task. This is appropriate for I/O tasks that use asyncio, allowing the
2902
+
2903
+ * **asyncio**: To run in an asyncio task. This is appropriate for I/O tasks that use asyncio, allowing the
2917
2904
  event loop to continue running while waiting for a response.
2918
- * "shared_executor" – Reuses an external executor (typically managed by the flow or context) to execute the
2905
+
2906
+ * **shared_executor": Reuses an external executor (typically managed by the flow or context) to execute the
2919
2907
  runnable. Should be used only if you have multiply `ParallelExecution` in the same flow and especially
2920
2908
  useful when:
2909
+
2921
2910
  - You want to share a heavy resource like a large model loaded onto a GPU.
2911
+
2922
2912
  - You want to centralize task scheduling or coordination for multiple lightweight tasks.
2913
+
2923
2914
  - You aim to minimize overhead from creating new executors or processes/threads per runnable.
2915
+
2924
2916
  The runnable is expected to be pre-initialized and reused across events, enabling efficient use of
2925
2917
  memory and hardware accelerators.
2926
- * "naive" – To run in the main event loop. This is appropriate only for trivial computation and/or file I/O.
2927
- It means that the runnable will not actually be run in parallel to anything else.
2918
+
2919
+ * **naive**: To run in the main event loop. This is appropriate only for trivial computation and/or file
2920
+ I/O. It means that the runnable will not actually be run in parallel to anything else.
2928
2921
 
2929
2922
  :param model_artifact: model artifact or mlrun model artifact uri
2930
2923
  :param inputs: list of the model inputs (e.g. features) ,if provided will override the inputs
mlrun/utils/helpers.py CHANGED
@@ -1025,8 +1025,10 @@ def enrich_image_url(
1025
1025
  # use the tag from image URL if available, else fallback to the given tag
1026
1026
  tag = image_tag or tag
1027
1027
  if tag:
1028
+ # Remove '-pyXY' suffix if present, since the compatibility check expects a valid semver string
1029
+ tag_for_compatibility = re.sub(r"-py\d+$", "", tag)
1028
1030
  if mlrun.utils.helpers.validate_component_version_compatibility(
1029
- "mlrun-client", "1.10.0-rc0", mlrun_client_version=tag
1031
+ "mlrun-client", "1.10.0-rc0", mlrun_client_version=tag_for_compatibility
1030
1032
  ):
1031
1033
  warnings.warn(
1032
1034
  "'mlrun/ml-base' image is deprecated in 1.10.0 and will be removed in 1.12.0, "