mlrun 1.7.2rc3__py3-none-any.whl → 1.8.0rc1__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 (222) hide show
  1. mlrun/__init__.py +14 -12
  2. mlrun/__main__.py +3 -3
  3. mlrun/alerts/alert.py +19 -12
  4. mlrun/artifacts/__init__.py +0 -2
  5. mlrun/artifacts/base.py +34 -11
  6. mlrun/artifacts/dataset.py +16 -16
  7. mlrun/artifacts/manager.py +13 -13
  8. mlrun/artifacts/model.py +66 -53
  9. mlrun/common/constants.py +6 -0
  10. mlrun/common/formatters/__init__.py +1 -0
  11. mlrun/common/formatters/feature_set.py +1 -0
  12. mlrun/common/formatters/function.py +1 -0
  13. mlrun/common/formatters/model_endpoint.py +30 -0
  14. mlrun/common/formatters/pipeline.py +1 -2
  15. mlrun/common/model_monitoring/__init__.py +0 -3
  16. mlrun/common/model_monitoring/helpers.py +1 -1
  17. mlrun/common/runtimes/constants.py +1 -2
  18. mlrun/common/schemas/__init__.py +4 -2
  19. mlrun/common/schemas/artifact.py +0 -6
  20. mlrun/common/schemas/common.py +50 -0
  21. mlrun/common/schemas/model_monitoring/__init__.py +8 -1
  22. mlrun/common/schemas/model_monitoring/constants.py +62 -12
  23. mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +149 -0
  24. mlrun/common/schemas/model_monitoring/model_endpoints.py +21 -5
  25. mlrun/common/schemas/partition.py +122 -0
  26. mlrun/config.py +43 -15
  27. mlrun/data_types/__init__.py +0 -2
  28. mlrun/data_types/data_types.py +0 -1
  29. mlrun/data_types/infer.py +3 -1
  30. mlrun/data_types/spark.py +4 -4
  31. mlrun/data_types/to_pandas.py +2 -11
  32. mlrun/datastore/__init__.py +0 -2
  33. mlrun/datastore/alibaba_oss.py +4 -1
  34. mlrun/datastore/azure_blob.py +4 -1
  35. mlrun/datastore/base.py +12 -4
  36. mlrun/datastore/datastore.py +9 -3
  37. mlrun/datastore/datastore_profile.py +1 -1
  38. mlrun/datastore/dbfs_store.py +4 -1
  39. mlrun/datastore/filestore.py +4 -1
  40. mlrun/datastore/google_cloud_storage.py +4 -1
  41. mlrun/datastore/hdfs.py +4 -1
  42. mlrun/datastore/inmem.py +4 -1
  43. mlrun/datastore/redis.py +4 -1
  44. mlrun/datastore/s3.py +4 -1
  45. mlrun/datastore/sources.py +51 -49
  46. mlrun/datastore/store_resources.py +0 -2
  47. mlrun/datastore/targets.py +22 -23
  48. mlrun/datastore/utils.py +2 -2
  49. mlrun/datastore/v3io.py +4 -1
  50. mlrun/datastore/wasbfs/fs.py +13 -12
  51. mlrun/db/base.py +126 -62
  52. mlrun/db/factory.py +3 -0
  53. mlrun/db/httpdb.py +767 -231
  54. mlrun/db/nopdb.py +126 -57
  55. mlrun/errors.py +2 -2
  56. mlrun/execution.py +55 -29
  57. mlrun/feature_store/__init__.py +0 -2
  58. mlrun/feature_store/api.py +40 -40
  59. mlrun/feature_store/common.py +9 -9
  60. mlrun/feature_store/feature_set.py +20 -18
  61. mlrun/feature_store/feature_vector.py +27 -24
  62. mlrun/feature_store/retrieval/base.py +14 -9
  63. mlrun/feature_store/retrieval/job.py +2 -1
  64. mlrun/feature_store/steps.py +2 -2
  65. mlrun/features.py +30 -13
  66. mlrun/frameworks/__init__.py +1 -2
  67. mlrun/frameworks/_common/__init__.py +1 -2
  68. mlrun/frameworks/_common/artifacts_library.py +2 -2
  69. mlrun/frameworks/_common/mlrun_interface.py +10 -6
  70. mlrun/frameworks/_common/model_handler.py +29 -27
  71. mlrun/frameworks/_common/producer.py +3 -1
  72. mlrun/frameworks/_dl_common/__init__.py +1 -2
  73. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
  74. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
  75. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
  76. mlrun/frameworks/_ml_common/__init__.py +1 -2
  77. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
  78. mlrun/frameworks/_ml_common/model_handler.py +21 -21
  79. mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
  80. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
  81. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  82. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  83. mlrun/frameworks/auto_mlrun/__init__.py +1 -2
  84. mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
  85. mlrun/frameworks/huggingface/__init__.py +1 -2
  86. mlrun/frameworks/huggingface/model_server.py +9 -9
  87. mlrun/frameworks/lgbm/__init__.py +47 -44
  88. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
  89. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
  90. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
  91. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
  92. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
  93. mlrun/frameworks/lgbm/model_handler.py +15 -11
  94. mlrun/frameworks/lgbm/model_server.py +11 -7
  95. mlrun/frameworks/lgbm/utils.py +2 -2
  96. mlrun/frameworks/onnx/__init__.py +1 -2
  97. mlrun/frameworks/onnx/dataset.py +3 -3
  98. mlrun/frameworks/onnx/mlrun_interface.py +2 -2
  99. mlrun/frameworks/onnx/model_handler.py +7 -5
  100. mlrun/frameworks/onnx/model_server.py +8 -6
  101. mlrun/frameworks/parallel_coordinates.py +11 -11
  102. mlrun/frameworks/pytorch/__init__.py +22 -23
  103. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
  104. mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
  105. mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
  106. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
  107. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
  108. mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
  109. mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
  110. mlrun/frameworks/pytorch/model_handler.py +21 -17
  111. mlrun/frameworks/pytorch/model_server.py +13 -9
  112. mlrun/frameworks/sklearn/__init__.py +19 -18
  113. mlrun/frameworks/sklearn/estimator.py +2 -2
  114. mlrun/frameworks/sklearn/metric.py +3 -3
  115. mlrun/frameworks/sklearn/metrics_library.py +8 -6
  116. mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
  117. mlrun/frameworks/sklearn/model_handler.py +4 -3
  118. mlrun/frameworks/tf_keras/__init__.py +11 -12
  119. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
  120. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
  121. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
  122. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
  123. mlrun/frameworks/tf_keras/model_handler.py +17 -13
  124. mlrun/frameworks/tf_keras/model_server.py +12 -8
  125. mlrun/frameworks/xgboost/__init__.py +19 -18
  126. mlrun/frameworks/xgboost/model_handler.py +13 -9
  127. mlrun/launcher/base.py +3 -4
  128. mlrun/launcher/local.py +1 -1
  129. mlrun/launcher/remote.py +1 -1
  130. mlrun/lists.py +4 -3
  131. mlrun/model.py +108 -44
  132. mlrun/model_monitoring/__init__.py +1 -2
  133. mlrun/model_monitoring/api.py +6 -6
  134. mlrun/model_monitoring/applications/_application_steps.py +13 -15
  135. mlrun/model_monitoring/applications/histogram_data_drift.py +41 -15
  136. mlrun/model_monitoring/applications/results.py +55 -3
  137. mlrun/model_monitoring/controller.py +185 -223
  138. mlrun/model_monitoring/db/_schedules.py +156 -0
  139. mlrun/model_monitoring/db/_stats.py +189 -0
  140. mlrun/model_monitoring/db/stores/__init__.py +1 -1
  141. mlrun/model_monitoring/db/stores/base/store.py +6 -65
  142. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -25
  143. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -97
  144. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +2 -58
  145. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -15
  146. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +6 -257
  147. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +9 -271
  148. mlrun/model_monitoring/db/tsdb/base.py +74 -22
  149. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +66 -35
  150. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
  151. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +284 -51
  152. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
  153. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +35 -17
  154. mlrun/model_monitoring/helpers.py +97 -1
  155. mlrun/model_monitoring/model_endpoint.py +4 -2
  156. mlrun/model_monitoring/stream_processing.py +2 -2
  157. mlrun/model_monitoring/tracking_policy.py +10 -3
  158. mlrun/model_monitoring/writer.py +47 -26
  159. mlrun/package/__init__.py +3 -6
  160. mlrun/package/context_handler.py +1 -1
  161. mlrun/package/packager.py +12 -9
  162. mlrun/package/packagers/__init__.py +0 -2
  163. mlrun/package/packagers/default_packager.py +14 -11
  164. mlrun/package/packagers/numpy_packagers.py +16 -7
  165. mlrun/package/packagers/pandas_packagers.py +18 -18
  166. mlrun/package/packagers/python_standard_library_packagers.py +25 -11
  167. mlrun/package/packagers_manager.py +31 -14
  168. mlrun/package/utils/__init__.py +0 -3
  169. mlrun/package/utils/_pickler.py +6 -6
  170. mlrun/platforms/__init__.py +3 -3
  171. mlrun/platforms/iguazio.py +4 -1
  172. mlrun/projects/__init__.py +1 -6
  173. mlrun/projects/operations.py +27 -27
  174. mlrun/projects/pipelines.py +85 -215
  175. mlrun/projects/project.py +444 -158
  176. mlrun/run.py +9 -9
  177. mlrun/runtimes/__init__.py +1 -3
  178. mlrun/runtimes/base.py +13 -10
  179. mlrun/runtimes/daskjob.py +9 -9
  180. mlrun/runtimes/generators.py +2 -1
  181. mlrun/runtimes/kubejob.py +4 -5
  182. mlrun/runtimes/mpijob/__init__.py +0 -2
  183. mlrun/runtimes/mpijob/abstract.py +7 -6
  184. mlrun/runtimes/nuclio/api_gateway.py +7 -7
  185. mlrun/runtimes/nuclio/application/application.py +11 -11
  186. mlrun/runtimes/nuclio/function.py +14 -13
  187. mlrun/runtimes/nuclio/serving.py +9 -9
  188. mlrun/runtimes/pod.py +74 -29
  189. mlrun/runtimes/remotesparkjob.py +3 -2
  190. mlrun/runtimes/sparkjob/__init__.py +0 -2
  191. mlrun/runtimes/sparkjob/spark3job.py +21 -11
  192. mlrun/runtimes/utils.py +6 -5
  193. mlrun/serving/merger.py +6 -4
  194. mlrun/serving/remote.py +18 -17
  195. mlrun/serving/routers.py +27 -27
  196. mlrun/serving/server.py +1 -1
  197. mlrun/serving/states.py +76 -71
  198. mlrun/serving/utils.py +13 -2
  199. mlrun/serving/v1_serving.py +3 -2
  200. mlrun/serving/v2_serving.py +4 -4
  201. mlrun/track/__init__.py +1 -1
  202. mlrun/track/tracker.py +2 -2
  203. mlrun/track/trackers/mlflow_tracker.py +6 -5
  204. mlrun/utils/async_http.py +1 -1
  205. mlrun/utils/helpers.py +72 -28
  206. mlrun/utils/logger.py +104 -2
  207. mlrun/utils/notifications/notification/base.py +23 -4
  208. mlrun/utils/notifications/notification/console.py +1 -1
  209. mlrun/utils/notifications/notification/git.py +6 -6
  210. mlrun/utils/notifications/notification/ipython.py +5 -4
  211. mlrun/utils/notifications/notification/slack.py +1 -1
  212. mlrun/utils/notifications/notification/webhook.py +13 -17
  213. mlrun/utils/notifications/notification_pusher.py +23 -19
  214. mlrun/utils/regex.py +1 -1
  215. mlrun/utils/version/version.json +2 -2
  216. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc1.dist-info}/METADATA +186 -186
  217. mlrun-1.8.0rc1.dist-info/RECORD +356 -0
  218. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc1.dist-info}/WHEEL +1 -1
  219. mlrun-1.7.2rc3.dist-info/RECORD +0 -351
  220. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc1.dist-info}/LICENSE +0 -0
  221. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc1.dist-info}/entry_points.txt +0 -0
  222. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc1.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py CHANGED
