mlrun 1.7.0rc4__py3-none-any.whl → 1.7.0rc20__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 (200) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +25 -111
  3. mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +4 -3
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +38 -254
  8. mlrun/artifacts/dataset.py +9 -190
  9. mlrun/artifacts/manager.py +41 -47
  10. mlrun/artifacts/model.py +30 -158
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +68 -0
  13. mlrun/common/formatters/__init__.py +19 -0
  14. mlrun/{model_monitoring/stores/models/sqlite.py → common/formatters/artifact.py} +6 -8
  15. mlrun/common/formatters/base.py +78 -0
  16. mlrun/common/formatters/function.py +41 -0
  17. mlrun/common/formatters/pipeline.py +53 -0
  18. mlrun/common/formatters/project.py +51 -0
  19. mlrun/{runtimes → common/runtimes}/constants.py +32 -4
  20. mlrun/common/schemas/__init__.py +25 -4
  21. mlrun/common/schemas/alert.py +203 -0
  22. mlrun/common/schemas/api_gateway.py +148 -0
  23. mlrun/common/schemas/artifact.py +15 -5
  24. mlrun/common/schemas/auth.py +8 -2
  25. mlrun/common/schemas/client_spec.py +2 -0
  26. mlrun/common/schemas/frontend_spec.py +1 -0
  27. mlrun/common/schemas/function.py +4 -0
  28. mlrun/common/schemas/hub.py +7 -9
  29. mlrun/common/schemas/model_monitoring/__init__.py +19 -3
  30. mlrun/common/schemas/model_monitoring/constants.py +96 -26
  31. mlrun/common/schemas/model_monitoring/grafana.py +9 -5
  32. mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
  33. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  34. mlrun/common/schemas/pipeline.py +0 -9
  35. mlrun/common/schemas/project.py +22 -21
  36. mlrun/common/types.py +7 -1
  37. mlrun/config.py +87 -19
  38. mlrun/data_types/data_types.py +4 -0
  39. mlrun/data_types/to_pandas.py +9 -9
  40. mlrun/datastore/__init__.py +5 -8
  41. mlrun/datastore/alibaba_oss.py +130 -0
  42. mlrun/datastore/azure_blob.py +4 -5
  43. mlrun/datastore/base.py +69 -30
  44. mlrun/datastore/datastore.py +10 -2
  45. mlrun/datastore/datastore_profile.py +90 -6
  46. mlrun/datastore/google_cloud_storage.py +1 -1
  47. mlrun/datastore/hdfs.py +5 -0
  48. mlrun/datastore/inmem.py +2 -2
  49. mlrun/datastore/redis.py +2 -2
  50. mlrun/datastore/s3.py +5 -0
  51. mlrun/datastore/snowflake_utils.py +43 -0
  52. mlrun/datastore/sources.py +172 -44
  53. mlrun/datastore/store_resources.py +7 -7
  54. mlrun/datastore/targets.py +285 -41
  55. mlrun/datastore/utils.py +68 -5
  56. mlrun/datastore/v3io.py +27 -50
  57. mlrun/db/auth_utils.py +152 -0
  58. mlrun/db/base.py +149 -14
  59. mlrun/db/factory.py +1 -1
  60. mlrun/db/httpdb.py +608 -178
  61. mlrun/db/nopdb.py +191 -7
  62. mlrun/errors.py +11 -0
  63. mlrun/execution.py +37 -20
  64. mlrun/feature_store/__init__.py +0 -2
  65. mlrun/feature_store/api.py +21 -52
  66. mlrun/feature_store/feature_set.py +48 -23
  67. mlrun/feature_store/feature_vector.py +2 -1
  68. mlrun/feature_store/ingestion.py +7 -6
  69. mlrun/feature_store/retrieval/base.py +9 -4
  70. mlrun/feature_store/retrieval/conversion.py +9 -9
  71. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  72. mlrun/feature_store/retrieval/job.py +9 -3
  73. mlrun/feature_store/retrieval/local_merger.py +2 -0
  74. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  75. mlrun/feature_store/steps.py +30 -19
  76. mlrun/features.py +4 -13
  77. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
  78. mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
  79. mlrun/frameworks/lgbm/__init__.py +1 -1
  80. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  81. mlrun/frameworks/lgbm/model_handler.py +1 -1
  82. mlrun/frameworks/parallel_coordinates.py +2 -1
  83. mlrun/frameworks/pytorch/__init__.py +2 -2
  84. mlrun/frameworks/sklearn/__init__.py +1 -1
  85. mlrun/frameworks/tf_keras/__init__.py +5 -2
  86. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  87. mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
  88. mlrun/frameworks/xgboost/__init__.py +1 -1
  89. mlrun/k8s_utils.py +10 -11
  90. mlrun/launcher/__init__.py +1 -1
  91. mlrun/launcher/base.py +6 -5
  92. mlrun/launcher/client.py +8 -6
  93. mlrun/launcher/factory.py +1 -1
  94. mlrun/launcher/local.py +9 -3
  95. mlrun/launcher/remote.py +9 -3
  96. mlrun/lists.py +6 -2
  97. mlrun/model.py +58 -19
  98. mlrun/model_monitoring/__init__.py +1 -1
  99. mlrun/model_monitoring/api.py +127 -301
  100. mlrun/model_monitoring/application.py +5 -296
  101. mlrun/model_monitoring/applications/__init__.py +11 -0
  102. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  103. mlrun/model_monitoring/applications/base.py +282 -0
  104. mlrun/model_monitoring/applications/context.py +214 -0
  105. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  106. mlrun/model_monitoring/applications/histogram_data_drift.py +224 -93
  107. mlrun/model_monitoring/applications/results.py +99 -0
  108. mlrun/model_monitoring/controller.py +30 -36
  109. mlrun/model_monitoring/db/__init__.py +18 -0
  110. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  111. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  112. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +58 -32
  113. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  114. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  115. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  116. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  117. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  118. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  119. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  120. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +302 -155
  121. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  122. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  123. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  124. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  125. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  126. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  127. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  128. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  129. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  130. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  131. mlrun/model_monitoring/evidently_application.py +6 -118
  132. mlrun/model_monitoring/features_drift_table.py +34 -22
  133. mlrun/model_monitoring/helpers.py +100 -7
  134. mlrun/model_monitoring/model_endpoint.py +3 -2
  135. mlrun/model_monitoring/stream_processing.py +93 -228
  136. mlrun/model_monitoring/tracking_policy.py +7 -1
  137. mlrun/model_monitoring/writer.py +152 -124
  138. mlrun/package/packagers_manager.py +1 -0
  139. mlrun/package/utils/_formatter.py +2 -2
  140. mlrun/platforms/__init__.py +11 -10
  141. mlrun/platforms/iguazio.py +21 -202
  142. mlrun/projects/operations.py +30 -16
  143. mlrun/projects/pipelines.py +92 -99
  144. mlrun/projects/project.py +757 -268
  145. mlrun/render.py +15 -14
  146. mlrun/run.py +160 -162
  147. mlrun/runtimes/__init__.py +55 -3
  148. mlrun/runtimes/base.py +33 -19
  149. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  150. mlrun/runtimes/funcdoc.py +0 -28
  151. mlrun/runtimes/kubejob.py +28 -122
  152. mlrun/runtimes/local.py +5 -2
  153. mlrun/runtimes/mpijob/__init__.py +0 -20
  154. mlrun/runtimes/mpijob/abstract.py +8 -8
  155. mlrun/runtimes/mpijob/v1.py +1 -1
  156. mlrun/runtimes/nuclio/__init__.py +1 -0
  157. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  158. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  159. mlrun/runtimes/nuclio/application/application.py +523 -0
  160. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  161. mlrun/runtimes/nuclio/function.py +98 -58
  162. mlrun/runtimes/nuclio/serving.py +36 -42
  163. mlrun/runtimes/pod.py +196 -45
  164. mlrun/runtimes/remotesparkjob.py +1 -1
  165. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  166. mlrun/runtimes/utils.py +6 -73
  167. mlrun/secrets.py +6 -2
  168. mlrun/serving/remote.py +2 -3
  169. mlrun/serving/routers.py +7 -4
  170. mlrun/serving/server.py +7 -8
  171. mlrun/serving/states.py +73 -43
  172. mlrun/serving/v2_serving.py +8 -7
  173. mlrun/track/tracker.py +2 -1
  174. mlrun/utils/async_http.py +25 -5
  175. mlrun/utils/helpers.py +141 -75
  176. mlrun/utils/http.py +1 -1
  177. mlrun/utils/logger.py +39 -7
  178. mlrun/utils/notifications/notification/__init__.py +14 -9
  179. mlrun/utils/notifications/notification/base.py +12 -0
  180. mlrun/utils/notifications/notification/console.py +2 -0
  181. mlrun/utils/notifications/notification/git.py +3 -1
  182. mlrun/utils/notifications/notification/ipython.py +2 -0
  183. mlrun/utils/notifications/notification/slack.py +101 -21
  184. mlrun/utils/notifications/notification/webhook.py +11 -1
  185. mlrun/utils/notifications/notification_pusher.py +147 -16
  186. mlrun/utils/retryer.py +3 -2
  187. mlrun/utils/v3io_clients.py +0 -1
  188. mlrun/utils/version/version.json +2 -2
  189. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +33 -18
  190. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  191. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +1 -1
  192. mlrun/kfpops.py +0 -868
  193. mlrun/model_monitoring/batch.py +0 -974
  194. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  195. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
  196. mlrun/platforms/other.py +0 -305
  197. mlrun-1.7.0rc4.dist-info/RECORD +0 -321
  198. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  199. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  200. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/render.py CHANGED
