mlrun 1.7.1rc4__py3-none-any.whl → 1.8.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 (257) hide show
  1. mlrun/__init__.py +23 -21
  2. mlrun/__main__.py +3 -3
  3. mlrun/alerts/alert.py +148 -14
  4. mlrun/artifacts/__init__.py +1 -2
  5. mlrun/artifacts/base.py +46 -12
  6. mlrun/artifacts/dataset.py +16 -16
  7. mlrun/artifacts/document.py +334 -0
  8. mlrun/artifacts/manager.py +15 -13
  9. mlrun/artifacts/model.py +66 -53
  10. mlrun/common/constants.py +7 -0
  11. mlrun/common/formatters/__init__.py +1 -0
  12. mlrun/common/formatters/feature_set.py +1 -0
  13. mlrun/common/formatters/function.py +1 -0
  14. mlrun/{model_monitoring/db/stores/base/__init__.py → common/formatters/model_endpoint.py} +16 -1
  15. mlrun/common/formatters/pipeline.py +1 -2
  16. mlrun/common/formatters/project.py +9 -0
  17. mlrun/common/model_monitoring/__init__.py +0 -5
  18. mlrun/common/model_monitoring/helpers.py +1 -29
  19. mlrun/common/runtimes/constants.py +1 -2
  20. mlrun/common/schemas/__init__.py +6 -2
  21. mlrun/common/schemas/alert.py +111 -19
  22. mlrun/common/schemas/api_gateway.py +3 -3
  23. mlrun/common/schemas/artifact.py +11 -7
  24. mlrun/common/schemas/auth.py +6 -4
  25. mlrun/common/schemas/background_task.py +7 -7
  26. mlrun/common/schemas/client_spec.py +2 -3
  27. mlrun/common/schemas/clusterization_spec.py +2 -2
  28. mlrun/common/schemas/common.py +53 -3
  29. mlrun/common/schemas/constants.py +15 -0
  30. mlrun/common/schemas/datastore_profile.py +1 -1
  31. mlrun/common/schemas/feature_store.py +9 -9
  32. mlrun/common/schemas/frontend_spec.py +4 -4
  33. mlrun/common/schemas/function.py +10 -10
  34. mlrun/common/schemas/hub.py +1 -1
  35. mlrun/common/schemas/k8s.py +3 -3
  36. mlrun/common/schemas/memory_reports.py +3 -3
  37. mlrun/common/schemas/model_monitoring/__init__.py +2 -1
  38. mlrun/common/schemas/model_monitoring/constants.py +66 -14
  39. mlrun/common/schemas/model_monitoring/grafana.py +1 -1
  40. mlrun/common/schemas/model_monitoring/model_endpoints.py +91 -147
  41. mlrun/common/schemas/notification.py +24 -3
  42. mlrun/common/schemas/object.py +1 -1
  43. mlrun/common/schemas/pagination.py +4 -4
  44. mlrun/common/schemas/partition.py +137 -0
  45. mlrun/common/schemas/pipeline.py +2 -2
  46. mlrun/common/schemas/project.py +25 -17
  47. mlrun/common/schemas/runs.py +2 -2
  48. mlrun/common/schemas/runtime_resource.py +5 -5
  49. mlrun/common/schemas/schedule.py +1 -1
  50. mlrun/common/schemas/secret.py +1 -1
  51. mlrun/common/schemas/tag.py +3 -3
  52. mlrun/common/schemas/workflow.py +5 -5
  53. mlrun/config.py +67 -10
  54. mlrun/data_types/__init__.py +0 -2
  55. mlrun/data_types/infer.py +3 -1
  56. mlrun/data_types/spark.py +2 -1
  57. mlrun/datastore/__init__.py +0 -2
  58. mlrun/datastore/alibaba_oss.py +4 -1
  59. mlrun/datastore/azure_blob.py +4 -1
  60. mlrun/datastore/base.py +12 -4
  61. mlrun/datastore/datastore.py +9 -3
  62. mlrun/datastore/datastore_profile.py +79 -20
  63. mlrun/datastore/dbfs_store.py +4 -1
  64. mlrun/datastore/filestore.py +4 -1
  65. mlrun/datastore/google_cloud_storage.py +4 -1
  66. mlrun/datastore/hdfs.py +4 -1
  67. mlrun/datastore/inmem.py +4 -1
  68. mlrun/datastore/redis.py +4 -1
  69. mlrun/datastore/s3.py +4 -1
  70. mlrun/datastore/sources.py +52 -51
  71. mlrun/datastore/store_resources.py +0 -2
  72. mlrun/datastore/targets.py +21 -21
  73. mlrun/datastore/utils.py +2 -2
  74. mlrun/datastore/v3io.py +4 -1
  75. mlrun/datastore/vectorstore.py +194 -0
  76. mlrun/datastore/wasbfs/fs.py +13 -12
  77. mlrun/db/base.py +208 -82
  78. mlrun/db/factory.py +0 -3
  79. mlrun/db/httpdb.py +1237 -386
  80. mlrun/db/nopdb.py +201 -74
  81. mlrun/errors.py +2 -2
  82. mlrun/execution.py +136 -50
  83. mlrun/feature_store/__init__.py +0 -2
  84. mlrun/feature_store/api.py +41 -40
  85. mlrun/feature_store/common.py +9 -9
  86. mlrun/feature_store/feature_set.py +20 -18
  87. mlrun/feature_store/feature_vector.py +27 -24
  88. mlrun/feature_store/retrieval/base.py +14 -9
  89. mlrun/feature_store/retrieval/job.py +2 -1
  90. mlrun/feature_store/steps.py +2 -2
  91. mlrun/features.py +30 -13
  92. mlrun/frameworks/__init__.py +1 -2
  93. mlrun/frameworks/_common/__init__.py +1 -2
  94. mlrun/frameworks/_common/artifacts_library.py +2 -2
  95. mlrun/frameworks/_common/mlrun_interface.py +10 -6
  96. mlrun/frameworks/_common/model_handler.py +29 -27
  97. mlrun/frameworks/_common/producer.py +3 -1
  98. mlrun/frameworks/_dl_common/__init__.py +1 -2
  99. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
  100. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
  101. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
  102. mlrun/frameworks/_ml_common/__init__.py +1 -2
  103. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
  104. mlrun/frameworks/_ml_common/model_handler.py +21 -21
  105. mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
  106. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
  107. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  108. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  109. mlrun/frameworks/auto_mlrun/__init__.py +1 -2
  110. mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
  111. mlrun/frameworks/huggingface/__init__.py +1 -2
  112. mlrun/frameworks/huggingface/model_server.py +9 -9
  113. mlrun/frameworks/lgbm/__init__.py +47 -44
  114. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
  115. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
  116. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
  117. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
  118. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
  119. mlrun/frameworks/lgbm/model_handler.py +15 -11
  120. mlrun/frameworks/lgbm/model_server.py +11 -7
  121. mlrun/frameworks/lgbm/utils.py +2 -2
  122. mlrun/frameworks/onnx/__init__.py +1 -2
  123. mlrun/frameworks/onnx/dataset.py +3 -3
  124. mlrun/frameworks/onnx/mlrun_interface.py +2 -2
  125. mlrun/frameworks/onnx/model_handler.py +7 -5
  126. mlrun/frameworks/onnx/model_server.py +8 -6
  127. mlrun/frameworks/parallel_coordinates.py +11 -11
  128. mlrun/frameworks/pytorch/__init__.py +22 -23
  129. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
  130. mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
  131. mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
  132. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
  133. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
  134. mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
  135. mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
  136. mlrun/frameworks/pytorch/model_handler.py +21 -17
  137. mlrun/frameworks/pytorch/model_server.py +13 -9
  138. mlrun/frameworks/sklearn/__init__.py +19 -18
  139. mlrun/frameworks/sklearn/estimator.py +2 -2
  140. mlrun/frameworks/sklearn/metric.py +3 -3
  141. mlrun/frameworks/sklearn/metrics_library.py +8 -6
  142. mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
  143. mlrun/frameworks/sklearn/model_handler.py +4 -3
  144. mlrun/frameworks/tf_keras/__init__.py +11 -12
  145. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
  146. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
  147. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
  148. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
  149. mlrun/frameworks/tf_keras/model_handler.py +17 -13
  150. mlrun/frameworks/tf_keras/model_server.py +12 -8
  151. mlrun/frameworks/xgboost/__init__.py +19 -18
  152. mlrun/frameworks/xgboost/model_handler.py +13 -9
  153. mlrun/launcher/base.py +3 -4
  154. mlrun/launcher/local.py +1 -1
  155. mlrun/launcher/remote.py +1 -1
  156. mlrun/lists.py +4 -3
  157. mlrun/model.py +117 -46
  158. mlrun/model_monitoring/__init__.py +4 -4
  159. mlrun/model_monitoring/api.py +61 -59
  160. mlrun/model_monitoring/applications/_application_steps.py +17 -17
  161. mlrun/model_monitoring/applications/base.py +165 -6
  162. mlrun/model_monitoring/applications/context.py +88 -37
  163. mlrun/model_monitoring/applications/evidently_base.py +1 -2
  164. mlrun/model_monitoring/applications/histogram_data_drift.py +43 -21
  165. mlrun/model_monitoring/applications/results.py +55 -3
  166. mlrun/model_monitoring/controller.py +207 -239
  167. mlrun/model_monitoring/db/__init__.py +0 -2
  168. mlrun/model_monitoring/db/_schedules.py +156 -0
  169. mlrun/model_monitoring/db/_stats.py +189 -0
  170. mlrun/model_monitoring/db/tsdb/base.py +78 -25
  171. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +90 -16
  172. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
  173. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +279 -59
  174. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
  175. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +78 -17
  176. mlrun/model_monitoring/helpers.py +152 -49
  177. mlrun/model_monitoring/stream_processing.py +99 -283
  178. mlrun/model_monitoring/tracking_policy.py +10 -3
  179. mlrun/model_monitoring/writer.py +48 -36
  180. mlrun/package/__init__.py +3 -6
  181. mlrun/package/context_handler.py +1 -1
  182. mlrun/package/packager.py +12 -9
  183. mlrun/package/packagers/__init__.py +0 -2
  184. mlrun/package/packagers/default_packager.py +14 -11
  185. mlrun/package/packagers/numpy_packagers.py +16 -7
  186. mlrun/package/packagers/pandas_packagers.py +18 -18
  187. mlrun/package/packagers/python_standard_library_packagers.py +25 -11
  188. mlrun/package/packagers_manager.py +31 -14
  189. mlrun/package/utils/__init__.py +0 -3
  190. mlrun/package/utils/_pickler.py +6 -6
  191. mlrun/platforms/__init__.py +47 -16
  192. mlrun/platforms/iguazio.py +4 -1
  193. mlrun/projects/operations.py +27 -27
  194. mlrun/projects/pipelines.py +75 -38
  195. mlrun/projects/project.py +865 -206
  196. mlrun/run.py +53 -10
  197. mlrun/runtimes/__init__.py +1 -3
  198. mlrun/runtimes/base.py +15 -11
  199. mlrun/runtimes/daskjob.py +9 -9
  200. mlrun/runtimes/generators.py +2 -1
  201. mlrun/runtimes/kubejob.py +4 -5
  202. mlrun/runtimes/mounts.py +572 -0
  203. mlrun/runtimes/mpijob/__init__.py +0 -2
  204. mlrun/runtimes/mpijob/abstract.py +7 -6
  205. mlrun/runtimes/nuclio/api_gateway.py +7 -7
  206. mlrun/runtimes/nuclio/application/application.py +11 -11
  207. mlrun/runtimes/nuclio/function.py +19 -17
  208. mlrun/runtimes/nuclio/serving.py +18 -11
  209. mlrun/runtimes/pod.py +154 -45
  210. mlrun/runtimes/remotesparkjob.py +3 -2
  211. mlrun/runtimes/sparkjob/__init__.py +0 -2
  212. mlrun/runtimes/sparkjob/spark3job.py +21 -11
  213. mlrun/runtimes/utils.py +6 -5
  214. mlrun/serving/merger.py +6 -4
  215. mlrun/serving/remote.py +18 -17
  216. mlrun/serving/routers.py +185 -172
  217. mlrun/serving/server.py +7 -1
  218. mlrun/serving/states.py +97 -78
  219. mlrun/serving/utils.py +13 -2
  220. mlrun/serving/v1_serving.py +3 -2
  221. mlrun/serving/v2_serving.py +74 -65
  222. mlrun/track/__init__.py +1 -1
  223. mlrun/track/tracker.py +2 -2
  224. mlrun/track/trackers/mlflow_tracker.py +6 -5
  225. mlrun/utils/async_http.py +1 -1
  226. mlrun/utils/clones.py +1 -1
  227. mlrun/utils/helpers.py +66 -18
  228. mlrun/utils/logger.py +106 -4
  229. mlrun/utils/notifications/notification/__init__.py +22 -19
  230. mlrun/utils/notifications/notification/base.py +33 -14
  231. mlrun/utils/notifications/notification/console.py +6 -6
  232. mlrun/utils/notifications/notification/git.py +11 -11
  233. mlrun/utils/notifications/notification/ipython.py +10 -9
  234. mlrun/utils/notifications/notification/mail.py +176 -0
  235. mlrun/utils/notifications/notification/slack.py +6 -6
  236. mlrun/utils/notifications/notification/webhook.py +6 -6
  237. mlrun/utils/notifications/notification_pusher.py +86 -44
  238. mlrun/utils/regex.py +3 -1
  239. mlrun/utils/version/version.json +2 -2
  240. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/METADATA +191 -186
  241. mlrun-1.8.0rc8.dist-info/RECORD +347 -0
  242. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/WHEEL +1 -1
  243. mlrun/model_monitoring/db/stores/__init__.py +0 -136
  244. mlrun/model_monitoring/db/stores/base/store.py +0 -213
  245. mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
  246. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -71
  247. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -190
  248. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -103
  249. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -40
  250. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -659
  251. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
  252. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
  253. mlrun/model_monitoring/model_endpoint.py +0 -118
  254. mlrun-1.7.1rc4.dist-info/RECORD +0 -351
  255. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/LICENSE +0 -0
  256. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/entry_points.txt +0 -0
  257. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py CHANGED