@@ -33,13 +33,11 @@ from typing import Callable, Optional, Union
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
@@ -57,10 +55,13 @@ import mlrun.runtimes.utils
57
55
  import mlrun.serving
58
56
  import mlrun.utils
59
57
  import mlrun.utils.regex
58
+ import mlrun_pipelines.common.models
59
+ import mlrun_pipelines.mounts
60
60
  from mlrun.alerts.alert import AlertConfig
61
61
  from mlrun.common.schemas.alert import AlertTemplate
62
62
  from mlrun.datastore.datastore_profile import DatastoreProfile, DatastoreProfile2Json
63
63
  from mlrun.runtimes.nuclio.function import RemoteRuntime
64
+ from mlrun_pipelines.models import PipelineNodeWrapper
64
65
 
65
66
  from ..artifacts import Artifact, ArtifactProducer, DatasetArtifact, ModelArtifact
66
67
  from ..artifacts.manager import ArtifactManager, dict_to_artifact, extend_artifact_path
@@ -126,15 +127,15 @@ def new_project(
126
127
  context: str = "./",
127
128
  init_git: bool = False,
128
129
  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,
130
+ remote: Optional[str] = None,
131
+ from_template: Optional[str] = None,
132
+ secrets: Optional[dict] = None,
133
+ description: Optional[str] = None,
134
+ subpath: Optional[str] = None,
134
135
  save: bool = True,
135
136
  overwrite: bool = False,
136
- parameters: dict = None,
137
- default_function_node_selector: dict = None,
137
+ parameters: Optional[dict] = None,
138
+ default_function_node_selector: Optional[dict] = None,
138
139
  ) -> "MlrunProject":
