mlrun 1.6.0rc6__py3-none-any.whl → 1.6.0rc8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mlrun might be problematic. Click here for more details.

Files changed (50) hide show
  1. mlrun/__main__.py +32 -31
  2. mlrun/common/schemas/auth.py +2 -0
  3. mlrun/common/schemas/workflow.py +2 -0
  4. mlrun/config.py +3 -3
  5. mlrun/datastore/base.py +9 -3
  6. mlrun/datastore/datastore.py +10 -7
  7. mlrun/datastore/datastore_profile.py +19 -2
  8. mlrun/datastore/dbfs_store.py +6 -6
  9. mlrun/datastore/s3.py +6 -2
  10. mlrun/datastore/sources.py +12 -2
  11. mlrun/datastore/targets.py +43 -20
  12. mlrun/db/httpdb.py +22 -0
  13. mlrun/feature_store/feature_set.py +5 -2
  14. mlrun/feature_store/retrieval/spark_merger.py +7 -1
  15. mlrun/kfpops.py +1 -1
  16. mlrun/launcher/client.py +1 -6
  17. mlrun/launcher/remote.py +5 -3
  18. mlrun/model.py +2 -2
  19. mlrun/model_monitoring/batch_application.py +61 -94
  20. mlrun/package/packager.py +115 -89
  21. mlrun/package/packagers/default_packager.py +66 -65
  22. mlrun/package/packagers/numpy_packagers.py +109 -62
  23. mlrun/package/packagers/pandas_packagers.py +12 -23
  24. mlrun/package/packagers/python_standard_library_packagers.py +35 -57
  25. mlrun/package/packagers_manager.py +16 -13
  26. mlrun/package/utils/_pickler.py +8 -18
  27. mlrun/package/utils/_supported_format.py +1 -1
  28. mlrun/projects/pipelines.py +63 -4
  29. mlrun/projects/project.py +34 -11
  30. mlrun/runtimes/__init__.py +6 -0
  31. mlrun/runtimes/base.py +12 -1
  32. mlrun/runtimes/daskjob.py +73 -5
  33. mlrun/runtimes/databricks_job/databricks_runtime.py +2 -0
  34. mlrun/runtimes/function.py +53 -4
  35. mlrun/runtimes/kubejob.py +1 -1
  36. mlrun/runtimes/local.py +9 -9
  37. mlrun/runtimes/pod.py +1 -1
  38. mlrun/runtimes/remotesparkjob.py +1 -0
  39. mlrun/runtimes/serving.py +11 -1
  40. mlrun/runtimes/sparkjob/spark3job.py +4 -1
  41. mlrun/runtimes/utils.py +1 -46
  42. mlrun/utils/helpers.py +1 -17
  43. mlrun/utils/notifications/notification_pusher.py +27 -6
  44. mlrun/utils/version/version.json +2 -2
  45. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/METADATA +7 -6
  46. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/RECORD +50 -50
  47. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/WHEEL +1 -1
  48. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/LICENSE +0 -0
  49. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/entry_points.txt +0 -0
  50. {mlrun-1.6.0rc6.dist-info → mlrun-1.6.0rc8.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py CHANGED
@@ -87,6 +87,7 @@ from .pipelines import (
87
87
  FunctionsDict,
88
88
  WorkflowSpec,
89
89
  _PipelineRunStatus,
90
+ _RemoteRunner,
90
91
  enrich_function_object,
91
92
  get_db_function,
92
93
  get_workflow_engine,
@@ -102,9 +103,9 @@ def init_repo(context, url, init_git):
102
103
  repo = None
103
104
  context_path = pathlib.Path(context)
104
105
  if not context_path.exists():
105
- context_path.mkdir(parents=True)
106
+ context_path.mkdir(parents=True, exist_ok=True)
106
107
  elif not context_path.is_dir():
107
- raise ValueError(f"context {context} is not a dir path")
108
+ raise ValueError(f"Context {context} is not a dir path")
108
109
  try:
109
110
  repo = git.Repo(context)
110
111
  url = get_repo_url(repo)
@@ -221,6 +222,7 @@ def new_project(
221
222
  if remote and url != remote:
222
223
  project.create_remote(remote)
223
224
  elif url:
225
+ logger.info("Identified pre-initialized git repo, using it", url=url)
224
226
  project.spec._source = url
225
227
  project.spec.origin_url = url
226
228
  if description:
@@ -366,7 +368,7 @@ def load_project(
366
368
  project = _load_project_dir(context, name, subpath)
367
369
 
368
370
  if not project.metadata.name:
369
- raise ValueError("project name must be specified")
371
+ raise ValueError("Project name must be specified")
370
372
 
371
373
  if parameters:
372
374
  # Enable setting project parameters at load time, can be used to customize the project_setup
@@ -1593,7 +1595,7 @@ class MlrunProject(ModelObj):
1593
1595
  :param parameters: key/value dict of model parameters
1594
1596
  :param inputs: ordered list of model input features (name, type, ..)
1595
1597
  :param outputs: ordered list of model output/result elements (name, type, ..)
1596
- :param upload: upload to datastore (default is True)
1598
+ :param upload: upload to datastore (if not specified, defaults to True (uploads artifact))
1597
1599
  :param labels: a set of key/value labels to tag the artifact with
1598
1600
  :param feature_vector: feature store feature vector uri (store://feature-vectors/<project>/<name>[:tag])
1599
1601
  :param feature_weights: list of feature weights, one per input column
@@ -2499,6 +2501,7 @@ class MlrunProject(ModelObj):
2499
2501
  timeout: int = None,
2500
2502
  source: str = None,
2501
2503
  cleanup_ttl: int = None,
2504
+ notifications: typing.List[mlrun.model.Notification] = None,
2502
2505
  ) -> _PipelineRunStatus:
2503
2506
  """run a workflow using kubeflow pipelines
2504
2507
 
@@ -2531,6 +2534,8 @@ class MlrunProject(ModelObj):
2531
2534
  :param cleanup_ttl:
2532
2535
  pipeline cleanup ttl in secs (time to wait after workflow completion, at which point the
2533
2536
  workflow and all its resources are deleted)
2537
+ :param notifications:
2538
+ list of notifications to send for workflow completion
2534
2539
  :returns: run id
2535
2540
  """
2536
2541
 
@@ -2598,6 +2603,7 @@ class MlrunProject(ModelObj):
2598
2603
  artifact_path=artifact_path,
2599
2604
  namespace=namespace,
2600
2605
  source=source,
2606
+ notifications=notifications,
2601
2607
  )
2602
2608
  # run is None when scheduling
2603
2609
  if run and run.state == mlrun.run.RunStatuses.failed:
@@ -2609,7 +2615,14 @@ class MlrunProject(ModelObj):
2609
2615
  )
2610
2616
  workflow_spec.clear_tmp()
2611
2617
  if (timeout or watch) and not workflow_spec.schedule:
2612
- run._engine.get_run_status(project=self, run=run, timeout=timeout)
2618
+ # run's engine gets replaced with inner engine if engine is remote,
2619
+ # so in that case we need to get the status from the remote engine manually
2620
+ if engine == "remote":
2621
+ status_engine = _RemoteRunner
2622
+ else:
2623
+ status_engine = run._engine
2624
+
2625
+ status_engine.get_run_status(project=self, run=run, timeout=timeout)
2613
2626
  return run
2614
2627
 
2615
2628
  def save_workflow(self, name, target, artifact_path=None, ttl=None):
@@ -2711,6 +2724,7 @@ class MlrunProject(ModelObj):
2711
2724
  """Set the credentials that will be used by the project's model monitoring
2712
2725
  infrastructure functions.
2713
2726
 
2727
+ :param access_key: Model Monitoring access key for managing user permissions
2714
2728
  :param access_key: Model Monitoring access key for managing user permissions
2715
2729
  :param endpoint_store_connection: Endpoint store connection string
2716
2730
  :param stream_path: Path to the model monitoring stream
@@ -2995,7 +3009,7 @@ class MlrunProject(ModelObj):
2995
3009
  * True: The existing params are replaced by the new ones
2996
3010
  :param extra_args: A string containing additional builder arguments in the format of command-line options,
2997
3011
  e.g. extra_args="--skip-tls-verify --build-arg A=val"r
2998
- :param force_build:
3012
+ :param force_build: set True for force building the image
2999
3013
  """
3000
3014
 
3001
3015
  if skip_deployed:
@@ -3228,13 +3242,16 @@ class MlrunProject(ModelObj):
3228
3242
  :param labels: Return functions that have specific labels assigned to them.
3229
3243
  :returns: List of function objects.
3230
3244
  """
3231
- labels = labels or []
3245
+
3246
+ model_monitoring_labels_list = [
3247
+ f"{mm_constants.ModelMonitoringAppLabel.KEY}={mm_constants.ModelMonitoringAppLabel.VAL}"
3248
+ ]
3249
+ if labels:
3250
+ model_monitoring_labels_list += labels
3232
3251
  return self.list_functions(
3233
3252
  name=name,
3234
3253
  tag=tag,
3235
- labels=[
3236
- f"{mm_constants.ModelMonitoringAppLabel.KEY}={mm_constants.ModelMonitoringAppLabel.VAL}"
3237
- ].extend(labels),
3254
+ labels=model_monitoring_labels_list,
3238
3255
  )
3239
3256
 
3240
3257
  def list_runs(
@@ -3463,7 +3480,13 @@ def _init_function_from_dict(
3463
3480
  )
3464
3481
 
3465
3482
  elif url.endswith(".py"):
3466
- if not image and not project.default_image and kind != "local":
3483
+ # when load_source_on_run is used we allow not providing image as code will be loaded pre-run. ML-4994
3484
+ if (
3485
+ not image
3486
+ and not project.default_image
3487
+ and kind != "local"
3488
+ and not project.spec.load_source_on_run
3489
+ ):
3467
3490
  raise ValueError(
3468
3491
  "image must be provided with py code files which do not "
3469
3492
  "run on 'local' engine kind"
@@ -199,6 +199,12 @@ class RuntimeKinds(object):
199
199
  return True
200
200
  return False
201
201
 
202
+ @staticmethod
203
+ def requires_image_name_for_execution(kind):
204
+ if RuntimeKinds.is_local_runtime(kind):
205
+ return False
206
+ return kind not in [RuntimeKinds.spark]
207
+
202
208
 
203
209
  def get_runtime_class(kind: str):
204
210
  if kind == RuntimeKinds.mpijob:
mlrun/runtimes/base.py CHANGED
@@ -196,6 +196,9 @@ class BaseRuntime(ModelObj):
196
196
  self.metadata.labels[key] = str(value)
197
197
  return self
198
198
 
199
+ def set_categories(self, categories: List[str]):
200
+ self.metadata.categories = mlrun.utils.helpers.as_list(categories)
201
+
199
202
  @property
200
203
  def uri(self):
201
204
  return self._function_uri()
@@ -356,7 +359,7 @@ class BaseRuntime(ModelObj):
356
359
  type can be given there. The artifact key must appear in the dictionary as "key": "the_key".
357
360
  :param state_thresholds: Dictionary of states to time thresholds. The state will be matched against the
358
361
  pod's status. The threshold should be a time string that conforms to timelength python package
359
- standards and is at least 1 second (-1 for infinite).
362
+ standards and is at least 1 minute (-1 for infinite).
360
363
  If the phase is active for longer than the threshold, the run will be aborted.
361
364
  See mlconf.function.spec.state_thresholds for the state options and default values.
362
365
  :return: Run context object (RunObject) with run metadata, results and status
@@ -797,6 +800,14 @@ class BaseRuntime(ModelObj):
797
800
  self.spec.build = {}
798
801
  return self
799
802
 
803
+ def requires_build(self) -> bool:
804
+ build = self.spec.build
805
+ return (
806
+ build.commands
807
+ or build.requirements
808
+ or (build.source and not build.load_source_on_run)
809
+ )
810
+
800
811
  def prepare_image_for_deploy(self):
801
812
  """
802
813
  if a function has a 'spec.image' it is considered to be deployed,
mlrun/runtimes/daskjob.py CHANGED
@@ -16,6 +16,7 @@ import inspect
16
16
  import socket
17
17
  import time
18
18
  from os import environ
19
+ from typing import Callable, Dict, List, Optional, Union
19
20
 
20
21
  import mlrun.common.schemas
21
22
  import mlrun.errors
@@ -230,7 +231,7 @@ class DaskCluster(KubejobRuntime):
230
231
  if db_func and "status" in db_func:
231
232
  self.status = db_func["status"]
232
233
  if self.kfp:
233
- logger.info(f"dask status: {db_func['status']}")
234
+ logger.info(f"Dask status: {db_func['status']}")
234
235
  return "scheduler_address" in db_func["status"]
235
236
 
236
237
  return False
@@ -311,7 +312,7 @@ class DaskCluster(KubejobRuntime):
311
312
  if self.spec.service_type == "NodePort":
312
313
  dash = f"{config.remote_host}:{self.status.node_ports.get('dashboard')}"
313
314
  else:
314
- logger.info("to get a dashboard link, use NodePort service_type")
315
+ logger.info("To get a dashboard link, use NodePort service_type")
315
316
 
316
317
  return addr, dash
317
318
 
@@ -325,12 +326,12 @@ class DaskCluster(KubejobRuntime):
325
326
 
326
327
  if self.status.scheduler_address:
327
328
  addr, dash = self._remote_addresses()
328
- logger.info(f"trying dask client at: {addr}")
329
+ logger.info(f"Trying dask client at: {addr}")
329
330
  try:
330
331
  client = Client(addr)
331
332
  except OSError as exc:
332
333
  logger.warning(
333
- f"remote scheduler at {addr} not ready, will try to restart {err_to_str(exc)}"
334
+ f"Remote scheduler at {addr} not ready, will try to restart {err_to_str(exc)}"
334
335
  )
335
336
 
336
337
  status = self.get_status()
@@ -340,7 +341,7 @@ class DaskCluster(KubejobRuntime):
340
341
  client = Client(addr)
341
342
 
342
343
  logger.info(
343
- f"using remote dask scheduler ({self.status.cluster_name}) at: {addr}"
344
+ f"Using remote dask scheduler ({self.status.cluster_name}) at: {addr}"
344
345
  )
345
346
  if dash:
346
347
  ipython_display(
@@ -457,6 +458,73 @@ class DaskCluster(KubejobRuntime):
457
458
  """
458
459
  self.spec._verify_and_set_requests("worker_resources", mem, cpu, patch=patch)
459
460
 
461
+ def set_state_thresholds(
462
+ self,
463
+ state_thresholds: Dict[str, str],
464
+ patch: bool = True,
465
+ ):
466
+ raise NotImplementedError(
467
+ "State thresholds is not supported for Dask runtime yet, use spec.scheduler_timeout instead.",
468
+ )
469
+
470
+ def run(
471
+ self,
472
+ runspec: Optional[
473
+ Union["mlrun.run.RunTemplate", "mlrun.run.RunObject", dict]
474
+ ] = None,
475
+ handler: Optional[Union[str, Callable]] = None,
476
+ name: Optional[str] = "",
477
+ project: Optional[str] = "",
478
+ params: Optional[dict] = None,
479
+ inputs: Optional[Dict[str, str]] = None,
480
+ out_path: Optional[str] = "",
481
+ workdir: Optional[str] = "",
482
+ artifact_path: Optional[str] = "",
483
+ watch: Optional[bool] = True,
484
+ schedule: Optional[Union[str, mlrun.common.schemas.ScheduleCronTrigger]] = None,
485
+ hyperparams: Optional[Dict[str, list]] = None,
486
+ hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
487
+ verbose: Optional[bool] = None,
488
+ scrape_metrics: Optional[bool] = None,
489
+ local: Optional[bool] = False,
490
+ local_code_path: Optional[str] = None,
491
+ auto_build: Optional[bool] = None,
492
+ param_file_secrets: Optional[Dict[str, str]] = None,
493
+ notifications: Optional[List[mlrun.model.Notification]] = None,
494
+ returns: Optional[List[Union[str, Dict[str, str]]]] = None,
495
+ state_thresholds: Optional[Dict[str, int]] = None,
496
+ **launcher_kwargs,
497
+ ) -> RunObject:
498
+ if state_thresholds:
499
+ raise mlrun.errors.MLRunInvalidArgumentError(
500
+ "State thresholds is not supported for Dask runtime yet, use spec.scheduler_timeout instead."
501
+ )
502
+ return super().run(
503
+ runspec=runspec,
504
+ handler=handler,
505
+ name=name,
506
+ project=project,
507
+ params=params,
508
+ inputs=inputs,
509
+ out_path=out_path,
510
+ workdir=workdir,
511
+ artifact_path=artifact_path,
512
+ watch=watch,
513
+ schedule=schedule,
514
+ hyperparams=hyperparams,
515
+ hyper_param_options=hyper_param_options,
516
+ verbose=verbose,
517
+ scrape_metrics=scrape_metrics,
518
+ local=local,
519
+ local_code_path=local_code_path,
520
+ auto_build=auto_build,
521
+ param_file_secrets=param_file_secrets,
522
+ notifications=notifications,
523
+ returns=returns,
524
+ state_thresholds=state_thresholds,
525
+ **launcher_kwargs,
526
+ )
527
+
460
528
  def _run(self, runobj: RunObject, execution):
461
529
 
462
530
  handler = runobj.spec.handler
@@ -127,6 +127,7 @@ if result:
127
127
  param_file_secrets: Optional[Dict[str, str]] = None,
128
128
  notifications: Optional[List[mlrun.model.Notification]] = None,
129
129
  returns: Optional[List[Union[str, Dict[str, str]]]] = None,
130
+ state_thresholds: Optional[Dict[str, int]] = None,
130
131
  **launcher_kwargs,
131
132
  ) -> RunObject:
132
133
  if local:
@@ -153,6 +154,7 @@ if result:
153
154
  param_file_secrets=param_file_secrets,
154
155
  notifications=notifications,
155
156
  returns=returns,
157
+ state_thresholds=state_thresholds,
156
158
  **launcher_kwargs,
157
159
  )
158
160
 
@@ -120,6 +120,7 @@ class NuclioSpec(KubeResourceSpec):
120
120
  "base_image_pull",
121
121
  "service_type",
122
122
  "add_templated_ingress_host_mode",
123
+ "disable_default_http_trigger",
123
124
  ]
124
125
 
125
126
  def __init__(
@@ -163,6 +164,7 @@ class NuclioSpec(KubeResourceSpec):
163
164
  add_templated_ingress_host_mode=None,
164
165
  clone_target_dir=None,
165
166
  state_thresholds=None,
167
+ disable_default_http_trigger=None,
166
168
  ):
167
169
 
168
170
  super().__init__(
@@ -210,6 +212,8 @@ class NuclioSpec(KubeResourceSpec):
210
212
  self.min_replicas = min_replicas or 1
211
213
  self.max_replicas = max_replicas or 4
212
214
 
215
+ self.disable_default_http_trigger = disable_default_http_trigger
216
+
213
217
  # When True it will set Nuclio spec.noBaseImagesPull to False (negative logic)
214
218
  # indicate that the base image should be pulled from the container registry (not cached)
215
219
  self.base_image_pull = False
@@ -413,6 +417,11 @@ class RemoteRuntime(KubeResource):
413
417
  :param extra_attributes: key/value dict of extra nuclio trigger attributes
414
418
  :return: function object (self)
415
419
  """
420
+ if self.disable_default_http_trigger:
421
+ logger.warning(
422
+ "Adding HTTP trigger despite the default HTTP trigger creation being disabled"
423
+ )
424
+
416
425
  annotations = annotations or {}
417
426
  if worker_timeout:
418
427
  gateway_timeout = gateway_timeout or (worker_timeout + 60)
@@ -683,6 +692,24 @@ class RemoteRuntime(KubeResource):
683
692
  "State thresholds do not apply for nuclio as it has its own function pods healthiness monitoring"
684
693
  )
685
694
 
695
+ @min_nuclio_versions("1.12.8")
696
+ def disable_default_http_trigger(
697
+ self,
698
+ ):
699
+ """
700
+ Disables nuclio's default http trigger creation
701
+ """
702
+ self.spec.disable_default_http_trigger = True
703
+
704
+ @min_nuclio_versions("1.12.8")
705
+ def enable_default_http_trigger(
706
+ self,
707
+ ):
708
+ """
709
+ Enables nuclio's default http trigger creation
710
+ """
711
+ self.spec.disable_default_http_trigger = False
712
+
686
713
  def _get_state(
687
714
  self,
688
715
  dashboard="",
@@ -876,11 +903,22 @@ class RemoteRuntime(KubeResource):
876
903
 
877
904
  if "://" not in path:
878
905
  if not self.status.address:
879
- state, _, _ = self._get_state(dashboard, auth_info=auth_info)
880
- if state != "ready" or not self.status.address:
881
- raise ValueError(
882
- "no function address or not ready, first run .deploy()"
906
+ # here we check that if default http trigger is disabled, function contains a custom http trigger
907
+ # Otherwise, the function is not invokable, so we raise an error
908
+ if (
909
+ not self._trigger_of_kind_exists(kind="http")
910
+ and self.spec.disable_default_http_trigger
911
+ ):
912
+ raise mlrun.errors.MLRunPreconditionFailedError(
913
+ "Default http trigger creation is disabled and there is no any other custom http trigger, "
914
+ "so function can not be invoked via http. Either enable default http trigger creation or create"
915
+ "custom http trigger"
883
916
  )
917
+ state, _, _ = self._get_state(dashboard, auth_info=auth_info)
918
+ if state not in ["ready", "scaledToZero"]:
919
+ logger.warning(f"Function is in the {state} state")
920
+ if not self.status.address:
921
+ raise ValueError("no function address first run .deploy()")
884
922
 
885
923
  path = self._resolve_invocation_url(path, force_external_address)
886
924
 
@@ -914,6 +952,17 @@ class RemoteRuntime(KubeResource):
914
952
  data = json.loads(data)
915
953
  return data
916
954
 
955
+ def _trigger_of_kind_exists(self, kind: str) -> bool:
956
+ if not self.spec.config:
957
+ return False
958
+
959
+ for name, spec in self.spec.config.items():
960
+ if isinstance(spec, dict):
961
+ if spec.get("kind") == kind:
962
+ return True
963
+
964
+ return False
965
+
917
966
  def _pre_run_validations(self):
918
967
  if self.spec.function_kind != "mlrun":
919
968
  raise RunError(
mlrun/runtimes/kubejob.py CHANGED
@@ -175,7 +175,7 @@ class KubejobRuntime(KubeResource):
175
175
  :param show_on_failure: show logs only in case of build failure
176
176
  :param force_build: set True for force building the image, even when no changes were made
177
177
 
178
- :return True if the function is ready (deployed)
178
+ :return: True if the function is ready (deployed)
179
179
  """
180
180
 
181
181
  build = self.spec.build
mlrun/runtimes/local.py CHANGED
@@ -104,13 +104,13 @@ class ParallelRunner:
104
104
  num_errors += 1
105
105
  results.append(resp)
106
106
  if num_errors > generator.max_errors:
107
- logger.error("max errors reached, stopping iterations!")
107
+ logger.error("Max errors reached, stopping iterations!")
108
108
  return True
109
109
  run_results = resp["status"].get("results", {})
110
110
  stop = generator.eval_stop_condition(run_results)
111
111
  if stop:
112
112
  logger.info(
113
- f"reached early stop condition ({generator.options.stop_condition}), stopping iterations!"
113
+ f"Reached early stop condition ({generator.options.stop_condition}), stopping iterations!"
114
114
  )
115
115
  return stop
116
116
 
@@ -140,7 +140,7 @@ class ParallelRunner:
140
140
 
141
141
  client.close()
142
142
  if function_name and generator.options.teardown_dask:
143
- logger.info("tearing down the dask cluster..")
143
+ logger.info("Tearing down the dask cluster..")
144
144
  mlrun.get_run_db().delete_runtime_resources(
145
145
  kind="dask", object_id=function_name, force=True
146
146
  )
@@ -278,7 +278,7 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
278
278
 
279
279
  handler = runobj.spec.handler
280
280
  handler_str = handler or "main"
281
- logger.debug(f"starting local run: {self.spec.command} # {handler_str}")
281
+ logger.debug(f"Starting local run: {self.spec.command} # {handler_str}")
282
282
  pythonpath = self.spec.pythonpath
283
283
 
284
284
  if handler:
@@ -317,13 +317,13 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
317
317
  context.set_state(error=err_to_str(exc), commit=True)
318
318
  logger.error(f"run error, {traceback.format_exc()}")
319
319
  raise RunError(
320
- "failed on pre-loading / post-running of the function"
320
+ "Failed on pre-loading / post-running of the function"
321
321
  ) from exc
322
322
 
323
323
  else:
324
324
  command = self.spec.command
325
325
  command = command.format(**runobj.spec.parameters)
326
- logger.info(f"handler was not provided running main ({command})")
326
+ logger.info(f"Handler was not provided running main ({command})")
327
327
  arg_list = command.split()
328
328
  if self.spec.mode == "pass":
329
329
  cmd = arg_list
@@ -360,9 +360,9 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
360
360
  if resp:
361
361
  run_obj_dict = json.loads(resp)
362
362
  else:
363
- logger.error("empty context tmp file")
363
+ logger.debug("Empty context tmp file")
364
364
  else:
365
- logger.info("no context file found")
365
+ logger.info("No context file found")
366
366
 
367
367
  # If trackers where used, this is where we log all data collected to MLRun
368
368
  run_obj_dict = trackers_manager.post_run(run_obj_dict)
@@ -396,7 +396,7 @@ def run_exec(cmd, args, env=None, cwd=None):
396
396
  cmd += args
397
397
  if env and "SYSTEMROOT" in os.environ:
398
398
  env["SYSTEMROOT"] = os.environ["SYSTEMROOT"]
399
- print("running:", cmd)
399
+ print("Running:", cmd)
400
400
  process = Popen(
401
401
  cmd, stdout=PIPE, stderr=PIPE, env=os.environ, cwd=cwd, universal_newlines=True
402
402
  )
mlrun/runtimes/pod.py CHANGED
@@ -1067,7 +1067,7 @@ class KubeResource(BaseRuntime):
1067
1067
  Set the threshold for a specific state of the runtime.
1068
1068
  The threshold is the amount of time that the runtime will wait before aborting the run if the job is in the
1069
1069
  matching state.
1070
- The threshold time string must conform to timelength python package standards and be at least 1 second
1070
+ The threshold time string must conform to timelength python package standards and be at least 1 minute
1071
1071
  (e.g. 1000s, 1 hour 30m, 1h etc. or -1 for infinite).
1072
1072
  If the threshold is not set for a state, the default threshold will be used.
1073
1073
 
@@ -205,6 +205,7 @@ class RemoteSparkRuntime(KubejobRuntime):
205
205
  mlrun_version_specifier=mlrun_version_specifier,
206
206
  builder_env=builder_env,
207
207
  show_on_failure=show_on_failure,
208
+ force_build=force_build,
208
209
  )
209
210
 
210
211
 
mlrun/runtimes/serving.py CHANGED
@@ -147,6 +147,7 @@ class ServingSpec(NuclioSpec):
147
147
  add_templated_ingress_host_mode=None,
148
148
  clone_target_dir=None,
149
149
  state_thresholds=None,
150
+ disable_default_http_trigger=None,
150
151
  ):
151
152
  super().__init__(
152
153
  command=command,
@@ -187,6 +188,7 @@ class ServingSpec(NuclioSpec):
187
188
  service_type=service_type,
188
189
  add_templated_ingress_host_mode=add_templated_ingress_host_mode,
189
190
  clone_target_dir=clone_target_dir,
191
+ disable_default_http_trigger=disable_default_http_trigger,
190
192
  )
191
193
 
192
194
  self.models = models or {}
@@ -584,6 +586,7 @@ class ServingRuntime(RemoteRuntime):
584
586
  verbose=False,
585
587
  auth_info: mlrun.common.schemas.AuthInfo = None,
586
588
  builder_env: dict = None,
589
+ force_build: bool = False,
587
590
  ):
588
591
  """deploy model serving function to a local/remote cluster
589
592
 
@@ -594,6 +597,7 @@ class ServingRuntime(RemoteRuntime):
594
597
  :param auth_info: The auth info to use to communicate with the Nuclio dashboard, required only when providing
595
598
  dashboard
596
599
  :param builder_env: env vars dict for source archive config/credentials e.g. builder_env={"GIT_TOKEN": token}
600
+ :param force_build: set True for force building the image
597
601
  """
598
602
  load_mode = self.spec.load_mode
599
603
  if load_mode and load_mode not in ["sync", "async"]:
@@ -633,7 +637,13 @@ class ServingRuntime(RemoteRuntime):
633
637
  logger.info(f"deploy root function {self.metadata.name} ...")
634
638
 
635
639
  return super().deploy(
636
- dashboard, project, tag, verbose, auth_info, builder_env=builder_env
640
+ dashboard,
641
+ project,
642
+ tag,
643
+ verbose,
644
+ auth_info,
645
+ builder_env=builder_env,
646
+ force_build=force_build,
637
647
  )
638
648
 
639
649
  def _get_runtime_env(self):
@@ -856,6 +856,7 @@ class Spark3Runtime(KubejobRuntime):
856
856
  mlrun_version_specifier=None,
857
857
  builder_env: dict = None,
858
858
  show_on_failure: bool = False,
859
+ force_build: bool = False,
859
860
  ):
860
861
  """deploy function, build container with dependencies
861
862
 
@@ -867,8 +868,9 @@ class Spark3Runtime(KubejobRuntime):
867
868
  :param builder_env: Kaniko builder pod env vars dict (for config/credentials)
868
869
  e.g. builder_env={"GIT_TOKEN": token}
869
870
  :param show_on_failure: show logs only in case of build failure
871
+ :param force_build: set True for force building the image, even when no changes were made
870
872
 
871
- :return True if the function is ready (deployed)
873
+ :return: True if the function is ready (deployed)
872
874
  """
873
875
  # connect will populate the config from the server config
874
876
  mlrun.db.get_run_db()
@@ -882,6 +884,7 @@ class Spark3Runtime(KubejobRuntime):
882
884
  mlrun_version_specifier=mlrun_version_specifier,
883
885
  builder_env=builder_env,
884
886
  show_on_failure=show_on_failure,
887
+ force_build=force_build,
885
888
  )
886
889
 
887
890
  @staticmethod