@@ -28,21 +28,20 @@ import warnings
28
28
  import zipfile
29
29
  from copy import deepcopy
30
30
  from os import environ, makedirs, path
31
- from typing import Callable, Optional, Union
31
+ from typing import Callable, Optional, Union, cast
32
32
 
33
33
  import dotenv
34
34
  import git
35
35
  import git.exc
36
- import mlrun_pipelines.common.models
37
- import mlrun_pipelines.mounts
38
36
  import nuclio.utils
39
37
  import requests
40
38
  import yaml
41
- from mlrun_pipelines.models import PipelineNodeWrapper
42
39
 
40
+ import mlrun.artifacts.model
43
41
  import mlrun.common.formatters
44
42
  import mlrun.common.helpers
45
43
  import mlrun.common.runtimes.constants
44
+ import mlrun.common.schemas.alert
46
45
  import mlrun.common.schemas.artifact
47
46
  import mlrun.common.schemas.model_monitoring.constants as mm_constants
48
47
  import mlrun.db
@@ -51,18 +50,37 @@ import mlrun.k8s_utils
51
50
  import mlrun.lists
52
51
  import mlrun.model_monitoring.applications as mm_app
53
52
  import mlrun.runtimes
53
+ import mlrun.runtimes.mounts
54
54
  import mlrun.runtimes.nuclio.api_gateway
55
55
  import mlrun.runtimes.pod
56
56
  import mlrun.runtimes.utils
57
57
  import mlrun.serving
58
58
  import mlrun.utils
59
59
  import mlrun.utils.regex
60
+ import mlrun_pipelines.common.models
60
61
  from mlrun.alerts.alert import AlertConfig
61
- from mlrun.common.schemas.alert import AlertTemplate
62
- from mlrun.datastore.datastore_profile import DatastoreProfile, DatastoreProfile2Json
62
+ from mlrun.common.schemas import alert as alert_constants
63
+ from mlrun.datastore.datastore_profile import (
64
+ DatastoreProfile,
65
+ DatastoreProfile2Json,
66
+ datastore_profile_read,
67
+ )
68
+ from mlrun.datastore.vectorstore import VectorStoreCollection
69
+ from mlrun.model_monitoring.helpers import (
70
+ filter_results_by_regex,
71
+ get_result_instance_fqn,
72
+ )
63
73
  from mlrun.runtimes.nuclio.function import RemoteRuntime
74
+ from mlrun_pipelines.models import PipelineNodeWrapper
64
75
 
65
- from ..artifacts import Artifact, ArtifactProducer, DatasetArtifact, ModelArtifact
76
+ from ..artifacts import (
77
+ Artifact,
78
+ ArtifactProducer,
79
+ DatasetArtifact,
80
+ DocumentArtifact,
81
+ DocumentLoaderSpec,
82
+ ModelArtifact,
83
+ )
66
84
  from ..artifacts.manager import ArtifactManager, dict_to_artifact, extend_artifact_path
67
85
  from ..datastore import store_manager
68
86
  from ..features import Feature
@@ -126,15 +144,15 @@ def new_project(
126
144
  context: str = "./",
127
145
  init_git: bool = False,
128
146
  user_project: bool = False,
129
- remote: str = None,
130
- from_template: str = None,
131
- secrets: dict = None,
132
- description: str = None,
133
- subpath: str = None,
147
+ remote: Optional[str] = None,
148
+ from_template: Optional[str] = None,
149
+ secrets: Optional[dict] = None,
150
+ description: Optional[str] = None,
151
+ subpath: Optional[str] = None,
134
152
  save: bool = True,
135
153
  overwrite: bool = False,
136
- parameters: dict = None,
137
- default_function_node_selector: dict = None,
154
+ parameters: Optional[dict] = None,
155
+ default_function_node_selector: Optional[dict] = None,
138
156
  ) -> "MlrunProject":
139
157
  """Create a new MLRun project, optionally load it from a yaml/zip/git template
140
158
 
@@ -291,17 +309,17 @@ def new_project(
291
309
 
292
310
  def load_project(
293
311
  context: str = "./",
294
- url: str = None,
295
- name: str = None,
296
- secrets: dict = None,
312
+ url: Optional[str] = None,
313
+ name: Optional[str] = None,
314
+ secrets: Optional[dict] = None,
297
315
  init_git: bool = False,
298
- subpath: str = None,
316
+ subpath: Optional[str] = None,
299
317
  clone: bool = False,
300
318
  user_project: bool = False,
301
319
  save: bool = True,
302
320
  sync_functions: bool = False,
303
- parameters: dict = None,
304
- allow_cross_project: bool = None,
321
+ parameters: Optional[dict] = None,
322
+ allow_cross_project: Optional[bool] = None,
305
323
  ) -> "MlrunProject":
306
324
  """Load an MLRun project from git or tar or dir
307
325
 