139
140
  """Create a new MLRun project, optionally load it from a yaml/zip/git template
140
141
 
@@ -291,17 +292,17 @@ def new_project(
291
292
 
292
293
  def load_project(
293
294
  context: str = "./",
294
- url: str = None,
295
- name: str = None,
296
- secrets: dict = None,
295
+ url: Optional[str] = None,
296
+ name: Optional[str] = None,
297
+ secrets: Optional[dict] = None,
297
298
  init_git: bool = False,
298
- subpath: str = None,
299
+ subpath: Optional[str] = None,
299
300
  clone: bool = False,
300
301
  user_project: bool = False,
301
302
  save: bool = True,
302
303
  sync_functions: bool = False,
303
- parameters: dict = None,
304
- allow_cross_project: bool = None,
304
+ parameters: Optional[dict] = None,
305
+ allow_cross_project: Optional[bool] = None,
305
306
  ) -> "MlrunProject":
306
307
  """Load an MLRun project from git or tar or dir
307
308
 
@@ -437,16 +438,16 @@ def load_project(
437
438
  def get_or_create_project(
438
439
  name: str,
439
440
  context: str = "./",
440
- url: str = None,
441
- secrets: dict = None,
441
+ url: Optional[str] = None,
442
+ secrets: Optional[dict] = None,
442
443
  init_git=False,
443
- subpath: str = None,
444
+ subpath: Optional[str] = None,
444
445
  clone: bool = False,
445
446
  user_project: bool = False,
446
- from_template: str = None,
447
+ from_template: Optional[str] = None,
447
448
  save: bool = True,
448
- parameters: dict = None,
449
- allow_cross_project: bool = None,
449
+ parameters: Optional[dict] = None,
450
+ allow_cross_project: Optional[bool] = None,
450
451
  ) -> "MlrunProject":
451
452
  """Load a project from MLRun DB, or create/import if it does not exist
452
453
 
@@ -823,14 +824,14 @@ class ProjectSpec(ModelObj):
823
824
  origin_url=None,
824
825
  goals=None,
825
826
  load_source_on_run=None,
826
- default_requirements: typing.Union[str, list[str]] = None,
827
+ default_requirements: Optional[typing.Union[str, list[str]]] = None,
827
828
  desired_state=mlrun.common.schemas.ProjectState.online.value,
828
829
  owner=None,
829
830
  disable_auto_mount=None,
830
831
  workdir=None,
831
832
  default_image=None,
832
833
  build=None,
833
- custom_packagers: list[tuple[str, bool]] = None,
834
+ custom_packagers: Optional[list[tuple[str, bool]]] = None,
834
835
  default_function_node_selector=None,
835
836
  ):
836
837
  self.repo = None
@@ -1253,7 +1254,11 @@ class MlrunProject(ModelObj):
1253
1254
  raise exc
1254
1255
 
1255
1256
  def get_artifact_uri(
1256
- self, key: str, category: str = "artifact", tag: str = None, iter: int = None
1257
+ self,
1258
+ key: str,
1259
+ category: str = "artifact",
1260
+ tag: Optional[str] = None,
1261
+ iter: Optional[int] = None,
1257
1262
  ) -> str:
1258
1263
  """return the project artifact uri (store://..) from the artifact key
1259
1264
 
@@ -1353,7 +1358,7 @@ class MlrunProject(ModelObj):
1353
1358
  workflow_path: str,
1354
1359
  embed: bool = False,
1355
1360
  engine: Optional[str] = None,
1356
- args_schema: list[EntrypointParam] = None,
1361
+ args_schema: Optional[list[EntrypointParam]] = None,
1357
1362
  handler: Optional[str] = None,
1358
1363
  schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
1359
1364
  ttl: Optional[int] = None,
@@ -1425,8 +1430,8 @@ class MlrunProject(ModelObj):
1425
1430
  self,
1426
1431
  key,
1427
1432
  artifact: typing.Union[str, dict, Artifact] = None,
1428
- target_path: str = None,
1429
- tag: str = None,
1433
+ target_path: Optional[str] = None,
1434
+ tag: Optional[str] = None,
1430
1435
  ):
1431
1436
  """add/set an artifact in the project spec (will be registered on load)
1432
1437
 
@@ -1646,7 +1651,7 @@ class MlrunProject(ModelObj):
1646
1651
  deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
1647
1652
  mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
1648
1653
  ),
1649
- secrets: dict = None,
1654
+ secrets: Optional[dict] = None,
1650
1655
  ):
1651
1656
  """Delete an artifact object in the DB and optionally delete the artifact data
1652
1657
 
@@ -1777,7 +1782,7 @@ class MlrunProject(ModelObj):
1777
1782
  :param key: artifact key or artifact class ()
1778
1783
  :param body: will use the body as the artifact content
1779
1784
  :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)
1785
+ or to a model file data url (e.g. `http://host/path/model.pkl`)
1781
1786
  :param model_dir: path to the local dir holding the model file and extra files
1782
1787
  :param artifact_path: target artifact path (when not using the default)
1783
1788
  to define a subpath under the default location use:
@@ -1953,12 +1958,12 @@ class MlrunProject(ModelObj):
1953
1958
  str,
1954
1959
  mm_app.ModelMonitoringApplicationBase,
1955
1960
  ] = None,
1956
- name: str = None,
1957
- image: str = None,
1961
+ name: Optional[str] = None,
1962
+ image: Optional[str] = None,
1958
1963
  handler=None,
1959
- with_repo: bool = None,
1960
- tag: str = None,
1961
- requirements: typing.Union[str, list[str]] = None,
1964
+ with_repo: Optional[bool] = None,
1965
+ tag: Optional[str] = None,
1966
+ requirements: Optional[typing.Union[str, list[str]]] = None,
1962
1967
  requirements_file: str = "",
1963
1968
  **application_kwargs,
1964
1969
  ) -> mlrun.runtimes.BaseRuntime:
@@ -2015,17 +2020,17 @@ class MlrunProject(ModelObj):
2015
2020
 