@@ -121,20 +121,12 @@ def artifacts_html(
121
121
  html = ""
122
122
 
123
123
  for artifact in artifacts:
124
- # TODO: remove this in 1.7.0 once we no longer support legacy format
125
- if mlrun.utils.is_legacy_artifact(artifact):
126
- attribute_value = artifact.get(attribute_name)
127
- else:
128
- attribute_value = artifact["spec"].get(attribute_name)
129
-
130
- if mlrun.utils.is_legacy_artifact(artifact):
131
- key = artifact["key"]
132
- else:
133
- key = artifact["metadata"]["key"]
124
+ attribute_value = artifact["spec"].get(attribute_name)
125
+ key = artifact["metadata"]["key"]
134
126
 
135
127
  if not attribute_value:
136
128
  mlrun.utils.logger.warning(
137
- "Artifact is incomplete, omitting from output (most likely due to a failed artifact logging)",
129
+ f"Artifact required attribute {attribute_name} is missing, omitting from output",
138
130
  artifact_key=key,
139
131
  )
140
132
  continue
@@ -404,12 +396,21 @@ def runs_to_html(
404
396
  df.drop("labels", axis=1, inplace=True)
405
397
  df.drop("inputs", axis=1, inplace=True)
406
398
  df.drop("artifacts", axis=1, inplace=True)
399
+ df.drop("artifact_uris", axis=1, inplace=True)
407
400
  else:
408
401
  df["labels"] = df["labels"].apply(dict_html)
409
402
  df["inputs"] = df["inputs"].apply(inputs_html)
410
- df["artifacts"] = df["artifacts"].apply(
411
- lambda artifacts: artifacts_html(artifacts, "target_path"),
412
- )
403
+ if df["artifacts"][0]:
404
+ df["artifacts"] = df["artifacts"].apply(
405
+ lambda artifacts: artifacts_html(artifacts, "target_path"),
406
+ )
407
+ df.drop("artifact_uris", axis=1, inplace=True)
408
+ elif df["artifact_uris"][0]:
409
+ df["artifact_uris"] = df["artifact_uris"].apply(dict_html)
410
+ df.drop("artifacts", axis=1, inplace=True)
411
+ else:
412
+ df.drop("artifacts", axis=1, inplace=True)
413
+ df.drop("artifact_uris", axis=1, inplace=True)
413
414
 
414
415
  def expand_error(x):
415
416
  if x["state"] == "error":
mlrun/run.py CHANGED
@@ -29,12 +29,13 @@ from typing import Optional, Union
29
29
  import nuclio
30
30
  import yaml
31
31
  from kfp import Client
32
+ from mlrun_pipelines.common.models import RunStatuses
33
+ from mlrun_pipelines.common.ops import format_summary_from_kfp_run, show_kfp_run
32
34
 
35
+ import mlrun.common.formatters
33
36
  import mlrun.common.schemas
34
37
  import mlrun.errors
35
38
  import mlrun.utils.helpers
36
- from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
37
- from mlrun.runtimes.nuclio.serving import serving_subkind
38
39
 
39
40
  from .common.helpers import parse_versioned_object_uri
40
41
  from .config import config as mlconf
@@ -48,7 +49,6 @@ from .runtimes import (
48
49
  KubejobRuntime,
49
50
  LocalRuntime,
50
51
  MpiRuntimeV1,
51
- MpiRuntimeV1Alpha1,
52
52
  RemoteRuntime,
53
53
  RemoteSparkRuntime,
54
54
  RuntimeKinds,
@@ -58,6 +58,7 @@ from .runtimes import (
58
58
  )
59
59
  from .runtimes.databricks_job.databricks_runtime import DatabricksRuntime
60
60
  from .runtimes.funcdoc import update_function_entry_points
61
+ from .runtimes.nuclio.application import ApplicationRuntime
61
62
  from .runtimes.utils import add_code_metadata, global_context
62
63
  from .utils import (
63
64
  extend_hub_uri_if_needed,
@@ -69,41 +70,6 @@ from .utils import (
69
70
  )
70
71
 
71
72
 
72
- class RunStatuses:
73
- succeeded = "Succeeded"
74
- failed = "Failed"
75
- skipped = "Skipped"
76
- error = "Error"
77
- running = "Running"
78
-
79
- @staticmethod
80
- def all():
81
- return [
82
- RunStatuses.succeeded,
83
- RunStatuses.failed,
84
- RunStatuses.skipped,
85
- RunStatuses.error,
86
- RunStatuses.running,
87
- ]
88
-
89
- @staticmethod
90
- def stable_statuses():
91
- return [
92
- RunStatuses.succeeded,
93
- RunStatuses.failed,
94
- RunStatuses.skipped,
95
- RunStatuses.error,
96
- ]
97
-
98
- @staticmethod
99
- def transient_statuses():
100
- return [
101
- status
102
- for status in RunStatuses.all()
103
- if status not in RunStatuses.stable_statuses()
104
- ]
105
-
106
-
107
73
  def function_to_module(code="", workdir=None, secrets=None, silent=False):
108
74
  """Load code, notebook or mlrun function as .py module
109
75
  this function can import a local/remote py file or notebook
@@ -114,16 +80,18 @@ def function_to_module(code="", workdir=None, secrets=None, silent=False):
114
80
 
115
81
  example::
116
82
 
117
- mod = mlrun.function_to_module('./examples/training.py')
118
- task = mlrun.new_task(inputs={'infile.txt': '../examples/infile.txt'})
119
- context = mlrun.get_or_create_ctx('myfunc', spec=task)
120
- mod.my_job(context, p1=1, p2='x')
83
+ mod = mlrun.function_to_module("./examples/training.py")
84
+ task = mlrun.new_task(inputs={"infile.txt": "../examples/infile.txt"})
85
+ context = mlrun.get_or_create_ctx("myfunc", spec=task)
86
+ mod.my_job(context, p1=1, p2="x")
121
87
  print(context.to_yaml())
122
88
 
123
- fn = mlrun.import_function('hub://open-archive')
89
+ fn = mlrun.import_function("hub://open-archive")
124
90
  mod = mlrun.function_to_module(fn)
125
- data = mlrun.run.get_dataitem("https://fpsignals-public.s3.amazonaws.com/catsndogs.tar.gz")
126
- context = mlrun.get_or_create_ctx('myfunc')
91
+ data = mlrun.run.get_dataitem(
92
+ "https://fpsignals-public.s3.amazonaws.com/catsndogs.tar.gz"
93
+ )
94
+ context = mlrun.get_or_create_ctx("myfunc")
127
95
  mod.open_archive(context, archive_url=data)
128
96
  print(context.to_yaml())
129
97
 
@@ -256,29 +224,31 @@ def get_or_create_ctx(
256
224
  Examples::
257
225
 
258
226
  # load MLRUN runtime context (will be set by the runtime framework e.g. KubeFlow)
259
- context = get_or_create_ctx('train')
227
+ context = get_or_create_ctx("train")
260
228
 
261
229
  # get parameters from the runtime context (or use defaults)
262
- p1 = context.get_param('p1', 1)
263
- p2 = context.get_param('p2', 'a-string')
230
+ p1 = context.get_param("p1", 1)
231
+ p2 = context.get_param("p2", "a-string")
264
232
 
265
233
  # access input metadata, values, files, and secrets (passwords)
266
- print(f'Run: {context.name} (uid={context.uid})')
267
- print(f'Params: p1={p1}, p2={p2}')
234
+ print(f"Run: {context.name} (uid={context.uid})")
235
+ print(f"Params: p1={p1}, p2={p2}")
268
236
  print(f'accesskey = {context.get_secret("ACCESS_KEY")}')
269
- input_str = context.get_input('infile.txt').get()
270
- print(f'file: {input_str}')
237
+ input_str = context.get_input("infile.txt").get()
238
+ print(f"file: {input_str}")
271
239
 
272
240
  # RUN some useful code e.g. ML training, data prep, etc.
273
241
 
274
242
  # log scalar result values (job result metrics)
275
- context.log_result('accuracy', p1 * 2)
276
- context.log_result('loss', p1 * 3)
277
- context.set_label('framework', 'sklearn')
243
+ context.log_result("accuracy", p1 * 2)
244
+ context.log_result("loss", p1 * 3)
245
+ context.set_label("framework", "sklearn")
278
246
 
279
247
  # log various types of artifacts (file, web page, table), will be versioned and visible in the UI
280
- context.log_artifact('model.txt', body=b'abc is 123', labels={'framework': 'xgboost'})
281
- context.log_artifact('results.html', body=b'<b> Some HTML <b>', viewer='web-app')
248
+ context.log_artifact(
249
+ "model.txt", body=b"abc is 123", labels={"framework": "xgboost"}
250
+ )
251
+ context.log_artifact("results.html", body=b"<b> Some HTML <b>", viewer="web-app")
282
252
 
283
253
  """
284
254
 
@@ -348,7 +318,9 @@ def import_function(url="", secrets=None, db="", project=None, new_name=None):
348
318
 
349
319
  function = mlrun.import_function("hub://auto-trainer")
350
320
  function = mlrun.import_function("./func.yaml")
351
- function = mlrun.import_function("https://raw.githubusercontent.com/org/repo/func.yaml")
321
+ function = mlrun.import_function(
322
+ "https://raw.githubusercontent.com/org/repo/func.yaml"
323
+ )
352
324
 
353
325
  :param url: path/url to Function Hub, db or function YAML file
354
326
  :param secrets: optional, credentials dict for DB or URL (s3, v3io, ...)
@@ -389,6 +361,8 @@ def import_function_to_dict(url, secrets=None):
389
361
  code = get_in(runtime, "spec.build.functionSourceCode")
390
362
  update_in(runtime, "metadata.build.code_origin", url)
391
363
  cmd = code_file = get_in(runtime, "spec.command", "")
364
+ # use kind = "job" by default if not specified
365
+ runtime.setdefault("kind", "job")
392
366
  if " " in cmd:
393
367
  code_file = cmd[: cmd.find(" ")]
394
368
  if runtime["kind"] in ["", "local"]:
@@ -425,19 +399,19 @@ def import_function_to_dict(url, secrets=None):
425
399
 
426
400
 
427
401
  def new_function(
428
- name: str = "",
429
- project: str = "",
430
- tag: str = "",
431
- kind: str = "",
432
- command: str = "",
433
- image: str = "",
434
- args: list = None,
435
- runtime=None,
436
- mode=None,
437
- handler: str = None,
438
- source: str = None,
402
+ name: Optional[str] = "",
403
+ project: Optional[str] = "",
404
+ tag: Optional[str] = "",
405
+ kind: Optional[str] = "",
406
+ command: Optional[str] = "",
407
+ image: Optional[str] = "",
408
+ args: Optional[list] = None,
409
+ runtime: Optional[Union[mlrun.runtimes.BaseRuntime, dict]] = None,
410
+ mode: Optional[str] = None,
411
+ handler: Optional[str] = None,
412
+ source: Optional[str] = None,
439
413
  requirements: Union[str, list[str]] = None,
440
- kfp=None,
414
+ kfp: Optional[bool] = None,
441
415
  requirements_file: str = "",
442
416
  ):
443
417
  """Create a new ML function from base properties
@@ -445,12 +419,18 @@ def new_function(
445
419
  Example::
446
420
 
447
421
  # define a container based function (the `training.py` must exist in the container workdir)
448
- f = new_function(command='training.py -x {x}', image='myrepo/image:latest', kind='job')
422
+ f = new_function(
423
+ command="training.py -x {x}", image="myrepo/image:latest", kind="job"
424
+ )
449
425
  f.run(params={"x": 5})
450
426
 
451
427
  # define a container based function which reads its source from a git archive
452
- f = new_function(command='training.py -x {x}', image='myrepo/image:latest', kind='job',
453
- source='git://github.com/mlrun/something.git')
428
+ f = new_function(
429
+ command="training.py -x {x}",
430
+ image="myrepo/image:latest",
431
+ kind="job",
432
+ source="git://github.com/mlrun/something.git",
433
+ )
454
434
  f.run(params={"x": 5})
455
435
 
456
436
  # define a local handler function (execute a local function handler)
@@ -535,9 +515,9 @@ def new_function(
535
515
  if source:
536
516
  runner.spec.build.source = source
537
517
  if handler:
538
- if kind == RuntimeKinds.serving:
518
+ if kind in RuntimeKinds.handlerless_runtimes():
539
519
  raise MLRunInvalidArgumentError(
540
- "cannot set the handler for serving runtime"
520
+ f"Handler is not supported for {kind} runtime"
541
521
  )
542
522
  elif kind in RuntimeKinds.nuclio_runtimes():
543
523
  runner.spec.function_handler = handler
@@ -575,24 +555,23 @@ def _process_runtime(command, runtime, kind):
575
555
 
576
556
 
577
557
  def code_to_function(
578
- name: str = "",
579
- project: str = "",
580
- tag: str = "",
581
- filename: str = "",
582
- handler: str = "",
583
- kind: str = "",
584
- image: str = None,
585
- code_output: str = "",
558
+ name: Optional[str] = "",
559
+ project: Optional[str] = "",
560
+ tag: Optional[str] = "",
561
+ filename: Optional[str] = "",
562
+ handler: Optional[str] = "",
563
+ kind: Optional[str] = "",
564
+ image: Optional[str] = None,
565
+ code_output: Optional[str] = "",
586
566
  embed_code: bool = True,
587
- description: str = "",
588
- requirements: Union[str, list[str]] = None,
589
- categories: list[str] = None,
590
- labels: dict[str, str] = None,
591
- with_doc: bool = True,
592
- ignored_tags=None,
593
- requirements_file: str = "",
567
+ description: Optional[str] = "",
568
+ requirements: Optional[Union[str, list[str]]] = None,
569
+ categories: Optional[list[str]] = None,
570
+ labels: Optional[dict[str, str]] = None,
571
+ with_doc: Optional[bool] = True,
572
+ ignored_tags: Optional[str] = None,
573
+ requirements_file: Optional[str] = "",
594
574
  ) -> Union[
595
- MpiRuntimeV1Alpha1,
596
575
  MpiRuntimeV1,
597
576
  RemoteRuntime,
598
577
  ServingRuntime,
@@ -602,6 +581,7 @@ def code_to_function(
602
581
  Spark3Runtime,
603
582
  RemoteSparkRuntime,
604
583
  DatabricksRuntime,
584
+ ApplicationRuntime,
605
585
  ]:
606
586
  """Convenience function to insert code and configure an mlrun runtime.
607
587
 
@@ -627,8 +607,10 @@ def code_to_function(
627
607
  - mpijob: run distributed Horovod jobs over the MPI job operator
628
608
  - spark: run distributed Spark job using Spark Kubernetes Operator
629
609
  - remote-spark: run distributed Spark job on remote Spark service
610
+ - databricks: run code on Databricks cluster (python scripts, Spark etc.)
611
+ - application: run a long living application (e.g. a web server, UI, etc.)
630
612
 
631
- Learn more about {Kinds of function (runtimes)](../concepts/functions-overview.html).
613
+ Learn more about [Kinds of function (runtimes)](../concepts/functions-overview.html).
632
614
 
633
615
  :param name: function name, typically best to use hyphen-case
634
616
  :param project: project used to namespace the function, defaults to 'default'
@@ -644,7 +626,6 @@ def code_to_function(
644
626
  :param embed_code: indicates whether or not to inject the code directly into the function runtime spec,
645
627
  defaults to True
646
628
  :param description: short function description, defaults to ''
647
- :param requirements: list of python packages or pip requirements file path, defaults to None
648
629
  :param requirements: a list of python packages
649
630
  :param requirements_file: path to a python requirements file
650
631
  :param categories: list of categories for mlrun Function Hub, defaults to None
@@ -660,11 +641,15 @@ def code_to_function(
660
641
  import mlrun
661
642
 
662
643
  # create job function object from notebook code and add doc/metadata
663
- fn = mlrun.code_to_function("file_utils", kind="job",
664
- handler="open_archive", image="mlrun/mlrun",
665
- description = "this function opens a zip archive into a local/mounted folder",
666
- categories = ["fileutils"],
667
- labels = {"author": "me"})
644
+ fn = mlrun.code_to_function(
645
+ "file_utils",
646
+ kind="job",
647
+ handler="open_archive",
648
+ image="mlrun/mlrun",
649
+ description="this function opens a zip archive into a local/mounted folder",
650
+ categories=["fileutils"],
651
+ labels={"author": "me"},
652
+ )
668
653
 
669
654
  example::
670
655
 
@@ -675,11 +660,15 @@ def code_to_function(
675
660
  Path("mover.py").touch()
676
661
 
677
662
  # create nuclio function object from python module call mover.py
678
- fn = mlrun.code_to_function("nuclio-mover", kind="nuclio",
679
- filename="mover.py", image="python:3.7",
680
- description = "this function moves files from one system to another",
681
- requirements = ["pandas"],
682
- labels = {"author": "me"})
663
+ fn = mlrun.code_to_function(
664
+ "nuclio-mover",
665
+ kind="nuclio",
666
+ filename="mover.py",
667
+ image="python:3.9",
668
+ description="this function moves files from one system to another",
669
+ requirements=["pandas"],
670
+ labels={"author": "me"},
671
+ )
683
672
 
684
673
  """
685
674
  filebase, _ = path.splitext(path.basename(filename))
@@ -718,35 +707,34 @@ def code_to_function(
718
707
  fn.metadata.categories = categories
719
708
  fn.metadata.labels = labels or fn.metadata.labels
720
709
 
721
- def resolve_nuclio_subkind(kind):
722
- is_nuclio = kind.startswith("nuclio")
723
- subkind = kind[kind.find(":") + 1 :] if is_nuclio and ":" in kind else None
724
- if kind == RuntimeKinds.serving:
725
- is_nuclio = True
726
- subkind = serving_subkind
727
- return is_nuclio, subkind
728
-
729
710
  if (
730
711
  not embed_code
731
712
  and not code_output
732
713
  and (not filename or filename.endswith(".ipynb"))
733
714
  ):
734
715
  raise ValueError(
735
- "a valid code file must be specified "
716
+ "A valid code file must be specified "
736
717
  "when not using the embed_code option"
737
718
  )
738
719
 
739
720
  if kind == RuntimeKinds.databricks and not embed_code:
740
- raise ValueError("databricks tasks only support embed_code=True")
721
+ raise ValueError("Databricks tasks only support embed_code=True")
722
+
723
+ if kind == RuntimeKinds.application:
724
+ if handler:
725
+ raise MLRunInvalidArgumentError(
726
+ "Handler is not supported for application runtime"
727
+ )
728
+ filename, handler = ApplicationRuntime.get_filename_and_handler()
741
729
 
742
- is_nuclio, subkind = resolve_nuclio_subkind(kind)
730
+ is_nuclio, sub_kind = RuntimeKinds.resolve_nuclio_sub_kind(kind)
743
731
  code_origin = add_name(add_code_metadata(filename), name)
744
732
 
745
733
  name, spec, code = nuclio.build_file(
746
734
  filename,
747
735
  name=name,
748
736
  handler=handler or "handler",
749
- kind=subkind,
737
+ kind=sub_kind,
750
738
  ignored_tags=ignored_tags,
751
739
  )
752
740
  spec["spec"]["env"].append(
@@ -759,14 +747,14 @@ def code_to_function(
759
747
  if not kind and spec_kind not in ["", "Function"]:
760
748
  kind = spec_kind.lower()
761
749
 
762
- # if its a nuclio subkind, redo nb parsing
763
- is_nuclio, subkind = resolve_nuclio_subkind(kind)
750
+ # if its a nuclio sub kind, redo nb parsing
751
+ is_nuclio, sub_kind = RuntimeKinds.resolve_nuclio_sub_kind(kind)
764
752
  if is_nuclio:
765
753
  name, spec, code = nuclio.build_file(
766
754
  filename,
767
755
  name=name,
768
756
  handler=handler or "handler",
769
- kind=subkind,
757
+ kind=sub_kind,
770
758
  ignored_tags=ignored_tags,
771
759
  )
772
760
 
@@ -780,33 +768,29 @@ def code_to_function(
780
768
  raise ValueError("code_output option is only used with notebooks")
781
769
 
782
770
  if is_nuclio:
783
- if subkind == serving_subkind:
784
- r = ServingRuntime()
785
- else:
786
- r = RemoteRuntime()
787
- r.spec.function_kind = subkind
788
- # default_handler is only used in :mlrun subkind, determine the handler to invoke in function.run()
789
- r.spec.default_handler = handler if subkind == "mlrun" else ""
790
- r.spec.function_handler = (
771
+ runtime = RuntimeKinds.resolve_nuclio_runtime(kind, sub_kind)
772
+ # default_handler is only used in :mlrun sub kind, determine the handler to invoke in function.run()
773
+ runtime.spec.default_handler = handler if sub_kind == "mlrun" else ""
774
+ runtime.spec.function_handler = (
791
775
  handler if handler and ":" in handler else get_in(spec, "spec.handler")
792
776
  )
793
777
  if not embed_code:
794
- r.spec.source = filename
778
+ runtime.spec.source = filename
795
779
  nuclio_runtime = get_in(spec, "spec.runtime")
796
780
  if nuclio_runtime and not nuclio_runtime.startswith("py"):
797
- r.spec.nuclio_runtime = nuclio_runtime
781
+ runtime.spec.nuclio_runtime = nuclio_runtime
798
782
  if not name:
799
- raise ValueError("name must be specified")
800
- r.metadata.name = name
801
- r.spec.build.code_origin = code_origin
802
- r.spec.build.origin_filename = filename or (name + ".ipynb")
803
- update_common(r, spec)
804
- return r
783
+ raise ValueError("Missing required parameter: name")
784
+ runtime.metadata.name = name
785
+ runtime.spec.build.code_origin = code_origin
786
+ runtime.spec.build.origin_filename = filename or (name + ".ipynb")
787
+ update_common(runtime, spec)
788
+ return runtime
805
789
 
806
790
  if kind is None or kind in ["", "Function"]:
807
791
  raise ValueError("please specify the function kind")
808
792
  elif kind in RuntimeKinds.all():
809
- r = get_runtime_class(kind)()
793
+ runtime = get_runtime_class(kind)()
810
794
  else:
811
795
  raise ValueError(f"unsupported runtime ({kind})")
812
796
 
@@ -815,10 +799,10 @@ def code_to_function(
815
799
  if not name:
816
800
  raise ValueError("name must be specified")
817
801
  h = get_in(spec, "spec.handler", "").split(":")
818
- r.handler = h[0] if len(h) <= 1 else h[1]
819
- r.metadata = get_in(spec, "spec.metadata")
820
- r.metadata.name = name
821
- build = r.spec.build
802
+ runtime.handler = h[0] if len(h) <= 1 else h[1]
803
+ runtime.metadata = get_in(spec, "spec.metadata")
804
+ runtime.metadata.name = name
805
+ build = runtime.spec.build
822
806
  build.code_origin = code_origin
823
807
  build.origin_filename = filename or (name + ".ipynb")
824
808
  build.extra = get_in(spec, "spec.build.extra")
@@ -826,18 +810,18 @@ def code_to_function(
826
810
  build.builder_env = get_in(spec, "spec.build.builder_env")
827
811
  if not embed_code:
828
812
  if code_output:
829
- r.spec.command = code_output
813
+ runtime.spec.command = code_output
830
814
  else:
831
- r.spec.command = filename
815
+ runtime.spec.command = filename
832
816
 
833
817
  build.image = get_in(spec, "spec.build.image")
834
- update_common(r, spec)
835
- r.prepare_image_for_deploy()
818
+ update_common(runtime, spec)
819
+ runtime.prepare_image_for_deploy()
836
820
 
837
821
  if with_doc:
838
- update_function_entry_points(r, code)
839
- r.spec.default_handler = handler
840
- return r
822
+ update_function_entry_points(runtime, code)
823
+ runtime.spec.default_handler = handler
824
+ return runtime
841
825
 
842
826
 
843
827
  def _run_pipeline(
@@ -851,6 +835,7 @@ def _run_pipeline(
851
835
  ops=None,
852
836
  url=None,
853
837
  cleanup_ttl=None,
838
+ timeout=60,
854
839
  ):
855
840
  """remote KubeFlow pipeline execution
856
841
 
@@ -888,6 +873,7 @@ def _run_pipeline(
888
873
  ops=ops,
889
874
  artifact_path=artifact_path,
890
875
  cleanup_ttl=cleanup_ttl,
876
+ timeout=timeout,
891
877
  )
892
878
  logger.info(f"Pipeline run id={pipeline_run_id}, check UI for progress")
893
879
  return pipeline_run_id
@@ -965,7 +951,7 @@ def wait_for_pipeline_completion(
965
951
  show_kfp_run(resp)
966
952
 
967
953
  status = resp["run"]["status"] if resp else "unknown"
968
- message = resp["run"].get("message", "")
954
+ message = resp["run"].get("message", "") if resp else ""
969
955
  if expected_statuses:
970
956
  if status not in expected_statuses:
971
957
  raise RuntimeError(
@@ -987,8 +973,8 @@ def get_pipeline(
987
973
  run_id,
988
974
  namespace=None,
989
975
  format_: Union[
990
- str, mlrun.common.schemas.PipelinesFormat
991
- ] = mlrun.common.schemas.PipelinesFormat.summary,
976
+ str, mlrun.common.formatters.PipelineFormat
977
+ ] = mlrun.common.formatters.PipelineFormat.summary,
992
978
  project: str = None,
993
979
  remote: bool = True,
994
980
  ):
@@ -1002,7 +988,7 @@ def get_pipeline(
1002
988
  :param project: the project of the pipeline run
1003
989
  :param remote: read kfp data from mlrun service (default=True)
1004
990
 
1005
- :return: kfp run dict
991
+ :return: kfp run
1006
992
  """
1007
993
  namespace = namespace or mlconf.namespace
1008
994
  if remote:
@@ -1024,9 +1010,9 @@ def get_pipeline(
1024
1010
  resp = resp.to_dict()
1025
1011
  if (
1026
1012
  not format_
1027
- or format_ == mlrun.common.schemas.PipelinesFormat.summary.value
1013
+ or format_ == mlrun.common.formatters.PipelineFormat.summary.value
1028
1014
  ):
1029
- resp = format_summary_from_kfp_run(resp)
1015
+ resp = mlrun.common.formatters.PipelineFormat.format_obj(resp, format_)
1030
1016
 
1031
1017
  show_kfp_run(resp)
1032
1018
  return resp
@@ -1040,7 +1026,7 @@ def list_pipelines(
1040
1026
  filter_="",
1041
1027
  namespace=None,
1042
1028
  project="*",
1043
- format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
1029
+ format_: mlrun.common.formatters.PipelineFormat = mlrun.common.formatters.PipelineFormat.metadata_only,
1044
1030
  ) -> tuple[int, Optional[int], list[dict]]:
1045
1031
  """List pipelines
1046
1032
 
@@ -1060,7 +1046,7 @@ def list_pipelines(
1060
1046
  :param format_: Control what will be returned (full/metadata_only/name_only)
1061
1047
  """
1062
1048
  if full:
1063
- format_ = mlrun.common.schemas.PipelinesFormat.full
1049
+ format_ = mlrun.common.formatters.PipelineFormat.full
1064
1050
  run_db = mlrun.db.get_run_db()
1065
1051
  pipelines = run_db.list_pipelines(
1066
1052
  project, namespace, sort_by, page_token, filter_, format_, page_size
@@ -1096,13 +1082,25 @@ def wait_for_runs_completion(
1096
1082
  example::
1097
1083
 
1098
1084
  # run two training functions in parallel and wait for the results
1099
- inputs = {'dataset': cleaned_data}
1100
- run1 = train.run(name='train_lr', inputs=inputs, watch=False,
1101
- params={'model_pkg_class': 'sklearn.linear_model.LogisticRegression',
1102
- 'label_column': 'label'})
1103
- run2 = train.run(name='train_lr', inputs=inputs, watch=False,
1104
- params={'model_pkg_class': 'sklearn.ensemble.RandomForestClassifier',
1105
- 'label_column': 'label'})
1085
+ inputs = {"dataset": cleaned_data}
1086
+ run1 = train.run(
1087
+ name="train_lr",
1088
+ inputs=inputs,
1089
+ watch=False,
1090
+ params={
1091
+ "model_pkg_class": "sklearn.linear_model.LogisticRegression",
1092
+ "label_column": "label",
1093
+ },
1094
+ )
1095
+ run2 = train.run(
1096
+ name="train_lr",
1097
+ inputs=inputs,
1098
+ watch=False,
1099
+ params={
1100
+ "model_pkg_class": "sklearn.ensemble.RandomForestClassifier",
1101
+ "label_column": "label",
1102
+ },
1103
+ )
1106
1104
  completed = wait_for_runs_completion([run1, run2])
1107
1105
 
1108
1106
  :param runs: list of run objects (the returned values of function.run())
@@ -1117,7 +1115,7 @@ def wait_for_runs_completion(
1117
1115
  running = []
1118
1116
  for run in runs:
1119
1117
  state = run.state()
1120
- if state in mlrun.runtimes.constants.RunStates.terminal_states():
1118
+ if state in mlrun.common.runtimes.constants.RunStates.terminal_states():
1121
1119
  completed.append(run)
1122
1120
  else:
1123
1121
  running.append(run)