@@ -437,16 +455,16 @@ def load_project(
437
455
  def get_or_create_project(
438
456
  name: str,
439
457
  context: str = "./",
440
- url: str = None,
441
- secrets: dict = None,
458
+ url: Optional[str] = None,
459
+ secrets: Optional[dict] = None,
442
460
  init_git=False,
443
- subpath: str = None,
461
+ subpath: Optional[str] = None,
444
462
  clone: bool = False,
445
463
  user_project: bool = False,
446
- from_template: str = None,
464
+ from_template: Optional[str] = None,
447
465
  save: bool = True,
448
- parameters: dict = None,
449
- allow_cross_project: bool = None,
466
+ parameters: Optional[dict] = None,
467
+ allow_cross_project: Optional[bool] = None,
450
468
  ) -> "MlrunProject":
451
469
  """Load a project from MLRun DB, or create/import if it does not exist
452
470
 
@@ -823,14 +841,14 @@ class ProjectSpec(ModelObj):
823
841
  origin_url=None,
824
842
  goals=None,
825
843
  load_source_on_run=None,
826
- default_requirements: typing.Union[str, list[str]] = None,
844
+ default_requirements: Optional[typing.Union[str, list[str]]] = None,
827
845
  desired_state=mlrun.common.schemas.ProjectState.online.value,
828
846
  owner=None,
829
847
  disable_auto_mount=None,
830
848
  workdir=None,
831
849
  default_image=None,
832
850
  build=None,
833
- custom_packagers: list[tuple[str, bool]] = None,
851
+ custom_packagers: Optional[list[tuple[str, bool]]] = None,
834
852
  default_function_node_selector=None,
835
853
  ):
836
854
  self.repo = None
@@ -1253,7 +1271,11 @@ class MlrunProject(ModelObj):
1253
1271
  raise exc
1254
1272
 
1255
1273
  def get_artifact_uri(
1256
- self, key: str, category: str = "artifact", tag: str = None, iter: int = None
1274
+ self,
1275
+ key: str,
1276
+ category: str = "artifact",
1277
+ tag: Optional[str] = None,
1278
+ iter: Optional[int] = None,
1257
1279
  ) -> str:
1258
1280
  """return the project artifact uri (store://..) from the artifact key
1259
1281
 
@@ -1353,7 +1375,7 @@ class MlrunProject(ModelObj):
1353
1375
  workflow_path: str,
1354
1376
  embed: bool = False,
1355
1377
  engine: Optional[str] = None,
1356
- args_schema: list[EntrypointParam] = None,
1378
+ args_schema: Optional[list[EntrypointParam]] = None,
1357
1379
  handler: Optional[str] = None,
1358
1380
  schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
1359
1381
  ttl: Optional[int] = None,
@@ -1425,8 +1447,8 @@ class MlrunProject(ModelObj):
1425
1447
  self,
1426
1448
  key,
1427
1449
  artifact: typing.Union[str, dict, Artifact] = None,
1428
- target_path: str = None,
1429
- tag: str = None,
1450
+ target_path: Optional[str] = None,
1451
+ tag: Optional[str] = None,
1430
1452
  ):
1431
1453
  """add/set an artifact in the project spec (will be registered on load)
1432
1454
 
@@ -1515,6 +1537,12 @@ class MlrunProject(ModelObj):
1515
1537
  is_retained_producer=is_retained_producer,
1516
1538
  )
1517
1539
 
1540
+ def update_artifact(self, artifact_object: Artifact):
1541
+ artifacts_manager = self._get_artifact_manager()
1542
+ project_tag = self._get_project_tag()
1543
+ producer, _ = self._resolve_artifact_producer(artifact_object, project_tag)
1544
+ artifacts_manager.update_artifact(producer, artifact_object)
1545
+
1518
1546
  def _get_artifact_manager(self):
1519
1547
  if self._artifact_manager:
1520
1548
  return self._artifact_manager
@@ -1646,7 +1674,7 @@ class MlrunProject(ModelObj):
1646
1674
  deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
1647
1675
  mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
1648
1676
  ),
1649
- secrets: dict = None,
1677
+ secrets: Optional[dict] = None,
1650
1678
  ):
1651
1679
  """Delete an artifact object in the DB and optionally delete the artifact data
1652
1680
 
@@ -1710,7 +1738,7 @@ class MlrunProject(ModelObj):
1710
1738
  :param upload: upload to datastore (default is True)
1711
1739
  :param labels: a set of key/value labels to tag the artifact with
1712
1740
 
1713
- :returns: artifact object
1741
+ :returns: dataset artifact object
1714
1742
  """
1715
1743
  ds = DatasetArtifact(
1716
1744
  key,
@@ -1723,14 +1751,17 @@ class MlrunProject(ModelObj):
1723
1751
  **kwargs,
1724
1752
  )
1725
1753
 
1726
- item = self.log_artifact(
1727
- ds,
1728
- local_path=local_path,
1729
- artifact_path=artifact_path,
1730
- target_path=target_path,
1731
- tag=tag,
1732
- upload=upload,
1733
- labels=labels,
1754
+ item = cast(
1755
+ DatasetArtifact,
1756
+ self.log_artifact(
1757
+ ds,
1758
+ local_path=local_path,
1759
+ artifact_path=artifact_path,
1760
+ target_path=target_path,
1761
+ tag=tag,
1762
+ upload=upload,
1763
+ labels=labels,
1764
+ ),
1734
1765
  )
1735
1766
  return item
1736
1767
 
@@ -1777,7 +1808,7 @@ class MlrunProject(ModelObj):
1777
1808
  :param key: artifact key or artifact class ()
1778
1809
  :param body: will use the body as the artifact content
1779
1810
  :param model_file: path to the local model file we upload (see also model_dir)
1780
- or to a model file data url (e.g. http://host/path/model.pkl)
1811
+ or to a model file data url (e.g. `http://host/path/model.pkl`)
1781
1812
  :param model_dir: path to the local dir holding the model file and extra files
1782
1813
  :param artifact_path: target artifact path (when not using the default)
1783
1814
  to define a subpath under the default location use:
@@ -1798,7 +1829,7 @@ class MlrunProject(ModelObj):
1798
1829
  :param extra_data: key/value list of extra files/charts to link with this dataset
1799
1830
  value can be absolute path | relative path (to model dir) | bytes | artifact object
1800
1831
 
1801
- :returns: artifact object
1832
+ :returns: model artifact object
1802
1833
  """
1803
1834
 
1804
1835
  if training_set is not None and inputs:
@@ -1825,14 +1856,73 @@ class MlrunProject(ModelObj):
1825
1856
  if training_set is not None:
1826
1857
  model.infer_from_df(training_set, label_column)
1827
1858
 
1828
- item = self.log_artifact(
1829
- model,
1830
- artifact_path=artifact_path,
1859
+ item = cast(
1860
+ ModelArtifact,
1861
+ self.log_artifact(
1862
+ model,
1863
+ artifact_path=artifact_path,
1864
+ tag=tag,
1865
+ upload=upload,
1866
+ labels=labels,
1867
+ ),
1868
+ )
1869
+ return item
1870
+
1871
+ def get_vector_store_collection(
1872
+ self,
1873
+ collection_name: str,
1874
+ vector_store: "VectorStore", # noqa: F821
1875
+ ) -> VectorStoreCollection:
1876
+ return VectorStoreCollection(
1877
+ self,
1878
+ collection_name,
1879
+ vector_store,
1880
+ )
1881
+
1882
+ def log_document(
1883
+ self,
1884
+ key: str,
1885
+ tag: str = "",
1886
+ local_path: str = "",
1887
+ artifact_path: Optional[str] = None,
1888
+ document_loader_spec: Optional[DocumentLoaderSpec] = None,
1889
+ upload: Optional[bool] = False,
1890
+ labels: Optional[dict[str, str]] = None,
1891
+ target_path: Optional[str] = None,
1892
+ **kwargs,
1893
+ ) -> DocumentArtifact:
1894
+ """
1895
+ Log a document as an artifact.
1896
+
1897
+ :param key: Artifact key
1898
+ :param tag: Version tag
1899
+ :param local_path: path to the local file we upload, will also be use
1900
+ as the destination subpath (under "artifact_path")
1901
+ :param artifact_path: Target path for artifact storage
1902
+ :param document_loader_spec: Spec to use to load the artifact as langchain document
1903
+ :param upload: Whether to upload the artifact
1904
+ :param labels: Key-value labels
1905
+ :param target_path: Target file path
1906
+ :param kwargs: Additional keyword arguments
1907
+ :return: DocumentArtifact object
1908
+ """
1909
+ doc_artifact = DocumentArtifact(
1910
+ key=key,
1911
+ original_source=local_path or target_path,
1912
+ document_loader_spec=document_loader_spec
1913
+ if document_loader_spec
1914
+ else DocumentLoaderSpec(),
1915
+ **kwargs,
1916
+ )
1917
+ return self.log_artifact(
1918
+ item=doc_artifact,
1831
1919
  tag=tag,
1920
+ local_path=local_path,
1921
+ artifact_path=artifact_path,
1832
1922
  upload=upload,
1833
1923
  labels=labels,
1924
+ target_path=target_path,
1834
1925
  )
1835
- return item
1836
1926
 
1837
1927
  def import_artifact(
1838
1928
  self, item_path: str, new_key=None, artifact_path=None, tag=None
@@ -1946,6 +2036,85 @@ class MlrunProject(ModelObj):
1946
2036
  )
1947
2037
  return _run_project_setup(self, setup_file_path, save)
1948
2038
 
2039
+ def create_model_monitoring_alert_configs(
2040
+ self,
2041
+ name: str,
2042
+ summary: str,
2043
+ endpoints: mlrun.common.schemas.ModelEndpointList,
2044
+ events: Union[list[alert_constants.EventKind], alert_constants.EventKind],
2045
+ notifications: list[alert_constants.AlertNotification],
2046
+ result_names: Optional[
2047
+ list[str]
2048
+ ] = None, # can use wildcards - see below for explanation.
2049
+ severity: alert_constants.AlertSeverity = alert_constants.AlertSeverity.MEDIUM,
2050
+ criteria: alert_constants.AlertCriteria = alert_constants.AlertCriteria(
2051
+ count=1, period="10m"
2052
+ ),
2053
+ reset_policy: mlrun.common.schemas.alert.ResetPolicy = mlrun.common.schemas.alert.ResetPolicy.AUTO,
2054
+ ) -> list[mlrun.alerts.alert.AlertConfig]:
2055
+ """
2056
+ :param name: AlertConfig name.
2057
+ :param summary: Summary of the alert, will be sent in the generated notifications
2058
+ :param endpoints: The endpoints from which to retrieve the metrics that the
2059
+ alerts will be based on.
2060
+ :param events: AlertTrigger event types (EventKind).
2061
+ :param notifications: List of notifications to invoke once the alert is triggered
2062
+ :param result_names: Optional. Filters the result names used to create the alert configuration,
2063
+ constructed from the app and result_name regex.
2064
+
2065
+ For example:
2066
+ [`app1.result-*`, `*.result1`]
2067
+ will match "mep1.app1.result.result-1" and "mep1.app2.result.result1".
2068
+ :param severity: Severity of the alert.
2069
+ :param criteria: When the alert will be triggered based on the
2070
+ specified number of events within the defined time period.
2071
+ :param reset_policy: When to clear the alert. May be "manual" for manual reset of the alert,
2072
+ or "auto" if the criteria contains a time period.
2073
+ :returns: List of AlertConfig according to endpoints results,
2074
+ filtered by result_names.
2075
+ """
2076
+ db = mlrun.db.get_run_db(secrets=self._secrets)
2077
+ matching_results = []
2078
+ alerts = []
2079
+ # TODO: Refactor to use a single request to improve performance at scale, ML-8473
2080
+ for endpoint in endpoints.endpoints:
2081
+ results_by_endpoint = db.get_model_endpoint_monitoring_metrics(
2082
+ project=self.name, endpoint_id=endpoint.metadata.uid, type="results"
2083
+ )
2084
+ results_fqn_by_endpoint = [
2085
+ get_result_instance_fqn(
2086
+ model_endpoint_id=endpoint.metadata.uid,
2087
+ app_name=result.app,
2088
+ result_name=result.name,
2089
+ )
2090
+ for result in results_by_endpoint
2091
+ ]
2092
+ matching_results += filter_results_by_regex(
2093
+ existing_result_names=results_fqn_by_endpoint,
2094
+ result_name_filters=result_names,
2095
+ )
2096
+ for result_fqn in matching_results:
2097
+ alerts.append(
2098
+ mlrun.alerts.alert.AlertConfig(
2099
+ project=self.name,
2100
+ name=name,
2101
+ summary=summary,
2102
+ severity=severity,
2103
+ entities=alert_constants.EventEntities(
2104
+ kind=alert_constants.EventEntityKind.MODEL_ENDPOINT_RESULT,
2105
+ project=self.name,
2106
+ ids=[result_fqn],
2107
+ ),
2108
+ trigger=alert_constants.AlertTrigger(
2109
+ events=events if isinstance(events, list) else [events]
2110
+ ),
2111
+ criteria=criteria,
2112
+ notifications=notifications,
2113
+ reset_policy=reset_policy,
2114
+ )
2115
+ )
2116
+ return alerts
2117
+
1949
2118
  def set_model_monitoring_function(
1950
2119
  self,
1951
2120
  func: typing.Union[str, mlrun.runtimes.BaseRuntime, None] = None,
@@ -1953,12 +2122,12 @@ class MlrunProject(ModelObj):
1953
2122
  str,
1954
2123
  mm_app.ModelMonitoringApplicationBase,
1955
2124
  ] = None,
1956
- name: str = None,
1957
- image: str = None,
2125
+ name: Optional[str] = None,
2126
+ image: Optional[str] = None,
1958
2127
  handler=None,
1959
- with_repo: bool = None,
1960
- tag: str = None,
1961
- requirements: typing.Union[str, list[str]] = None,
2128
+ with_repo: Optional[bool] = None,
2129
+ tag: Optional[str] = None,
2130
+ requirements: Optional[typing.Union[str, list[str]]] = None,
1962
2131
  requirements_file: str = "",
1963
2132
  **application_kwargs,
1964
2133
  ) -> mlrun.runtimes.BaseRuntime:
@@ -1990,8 +2159,6 @@ class MlrunProject(ModelObj):
1990
2159
  :param application_kwargs: Additional keyword arguments to be passed to the
1991
2160
  monitoring application's constructor.
1992
2161
  """
1993
-
1994
- function_object: RemoteRuntime = None
1995
2162
  (
1996
2163
  resolved_function_name,
1997
2164
  function_object,
@@ -2015,17 +2182,17 @@ class MlrunProject(ModelObj):
2015
2182
 
2016
2183
  def create_model_monitoring_function(
2017
2184
  self,
2018
- func: str = None,
2185
+ func: Optional[str] = None,
2019
2186
  application_class: typing.Union[
2020
2187
  str,
2021
2188
  mm_app.ModelMonitoringApplicationBase,
2022
2189
  ] = None,
2023
- name: str = None,
2024
- image: str = None,
2025
- handler: str = None,
2026
- with_repo: bool = None,
2027
- tag: str = None,
2028
- requirements: typing.Union[str, list[str]] = None,
2190
+ name: Optional[str] = None,
2191
+ image: Optional[str] = None,
2192
+ handler: Optional[str] = None,
2193
+ with_repo: Optional[bool] = None,
2194
+ tag: Optional[str] = None,
2195
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2029
2196
  requirements_file: str = "",
2030
2197
  **application_kwargs,
2031
2198
  ) -> mlrun.runtimes.BaseRuntime:
@@ -2089,7 +2256,6 @@ class MlrunProject(ModelObj):
2089
2256
  ) -> tuple[str, mlrun.runtimes.BaseRuntime, dict]:
2090
2257
  import mlrun.model_monitoring.api
2091
2258
 
2092
- function_object: RemoteRuntime = None
2093
2259
  kind = None
2094
2260
  if (isinstance(func, str) or func is None) and application_class is not None:
2095
2261
  kind = mlrun.run.RuntimeKinds.serving
@@ -2128,9 +2294,6 @@ class MlrunProject(ModelObj):
2128
2294
  mm_constants.ModelMonitoringAppLabel.VAL,
2129
2295
  )
2130
2296
 
2131
- if not mlrun.mlconf.is_ce_mode():
2132
- function_object.apply(mlrun.mount_v3io())
2133
-
2134
2297
  return resolved_function_name, function_object, func
2135
2298
 
2136
2299
  def _wait_for_functions_deployment(self, function_names: list[str]) -> None:
@@ -2269,7 +2432,7 @@ class MlrunProject(ModelObj):
2269
2432
  delete_stream_function: bool = False,
2270
2433
  delete_histogram_data_drift_app: bool = True,
2271
2434
  delete_user_applications: bool = False,
2272
- user_application_list: list[str] = None,
2435
+ user_application_list: Optional[list[str]] = None,
2273
2436
  ) -> None:
2274
2437
  """
2275
2438
  Disable model monitoring application controller, writer, stream, histogram data drift application
@@ -2326,14 +2489,14 @@ class MlrunProject(ModelObj):
2326
2489
 
2327
2490
  def set_function(
2328
2491
  self,
2329
- func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
2492
+ func: typing.Union[str, mlrun.runtimes.BaseRuntime, None] = None,
2330
2493
  name: str = "",
2331
2494
  kind: str = "job",
2332
- image: str = None,
2333
- handler: str = None,
2334
- with_repo: bool = None,
2335
- tag: str = None,
2336
- requirements: typing.Union[str, list[str]] = None,
2495
+ image: Optional[str] = None,
2496
+ handler: Optional[str] = None,
2497
+ with_repo: Optional[bool] = None,
2498
+ tag: Optional[str] = None,
2499
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2337
2500
  requirements_file: str = "",
2338
2501
  ) -> mlrun.runtimes.BaseRuntime:
2339
2502
  """
@@ -2427,11 +2590,11 @@ class MlrunProject(ModelObj):
2427
2590
  func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
2428
2591
  name: str = "",
2429
2592
  kind: str = "",
2430
- image: str = None,
2431
- handler: str = None,
2432
- with_repo: bool = None,
2433
- tag: str = None,
2434
- requirements: typing.Union[str, list[str]] = None,
2593
+ image: Optional[str] = None,
2594
+ handler: Optional[str] = None,
2595
+ with_repo: Optional[bool] = None,
2596
+ tag: Optional[str] = None,
2597
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2435
2598
  requirements_file: str = "",
2436
2599
  ) -> tuple[str, str, mlrun.runtimes.BaseRuntime, dict]:
2437
2600
  if (
@@ -2654,8 +2817,8 @@ class MlrunProject(ModelObj):
2654
2817
 
2655
2818
  def pull(
2656
2819
  self,
2657
- branch: str = None,
2658
- remote: str = None,
2820
+ branch: Optional[str] = None,
2821
+ remote: Optional[str] = None,
2659
2822
  secrets: Union[SecretsStore, dict] = None,
2660
2823
  ):
2661
2824
  """pull/update sources from git or tar into the context dir
@@ -2768,10 +2931,10 @@ class MlrunProject(ModelObj):
2768
2931
  branch,
2769
2932
  message=None,
2770
2933
  update=True,
2771
- remote: str = None,
2772
- add: list = None,
2773
- author_name: str = None,
2774
- author_email: str = None,
2934
+ remote: Optional[str] = None,
2935
+ add: Optional[list] = None,
2936
+ author_name: Optional[str] = None,
2937
+ author_email: Optional[str] = None,
2775
2938
  secrets: Union[SecretsStore, dict] = None,
2776
2939
  ):