2016
2021
  def create_model_monitoring_function(
2017
2022
  self,
2018
- func: str = None,
2023
+ func: Optional[str] = None,
2019
2024
  application_class: typing.Union[
2020
2025
  str,
2021
2026
  mm_app.ModelMonitoringApplicationBase,
2022
2027
  ] = 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,
2028
+ name: Optional[str] = None,
2029
+ image: Optional[str] = None,
2030
+ handler: Optional[str] = None,
2031
+ with_repo: Optional[bool] = None,
2032
+ tag: Optional[str] = None,
2033
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2029
2034
  requirements_file: str = "",
2030
2035
  **application_kwargs,
2031
2036
  ) -> mlrun.runtimes.BaseRuntime:
@@ -2269,7 +2274,7 @@ class MlrunProject(ModelObj):
2269
2274
  delete_stream_function: bool = False,
2270
2275
  delete_histogram_data_drift_app: bool = True,
2271
2276
  delete_user_applications: bool = False,
2272
- user_application_list: list[str] = None,
2277
+ user_application_list: Optional[list[str]] = None,
2273
2278
  ) -> None:
2274
2279
  """
2275
2280
  Disable model monitoring application controller, writer, stream, histogram data drift application
@@ -2329,11 +2334,11 @@ class MlrunProject(ModelObj):
2329
2334
  func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
2330
2335
  name: str = "",
2331
2336
  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,
2337
+ image: Optional[str] = None,
2338
+ handler: Optional[str] = None,
2339
+ with_repo: Optional[bool] = None,
2340
+ tag: Optional[str] = None,
2341
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2337
2342
  requirements_file: str = "",
2338
2343
  ) -> mlrun.runtimes.BaseRuntime:
2339
2344
  """
@@ -2427,11 +2432,11 @@ class MlrunProject(ModelObj):
2427
2432
  func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
2428
2433
  name: str = "",
2429
2434
  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,
2435
+ image: Optional[str] = None,
2436
+ handler: Optional[str] = None,
2437
+ with_repo: Optional[bool] = None,
2438
+ tag: Optional[str] = None,
2439
+ requirements: Optional[typing.Union[str, list[str]]] = None,
2435
2440
  requirements_file: str = "",
2436
2441
  ) -> tuple[str, str, mlrun.runtimes.BaseRuntime, dict]:
2437
2442
  if (
@@ -2654,8 +2659,8 @@ class MlrunProject(ModelObj):
2654
2659
 
2655
2660
  def pull(
2656
2661
  self,
2657
- branch: str = None,
2658
- remote: str = None,
2662
+ branch: Optional[str] = None,
2663
+ remote: Optional[str] = None,
2659
2664
  secrets: Union[SecretsStore, dict] = None,
2660
2665
  ):
2661
2666
  """pull/update sources from git or tar into the context dir
@@ -2768,10 +2773,10 @@ class MlrunProject(ModelObj):
2768
2773
  branch,
2769
2774
  message=None,
2770
2775
  update=True,
2771
- remote: str = None,
2772
- add: list = None,
2773
- author_name: str = None,
2774
- author_email: str = None,
2776
+ remote: Optional[str] = None,
2777
+ add: Optional[list] = None,
2778
+ author_name: Optional[str] = None,
2779
+ author_email: Optional[str] = None,
2775
2780
  secrets: Union[SecretsStore, dict] = None,
2776
2781
  ):
2777
2782
  """update spec and push updates to remote git repo
@@ -2834,7 +2839,7 @@ class MlrunProject(ModelObj):
2834
2839
 
2835
2840
  def sync_functions(
2836
2841
  self,
2837
- names: list = None,
2842
+ names: Optional[list] = None,
2838
2843
  always: bool = True,
2839
2844
  save: bool = False,
2840
2845
  silent: bool = False,
@@ -2978,8 +2983,8 @@ class MlrunProject(ModelObj):
2978
2983
 
2979
2984
  def set_secrets(
2980
2985
  self,
2981
- secrets: dict = None,
2982
- file_path: str = None,
2986
+ secrets: Optional[dict] = None,
2987
+ file_path: Optional[str] = None,
2983
2988
  provider: typing.Union[str, mlrun.common.schemas.SecretProviderName] = None,
2984
2989
  ):
2985
2990
  """
@@ -3056,24 +3061,24 @@ class MlrunProject(ModelObj):
3056
3061
 
3057
3062
  def run(
3058
3063
  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,
3064
+ name: Optional[str] = None,
3065
+ workflow_path: Optional[str] = None,
3066
+ arguments: Optional[dict[str, typing.Any]] = None,
3067
+ artifact_path: Optional[str] = None,
3068
+ workflow_handler: Optional[typing.Union[str, typing.Callable]] = None,
3069
+ namespace: Optional[str] = None,
3065
3070
  sync: bool = False,
3066
3071
  watch: bool = False,
3067
3072
  dirty: bool = False,
3068
- engine: str = None,
3069
- local: bool = None,
3073
+ engine: Optional[str] = None,
3074
+ local: Optional[bool] = None,
3070
3075
  schedule: typing.Union[
3071
3076
  str, mlrun.common.schemas.ScheduleCronTrigger, bool
3072
3077
  ] = None,
3073
- timeout: int = None,
3074
- source: str = None,
3075
- cleanup_ttl: int = None,
3076
- notifications: list[mlrun.model.Notification] = None,
3078
+ timeout: Optional[int] = None,
3079
+ source: Optional[str] = None,
3080
+ cleanup_ttl: Optional[int] = None,
3081
+ notifications: Optional[list[mlrun.model.Notification]] = None,
3077
3082
  workflow_runner_node_selector: typing.Optional[dict[str, str]] = None,
3078
3083
  ) -> _PipelineRunStatus:
3079
3084
  """Run a workflow using kubeflow pipelines
@@ -3280,7 +3285,7 @@ class MlrunProject(ModelObj):
3280
3285
 
3281
3286
  return db.create_project(self.to_dict())
3282
3287
 
3283
- def export(self, filepath=None, include_files: str = None):
3288
+ def export(self, filepath=None, include_files: Optional[str] = None):
3284
3289
  """save the project object into a yaml file or zip archive (default to project.yaml)
3285
3290
 
3286
3291
  By default, the project object is exported to a yaml file, when the filepath suffix is '.zip'
@@ -3388,27 +3393,27 @@ class MlrunProject(ModelObj):
3388
3393
  def run_function(
3389
3394
  self,
3390
3395
  function: typing.Union[str, mlrun.runtimes.BaseRuntime],
3391
- handler: str = None,
3396
+ handler: Optional[str] = None,
3392
3397
  name: str = "",
3393
- params: dict = None,
3394
- hyperparams: dict = None,
3398
+ params: Optional[dict] = None,
3399
+ hyperparams: Optional[dict] = None,
3395
3400
  hyper_param_options: mlrun.model.HyperParamOptions = None,
3396
- inputs: dict = None,
3397
- outputs: list[str] = None,
3401
+ inputs: Optional[dict] = None,
3402
+ outputs: Optional[list[str]] = None,
3398
3403
  workdir: str = "",
3399
- labels: dict = None,
3404
+ labels: Optional[dict] = None,
3400
3405
  base_task: mlrun.model.RunTemplate = None,
3401
3406
  watch: bool = True,
3402
- local: bool = None,
3403
- verbose: bool = None,
3404
- selector: str = None,
3405
- auto_build: bool = None,
3407
+ local: Optional[bool] = None,
3408
+ verbose: Optional[bool] = None,
3409
+ selector: Optional[str] = None,
3410
+ auto_build: Optional[bool] = None,
3406
3411
  schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
3407
- artifact_path: str = None,
3408
- notifications: list[mlrun.model.Notification] = None,
3412
+ artifact_path: Optional[str] = None,
3413
+ notifications: Optional[list[mlrun.model.Notification]] = None,
3409
3414
  returns: Optional[list[Union[str, dict[str, str]]]] = None,
3410
3415
  builder_env: Optional[dict] = None,
3411
- reset_on_run: bool = None,
3416
+ reset_on_run: Optional[bool] = None,
3412
3417
  ) -> typing.Union[mlrun.model.RunObject, PipelineNodeWrapper]:
3413
3418
  """Run a local or remote task as part of a local/kubeflow pipeline
3414
3419
 
@@ -3501,18 +3506,18 @@ class MlrunProject(ModelObj):
3501
3506
  def build_function(
3502
3507
  self,
3503
3508
  function: typing.Union[str, mlrun.runtimes.BaseRuntime],
3504
- with_mlrun: bool = None,
3509
+ with_mlrun: Optional[bool] = None,
3505
3510
  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,
3511
+ image: Optional[str] = None,
3512
+ base_image: Optional[str] = None,
3513
+ commands: Optional[list] = None,
3514
+ secret_name: Optional[str] = None,
3515
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3516
+ mlrun_version_specifier: Optional[str] = None,
3517
+ builder_env: Optional[dict] = None,
3513
3518
  overwrite_build_params: bool = False,
3514
- requirements_file: str = None,
3515
- extra_args: str = None,
3519
+ requirements_file: Optional[str] = None,
3520
+ extra_args: Optional[str] = None,
3516
3521
  force_build: bool = False,
3517
3522
  ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3518
3523
  """deploy ML function, build container with its dependencies
@@ -3557,18 +3562,18 @@ class MlrunProject(ModelObj):
3557
3562
 
3558
3563
  def build_config(
3559
3564
  self,
3560
- image: str = None,
3565
+ image: Optional[str] = None,
3561
3566
  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,
3567
+ with_mlrun: Optional[bool] = None,
3568
+ base_image: Optional[str] = None,
3569
+ commands: Optional[list] = None,
3570
+ secret_name: Optional[str] = None,
3571
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3567
3572
  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,
3573
+ requirements_file: Optional[str] = None,
3574
+ builder_env: Optional[dict] = None,
3575
+ extra_args: Optional[str] = None,
3576
+ source_code_target_dir: Optional[str] = None,
3572
3577
  ):
3573
3578
  """specify builder configuration for the project
3574
3579
 
@@ -3622,19 +3627,19 @@ class MlrunProject(ModelObj):
3622
3627
 
3623
3628
  def build_image(
3624
3629
  self,
3625
- image: str = None,
3630
+ image: Optional[str] = None,
3626
3631
  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,
3632
+ with_mlrun: Optional[bool] = None,
3633
+ base_image: Optional[str] = None,
3634
+ commands: Optional[list] = None,
3635
+ secret_name: Optional[str] = None,
3636
+ requirements: Optional[typing.Union[str, list[str]]] = None,
3637
+ mlrun_version_specifier: Optional[str] = None,
3638
+ builder_env: Optional[dict] = None,
3634
3639
  overwrite_build_params: bool = False,
3635
- requirements_file: str = None,
3636
- extra_args: str = None,
3637
- target_dir: str = None,
3640
+ requirements_file: Optional[str] = None,
3641
+ extra_args: Optional[str] = None,
3642
+ target_dir: Optional[str] = None,
3638
3643
  ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3639
3644
  """Builder docker image for the project, based on the project's build config. Parameters allow to override
3640
3645
  the build config.
@@ -3740,12 +3745,12 @@ class MlrunProject(ModelObj):
3740
3745
  def deploy_function(
3741
3746
  self,
3742
3747
  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,
3748
+ models: Optional[list] = None,
3749
+ env: Optional[dict] = None,
3750
+ tag: Optional[str] = None,
3751
+ verbose: Optional[bool] = None,
3752
+ builder_env: Optional[dict] = None,
3753
+ mock: Optional[bool] = None,
3749
3754
  ) -> typing.Union[DeployStatus, PipelineNodeWrapper]:
3750
3755
  """deploy real-time (nuclio based) functions
3751
3756
 
@@ -3792,15 +3797,15 @@ class MlrunProject(ModelObj):
3792
3797
  self,
3793
3798
  name=None,
3794
3799
  tag=None,
3795
- labels: Optional[Union[dict[str, str], list[str]]] = None,
3800
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3796
3801
  since=None,
3797
3802
  until=None,
3798
- iter: int = None,
3803
+ iter: Optional[int] = None,
3799
3804
  best_iteration: bool = False,
3800
- kind: str = None,
3805
+ kind: Optional[str] = None,
3801
3806
  category: typing.Union[str, mlrun.common.schemas.ArtifactCategories] = None,
3802
- tree: str = None,
3803
- limit: int = None,
3807
+ tree: Optional[str] = None,
3808
+ limit: Optional[int] = None,
3804
3809
  format_: Optional[
3805
3810
  mlrun.common.formatters.ArtifactFormat
3806
3811
  ] = mlrun.common.formatters.ArtifactFormat.full,
@@ -3813,7 +3818,7 @@ class MlrunProject(ModelObj):
3813
3818
  Examples::
3814
3819
 
3815
3820
  # Get latest version of all artifacts in project
3816
- latest_artifacts = project.list_artifacts("", tag="latest")
3821
+ latest_artifacts = project.list_artifacts(tag="latest")
3817
3822
  # check different artifact versions for a specific artifact, return as objects list
3818
3823
  result_versions = project.list_artifacts("results", tag="*").to_objects()
3819
3824
 
@@ -3821,8 +3826,13 @@ class MlrunProject(ModelObj):
3821
3826
  case-sensitive. This means that querying for ``~name`` may return artifacts named
3822
3827
  ``my_Name_1`` or ``surname``.
3823
3828
  :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.
3829
+ :param labels: Filter artifacts by label key-value pairs or key existence. This can be provided as:
3830
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
3831
+ or `{"label": None}` to check for key existence.
3832
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
3833
+ or just `"label"` for key existence.
3834
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
3835
+ the specified key-value pairs or key existence.
3826
3836
  :param since: Not in use in :py:class:`HTTPRunDB`.
3827
3837
  :param until: Not in use in :py:class:`HTTPRunDB`.
3828
3838
  :param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
@@ -3853,17 +3863,80 @@ class MlrunProject(ModelObj):
3853
3863
  limit=limit,
3854
3864
  )
3855
3865
 
3866
+ def paginated_list_artifacts(
3867
+ self,
3868
+ *args,
3869
+ page: Optional[int] = None,
3870
+ page_size: Optional[int] = None,
3871
+ page_token: Optional[str] = None,
3872
+ **kwargs,
3873
+ ) -> tuple[mlrun.lists.ArtifactList, Optional[str]]:
3874
+ """List artifacts with support for pagination and various filtering options.
3875
+
3876
+ This method retrieves a paginated list of artifacts based on the specified filter parameters.
3877
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
3878
+ will return a list of artifacts that match the filtering criteria provided.
3879
+
3880
+ The returned result is an `ArtifactList` (list of dict), use `.to_objects()` to convert it to a list of
3881
+ RunObjects, `.show()` to view graphically in Jupyter, and `.to_df()` to convert to a DataFrame.
3882
+
3883
+ For detailed information about the parameters, refer to the list_artifacts method:
3884
+ See :py:func:`~list_artifacts` for more details.
3885
+
3886
+ Examples::
3887
+
3888
+ # Fetch first page of artifacts with page size of 5
3889
+ artifacts, token = project.paginated_list_artifacts("results", page_size=5)
3890
+ # Fetch next page using the pagination token from the previous response
3891
+ artifacts, token = project.paginated_list_artifacts("results", page_token=token)
3892
+ # Fetch artifacts for a specific page (e.g., page 3)
3893
+ artifacts, token = project.paginated_list_artifacts(
3894
+ "results", page=3, page_size=5
3895
+ )
3896
+
3897
+ # Automatically iterate over all pages without explicitly specifying the page number
3898
+ artifacts = []
3899
+ token = None
3900
+ while True:
3901
+ page_artifacts, token = project.paginated_list_artifacts(
3902
+ page_token=token, page_size=5
3903
+ )
3904
+ artifacts.extend(page_artifacts)
3905
+
3906
+ # If token is None and page_artifacts is empty, we've reached the end (no more artifacts).
3907
+ # If token is None and page_artifacts is not empty, we've fetched the last page of artifacts.
3908
+ if not token:
3909
+ break
3910
+ print(f"Total artifacts retrieved: {len(artifacts)}")
3911
+
3912
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
3913
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
3914
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
3915
+ for the first request.
3916
+
3917
+ :returns: A tuple containing the list of artifacts and an optional `page_token` for pagination.
3918
+ """
3919
+ db = mlrun.db.get_run_db(secrets=self._secrets)
3920
+ return db.paginated_list_artifacts(
3921
+ *args,
3922
+ project=self.metadata.name,
3923
+ page=page,
3924
+ page_size=page_size,
3925
+ page_token=page_token,
3926
+ **kwargs,
3927
+ )
3928
+
3856
3929
  def list_models(
3857
3930
  self,
3858
3931
  name=None,
3859
3932
  tag=None,
3860
- labels: Optional[Union[dict[str, str], list[str]]] = None,
3933
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3861
3934
  since=None,
3862
3935
  until=None,
3863
- iter: int = None,
3936
+ iter: Optional[int] = None,
3864
3937
  best_iteration: bool = False,
3865
- tree: str = None,
3866
- limit: int = None,
3938
+ tree: Optional[str] = None,
3939
+ limit: Optional[int] = None,
3867
3940
  format_: Optional[
3868
3941
  mlrun.common.formatters.ArtifactFormat
3869
3942
  ] = mlrun.common.formatters.ArtifactFormat.full,
@@ -3873,15 +3946,20 @@ class MlrunProject(ModelObj):
3873
3946
  Examples::
3874
3947
 
3875
3948
  # Get latest version of all models in project
3876
- latest_models = project.list_models("", tag="latest")
3949
+ latest_models = project.list_models(tag="latest")
3877
3950
 
3878
3951
 
3879
3952
  :param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
3880
3953
  case-sensitive. This means that querying for ``~name`` may return artifacts named
3881
3954
  ``my_Name_1`` or ``surname``.
3882
3955
  :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.
3956
+ :param labels: Filter model artifacts by label key-value pairs or key existence. This can be provided as:
3957
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
3958
+ or `{"label": None}` to check for key existence.
3959
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
3960
+ or just `"label"` for key existence.
3961
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
3962
+ the specified key-value pairs or key existence.
3885
3963
  :param since: Not in use in :py:class:`HTTPRunDB`.
3886
3964
  :param until: Not in use in :py:class:`HTTPRunDB`.
3887
3965
  :param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
@@ -3903,13 +3981,77 @@ class MlrunProject(ModelObj):
3903
3981
  until=until,
3904
3982
  iter=iter,
3905
3983
  best_iteration=best_iteration,
3906
- kind="model",
3984
+ kind=mlrun.artifacts.model.ModelArtifact.kind,
3907
3985
  tree=tree,
3908
3986
  limit=limit,
3909
3987
  format_=format_,
3910
3988
  ).to_objects()
3911
3989
 
3912
- def list_functions(self, name=None, tag=None, labels=None):
3990
+ def paginated_list_models(
3991
+ self,
3992
+ *args,
3993
+ page: Optional[int] = None,
3994
+ page_size: Optional[int] = None,
3995
+ page_token: Optional[str] = None,
3996
+ **kwargs,
3997
+ ) -> tuple[mlrun.lists.ArtifactList, Optional[str]]:
3998
+ """List models in project with support for pagination and various filtering options.
3999
+
4000
+ This method retrieves a paginated list of artifacts based on the specified filter parameters.
4001
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4002
+ will return a list of artifacts that match the filtering criteria provided.
4003
+
4004
+ For detailed information about the parameters, refer to the list_models method:
4005
+ See :py:func:`~list_models` for more details.
4006
+
4007
+ Examples::
4008
+
4009
+ # Fetch first page of artifacts with page size of 5
4010
+ artifacts, token = project.paginated_list_models("results", page_size=5)
4011
+ # Fetch next page using the pagination token from the previous response
4012
+ artifacts, token = project.paginated_list_models("results", page_token=token)
4013
+ # Fetch artifacts for a specific page (e.g., page 3)
4014
+ artifacts, token = project.paginated_list_models("results", page=3, page_size=5)
4015
+
4016
+ # Automatically iterate over all pages without explicitly specifying the page number
4017
+ artifacts = []
4018
+ token = None
4019
+ while True:
4020
+ page_artifacts, token = project.paginated_list_models(
4021
+ page_token=token, page_size=5
4022
+ )
4023
+ artifacts.extend(page_artifacts)
4024
+
4025
+ # If token is None and page_artifacts is empty, we've reached the end (no more artifacts).
4026
+ # If token is None and page_artifacts is not empty, we've fetched the last page of artifacts.
4027
+ if not token:
4028
+ break
4029
+ print(f"Total artifacts retrieved: {len(artifacts)}")
4030
+
4031
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4032
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4033
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4034
+ for the first request.
4035
+
4036
+ :returns: A tuple containing the list of artifacts and an optional `page_token` for pagination.
4037
+ """
4038
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4039
+ return db.paginated_list_artifacts(
4040
+ *args,
4041
+ project=self.metadata.name,
4042
+ kind=mlrun.artifacts.model.ModelArtifact.kind,
4043
+ page=page,
4044
+ page_size=page_size,
4045
+ page_token=page_token,
4046
+ **kwargs,
4047
+ )
4048
+
4049
+ def list_functions(
4050
+ self,
4051
+ name: Optional[str] = None,
4052
+ tag: Optional[str] = None,
4053
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
4054
+ ):
3913
4055
  """Retrieve a list of functions, filtered by specific criteria.
3914
4056
 
3915
4057
  example::
@@ -3919,7 +4061,13 @@ class MlrunProject(ModelObj):
3919
4061
 
3920
4062
  :param name: Return only functions with a specific name.
3921
4063
  :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.
4064
+ :param labels: Filter functions by label key-value pairs or key existence. This can be provided as:
4065
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4066
+ or `{"label": None}` to check for key existence.
4067
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4068
+ or just `"label"` for key existence.
4069
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4070
+ the specified key-value pairs or key existence.
3923
4071
  :returns: List of function objects.
3924
4072
  """
3925
4073
  db = mlrun.db.get_run_db(secrets=self._secrets)
@@ -3928,11 +4076,72 @@ class MlrunProject(ModelObj):
3928
4076
  # convert dict to function objects
3929
4077
  return [mlrun.new_function(runtime=func) for func in functions]
3930
4078
 
4079
+ def paginated_list_functions(
4080
+ self,
4081
+ *args,
4082
+ page: Optional[int] = None,
4083
+ page_size: Optional[int] = None,
4084
+ page_token: Optional[str] = None,
4085
+ **kwargs,
4086
+ ) -> tuple[list, Optional[str]]:
4087
+ """List functions with support for pagination and various filtering options.
4088
+
4089
+ This method retrieves a paginated list of functions based on the specified filter parameters.
4090
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4091
+ will return a list of functions that match the filtering criteria provided.
4092
+
4093
+ For detailed information about the parameters, refer to the list_functions method:
4094
+ See :py:func:`~list_functions` for more details.
4095
+
4096
+ Examples::
4097
+
4098
+ # Fetch first page of functions with page size of 5
4099
+ functions, token = project.paginated_list_functions(page_size=5)
4100
+ # Fetch next page using the pagination token from the previous response
4101
+ functions, token = project.paginated_list_functions(page_token=token)
4102
+ # Fetch functions for a specific page (e.g., page 3)
4103
+ functions, token = project.paginated_list_functions(page=3, page_size=5)
4104
+
4105
+ # Automatically iterate over all pages without explicitly specifying the page number
4106
+ functions = []
4107
+ token = None
4108
+ while True:
4109
+ page_functions, token = project.paginated_list_functions(
4110
+ page_token=token, page_size=5
4111
+ )
4112
+ functions.extend(page_functions)
4113
+
4114
+ # If token is None and page_functions is empty, we've reached the end (no more functions).
4115
+ # If token is None and page_functions is not empty, we've fetched the last page of functions.
4116
+ if not token:
4117
+ break
4118
+ print(f"Total functions retrieved: {len(functions)}")
4119
+
4120
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4121
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4122
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4123
+ for the first request.
4124
+
4125
+ :returns: A tuple containing the list of functions and an optional `page_token` for pagination.
4126
+ """
4127
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4128
+ functions, token = db.paginated_list_functions(
4129
+ *args,
4130
+ project=self.metadata.name,
4131
+ page=page,
4132
+ page_size=page_size,
4133
+ page_token=page_token,
4134
+ **kwargs,
4135
+ )
4136
+ if functions:
4137
+ # convert dict to function objects
4138
+ return [mlrun.new_function(runtime=func) for func in functions], token
4139
+
3931
4140
  def list_model_monitoring_functions(
3932
4141
  self,
3933
4142
  name: Optional[str] = None,
3934
4143
  tag: Optional[str] = None,
3935
- labels: Optional[list[str]] = None,
4144
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3936
4145
  ) -> Optional[list]:
3937
4146
  """
3938
4147
  Retrieve a list of all the model monitoring functions.
@@ -3942,8 +4151,13 @@ class MlrunProject(ModelObj):
3942
4151
 
3943
4152
  :param name: Return only functions with a specific name.
3944
4153
  :param tag: Return function versions with specific tags.
3945
- :param labels: Return functions that have specific labels assigned to them.
3946
-
4154
+ :param labels: Filter functions by label key-value pairs or key existence. This can be provided as:
4155
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4156
+ or `{"label": None}` to check for key existence.
4157
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4158
+ or just `"label"` for key existence.
4159
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4160
+ the specified key-value pairs or key existence.
3947
4161
  :returns: List of function objects.
3948
4162
  """
3949
4163
 
@@ -3960,7 +4174,7 @@ class MlrunProject(ModelObj):
3960
4174
  self,
3961
4175
  name: Optional[str] = None,
3962
4176
  uid: Optional[Union[str, list[str]]] = None,
3963
- labels: Optional[Union[str, list[str]]] = None,
4177
+ labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3964
4178
  state: Optional[
3965
4179
  mlrun.common.runtimes.constants.RunStates
3966
4180
  ] = None, # Backward compatibility
@@ -3995,9 +4209,13 @@ class MlrunProject(ModelObj):
3995
4209
 
3996
4210
  :param name: Name of the run to retrieve.
3997
4211
  :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").
4212
+ :param labels: Filter runs by label key-value pairs or key existence. This can be provided as:
4213
+ - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
4214
+ or `{"label": None}` to check for key existence.
4215
+ - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
4216
+ or just `"label"` for key existence.
4217
+ - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
4218
+ the specified key-value pairs or key existence.
4001
4219
  :param state: Deprecated - List only runs whose state is specified.
4002
4220
  :param states: List only runs whose state is one of the provided states.
4003
4221
  :param sort: Whether to sort the result according to their start time. Otherwise, results will be
@@ -4036,6 +4254,68 @@ class MlrunProject(ModelObj):
4036
4254
  **kwargs,
4037
4255
  )
4038
4256
 
4257
+ def paginated_list_runs(
4258
+ self,
4259
+ *args,
4260
+ page: Optional[int] = None,
4261
+ page_size: Optional[int] = None,
4262
+ page_token: Optional[str] = None,
4263
+ **kwargs,
4264
+ ) -> tuple[mlrun.lists.RunList, Optional[str]]:
4265
+ """List runs with support for pagination and various filtering options.
4266
+
4267
+ This method retrieves a paginated list of runs based on the specified filter parameters.
4268
+ Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
4269
+ will return a list of runs that match the filtering criteria provided.
4270
+
4271
+ The returned result is a `` (list of dict), use `.to_objects()` to convert it to a list of RunObjects,
4272
+ `.show()` to view graphically in Jupyter, `.to_df()` to convert to a DataFrame, and `compare()` to
4273
+ generate comparison table and PCP plot.
4274
+
4275
+ For detailed information about the parameters, refer to the list_runs method:
4276
+ See :py:func:`~list_runs` for more details.
4277
+
4278
+ Examples::
4279
+
4280
+ # Fetch first page of runs with page size of 5
4281
+ runs, token = project.paginated_list_runs(page_size=5)
4282
+ # Fetch next page using the pagination token from the previous response
4283
+ runs, token = project.paginated_list_runs(page_token=token)
4284
+ # Fetch runs for a specific page (e.g., page 3)
4285
+ runs, token = project.paginated_list_runs(page=3, page_size=5)
4286
+
4287
+ # Automatically iterate over all pages without explicitly specifying the page number
4288
+ runs = []
4289
+ token = None
4290
+ while True:
4291
+ page_runs, token = project.paginated_list_runs(
4292
+ page_token=token, page_size=5
4293
+ )
4294
+ runs.extend(page_runs)
4295
+
4296
+ # If token is None and page_runs is empty, we've reached the end (no more runs).
4297
+ # If token is None and page_runs is not empty, we've fetched the last page of runs.
4298
+ if not token:
4299
+ break
4300
+ print(f"Total runs retrieved: {len(runs)}")
4301
+
4302
+ :param page: The page number to retrieve. If not provided, the next page will be retrieved.
4303
+ :param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
4304
+ :param page_token: A pagination token used to retrieve the next page of results. Should not be provided
4305
+ for the first request.
4306
+
4307
+ :returns: A tuple containing the list of runs and an optional `page_token` for pagination.
4308
+ """
4309
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4310
+ return db.paginated_list_runs(
4311
+ *args,
4312
+ project=self.metadata.name,
4313
+ page=page,
4314
+ page_size=page_size,
4315
+ page_token=page_token,
4316
+ **kwargs,
4317
+ )
4318
+
4039
4319
  def register_datastore_profile(self, profile: DatastoreProfile):
4040
4320
  private_body = DatastoreProfile2Json.get_json_private(profile)
4041
4321
  public_body = DatastoreProfile2Json.get_json_public(profile)
@@ -4188,13 +4468,17 @@ class MlrunProject(ModelObj):
4188
4468
  mlrun.db.get_run_db().delete_api_gateway(name=name, project=self.name)
4189
4469
 
4190
4470
  def store_alert_config(
4191
- self, alert_data: AlertConfig, alert_name: typing.Optional[str] = None
4471
+ self,
4472
+ alert_data: AlertConfig,
4473
+ alert_name: typing.Optional[str] = None,
4474
+ force_reset: bool = False,
4192
4475
  ) -> AlertConfig:
4193
4476
  """
4194
4477
  Create/modify an alert.
4195
4478
 
4196
4479
  :param alert_data: The data of the alert.
4197
4480
  :param alert_name: The name of the alert.
4481
+ :param force_reset: If True and the alert already exists, the alert would be reset.
4198
4482
  :return: the created/modified alert.
4199
4483
  """
4200
4484
  if not alert_data:
@@ -4208,7 +4492,9 @@ class MlrunProject(ModelObj):
4208
4492
  project=alert_data.project,
4209
4493
  )
4210
4494
  alert_data.project = self.metadata.name
4211
- return db.store_alert_config(alert_name, alert_data, project=self.metadata.name)
4495
+ return db.store_alert_config(
4496
+ alert_name, alert_data, project=self.metadata.name, force_reset=force_reset
4497
+ )
4212
4498
 
4213
4499
  def get_alert_config(self, alert_name: str) -> AlertConfig:
4214
4500
  """
@@ -4230,7 +4516,7 @@ class MlrunProject(ModelObj):
4230
4516
  return db.list_alerts_configs(self.metadata.name)
4231
4517
 
4232
4518
  def delete_alert_config(
4233
- self, alert_data: AlertConfig = None, alert_name: str = None
4519
+ self, alert_data: AlertConfig = None, alert_name: Optional[str] = None
4234
4520
  ):
4235
4521
  """
4236
4522
  Delete an alert.
@@ -4250,7 +4536,7 @@ class MlrunProject(ModelObj):
4250
4536
  db.delete_alert_config(alert_name, self.metadata.name)
4251
4537
 
4252
4538
  def reset_alert_config(
4253
- self, alert_data: AlertConfig = None, alert_name: str = None
4539
+ self, alert_data: AlertConfig = None, alert_name: Optional[str] = None
4254
4540
  ):
4255
4541
  """
4256
4542
  Reset an alert.
@@ -4292,8 +4578,8 @@ class MlrunProject(ModelObj):
4292
4578
  self,
4293
4579
  action: Callable,
4294
4580
  remote: str,
4295
- args: list = None,
4296
- kwargs: dict = None,
4581
+ args: Optional[list] = None,
4582
+ kwargs: Optional[dict] = None,
4297
4583
  secrets: Union[SecretsStore, dict] = None,
4298
4584
  ):
4299
4585
  """Run an arbitrary Git routine while the remote is enriched with secrets
@@ -4370,7 +4656,7 @@ class MlrunProject(ModelObj):
4370
4656
  def _resolve_artifact_producer(
4371
4657
  self,
4372
4658
  artifact: typing.Union[str, Artifact],
4373
- project_producer_tag: str = None,
4659
+ project_producer_tag: Optional[str] = None,
4374
4660
  ) -> tuple[ArtifactProducer, bool]:
4375
4661
  """
4376
4662
  Resolve the artifact producer of the given artifact.
@@ -4421,7 +4707,7 @@ class MlrunProject(ModelObj):
4421
4707
  def _resolve_existing_artifact(
4422
4708
  self,
4423
4709
  item: typing.Union[str, Artifact],
4424
- tag: str = None,
4710
+ tag: Optional[str] = None,
4425
4711
  ) -> typing.Optional[Artifact]:
4426
4712
  """
4427
4713
  Check if there is and existing artifact with the given item and tag.