2777
2940
  """update spec and push updates to remote git repo
@@ -2834,7 +2997,7 @@ class MlrunProject(ModelObj):
2834
2997
 
2835
2998
  def sync_functions(
2836
2999
  self,
2837
- names: list = None,
3000
+ names: Optional[list] = None,
2838
3001
  always: bool = True,
2839
3002
  save: bool = False,
2840
3003
  silent: bool = False,
@@ -2978,8 +3141,8 @@ class MlrunProject(ModelObj):
2978
3141
 
2979
3142
  def set_secrets(
2980
3143
  self,
2981
- secrets: dict = None,
2982
- file_path: str = None,
3144
+ secrets: Optional[dict] = None,
3145
+ file_path: Optional[str] = None,
2983
3146
  provider: typing.Union[str, mlrun.common.schemas.SecretProviderName] = None,
2984
3147
  ):
2985
3148
  """
@@ -3056,24 +3219,24 @@ class MlrunProject(ModelObj):
3056
3219
 
3057
3220
  def run(
3058
3221
  self,
3059
- name: str = None,
3060
- workflow_path: str = None,
3061
- arguments: dict[str, typing.Any] = None,
3062
- artifact_path: str = None,
3063
- workflow_handler: typing.Union[str, typing.Callable] = None,
3064
- namespace: str = None,
3222
+ name: Optional[str] = None,
3223
+ workflow_path: Optional[str] = None,
3224
+ arguments: Optional[dict[str, typing.Any]] = None,
3225
+ artifact_path: Optional[str] = None,
3226
+ workflow_handler: Optional[typing.Union[str, typing.Callable]] = None,
3227
+ namespace: Optional[str] = None,
3065
3228
  sync: bool = False,
3066
3229
  watch: bool = False,
3067
3230
  dirty: bool = False,
3068
- engine: str = None,
3069
- local: bool = None,
3231
+ engine: Optional[str] = None,
3232
+ local: Optional[bool] = None,
3070
3233
  schedule: typing.Union[
3071
3234
  str, mlrun.common.schemas.ScheduleCronTrigger, bool
3072
3235
  ] = None,
3073
- timeout: int = None,
3074
- source: str = None,
3075
- cleanup_ttl: int = None,
3076
- notifications: list[mlrun.model.Notification] = None,
3236
+ timeout: Optional[int] = None,
3237
+ source: Optional[str] = None,
3238
+ cleanup_ttl: Optional[int] = None,
3239
+ notifications: Optional[list[mlrun.model.Notification]] = None,
3077
3240
  workflow_runner_node_selector: typing.Optional[dict[str, str]] = None,
3078
3241
  ) -> _PipelineRunStatus:
3079
3242
  """Run a workflow using kubeflow pipelines
@@ -3280,7 +3443,7 @@ class MlrunProject(ModelObj):
3280
3443
 
3281
3444
  return db.create_project(self.to_dict())
3282
3445
 
3283
- def export(self, filepath=None, include_files: str = None):
3446
+ def export(self, filepath=None, include_files: Optional[str] = None):
3284
3447
  """save the project object into a yaml file or zip archive (default to project.yaml)
3285
3448
 
3286
3449
  By default, the project object is exported to a yaml file, when the filepath suffix is '.zip'
@@ -3325,7 +3488,6 @@ class MlrunProject(ModelObj):
3325
3488
  def set_model_monitoring_credentials(
3326
3489
  self,
3327
3490
  access_key: Optional[str] = None,
3328
- endpoint_store_connection: Optional[str] = None,
3329
3491
  stream_path: Optional[str] = None,
3330
3492
  tsdb_connection: Optional[str] = None,
3331
3493
  replace_creds: bool = False,
@@ -3336,7 +3498,6 @@ class MlrunProject(ModelObj):
3336
3498
  model monitoring or serving function.
3337
3499
 
3338
3500
  :param access_key: Model monitoring access key for managing user permissions.
3339
- :param endpoint_store_connection: Endpoint store connection string. By default, None. Options:
3340
3501
 
3341
3502
  * None - will be set from the system configuration.
3342
3503
  * v3io - for v3io endpoint store, pass `v3io` and the system will generate the
@@ -3369,7 +3530,6 @@ class MlrunProject(ModelObj):
3369
3530
  project=self.name,
3370
3531
  credentials={
3371
3532
  "access_key": access_key,
3372
- "endpoint_store_connection": endpoint_store_connection,
3373
3533
  "stream_path": stream_path,
3374
3534
  "tsdb_connection": tsdb_connection,
3375
3535
  },
@@ -3385,30 +3545,86 @@ class MlrunProject(ModelObj):
3385
3545
  "and set `rebuild_images=True`"
3386
3546
  )
3387
3547
 
3548
+ def list_model_endpoints(
3549
+ self,
3550
+ name: Optional[str] = None,
3551
+ model_name: Optional[str] = None,
3552
+ function_name: Optional[str] = None,
3553
+ labels: Optional[list[str]] = None,
3554
+ start: Optional[datetime.datetime] = None,
3555
+ end: Optional[datetime.datetime] = None,
3556
+ top_level: bool = False,
3557
+ uids: Optional[list[str]] = None,
3558
+ ) -> mlrun.common.schemas.ModelEndpointList:
3559
+ """
3560
+ Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
3561
+ model endpoint. This functions supports filtering by the following parameters:
3562
+ 1) name
3563
+ 2) model_name
3564
+ 3) function_name
3565
+ 4) labels
3566
+ 5) top level
3567
+ 6) uids
3568
+ 7) start and end time, corresponding to the `created` field.
3569
+ By default, when no filters are applied, all available endpoints for the given project will be listed.
3570
+
3571
+ In addition, this functions provides a facade for listing endpoint related metrics. This facade is time-based
3572
+ and depends on the 'start' and 'end' parameters.
3573
+
3574
+ :param name: The name of the model to filter by
3575
+ :param model_name: The name of the model to filter by
3576
+ :param function_name: The name of the function to filter by
3577
+ :param labels: Filter model endpoints by label key-value pairs or key existence. This can be provided as:
3578
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
3579
+ or `{"label": None}` to check for key existence.
3580
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
3581
+ or just `"label"` for key existence.
3582
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
3583
+ the specified key-value pairs or key existence.
3584
+ :param start: The start time to filter by.Corresponding to the `created` field.
3585
+ :param end: The end time to filter by. Corresponding to the `created` field.
3586
+ :param top_level: if true will return only routers and endpoint that are NOT children of any router
3587
+ :param uids: if passed will return a list `ModelEndpoint` object with uid in uids
3588
+
3589
+ :returns: Returns a list of `ModelEndpoint` objects.
3590
+ """
3591
+ db = mlrun.db.get_run_db(secrets=self._secrets)
3592
+ return db.list_model_endpoints(
3593
+ project=self.name,
3594
+ name=name,
3595
+ model_name=model_name,
3596
+ function_name=function_name,
3597
+ labels=labels,
3598
+ start=start,
3599
+ end=end,
3600
+ top_level=top_level,
3601
+ uids=uids,
3602
+ )
3603
+
3388
3604
  def run_function(
3389
3605
  self,
3390
3606
  function: typing.Union[str, mlrun.runtimes.BaseRuntime],
3391
- handler: str = None,
3607
+ handler: Optional[str] = None,
3392
3608
  name: str = "",
3393
- params: dict = None,
3394
- hyperparams: dict = None,
3609
+ params: Optional[dict] = None,
3610
+ hyperparams: Optional[dict] = None,
3395
3611
  hyper_param_options: mlrun.model.HyperParamOptions = None,
3396
- inputs: dict = None,
3397
- outputs: list[str] = None,
3612
+ inputs: Optional[dict] = None,
3613
+ outputs: Optional[list[str]] = None,
3398
3614
  workdir: str = "",
3399
- labels: dict = None,
3615
+ labels: Optional[dict] = None,
3400
3616
  base_task: mlrun.model.RunTemplate = None,
3401
3617
  watch: bool = True,
3402
- local: bool = None,
3403
- verbose: bool = None,
3404
- selector: str = None,
3405
- auto_build: bool = None,
3618
+ local: Optional[bool] = None,
3619
+ verbose: Optional[bool] = None,
3620
+ selector: Optional[str] = None,
3621
+ auto_build: Optional[bool] = None,
3406
3622
  schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
3407
- artifact_path: str = None,
3408
- notifications: list[mlrun.model.Notification] = None,
3623
+ artifact_path: Optional[str] = None,
3624
+ notifications: Optional[list[mlrun.model.Notification]] = None,
3409
3625
  returns: Optional[list[Union[str, dict[str, str]]]] = None,
3410
3626
  builder_env: Optional[dict] = None,
3411
- reset_on_run: bool = None,
3627
+ reset_on_run: Optional[bool] = None,
3412
3628
  ) -> typing.Union[mlrun.model.RunObject, PipelineNodeWrapper]:
3413
3629
  """Run a local or remote task as part of a local/kubeflow pipeline
3414
3630
 
@@ -3501,18 +3717,18 @@ class MlrunProject(ModelObj):
3501
3717
  def build_function(
3502
3718
  self,
3503
3719
  function: typing.Union[str, mlrun.runtimes.BaseRuntime],
3504
- with_mlrun: bool = None,
3720
+ with_mlrun: Optional[bool] = None,
3505
3721
  skip_deployed: bool = False,
3506
- image: str = None,
3507
- base_image: str = None,
3508
- commands: list = None,
3509
- secret_name: str = None,
3510
- requirements: typing.Union[str, list[str]] = None,
3511
- mlrun_version_specifier: str = None,
3512
- builder_env: dict = None,
3722
+ image: Optional[str] = None,
3723
+ base_image: Optional[str] = None,
3724
+ commands: Optional[list] = None,
3725
+ secret_name: Optional[str] = None,
3726
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3727
+ mlrun_version_specifier: Optional[str] = None,
3728
+ builder_env: Optional[dict] = None,
3513
3729
  overwrite_build_params: bool = False,
3514
- requirements_file: str = None,
3515
- extra_args: str = None,
3730
+ requirements_file: Optional[str] = None,
3731
+ extra_args: Optional[str] = None,
3516
3732
  force_build: bool = False,
3517
3733
  ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3518
3734
  """deploy ML function, build container with its dependencies
@@ -3557,18 +3773,18 @@ class MlrunProject(ModelObj):
3557
3773
 
3558
3774
  def build_config(
3559
3775
  self,
3560
- image: str = None,
3776
+ image: Optional[str] = None,
3561
3777
  set_as_default: bool = False,
3562
- with_mlrun: bool = None,
3563
- base_image: str = None,
3564
- commands: list = None,
3565
- secret_name: str = None,
3566
- requirements: typing.Union[str, list[str]] = None,
3778
+ with_mlrun: Optional[bool] = None,
3779
+ base_image: Optional[str] = None,
3780
+ commands: Optional[list] = None,
3781
+ secret_name: Optional[str] = None,
3782
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3567
3783
  overwrite_build_params: bool = False,
3568
- requirements_file: str = None,
3569
- builder_env: dict = None,
3570
- extra_args: str = None,
3571
- source_code_target_dir: str = None,
3784
+ requirements_file: Optional[str] = None,
3785
+ builder_env: Optional[dict] = None,
3786
+ extra_args: Optional[str] = None,
3787
+ source_code_target_dir: Optional[str] = None,
3572
3788
  ):
3573
3789
  """specify builder configuration for the project
3574
3790
 
@@ -3622,19 +3838,19 @@ class MlrunProject(ModelObj):
3622
3838
 
3623
3839
  def build_image(
3624
3840
  self,
3625
- image: str = None,
3841
+ image: Optional[str] = None,
3626
3842
  set_as_default: bool = True,
3627
- with_mlrun: bool = None,
3628
- base_image: str = None,
3629
- commands: list = None,
3630
- secret_name: str = None,
3631
- requirements: typing.Union[str, list[str]] = None,
3632
- mlrun_version_specifier: str = None,
3633
- builder_env: dict = None,
3843
+ with_mlrun: Optional[bool] = None,
3844
+ base_image: Optional[str] = None,
3845
+ commands: Optional[list] = None,
3846
+ secret_name: Optional[str] = None,
3847
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3848
+ mlrun_version_specifier: Optional[str] = None,
3849
+ builder_env: Optional[dict] = None,
3634
3850
  overwrite_build_params: bool = False,
3635
- requirements_file: str = None,
3636
- extra_args: str = None,
3637
- target_dir: str = None,
3851
+ requirements_file: Optional[str] = None,
3852
+ extra_args: Optional[str] = None,
3853
+ target_dir: Optional[str] = None,
3638
3854
  ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3639
3855
  """Builder docker image for the project, based on the project's build config. Parameters allow to override
3640
3856
  the build config.
@@ -3740,12 +3956,12 @@ class MlrunProject(ModelObj):
3740
3956
  def deploy_function(
3741
3957
  self,
3742
3958
  function: typing.Union[str, mlrun.runtimes.BaseRuntime],
3743
- models: list = None,
3744
- env: dict = None,
3745
- tag: str = None,
3746
- verbose: bool = None,
3747
- builder_env: dict = None,
3748
- mock: bool = None,
3959
+ models: Optional[list] = None,
3960
+ env: Optional[dict] = None,
3961
+ tag: Optional[str] = None,
3962
+ verbose: Optional[bool] = None,
3963
+ builder_env: Optional[dict] = None,
3964
+ mock: Optional[bool] = None,
3749
3965
  ) -> typing.Union[DeployStatus, PipelineNodeWrapper]:
3750
3966
  """deploy real-time (nuclio based) functions
3751
3967
 
@@ -3792,18 +4008,28 @@ class MlrunProject(ModelObj):
3792
4008
  self,
3793
4009
  name=None,
3794
4010
  tag=None,
3795
- labels: Optional[Union[dict[str, str], list[str]]] = None,
4011
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3796
4012
  since=None,
3797
4013
  until=None,
3798
- iter: int = None,
4014
+ iter: Optional[int] = None,
3799
4015
  best_iteration: bool = False,
3800
- kind: str = None,
4016
+ kind: Optional[str] = None,
3801
4017
  category: typing.Union[str, mlrun.common.schemas.ArtifactCategories] = None,
3802
- tree: str = None,
3803
- limit: int = None,
4018
+ tree: Optional[str] = None,
4019
+ limit: Optional[int] = None,
3804
4020
  format_: Optional[
3805
4021
  mlrun.common.formatters.ArtifactFormat
3806
4022
  ] = mlrun.common.formatters.ArtifactFormat.full,
4023
+ partition_by: Optional[
4024
+ Union[mlrun.common.schemas.ArtifactPartitionByField, str]
4025
+ ] = None,
4026
+ rows_per_partition: int = 1,
4027
+ partition_sort_by: Optional[
4028
+ Union[mlrun.common.schemas.SortField, str]
4029
+ ] = mlrun.common.schemas.SortField.updated,
4030
+ partition_order: Union[
4031
+ mlrun.common.schemas.OrderType, str
4032
+ ] = mlrun.common.schemas.OrderType.desc,
3807
4033
  ) -> mlrun.lists.ArtifactList:
3808
4034
  """List artifacts filtered by various parameters.
3809
4035
 
@@ -3813,7 +4039,7 @@ class MlrunProject(ModelObj):
3813
4039
  Examples::
3814
4040
 
3815
4041
  # Get latest version of all artifacts in project
3816
- latest_artifacts = project.list_artifacts("", tag="latest")
4042
+ latest_artifacts = project.list_artifacts(tag="latest")
3817
4043
  # check different artifact versions for a specific artifact, return as objects list
3818
4044
  result_versions = project.list_artifacts("results", tag="*").to_objects()
3819
4045
 
@@ -3821,8 +4047,13 @@ class MlrunProject(ModelObj):
3821
4047
  case-sensitive. This means that querying for ``~name`` may return artifacts named
3822
4048
  ``my_Name_1`` or ``surname``.
3823
4049
  :param tag: Return artifacts assigned this tag.
3824
- :param labels: Return artifacts that have these labels. Labels can either be a dictionary {"label": "value"} or
3825
- a list of "label=value" (match label key and value) or "label" (match just label key) strings.
4050
+ :param labels: Filter artifacts by label key-value pairs or key existence. This can be provided as:
4051
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4052
+ or `{"label": None}` to check for key existence.
4053
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4054
+ or just `"label"` for key existence.
4055
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4056
+ the specified key-value pairs or key existence.
3826
4057
  :param since: Not in use in :py:class:`HTTPRunDB`.
3827
4058
  :param until: Not in use in :py:class:`HTTPRunDB`.
3828
4059
  :param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
@@ -3835,6 +4066,13 @@ class MlrunProject(ModelObj):
3835
4066
  :param tree: Return artifacts of the requested tree.
3836
4067
  :param limit: Maximum number of artifacts to return.
3837
4068
  :param format_: The format in which to return the artifacts. Default is 'full'.
4069
+ :param partition_by: Field to group results by. When `partition_by` is specified, the `partition_sort_by`
4070
+ parameter must be provided as well.
4071
+ :param rows_per_partition: How many top rows (per sorting defined by `partition_sort_by` and `partition_order`)
4072
+ to return per group. Default value is 1.
4073
+ :param partition_sort_by: What field to sort the results by, within each partition defined by `partition_by`.
4074
+ Currently the only allowed values are `created` and `updated`.
4075
+ :param partition_order: Order of sorting within partitions - `asc` or `desc`. Default is `desc`.
3838
4076
  """
3839
4077
  db = mlrun.db.get_run_db(secrets=self._secrets)
3840
4078
  return db.list_artifacts(
@@ -3851,19 +4089,86 @@ class MlrunProject(ModelObj):
3851
4089
  tree=tree,
3852
4090
  format_=format_,
3853
4091
  limit=limit,
4092
+ partition_by=partition_by,
4093
+ rows_per_partition=rows_per_partition,
4094
+ partition_sort_by=partition_sort_by,
4095
+ partition_order=partition_order,
4096
+ )
4097
+
4098
+ def paginated_list_artifacts(
4099
+ self,
4100
+ *args,
4101
+ page: Optional[int] = None,
4102
+ page_size: Optional[int] = None,
4103
+ page_token: Optional[str] = None,
4104
+ **kwargs,
4105
+ ) -> tuple[mlrun.lists.ArtifactList, Optional[str]]:
4106
+ """List artifacts with support for pagination and various filtering options.
4107
+
4108
+ This method retrieves a paginated list of artifacts based on the specified filter parameters.
4109
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4110
+ will return a list of artifacts that match the filtering criteria provided.
4111
+
4112
+ The returned result is an `ArtifactList` (list of dict), use `.to_objects()` to convert it to a list of
4113
+ RunObjects, `.show()` to view graphically in Jupyter, and `.to_df()` to convert to a DataFrame.
4114
+
4115
+ For detailed information about the parameters, refer to the list_artifacts method:
4116
+ See :py:func:`~list_artifacts` for more details.
4117
+
4118
+ Examples::
4119
+
4120
+ # Fetch first page of artifacts with page size of 5
4121
+ artifacts, token = project.paginated_list_artifacts("results", page_size=5)
4122
+ # Fetch next page using the pagination token from the previous response
4123
+ artifacts, token = project.paginated_list_artifacts("results", page_token=token)
4124
+ # Fetch artifacts for a specific page (e.g., page 3)
4125
+ artifacts, token = project.paginated_list_artifacts(
4126
+ "results", page=3, page_size=5
4127
+ )
4128
+
4129
+ # Automatically iterate over all pages without explicitly specifying the page number
4130
+ artifacts = []
4131
+ token = None
4132
+ while True:
4133
+ page_artifacts, token = project.paginated_list_artifacts(
4134
+ page_token=token, page_size=5
4135
+ )
4136
+ artifacts.extend(page_artifacts)
4137
+
4138
+ # If token is None and page_artifacts is empty, we've reached the end (no more artifacts).
4139
+ # If token is None and page_artifacts is not empty, we've fetched the last page of artifacts.
4140
+ if not token:
4141
+ break
4142
+ print(f"Total artifacts retrieved: {len(artifacts)}")
4143
+
4144
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4145
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4146
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4147
+ for the first request.
4148
+
4149
+ :returns: A tuple containing the list of artifacts and an optional `page_token` for pagination.
4150
+ """
4151
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4152
+ return db.paginated_list_artifacts(
4153
+ *args,
4154
+ project=self.metadata.name,
4155
+ page=page,
4156
+ page_size=page_size,
4157
+ page_token=page_token,
4158
+ **kwargs,
3854
4159
  )
3855
4160
 
3856
4161
  def list_models(
3857
4162
  self,
3858
4163
  name=None,
3859
4164
  tag=None,
3860
- labels: Optional[Union[dict[str, str], list[str]]] = None,
4165
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3861
4166
  since=None,
3862
4167
  until=None,
3863
- iter: int = None,
4168
+ iter: Optional[int] = None,
3864
4169
  best_iteration: bool = False,
3865
- tree: str = None,
3866
- limit: int = None,
4170
+ tree: Optional[str] = None,
4171
+ limit: Optional[int] = None,
3867
4172
  format_: Optional[
3868
4173
  mlrun.common.formatters.ArtifactFormat
3869
4174
  ] = mlrun.common.formatters.ArtifactFormat.full,
@@ -3873,15 +4178,20 @@ class MlrunProject(ModelObj):
3873
4178
  Examples::
3874
4179
 
3875
4180
  # Get latest version of all models in project
3876
- latest_models = project.list_models("", tag="latest")
4181
+ latest_models = project.list_models(tag="latest")
3877
4182
 
3878
4183
 
3879
4184
  :param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
3880
4185
  case-sensitive. This means that querying for ``~name`` may return artifacts named
3881
4186
  ``my_Name_1`` or ``surname``.
3882
4187
  :param tag: Return artifacts assigned this tag.
3883
- :param labels: Return artifacts that have these labels. Labels can either be a dictionary {"label": "value"} or
3884
- a list of "label=value" (match label key and value) or "label" (match just label key) strings.
4188
+ :param labels: Filter model artifacts by label key-value pairs or key existence. This can be provided as:
4189
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4190
+ or `{"label": None}` to check for key existence.
4191
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4192
+ or just `"label"` for key existence.
4193
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4194
+ the specified key-value pairs or key existence.
3885
4195
  :param since: Not in use in :py:class:`HTTPRunDB`.
3886
4196
  :param until: Not in use in :py:class:`HTTPRunDB`.
3887
4197
  :param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
@@ -3903,13 +4213,79 @@ class MlrunProject(ModelObj):
3903
4213
  until=until,
3904
4214
  iter=iter,
3905
4215
  best_iteration=best_iteration,
3906
- kind="model",
4216
+ kind=mlrun.artifacts.model.ModelArtifact.kind,
3907
4217
  tree=tree,
3908
4218
  limit=limit,
3909
4219
  format_=format_,
3910
4220
  ).to_objects()
3911
4221
 
3912
- def list_functions(self, name=None, tag=None, labels=None):
4222
+ def paginated_list_models(
4223
+ self,
4224
+ *args,
4225
+ page: Optional[int] = None,
4226
+ page_size: Optional[int] = None,
4227
+ page_token: Optional[str] = None,
4228
+ **kwargs,
4229
+ ) -> tuple[mlrun.lists.ArtifactList, Optional[str]]:
4230
+ """List models in project with support for pagination and various filtering options.
4231
+
4232
+ This method retrieves a paginated list of artifacts based on the specified filter parameters.
4233
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4234
+ will return a list of artifacts that match the filtering criteria provided.
4235
+
4236
+ For detailed information about the parameters, refer to the list_models method:
4237
+ See :py:func:`~list_models` for more details.
4238
+
4239
+ Examples::
4240
+
4241
+ # Fetch first page of artifacts with page size of 5
4242
+ artifacts, token = project.paginated_list_models("results", page_size=5)
4243
+ # Fetch next page using the pagination token from the previous response
4244
+ artifacts, token = project.paginated_list_models("results", page_token=token)
4245
+ # Fetch artifacts for a specific page (e.g., page 3)
4246
+ artifacts, token = project.paginated_list_models("results", page=3, page_size=5)
4247
+
4248
+ # Automatically iterate over all pages without explicitly specifying the page number
4249
+ artifacts = []
4250
+ token = None
4251
+ while True:
4252
+ page_artifacts, token = project.paginated_list_models(
4253
+ page_token=token, page_size=5
4254
+ )
4255
+ artifacts.extend(page_artifacts)
4256
+
4257
+ # If token is None and page_artifacts is empty, we've reached the end (no more artifacts).
4258
+ # If token is None and page_artifacts is not empty, we've fetched the last page of artifacts.
4259
+ if not token:
4260
+ break
4261
+ print(f"Total artifacts retrieved: {len(artifacts)}")
4262
+
4263
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4264
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4265
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4266
+ for the first request.
4267
+
4268
+ :returns: A tuple containing the list of artifacts and an optional `page_token` for pagination.
4269
+ """
4270
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4271
+ return db.paginated_list_artifacts(
4272
+ *args,
4273
+ project=self.metadata.name,
4274
+ kind=mlrun.artifacts.model.ModelArtifact.kind,
4275
+ page=page,
4276
+ page_size=page_size,
4277
+ page_token=page_token,
4278
+ **kwargs,
4279
+ )
4280
+
4281
+ def list_functions(
4282
+ self,
4283
+ name: Optional[str] = None,
4284
+ tag: Optional[str] = None,
4285
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
4286
+ kind: Optional[str] = None,
4287
+ format_: Optional[str] = None,
4288
+ ):
3913
4289
  """Retrieve a list of functions, filtered by specific criteria.
3914
4290
 
3915
4291
  example::
@@ -3919,20 +4295,95 @@ class MlrunProject(ModelObj):
3919
4295
 
3920
4296
  :param name: Return only functions with a specific name.
3921
4297
  :param tag: Return function versions with specific tags. To return only tagged functions, set tag to ``"*"``.
3922
- :param labels: Return functions that have specific labels assigned to them.
4298
+ :param labels: Filter functions by label key-value pairs or key existence. This can be provided as:
4299
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4300
+ or `{"label": None}` to check for key existence.
4301
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4302
+ or just `"label"` for key existence.
4303
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4304
+ the specified key-value pairs or key existence.
4305
+ :param kind: Return functions of the specified kind. If not provided, all function kinds will be returned.
4306
+ :param format_: The format in which to return the functions. Default is 'full'.
3923
4307
  :returns: List of function objects.
3924
4308
  """
3925
4309
  db = mlrun.db.get_run_db(secrets=self._secrets)
3926
- functions = db.list_functions(name, self.metadata.name, tag=tag, labels=labels)
4310
+ functions = db.list_functions(
4311
+ name,
4312
+ project=self.metadata.name,
4313
+ tag=tag,
4314
+ kind=kind,
4315
+ labels=labels,
4316
+ format_=format_,
4317
+ )
3927
4318
  if functions:
3928
4319
  # convert dict to function objects
3929
4320
  return [mlrun.new_function(runtime=func) for func in functions]
3930
4321
 
4322
+ def paginated_list_functions(
4323
+ self,
4324
+ *args,
4325
+ page: Optional[int] = None,
4326
+ page_size: Optional[int] = None,
4327
+ page_token: Optional[str] = None,
4328
+ **kwargs,
4329
+ ) -> tuple[list, Optional[str]]:
4330
+ """List functions with support for pagination and various filtering options.
4331
+
4332
+ This method retrieves a paginated list of functions based on the specified filter parameters.
4333
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4334
+ will return a list of functions that match the filtering criteria provided.
4335
+
4336
+ For detailed information about the parameters, refer to the list_functions method:
4337
+ See :py:func:`~list_functions` for more details.
4338
+
4339
+ Examples::
4340
+
4341
+ # Fetch first page of functions with page size of 5
4342
+ functions, token = project.paginated_list_functions(page_size=5)
4343
+ # Fetch next page using the pagination token from the previous response
4344
+ functions, token = project.paginated_list_functions(page_token=token)
4345
+ # Fetch functions for a specific page (e.g., page 3)
4346
+ functions, token = project.paginated_list_functions(page=3, page_size=5)
4347
+
4348
+ # Automatically iterate over all pages without explicitly specifying the page number
4349
+ functions = []
4350
+ token = None
4351
+ while True:
4352
+ page_functions, token = project.paginated_list_functions(
4353
+ page_token=token, page_size=5
4354
+ )
4355
+ functions.extend(page_functions)
4356
+
4357
+ # If token is None and page_functions is empty, we've reached the end (no more functions).
4358
+ # If token is None and page_functions is not empty, we've fetched the last page of functions.
4359
+ if not token:
4360
+ break
4361
+ print(f"Total functions retrieved: {len(functions)}")
4362
+
4363
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4364
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4365
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4366
+ for the first request.
4367
+
4368
+ :returns: A tuple containing the list of functions and an optional `page_token` for pagination.
4369
+ """
4370
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4371
+ functions, token = db.paginated_list_functions(
4372
+ *args,
4373
+ project=self.metadata.name,
4374
+ page=page,
4375
+ page_size=page_size,
4376
+ page_token=page_token,
4377
+ **kwargs,
4378
+ )
4379
+ # convert dict to function objects
4380
+ return [mlrun.new_function(runtime=func) for func in functions], token
4381
+
3931
4382
  def list_model_monitoring_functions(
3932
4383
  self,
3933
4384
  name: Optional[str] = None,
3934
4385
  tag: Optional[str] = None,
3935
- labels: Optional[list[str]] = None,
4386
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3936
4387
  ) -> Optional[list]:
3937
4388
  """
3938
4389
  Retrieve a list of all the model monitoring functions.
@@ -3942,8 +4393,13 @@ class MlrunProject(ModelObj):
3942
4393
 
3943
4394
  :param name: Return only functions with a specific name.
3944
4395
  :param tag: Return function versions with specific tags.
3945
- :param labels: Return functions that have specific labels assigned to them.
3946
-
4396
+ :param labels: Filter functions by label key-value pairs or key existence. This can be provided as:
4397
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4398
+ or `{"label": None}` to check for key existence.
4399
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4400
+ or just `"label"` for key existence.
4401
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4402
+ the specified key-value pairs or key existence.
3947
4403
  :returns: List of function objects.
3948
4404
  """
3949
4405
 
@@ -3960,7 +4416,7 @@ class MlrunProject(ModelObj):
3960
4416
  self,
3961
4417
  name: Optional[str] = None,
3962
4418
  uid: Optional[Union[str, list[str]]] = None,
3963
- labels: Optional[Union[str, list[str]]] = None,
4419
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3964
4420
  state: Optional[
3965
4421
  mlrun.common.runtimes.constants.RunStates
3966
4422
  ] = None, # Backward compatibility
@@ -3995,9 +4451,13 @@ class MlrunProject(ModelObj):
3995
4451
 
3996
4452
  :param name: Name of the run to retrieve.
3997
4453
  :param uid: Unique ID of the run.
3998
- :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
3999
- of a label (i.e. list("key=value")) or by looking for the existence of a given
4000
- key (i.e. "key").
4454
+ :param labels: Filter runs by label key-value pairs or key existence. This can be provided as:
4455
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4456
+ or `{"label": None}` to check for key existence.
4457
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4458
+ or just `"label"` for key existence.
4459
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4460
+ the specified key-value pairs or key existence.
4001
4461
  :param state: Deprecated - List only runs whose state is specified.
4002
4462
  :param states: List only runs whose state is one of the provided states.
4003
4463
  :param sort: Whether to sort the result according to their start time. Otherwise, results will be
@@ -4023,9 +4483,11 @@ class MlrunProject(ModelObj):
4023
4483
  uid,
4024
4484
  self.metadata.name,
4025
4485
  labels=labels,
4026
- states=mlrun.utils.helpers.as_list(state)
4027
- if state is not None
4028
- else states or None,
4486
+ states=(
4487
+ mlrun.utils.helpers.as_list(state)
4488
+ if state is not None
4489
+ else states or None
4490
+ ),
4029
4491
  sort=sort,
4030
4492
  last=last,
4031
4493
  iter=iter,
@@ -4036,6 +4498,68 @@ class MlrunProject(ModelObj):
4036
4498
  **kwargs,
4037
4499
  )
4038
4500
 
4501
+ def paginated_list_runs(
4502
+ self,
4503
+ *args,
4504
+ page: Optional[int] = None,
4505
+ page_size: Optional[int] = None,
4506
+ page_token: Optional[str] = None,
4507
+ **kwargs,
4508
+ ) -> tuple[mlrun.lists.RunList, Optional[str]]:
4509
+ """List runs with support for pagination and various filtering options.
4510
+
4511
+ This method retrieves a paginated list of runs based on the specified filter parameters.
4512
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4513
+ will return a list of runs that match the filtering criteria provided.
4514
+
4515
+ The returned result is a `` (list of dict), use `.to_objects()` to convert it to a list of RunObjects,
4516
+ `.show()` to view graphically in Jupyter, `.to_df()` to convert to a DataFrame, and `compare()` to
4517
+ generate comparison table and PCP plot.
4518
+
4519
+ For detailed information about the parameters, refer to the list_runs method:
4520
+ See :py:func:`~list_runs` for more details.
4521
+
4522
+ Examples::
4523
+
4524
+ # Fetch first page of runs with page size of 5
4525
+ runs, token = project.paginated_list_runs(page_size=5)
4526
+ # Fetch next page using the pagination token from the previous response
4527
+ runs, token = project.paginated_list_runs(page_token=token)
4528
+ # Fetch runs for a specific page (e.g., page 3)
4529
+ runs, token = project.paginated_list_runs(page=3, page_size=5)
4530
+
4531
+ # Automatically iterate over all pages without explicitly specifying the page number
4532
+ runs = []
4533
+ token = None
4534
+ while True:
4535
+ page_runs, token = project.paginated_list_runs(
4536
+ page_token=token, page_size=5
4537
+ )
4538
+ runs.extend(page_runs)
4539
+
4540
+ # If token is None and page_runs is empty, we've reached the end (no more runs).
4541
+ # If token is None and page_runs is not empty, we've fetched the last page of runs.
4542
+ if not token:
4543
+ break
4544
+ print(f"Total runs retrieved: {len(runs)}")
4545
+
4546
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4547
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4548
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4549
+ for the first request.
4550
+
4551
+ :returns: A tuple containing the list of runs and an optional `page_token` for pagination.
4552
+ """
4553
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4554
+ return db.paginated_list_runs(
4555
+ *args,
4556
+ project=self.metadata.name,
4557
+ page=page,
4558
+ page_size=page_size,
4559
+ page_token=page_token,
4560
+ **kwargs,
4561
+ )
4562
+
4039
4563
  def register_datastore_profile(self, profile: DatastoreProfile):
4040
4564
  private_body = DatastoreProfile2Json.get_json_private(profile)
4041
4565
  public_body = DatastoreProfile2Json.get_json_public(profile)
@@ -4051,6 +4575,25 @@ class MlrunProject(ModelObj):
4051
4575
  profile, self.name
4052
4576
  )
4053
4577
 
4578
+ def get_config_profile_attributes(self, name: str) -> dict:
4579
+ """
4580
+ Get the merged attributes from a named configuration profile.
4581
+
4582
+ Retrieves a profile from the datastore using the provided name and returns its
4583
+ merged public and private attributes as a dictionary.
4584
+
4585
+ Args:
4586
+ name (str): Name of the configuration profile to retrieve. Will be prefixed
4587
+ with "ds://" to form the full profile path.
4588
+
4589
+ Returns:
4590
+ dict: The merged attributes dictionary containing both public and private
4591
+ configuration settings from the profile. Returns nested dictionaries if
4592
+ the profile contains nested configurations.
4593
+ """
4594
+ profile = datastore_profile_read(f"ds://{name}", self.name)
4595
+ return profile.attributes()
4596
+
4054
4597
  def delete_datastore_profile(self, profile: str):
4055
4598
  mlrun.db.get_run_db(secrets=self._secrets).delete_datastore_profile(
4056
4599
  profile, self.name
@@ -4188,13 +4731,17 @@ class MlrunProject(ModelObj):
4188
4731
  mlrun.db.get_run_db().delete_api_gateway(name=name, project=self.name)
4189
4732
 
4190
4733
  def store_alert_config(
4191
- self, alert_data: AlertConfig, alert_name: typing.Optional[str] = None
4734
+ self,
4735
+ alert_data: AlertConfig,
4736
+ alert_name: typing.Optional[str] = None,
4737
+ force_reset: bool = False,
4192
4738
  ) -> AlertConfig:
4193
4739
  """
4194
4740
  Create/modify an alert.
4195
4741
 
4196
4742
  :param alert_data: The data of the alert.
4197
4743
  :param alert_name: The name of the alert.
4744
+ :param force_reset: If True and the alert already exists, the alert would be reset.
4198
4745
  :return: the created/modified alert.
4199
4746
  """
4200
4747
  if not alert_data:
@@ -4208,7 +4755,9 @@ class MlrunProject(ModelObj):
4208
4755
  project=alert_data.project,
4209
4756
  )
4210
4757
  alert_data.project = self.metadata.name
4211
- return db.store_alert_config(alert_name, alert_data, project=self.metadata.name)
4758
+ return db.store_alert_config(
4759
+ alert_name, alert_data, project=self.metadata.name, force_reset=force_reset
4760
+ )
4212
4761
 
4213
4762
  def get_alert_config(self, alert_name: str) -> AlertConfig:
4214
4763
  """
@@ -4230,7 +4779,7 @@ class MlrunProject(ModelObj):
4230
4779
  return db.list_alerts_configs(self.metadata.name)
4231
4780
 
4232
4781
  def delete_alert_config(
4233
- self, alert_data: AlertConfig = None, alert_name: str = None
4782
+ self, alert_data: AlertConfig = None, alert_name: Optional[str] = None
4234
4783
  ):
4235
4784
  """
4236
4785
  Delete an alert.
@@ -4250,7 +4799,7 @@ class MlrunProject(ModelObj):
4250
4799
  db.delete_alert_config(alert_name, self.metadata.name)
4251
4800
 
4252
4801
  def reset_alert_config(
4253
- self, alert_data: AlertConfig = None, alert_name: str = None
4802
+ self, alert_data: AlertConfig = None, alert_name: Optional[str] = None
4254
4803
  ):
4255
4804
  """
4256
4805
  Reset an alert.
@@ -4269,7 +4818,9 @@ class MlrunProject(ModelObj):
4269
4818
  alert_name = alert_data.name
4270
4819
  db.reset_alert_config(alert_name, self.metadata.name)
4271
4820
 
4272
- def get_alert_template(self, template_name: str) -> AlertTemplate:
4821
+ def get_alert_template(
4822
+ self, template_name: str
4823
+ ) -> mlrun.common.schemas.alert.AlertTemplate:
4273
4824
  """
4274
4825
  Retrieve a specific alert template.
4275
4826
 
@@ -4279,7 +4830,7 @@ class MlrunProject(ModelObj):
4279
4830
  db = mlrun.db.get_run_db(secrets=self._secrets)
4280
4831
  return db.get_alert_template(template_name)
4281
4832
 
4282
- def list_alert_templates(self) -> list[AlertTemplate]:
4833
+ def list_alert_templates(self) -> list[mlrun.common.schemas.alert.AlertTemplate]:
4283
4834
  """
4284
4835
  Retrieve list of all alert templates.
4285
4836
 
@@ -4288,12 +4839,114 @@ class MlrunProject(ModelObj):
4288
4839
  db = mlrun.db.get_run_db(secrets=self._secrets)
4289
4840
  return db.list_alert_templates()
4290
4841
 
4842
+ def list_alert_activations(
4843
+ self,
4844
+ name: Optional[str] = None,
4845
+ since: Optional[datetime.datetime] = None,
4846
+ until: Optional[datetime.datetime] = None,
4847
+ entity: Optional[str] = None,
4848
+ severity: Optional[
4849
+ list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
4850
+ ] = None,
4851
+ entity_kind: Optional[
4852
+ Union[mlrun.common.schemas.alert.EventEntityKind, str]
4853
+ ] = None,
4854
+ event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
4855
+ ) -> list[mlrun.common.schemas.alert.AlertActivation]:
4856
+ """
4857
+ Retrieve a list of alert activations for a project.
4858
+
4859
+ :param name: The alert name to filter by. Supports exact matching or partial matching if prefixed with `~`.
4860
+ :param since: Filters for alert activations occurring after this timestamp.
4861
+ :param until: Filters for alert activations occurring before this timestamp.
4862
+ :param entity: The entity ID to filter by. Supports wildcard matching if prefixed with `~`.
4863
+ :param severity: A list of severity levels to filter by (e.g., ["high", "low"]).
4864
+ :param entity_kind: The kind of entity (e.g., "job", "endpoint") to filter by.
4865
+ :param event_kind: The kind of event (e.g., ""data-drift-detected"", "failed") to filter by.
4866
+
4867
+ :returns: A list of alert activations matching the provided filters.
4868
+ """
4869
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4870
+ return db.list_alert_activations(
4871
+ project=self.metadata.name,
4872
+ name=name,
4873
+ since=since,
4874
+ until=until,
4875
+ entity=entity,
4876
+ severity=severity,
4877
+ entity_kind=entity_kind,
4878
+ event_kind=event_kind,
4879
+ )
4880
+
4881
+ def paginated_list_alert_activations(
4882
+ self,
4883
+ *args,
4884
+ page: Optional[int] = None,
4885
+ page_size: Optional[int] = None,
4886
+ page_token: Optional[str] = None,
4887
+ **kwargs,
4888
+ ) -> tuple[mlrun.common.schemas.alert.AlertActivation, Optional[str]]:
4889
+ """
4890
+ List alerts activations with support for pagination and various filtering options.
4891
+
4892
+ This method retrieves a paginated list of alert activations based on the specified filter parameters.
4893
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4894
+ will return a list of alert activations that match the filtering criteria provided.
4895
+
4896
+ For detailed information about the parameters, refer to the list_alert_activations method:
4897
+ See :py:func:`~list_alert_activations` for more details.
4898
+
4899
+ Examples::
4900
+
4901
+ # Fetch first page of alert activations with page size of 5
4902
+ alert_activations, token = project.paginated_list_alert_activations(page_size=5)
4903
+ # Fetch next page using the pagination token from the previous response
4904
+ alert_activations, token = project.paginated_list_alert_activations(
4905
+ page_token=token
4906
+ )
4907
+ # Fetch alert activations for a specific page (e.g., page 3)
4908
+ alert_activations, token = project.paginated_list_alert_activations(
4909
+ page=3, page_size=5
4910
+ )
4911
+
4912
+ # Automatically iterate over all pages without explicitly specifying the page number
4913
+ alert_activations = []
4914
+ token = None
4915
+ while True:
4916
+ page_alert_activations, token = project.paginated_list_alert_activations(
4917
+ page_token=token, page_size=5
4918
+ )
4919
+ alert_activations.extend(page_alert_activations)
4920
+
4921
+ # If token is None and page_alert_activations is empty, we've reached the end (no more activations).
4922
+ # If token is None and page_alert_activations is not empty, we've fetched the last page of activations.
4923
+ if not token:
4924
+ break
4925
+ print(f"Total alert activations retrieved: {len(alert_activations)}")
4926
+
4927
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4928
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4929
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4930
+ for the first request.
4931
+
4932
+ :returns: A tuple containing the list of alert activations and an optional `page_token` for pagination.
4933
+ """
4934
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4935
+ return db.paginated_list_alert_activations(
4936
+ *args,
4937
+ project=self.metadata.name,
4938
+ page=page,
4939
+ page_size=page_size,
4940
+ page_token=page_token,
4941
+ **kwargs,
4942
+ )
4943
+
4291
4944
  def _run_authenticated_git_action(
4292
4945
  self,
4293
4946
  action: Callable,
4294
4947
  remote: str,
4295
- args: list = None,
4296
- kwargs: dict = None,
4948
+ args: Optional[list] = None,
4949
+ kwargs: Optional[dict] = None,
4297
4950
  secrets: Union[SecretsStore, dict] = None,
4298
4951
  ):
4299
4952
  """Run an arbitrary Git routine while the remote is enriched with secrets
@@ -4370,7 +5023,7 @@ class MlrunProject(ModelObj):
4370
5023
  def _resolve_artifact_producer(
4371
5024
  self,
4372
5025
  artifact: typing.Union[str, Artifact],
4373
- project_producer_tag: str = None,
5026
+ project_producer_tag: Optional[str] = None,
4374
5027
  ) -> tuple[ArtifactProducer, bool]:
4375
5028
  """
4376
5029
  Resolve the artifact producer of the given artifact.
@@ -4400,28 +5053,34 @@ class MlrunProject(ModelObj):
4400
5053
  )
4401
5054
 
4402
5055
  if producer_dict.get("kind", "") == "run":
4403
- return ArtifactProducer(
4404
- name=producer_dict.get("name", ""),
4405
- kind=producer_dict.get("kind", ""),
4406
- project=producer_project,
4407
- tag=producer_tag,
4408
- owner=producer_dict.get("owner", ""),
4409
- ), True
5056
+ return (
5057
+ ArtifactProducer(
5058
+ name=producer_dict.get("name", ""),
5059
+ kind=producer_dict.get("kind", ""),
5060
+ project=producer_project,
5061
+ tag=producer_tag,
5062
+ owner=producer_dict.get("owner", ""),
5063
+ ),
5064
+ True,
5065
+ )
4410
5066
 
4411
5067
  # do not retain the artifact's producer, replace it with the project as the producer
4412
5068
  project_producer_tag = project_producer_tag or self._get_project_tag()
4413
- return ArtifactProducer(
4414
- kind="project",
4415
- name=self.metadata.name,
4416
- project=self.metadata.name,
4417
- tag=project_producer_tag,
4418
- owner=self._resolve_artifact_owner(),
4419
- ), False
5069
+ return (
5070
+ ArtifactProducer(
5071
+ kind="project",
5072
+ name=self.metadata.name,
5073
+ project=self.metadata.name,
5074
+ tag=project_producer_tag,
5075
+ owner=self._resolve_artifact_owner(),
5076
+ ),
5077
+ False,
5078
+ )
4420
5079
 
4421
5080
  def _resolve_existing_artifact(
4422
5081
  self,
4423
5082
  item: typing.Union[str, Artifact],
4424
- tag: str = None,
5083
+ tag: Optional[str] = None,
4425
5084
  ) -> typing.Optional[Artifact]:
4426
5085
  """
4427
5086
  Check if there is and existing artifact with the given item and tag.