mlrun 1.6.4rc2__py3-none-any.whl → 1.7.0rc20__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (291) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +26 -112
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +5 -4
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +46 -257
  8. mlrun/artifacts/dataset.py +11 -192
  9. mlrun/artifacts/manager.py +47 -48
  10. mlrun/artifacts/model.py +31 -159
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +69 -0
  13. mlrun/common/db/sql_session.py +2 -3
  14. mlrun/common/formatters/__init__.py +19 -0
  15. mlrun/common/formatters/artifact.py +21 -0
  16. mlrun/common/formatters/base.py +78 -0
  17. mlrun/common/formatters/function.py +41 -0
  18. mlrun/common/formatters/pipeline.py +53 -0
  19. mlrun/common/formatters/project.py +51 -0
  20. mlrun/common/helpers.py +1 -2
  21. mlrun/common/model_monitoring/helpers.py +9 -5
  22. mlrun/{runtimes → common/runtimes}/constants.py +37 -9
  23. mlrun/common/schemas/__init__.py +24 -4
  24. mlrun/common/schemas/alert.py +203 -0
  25. mlrun/common/schemas/api_gateway.py +148 -0
  26. mlrun/common/schemas/artifact.py +18 -8
  27. mlrun/common/schemas/auth.py +11 -5
  28. mlrun/common/schemas/background_task.py +1 -1
  29. mlrun/common/schemas/client_spec.py +4 -1
  30. mlrun/common/schemas/feature_store.py +16 -16
  31. mlrun/common/schemas/frontend_spec.py +8 -7
  32. mlrun/common/schemas/function.py +5 -1
  33. mlrun/common/schemas/hub.py +11 -18
  34. mlrun/common/schemas/memory_reports.py +2 -2
  35. mlrun/common/schemas/model_monitoring/__init__.py +18 -3
  36. mlrun/common/schemas/model_monitoring/constants.py +83 -26
  37. mlrun/common/schemas/model_monitoring/grafana.py +13 -9
  38. mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
  39. mlrun/common/schemas/notification.py +4 -4
  40. mlrun/common/schemas/object.py +2 -2
  41. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  42. mlrun/common/schemas/pipeline.py +1 -10
  43. mlrun/common/schemas/project.py +24 -23
  44. mlrun/common/schemas/runtime_resource.py +8 -12
  45. mlrun/common/schemas/schedule.py +3 -3
  46. mlrun/common/schemas/tag.py +1 -2
  47. mlrun/common/schemas/workflow.py +2 -2
  48. mlrun/common/types.py +7 -1
  49. mlrun/config.py +54 -17
  50. mlrun/data_types/to_pandas.py +10 -12
  51. mlrun/datastore/__init__.py +5 -8
  52. mlrun/datastore/alibaba_oss.py +130 -0
  53. mlrun/datastore/azure_blob.py +17 -5
  54. mlrun/datastore/base.py +62 -39
  55. mlrun/datastore/datastore.py +28 -9
  56. mlrun/datastore/datastore_profile.py +146 -20
  57. mlrun/datastore/filestore.py +0 -1
  58. mlrun/datastore/google_cloud_storage.py +6 -2
  59. mlrun/datastore/hdfs.py +56 -0
  60. mlrun/datastore/inmem.py +2 -2
  61. mlrun/datastore/redis.py +6 -2
  62. mlrun/datastore/s3.py +9 -0
  63. mlrun/datastore/snowflake_utils.py +43 -0
  64. mlrun/datastore/sources.py +201 -96
  65. mlrun/datastore/spark_utils.py +1 -2
  66. mlrun/datastore/store_resources.py +7 -7
  67. mlrun/datastore/targets.py +358 -104
  68. mlrun/datastore/utils.py +72 -58
  69. mlrun/datastore/v3io.py +5 -1
  70. mlrun/db/base.py +185 -35
  71. mlrun/db/factory.py +1 -1
  72. mlrun/db/httpdb.py +614 -179
  73. mlrun/db/nopdb.py +210 -26
  74. mlrun/errors.py +12 -1
  75. mlrun/execution.py +41 -24
  76. mlrun/feature_store/__init__.py +0 -2
  77. mlrun/feature_store/api.py +40 -72
  78. mlrun/feature_store/common.py +1 -1
  79. mlrun/feature_store/feature_set.py +76 -55
  80. mlrun/feature_store/feature_vector.py +28 -30
  81. mlrun/feature_store/ingestion.py +7 -6
  82. mlrun/feature_store/retrieval/base.py +16 -11
  83. mlrun/feature_store/retrieval/conversion.py +11 -13
  84. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  85. mlrun/feature_store/retrieval/job.py +9 -3
  86. mlrun/feature_store/retrieval/local_merger.py +2 -0
  87. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  88. mlrun/feature_store/steps.py +37 -34
  89. mlrun/features.py +9 -20
  90. mlrun/frameworks/_common/artifacts_library.py +9 -9
  91. mlrun/frameworks/_common/mlrun_interface.py +5 -5
  92. mlrun/frameworks/_common/model_handler.py +48 -48
  93. mlrun/frameworks/_common/plan.py +2 -3
  94. mlrun/frameworks/_common/producer.py +3 -4
  95. mlrun/frameworks/_common/utils.py +5 -5
  96. mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
  97. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
  98. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
  99. mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
  100. mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
  101. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
  102. mlrun/frameworks/_ml_common/model_handler.py +24 -24
  103. mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
  104. mlrun/frameworks/_ml_common/plan.py +1 -1
  105. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
  106. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
  107. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  108. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
  109. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  110. mlrun/frameworks/_ml_common/utils.py +4 -4
  111. mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
  112. mlrun/frameworks/huggingface/model_server.py +4 -4
  113. mlrun/frameworks/lgbm/__init__.py +33 -33
  114. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  115. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
  116. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
  117. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
  118. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
  119. mlrun/frameworks/lgbm/model_handler.py +10 -10
  120. mlrun/frameworks/lgbm/model_server.py +6 -6
  121. mlrun/frameworks/lgbm/utils.py +5 -5
  122. mlrun/frameworks/onnx/dataset.py +8 -8
  123. mlrun/frameworks/onnx/mlrun_interface.py +3 -3
  124. mlrun/frameworks/onnx/model_handler.py +6 -6
  125. mlrun/frameworks/onnx/model_server.py +7 -7
  126. mlrun/frameworks/parallel_coordinates.py +4 -3
  127. mlrun/frameworks/pytorch/__init__.py +18 -18
  128. mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
  129. mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
  130. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
  131. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
  132. mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
  133. mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
  134. mlrun/frameworks/pytorch/model_handler.py +17 -17
  135. mlrun/frameworks/pytorch/model_server.py +7 -7
  136. mlrun/frameworks/sklearn/__init__.py +13 -13
  137. mlrun/frameworks/sklearn/estimator.py +4 -4
  138. mlrun/frameworks/sklearn/metrics_library.py +14 -14
  139. mlrun/frameworks/sklearn/mlrun_interface.py +3 -6
  140. mlrun/frameworks/sklearn/model_handler.py +2 -2
  141. mlrun/frameworks/tf_keras/__init__.py +10 -7
  142. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
  143. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
  144. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
  145. mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
  146. mlrun/frameworks/tf_keras/model_handler.py +14 -14
  147. mlrun/frameworks/tf_keras/model_server.py +6 -6
  148. mlrun/frameworks/xgboost/__init__.py +13 -13
  149. mlrun/frameworks/xgboost/model_handler.py +6 -6
  150. mlrun/k8s_utils.py +14 -16
  151. mlrun/launcher/__init__.py +1 -1
  152. mlrun/launcher/base.py +16 -15
  153. mlrun/launcher/client.py +8 -6
  154. mlrun/launcher/factory.py +1 -1
  155. mlrun/launcher/local.py +17 -11
  156. mlrun/launcher/remote.py +16 -10
  157. mlrun/lists.py +7 -6
  158. mlrun/model.py +238 -73
  159. mlrun/model_monitoring/__init__.py +1 -1
  160. mlrun/model_monitoring/api.py +138 -315
  161. mlrun/model_monitoring/application.py +5 -296
  162. mlrun/model_monitoring/applications/__init__.py +24 -0
  163. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  164. mlrun/model_monitoring/applications/base.py +282 -0
  165. mlrun/model_monitoring/applications/context.py +214 -0
  166. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  167. mlrun/model_monitoring/applications/histogram_data_drift.py +349 -0
  168. mlrun/model_monitoring/applications/results.py +99 -0
  169. mlrun/model_monitoring/controller.py +104 -84
  170. mlrun/model_monitoring/controller_handler.py +13 -5
  171. mlrun/model_monitoring/db/__init__.py +18 -0
  172. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  173. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  174. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +64 -40
  175. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  176. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  177. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  178. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  179. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  180. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  181. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  182. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +310 -165
  183. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  184. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  185. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  186. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  187. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  188. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  189. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  190. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  191. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  192. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  193. mlrun/model_monitoring/evidently_application.py +6 -118
  194. mlrun/model_monitoring/features_drift_table.py +134 -106
  195. mlrun/model_monitoring/helpers.py +127 -28
  196. mlrun/model_monitoring/metrics/__init__.py +13 -0
  197. mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
  198. mlrun/model_monitoring/model_endpoint.py +3 -2
  199. mlrun/model_monitoring/prometheus.py +1 -4
  200. mlrun/model_monitoring/stream_processing.py +62 -231
  201. mlrun/model_monitoring/tracking_policy.py +9 -2
  202. mlrun/model_monitoring/writer.py +152 -124
  203. mlrun/package/__init__.py +6 -6
  204. mlrun/package/context_handler.py +5 -5
  205. mlrun/package/packager.py +7 -7
  206. mlrun/package/packagers/default_packager.py +6 -6
  207. mlrun/package/packagers/numpy_packagers.py +15 -15
  208. mlrun/package/packagers/pandas_packagers.py +5 -5
  209. mlrun/package/packagers/python_standard_library_packagers.py +10 -10
  210. mlrun/package/packagers_manager.py +19 -23
  211. mlrun/package/utils/_formatter.py +6 -6
  212. mlrun/package/utils/_pickler.py +2 -2
  213. mlrun/package/utils/_supported_format.py +4 -4
  214. mlrun/package/utils/log_hint_utils.py +2 -2
  215. mlrun/package/utils/type_hint_utils.py +4 -9
  216. mlrun/platforms/__init__.py +11 -10
  217. mlrun/platforms/iguazio.py +24 -203
  218. mlrun/projects/operations.py +35 -21
  219. mlrun/projects/pipelines.py +68 -99
  220. mlrun/projects/project.py +830 -266
  221. mlrun/render.py +3 -11
  222. mlrun/run.py +162 -166
  223. mlrun/runtimes/__init__.py +62 -7
  224. mlrun/runtimes/base.py +39 -32
  225. mlrun/runtimes/daskjob.py +8 -8
  226. mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
  227. mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
  228. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  229. mlrun/runtimes/funcdoc.py +0 -28
  230. mlrun/runtimes/function_reference.py +1 -1
  231. mlrun/runtimes/kubejob.py +28 -122
  232. mlrun/runtimes/local.py +6 -3
  233. mlrun/runtimes/mpijob/__init__.py +0 -20
  234. mlrun/runtimes/mpijob/abstract.py +9 -10
  235. mlrun/runtimes/mpijob/v1.py +1 -1
  236. mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
  237. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  238. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  239. mlrun/runtimes/nuclio/application/application.py +523 -0
  240. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  241. mlrun/runtimes/{function.py → nuclio/function.py} +112 -73
  242. mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
  243. mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
  244. mlrun/runtimes/pod.py +286 -88
  245. mlrun/runtimes/remotesparkjob.py +2 -2
  246. mlrun/runtimes/sparkjob/spark3job.py +51 -34
  247. mlrun/runtimes/utils.py +7 -75
  248. mlrun/secrets.py +9 -5
  249. mlrun/serving/remote.py +2 -7
  250. mlrun/serving/routers.py +13 -10
  251. mlrun/serving/server.py +22 -26
  252. mlrun/serving/states.py +99 -25
  253. mlrun/serving/utils.py +3 -3
  254. mlrun/serving/v1_serving.py +6 -7
  255. mlrun/serving/v2_serving.py +59 -20
  256. mlrun/track/tracker.py +2 -1
  257. mlrun/track/tracker_manager.py +3 -3
  258. mlrun/track/trackers/mlflow_tracker.py +1 -2
  259. mlrun/utils/async_http.py +5 -7
  260. mlrun/utils/azure_vault.py +1 -1
  261. mlrun/utils/clones.py +1 -2
  262. mlrun/utils/condition_evaluator.py +3 -3
  263. mlrun/utils/db.py +3 -3
  264. mlrun/utils/helpers.py +183 -197
  265. mlrun/utils/http.py +2 -5
  266. mlrun/utils/logger.py +76 -14
  267. mlrun/utils/notifications/notification/__init__.py +17 -12
  268. mlrun/utils/notifications/notification/base.py +14 -2
  269. mlrun/utils/notifications/notification/console.py +2 -0
  270. mlrun/utils/notifications/notification/git.py +3 -1
  271. mlrun/utils/notifications/notification/ipython.py +3 -1
  272. mlrun/utils/notifications/notification/slack.py +101 -21
  273. mlrun/utils/notifications/notification/webhook.py +11 -1
  274. mlrun/utils/notifications/notification_pusher.py +155 -30
  275. mlrun/utils/retryer.py +208 -0
  276. mlrun/utils/singleton.py +1 -1
  277. mlrun/utils/v3io_clients.py +2 -4
  278. mlrun/utils/version/version.json +2 -2
  279. mlrun/utils/version/version.py +2 -6
  280. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
  281. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  282. mlrun/kfpops.py +0 -868
  283. mlrun/model_monitoring/batch.py +0 -1095
  284. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  285. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
  286. mlrun/platforms/other.py +0 -306
  287. mlrun-1.6.4rc2.dist-info/RECORD +0 -314
  288. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  289. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
  290. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  291. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.py CHANGED
@@ -11,28 +11,35 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  import enum
15
16
  import http
16
17
  import re
17
- import tempfile
18
18
  import time
19
19
  import traceback
20
20
  import typing
21
21
  import warnings
22
+ from copy import deepcopy
22
23
  from datetime import datetime, timedelta
23
24
  from os import path, remove
24
- from typing import Dict, List, Optional, Union
25
+ from typing import Optional, Union
25
26
  from urllib.parse import urlparse
26
27
 
27
- import kfp
28
28
  import requests
29
29
  import semver
30
+ from mlrun_pipelines.utils import compile_pipeline
30
31
 
31
32
  import mlrun
33
+ import mlrun.common.formatters
34
+ import mlrun.common.runtimes
32
35
  import mlrun.common.schemas
36
+ import mlrun.common.types
33
37
  import mlrun.model_monitoring.model_endpoint
34
38
  import mlrun.platforms
35
39
  import mlrun.projects
40
+ import mlrun.runtimes.nuclio.api_gateway
41
+ import mlrun.utils
42
+ from mlrun.alerts.alert import AlertConfig
36
43
  from mlrun.db.auth_utils import OAuthClientIDTokenProvider, StaticTokenProvider
37
44
  from mlrun.errors import MLRunInvalidArgumentError, err_to_str
38
45
 
@@ -46,7 +53,6 @@ from ..utils import (
46
53
  datetime_to_iso,
47
54
  dict_to_json,
48
55
  logger,
49
- new_pipe_metadata,
50
56
  normalize_name,
51
57
  version,
52
58
  )
@@ -191,7 +197,7 @@ class HTTPRunDB(RunDBInterface):
191
197
  headers=None,
192
198
  timeout=45,
193
199
  version=None,
194
- ):
200
+ ) -> requests.Response:
195
201
  """Perform a direct REST API call on the :py:mod:`mlrun` API server.
196
202
 
197
203
  Caution:
@@ -209,7 +215,7 @@ class HTTPRunDB(RunDBInterface):
209
215
  :param version: API version to use, None (the default) will mean to use the default value from config,
210
216
  for un-versioned api set an empty string.
211
217
 
212
- :return: Python HTTP response object
218
+ :return: `requests.Response` HTTP response object
213
219
  """
214
220
  url = self.get_base_api_url(path, version)
215
221
  kw = {
@@ -292,6 +298,68 @@ class HTTPRunDB(RunDBInterface):
292
298
 
293
299
  return response
294
300
 
301
+ def paginated_api_call(
302
+ self,
303
+ method,
304
+ path,
305
+ error=None,
306
+ params=None,
307
+ body=None,
308
+ json=None,
309
+ headers=None,
310
+ timeout=45,
311
+ version=None,
312
+ ) -> typing.Generator[requests.Response, None, None]:
313
+ """
314
+ Calls the api with pagination, yielding each page of the response
315
+ """
316
+
317
+ def _api_call(_params):
318
+ return self.api_call(
319
+ method=method,
320
+ path=path,
321
+ error=error,
322
+ params=_params,
323
+ body=body,
324
+ json=json,
325
+ headers=headers,
326
+ timeout=timeout,
327
+ version=version,
328
+ )
329
+
330
+ first_page_params = deepcopy(params) or {}
331
+ first_page_params["page"] = 1
332
+ first_page_params["page-size"] = config.httpdb.pagination.default_page_size
333
+ response = _api_call(first_page_params)
334
+ page_token = response.json().get("pagination", {}).get("page-token")
335
+ if not page_token:
336
+ yield response
337
+ return
338
+
339
+ params_with_page_token = deepcopy(params) or {}
340
+ params_with_page_token["page-token"] = page_token
341
+ while page_token:
342
+ yield response
343
+ try:
344
+ response = _api_call(params_with_page_token)
345
+ except mlrun.errors.MLRunNotFoundError:
346
+ # pagination token expired
347
+ break
348
+
349
+ page_token = response.json().get("pagination", {}).get("page-token", None)
350
+
351
+ @staticmethod
352
+ def process_paginated_responses(
353
+ responses: typing.Generator[requests.Response, None, None], key: str = "data"
354
+ ) -> list[typing.Any]:
355
+ """
356
+ Processes the paginated responses and returns the combined data
357
+ """
358
+ data = []
359
+ for response in responses:
360
+ data.extend(response.json().get(key, []))
361
+ return data
362
+
295
363
  def _init_session(self, retry_on_post: bool = False):
296
364
  return mlrun.utils.HTTPSessionWithRetry(
297
365
  retry_on_exception=config.httpdb.retry_api_call_on_exception
@@ -324,7 +392,7 @@ class HTTPRunDB(RunDBInterface):
324
392
 
325
393
  For example::
326
394
 
327
- config.dbpath = config.dbpath or 'http://mlrun-api:8080'
395
+ config.dbpath = config.dbpath or "http://mlrun-api:8080"
328
396
  db = get_run_db().connect()
329
397
  """
330
398
  # hack to allow unit tests to instantiate HTTPRunDB without a real server behind
@@ -464,6 +532,10 @@ class HTTPRunDB(RunDBInterface):
464
532
  server_cfg.get("model_endpoint_monitoring_endpoint_store_connection")
465
533
  or config.model_endpoint_monitoring.endpoint_store_connection
466
534
  )
535
+ config.model_endpoint_monitoring.tsdb_connection = (
536
+ server_cfg.get("model_monitoring_tsdb_connection")
537
+ or config.model_endpoint_monitoring.tsdb_connection
538
+ )
467
539
  config.packagers = server_cfg.get("packagers") or config.packagers
468
540
  server_data_prefixes = server_cfg.get("feature_store_data_prefixes") or {}
469
541
  for prefix in ["default", "nosql", "redisnosql"]:
@@ -472,6 +544,11 @@ class HTTPRunDB(RunDBInterface):
472
544
  setattr(
473
545
  config.feature_store.data_prefixes, prefix, server_prefix_value
474
546
  )
547
+ config.feature_store.default_targets = (
548
+ server_cfg.get("feature_store_default_targets")
549
+ or config.feature_store.default_targets
550
+ )
551
+ config.alerts.mode = server_cfg.get("alerts_mode") or config.alerts.mode
475
552
 
476
553
  except Exception as exc:
477
554
  logger.warning(
@@ -518,7 +595,7 @@ class HTTPRunDB(RunDBInterface):
518
595
  if offset < 0:
519
596
  raise MLRunInvalidArgumentError("Offset cannot be negative")
520
597
  if size is None:
521
- size = int(config.httpdb.logs.pull_logs_default_size_limit)
598
+ size = int(mlrun.mlconf.httpdb.logs.pull_logs_default_size_limit)
522
599
  elif size == -1:
523
600
  logger.warning(
524
601
  "Retrieving all logs. This may be inefficient and can result in a large log."
@@ -564,33 +641,35 @@ class HTTPRunDB(RunDBInterface):
564
641
 
565
642
  state, text = self.get_log(uid, project, offset=offset)
566
643
  if text:
567
- print(text.decode(errors=config.httpdb.logs.decode.errors))
644
+ print(text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors))
568
645
  nil_resp = 0
569
646
  while True:
570
647
  offset += len(text)
571
648
  # if we get 3 nil responses in a row, increase the sleep time to 10 seconds
572
649
  # TODO: refactor this to use a conditional backoff mechanism
573
650
  if nil_resp < 3:
574
- time.sleep(int(config.httpdb.logs.pull_logs_default_interval))
651
+ time.sleep(int(mlrun.mlconf.httpdb.logs.pull_logs_default_interval))
575
652
  else:
576
653
  time.sleep(
577
- int(config.httpdb.logs.pull_logs_backoff_no_logs_default_interval)
654
+ int(
655
+ mlrun.mlconf.httpdb.logs.pull_logs_backoff_no_logs_default_interval
656
+ )
578
657
  )
579
658
  state, text = self.get_log(uid, project, offset=offset)
580
659
  if text:
581
660
  nil_resp = 0
582
661
  print(
583
- text.decode(errors=config.httpdb.logs.decode.errors),
662
+ text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors),
584
663
  end="",
585
664
  )
586
665
  else:
587
666
  nil_resp += 1
588
667
 
589
668
  if watch and state in [
590
- mlrun.runtimes.constants.RunStates.pending,
591
- mlrun.runtimes.constants.RunStates.running,
592
- mlrun.runtimes.constants.RunStates.created,
593
- mlrun.runtimes.constants.RunStates.aborting,
669
+ mlrun.common.runtimes.constants.RunStates.pending,
670
+ mlrun.common.runtimes.constants.RunStates.running,
671
+ mlrun.common.runtimes.constants.RunStates.created,
672
+ mlrun.common.runtimes.constants.RunStates.aborting,
594
673
  ]:
595
674
  continue
596
675
  else:
@@ -676,10 +755,13 @@ class HTTPRunDB(RunDBInterface):
676
755
  def list_runs(
677
756
  self,
678
757
  name: Optional[str] = None,
679
- uid: Optional[Union[str, List[str]]] = None,
758
+ uid: Optional[Union[str, list[str]]] = None,
680
759
  project: Optional[str] = None,
681
- labels: Optional[Union[str, List[str]]] = None,
682
- state: Optional[str] = None,
760
+ labels: Optional[Union[str, list[str]]] = None,
761
+ state: Optional[
762
+ mlrun.common.runtimes.constants.RunStates
763
+ ] = None, # Backward compatibility
764
+ states: typing.Optional[list[mlrun.common.runtimes.constants.RunStates]] = None,
683
765
  sort: bool = True,
684
766
  last: int = 0,
685
767
  iter: bool = False,
@@ -704,9 +786,11 @@ class HTTPRunDB(RunDBInterface):
704
786
 
705
787
  Example::
706
788
 
707
- runs = db.list_runs(name='download', project='iris', labels=['owner=admin', 'kind=job'])
789
+ runs = db.list_runs(
790
+ name="download", project="iris", labels=["owner=admin", "kind=job"]
791
+ )
708
792
  # If running in Jupyter, can use the .show() function to display the results
709
- db.list_runs(name='', project=project_name).show()
793
+ db.list_runs(name="", project=project_name).show()
710
794
 
711
795
 
712
796
  :param name: Name of the run to retrieve.
@@ -715,7 +799,8 @@ class HTTPRunDB(RunDBInterface):
715
799
  :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
716
800
  of a label (i.e. list("key=value")) or by looking for the existence of a given
717
801
  key (i.e. "key").
718
- :param state: List only runs whose state is specified.
802
+ :param state: Deprecated - List only runs whose state is specified (will be removed in 1.9.0)
803
+ :param states: List only runs whose state is one of the provided states.
719
804
  :param sort: Whether to sort the result according to their start time. Otherwise, results will be
720
805
  returned by their internal order in the DB (order will not be guaranteed).
721
806
  :param last: Deprecated - currently not used (will be removed in 1.8.0).
@@ -751,11 +836,19 @@ class HTTPRunDB(RunDBInterface):
751
836
  FutureWarning,
752
837
  )
753
838
 
839
+ if state:
840
+ # TODO: Remove this in 1.9.0
841
+ warnings.warn(
842
+ "'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
843
+ FutureWarning,
844
+ )
845
+
754
846
  if (
755
847
  not name
756
848
  and not uid
757
849
  and not labels
758
850
  and not state
851
+ and not states
759
852
  and not last
760
853
  and not start_time_from
761
854
  and not start_time_to
@@ -774,7 +867,9 @@ class HTTPRunDB(RunDBInterface):
774
867
  "name": name,
775
868
  "uid": uid,
776
869
  "label": labels or [],
777
- "state": state,
870
+ "state": mlrun.utils.helpers.as_list(state)
871
+ if state is not None
872
+ else states or None,
778
873
  "sort": bool2str(sort),
779
874
  "iter": bool2str(iter),
780
875
  "start_time_from": datetime_to_iso(start_time_from),
@@ -797,15 +892,15 @@ class HTTPRunDB(RunDBInterface):
797
892
  )
798
893
  error = "list runs"
799
894
  _path = self._path_of("runs", project)
800
- resp = self.api_call("GET", _path, error, params=params)
801
- return RunList(resp.json()["runs"])
895
+ responses = self.paginated_api_call("GET", _path, error, params=params)
896
+ return RunList(self.process_paginated_responses(responses, "runs"))
802
897
 
803
898
  def del_runs(self, name=None, project=None, labels=None, state=None, days_ago=0):
804
899
  """Delete a group of runs identified by the parameters of the function.
805
900
 
806
901
  Example::
807
902
 
808
- db.del_runs(state='completed')
903
+ db.del_runs(state="completed")
809
904
 
810
905
  :param name: Name of the task which the runs belong to.
811
906
  :param project: Project to which the runs belong.
@@ -901,7 +996,7 @@ class HTTPRunDB(RunDBInterface):
901
996
  error = f"read artifact {project}/{key}"
902
997
  # explicitly set artifacts format to 'full' since old servers may default to 'legacy'
903
998
  params = {
904
- "format": mlrun.common.schemas.ArtifactsFormat.full.value,
999
+ "format": mlrun.common.formatters.ArtifactFormat.full.value,
905
1000
  "tag": tag,
906
1001
  "tree": tree,
907
1002
  "uid": uid,
@@ -911,7 +1006,18 @@ class HTTPRunDB(RunDBInterface):
911
1006
  resp = self.api_call("GET", endpoint_path, error, params=params, version="v2")
912
1007
  return resp.json()
913
1008
 
914
- def del_artifact(self, key, tag=None, project="", tree=None, uid=None):
1009
+ def del_artifact(
1010
+ self,
1011
+ key,
1012
+ tag=None,
1013
+ project="",
1014
+ tree=None,
1015
+ uid=None,
1016
+ deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
1017
+ mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
1018
+ ),
1019
+ secrets: dict = None,
1020
+ ):
915
1021
  """Delete an artifact.
916
1022
 
917
1023
  :param key: Identifying key of the artifact.
@@ -919,6 +1025,8 @@ class HTTPRunDB(RunDBInterface):
919
1025
  :param project: Project that the artifact belongs to.
920
1026
  :param tree: The tree which generated this artifact.
921
1027
  :param uid: A unique ID for this specific version of the artifact (the uid that was generated in the backend)
1028
+ :param deletion_strategy: The artifact deletion strategy types.
1029
+ :param secrets: Credentials needed to access the artifact data.
922
1030
  """
923
1031
 
924
1032
  endpoint_path = f"projects/{project}/artifacts/{key}"
@@ -927,16 +1035,24 @@ class HTTPRunDB(RunDBInterface):
927
1035
  "tag": tag,
928
1036
  "tree": tree,
929
1037
  "uid": uid,
1038
+ "deletion_strategy": deletion_strategy,
930
1039
  }
931
1040
  error = f"del artifact {project}/{key}"
932
- self.api_call("DELETE", endpoint_path, error, params=params, version="v2")
1041
+ self.api_call(
1042
+ "DELETE",
1043
+ endpoint_path,
1044
+ error,
1045
+ params=params,
1046
+ version="v2",
1047
+ body=dict_to_json(secrets),
1048
+ )
933
1049
 
934
1050
  def list_artifacts(
935
1051
  self,
936
1052
  name=None,
937
1053
  project=None,
938
1054
  tag=None,
939
- labels: Optional[Union[Dict[str, str], List[str]]] = None,
1055
+ labels: Optional[Union[dict[str, str], list[str]]] = None,
940
1056
  since=None,
941
1057
  until=None,
942
1058
  iter: int = None,
@@ -951,11 +1067,13 @@ class HTTPRunDB(RunDBInterface):
951
1067
  Examples::
952
1068
 
953
1069
  # Show latest version of all artifacts in project
954
- latest_artifacts = db.list_artifacts('', tag='latest', project='iris')
1070
+ latest_artifacts = db.list_artifacts("", tag="latest", project="iris")
955
1071
  # check different artifact versions for a specific artifact
956
- result_versions = db.list_artifacts('results', tag='*', project='iris')
1072
+ result_versions = db.list_artifacts("results", tag="*", project="iris")
957
1073
  # Show artifacts with label filters - both uploaded and of binary type
958
- result_labels = db.list_artifacts('results', tag='*', project='iris', labels=['uploaded', 'type=binary'])
1074
+ result_labels = db.list_artifacts(
1075
+ "results", tag="*", project="iris", labels=["uploaded", "type=binary"]
1076
+ )
959
1077
 
960
1078
  :param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
961
1079
  case-sensitive. This means that querying for ``~name`` may return artifacts named
@@ -994,7 +1112,7 @@ class HTTPRunDB(RunDBInterface):
994
1112
  "kind": kind,
995
1113
  "category": category,
996
1114
  "tree": tree,
997
- "format": mlrun.common.schemas.ArtifactsFormat.full.value,
1115
+ "format": mlrun.common.formatters.ArtifactFormat.full.value,
998
1116
  "producer_uri": producer_uri,
999
1117
  }
1000
1118
  error = "list artifacts"
@@ -1032,7 +1150,7 @@ class HTTPRunDB(RunDBInterface):
1032
1150
  self,
1033
1151
  project=None,
1034
1152
  category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
1035
- ) -> List[str]:
1153
+ ) -> list[str]:
1036
1154
  """Return a list of all the tags assigned to artifacts in the scope of the given project."""
1037
1155
 
1038
1156
  project = project or config.default_project
@@ -1085,7 +1203,29 @@ class HTTPRunDB(RunDBInterface):
1085
1203
  project = project or config.default_project
1086
1204
  path = f"projects/{project}/functions/{name}"
1087
1205
  error_message = f"Failed deleting function {project}/{name}"
1088
- self.api_call("DELETE", path, error_message)
1206
+ response = self.api_call("DELETE", path, error_message, version="v2")
1207
+ if response.status_code == http.HTTPStatus.ACCEPTED:
1208
+ logger.info(
1209
+ "Function is being deleted", project_name=project, function_name=name
1210
+ )
1211
+ background_task = mlrun.common.schemas.BackgroundTask(**response.json())
1212
+ background_task = self._wait_for_background_task_to_reach_terminal_state(
1213
+ background_task.metadata.name, project=project
1214
+ )
1215
+ if (
1216
+ background_task.status.state
1217
+ == mlrun.common.schemas.BackgroundTaskState.succeeded
1218
+ ):
1219
+ logger.info(
1220
+ "Function deleted", project_name=project, function_name=name
1221
+ )
1222
+ elif (
1223
+ background_task.status.state
1224
+ == mlrun.common.schemas.BackgroundTaskState.failed
1225
+ ):
1226
+ logger.info(
1227
+ "Function deletion failed", project_name=project, function_name=name
1228
+ )
1089
1229
 
1090
1230
  def list_functions(self, name=None, project=None, tag=None, labels=None):
1091
1231
  """Retrieve a list of functions, filtered by specific criteria.
@@ -1104,8 +1244,8 @@ class HTTPRunDB(RunDBInterface):
1104
1244
  }
1105
1245
  error = "list functions"
1106
1246
  path = f"projects/{project}/functions"
1107
- resp = self.api_call("GET", path, error, params=params)
1108
- return resp.json()["funcs"]
1247
+ responses = self.paginated_api_call("GET", path, error, params=params)
1248
+ return self.process_paginated_responses(responses, "funcs")
1109
1249
 
1110
1250
  def list_runtime_resources(
1111
1251
  self,
@@ -1195,7 +1335,7 @@ class HTTPRunDB(RunDBInterface):
1195
1335
  period didn't pass.
1196
1336
  :param grace_period: Grace period given to the runtime resource before they are actually removed, counted from
1197
1337
  the moment they moved to terminal state
1198
- (defaults to mlrun.config.config.runtime_resources_deletion_grace_period).
1338
+ (defaults to mlrun.mlconf.runtime_resources_deletion_grace_period).
1199
1339
 
1200
1340
  :returns: :py:class:`~mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput` listing the runtime resources
1201
1341
  that were removed.
@@ -1251,7 +1391,9 @@ class HTTPRunDB(RunDBInterface):
1251
1391
  name="run_func_on_tuesdays",
1252
1392
  kind="job",
1253
1393
  scheduled_object=get_data_func,
1254
- cron_trigger=schemas.ScheduleCronTrigger(day_of_week='tue', hour=15, minute=30),
1394
+ cron_trigger=schemas.ScheduleCronTrigger(
1395
+ day_of_week="tue", hour=15, minute=30
1396
+ ),
1255
1397
  )
1256
1398
  db.create_schedule(project_name, schedule)
1257
1399
  """
@@ -1354,21 +1496,7 @@ class HTTPRunDB(RunDBInterface):
1354
1496
  :param builder_env: Kaniko builder pod env vars dict (for config/credentials)
1355
1497
  :param force_build: Force building the image, even when no changes were made
1356
1498
  """
1357
- is_s3_source = func.spec.build.source and func.spec.build.source.startswith(
1358
- "s3://"
1359
- )
1360
- is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
1361
- if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
1362
- logger.warning(
1363
- "Building a function image to ECR and loading an S3 source to the image may require conflicting access "
1364
- "keys. Only the permissions granted to the platform's configured secret will take affect "
1365
- "(see mlrun.config.config.httpdb.builder.docker_registry_secret). "
1366
- "In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
1367
- source=func.spec.build.source,
1368
- load_source_on_run=func.spec.build.load_source_on_run,
1369
- default_docker_registry=config.httpdb.builder.docker_registry,
1370
- )
1371
-
1499
+ self.warn_on_s3_and_ecr_permissions_conflict(func)
1372
1500
  try:
1373
1501
  req = {
1374
1502
  "function": func.to_dict(),
@@ -1387,10 +1515,102 @@ class HTTPRunDB(RunDBInterface):
1387
1515
 
1388
1516
  if not resp.ok:
1389
1517
  logger.error(f"bad resp!!\n{resp.text}")
1390
- raise ValueError("bad function run response")
1518
+ raise ValueError("bad submit build response")
1519
+
1520
+ return resp.json()
1521
+
1522
+ def deploy_nuclio_function(
1523
+ self,
1524
+ func: mlrun.runtimes.RemoteRuntime,
1525
+ builder_env: Optional[dict] = None,
1526
+ ):
1527
+ """
1528
+ Deploy a Nuclio function.
1529
+ :param func: Function to build.
1530
+ :param builder_env: Kaniko builder pod env vars dict (for config/credentials)
1531
+ """
1532
+ func.metadata.project = func.metadata.project or config.default_project
1533
+ self.warn_on_s3_and_ecr_permissions_conflict(func)
1534
+ try:
1535
+ req = {
1536
+ "function": func.to_dict(),
1537
+ }
1538
+ if builder_env:
1539
+ req["builder_env"] = builder_env
1540
+ _path = (
1541
+ f"projects/{func.metadata.project}/nuclio/{func.metadata.name}/deploy"
1542
+ )
1543
+ resp = self.api_call("POST", _path, json=req)
1544
+ except OSError as err:
1545
+ logger.error(f"error submitting nuclio deploy task: {err_to_str(err)}")
1546
+ raise OSError(f"error: cannot submit deploy, {err_to_str(err)}")
1547
+
1548
+ if not resp.ok:
1549
+ logger.error(f"deploy nuclio - bad response:\n{resp.text}")
1550
+ raise ValueError("bad nuclio deploy response")
1391
1551
 
1392
1552
  return resp.json()
1393
1553
 
1554
+ def get_nuclio_deploy_status(
1555
+ self,
1556
+ func: mlrun.runtimes.RemoteRuntime,
1557
+ last_log_timestamp: float = 0.0,
1558
+ verbose: bool = False,
1559
+ ):
1560
+ """Retrieve the status of a deploy operation currently in progress.
1561
+
1562
+ :param func: Function object that is being built.
1563
+ :param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
1564
+ later than this parameter.
1565
+ :param verbose: Add verbose logs into the output.
1566
+
1567
+ :returns: The following parameters:
1568
+
1569
+ - Text of builder logs.
1570
+ - Timestamp of last log retrieved, to be used in subsequent calls to this function.
1571
+ """
1572
+
1573
+ try:
1574
+ normalized_name = normalize_name(func.metadata.name)
1575
+ params = {
1576
+ "name": normalized_name,
1577
+ "project": func.metadata.project,
1578
+ "tag": func.metadata.tag,
1579
+ "last_log_timestamp": str(last_log_timestamp),
1580
+ "verbose": bool2str(verbose),
1581
+ }
1582
+ _path = f"projects/{func.metadata.project}/nuclio/{normalized_name}/deploy"
1583
+ resp = self.api_call("GET", _path, params=params)
1584
+ except OSError as err:
1585
+ logger.error(f"error getting deploy status: {err_to_str(err)}")
1586
+ raise OSError(f"error: cannot get deploy status, {err_to_str(err)}")
1587
+
1588
+ if not resp.ok:
1589
+ logger.warning(f"failed resp, {resp.text}")
1590
+ raise RunDBError("bad function build response")
1591
+
1592
+ if resp.headers:
1593
+ func.status.state = resp.headers.get("x-mlrun-function-status", "")
1594
+ last_log_timestamp = float(
1595
+ resp.headers.get("x-mlrun-last-timestamp", "0.0")
1596
+ )
1597
+ func.status.address = resp.headers.get("x-mlrun-address", "")
1598
+ func.status.nuclio_name = resp.headers.get("x-mlrun-name", "")
1599
+ func.status.internal_invocation_urls = resp.headers.get(
1600
+ "x-mlrun-internal-invocation-urls", ""
1601
+ ).split(",")
1602
+ func.status.external_invocation_urls = resp.headers.get(
1603
+ "x-mlrun-external-invocation-urls", ""
1604
+ ).split(",")
1605
+ func.status.container_image = resp.headers.get(
1606
+ "x-mlrun-container-image", ""
1607
+ )
1608
+
1609
+ text = ""
1610
+ if resp.content:
1611
+ text = resp.content.decode()
1612
+ return text, last_log_timestamp
1613
+
1394
1614
  def get_builder_status(
1395
1615
  self,
1396
1616
  func: BaseRuntime,
@@ -1452,9 +1672,14 @@ class HTTPRunDB(RunDBInterface):
1452
1672
  func.status.container_image = resp.headers.get(
1453
1673
  "x-mlrun-container-image", ""
1454
1674
  )
1455
- else:
1456
- func.status.build_pod = resp.headers.get("builder_pod", "")
1457
- func.spec.image = resp.headers.get("function_image", "")
1675
+
1676
+ builder_pod = resp.headers.get("builder_pod", "")
1677
+ if builder_pod:
1678
+ func.status.build_pod = builder_pod
1679
+
1680
+ function_image = resp.headers.get("function_image", "")
1681
+ if function_image:
1682
+ func.spec.image = function_image
1458
1683
 
1459
1684
  text = ""
1460
1685
  if resp.content:
@@ -1517,7 +1742,7 @@ class HTTPRunDB(RunDBInterface):
1517
1742
  Retrieve updated information on project background tasks being executed.
1518
1743
  If no filter is provided, will return background tasks from the last week.
1519
1744
 
1520
- :param project: Project name (defaults to mlrun.config.config.default_project).
1745
+ :param project: Project name (defaults to mlrun.mlconf.default_project).
1521
1746
  :param state: List only background tasks whose state is specified.
1522
1747
  :param created_from: Filter by background task created time in ``[created_from, created_to]``.
1523
1748
  :param created_to: Filter by background task created time in ``[created_from, created_to]``.
@@ -1650,14 +1875,11 @@ class HTTPRunDB(RunDBInterface):
1650
1875
  if isinstance(pipeline, str):
1651
1876
  pipe_file = pipeline
1652
1877
  else:
1653
- pipe_file = tempfile.NamedTemporaryFile(suffix=".yaml", delete=False).name
1654
- conf = new_pipe_metadata(
1878
+ pipe_file = compile_pipeline(
1655
1879
  artifact_path=artifact_path,
1656
1880
  cleanup_ttl=cleanup_ttl,
1657
- op_transformers=ops,
1658
- )
1659
- kfp.compiler.Compiler().compile(
1660
- pipeline, pipe_file, type_check=False, pipeline_conf=conf
1881
+ ops=ops,
1882
+ pipeline=pipeline,
1661
1883
  )
1662
1884
 
1663
1885
  if pipe_file.endswith(".yaml"):
@@ -1712,8 +1934,8 @@ class HTTPRunDB(RunDBInterface):
1712
1934
  page_token: str = "",
1713
1935
  filter_: str = "",
1714
1936
  format_: Union[
1715
- str, mlrun.common.schemas.PipelinesFormat
1716
- ] = mlrun.common.schemas.PipelinesFormat.metadata_only,
1937
+ str, mlrun.common.formatters.PipelineFormat
1938
+ ] = mlrun.common.formatters.PipelineFormat.metadata_only,
1717
1939
  page_size: int = None,
1718
1940
  ) -> mlrun.common.schemas.PipelinesOutput:
1719
1941
  """Retrieve a list of KFP pipelines. This function can be invoked to get all pipelines from all projects,
@@ -1759,8 +1981,8 @@ class HTTPRunDB(RunDBInterface):
1759
1981
  namespace: str = None,
1760
1982
  timeout: int = 30,
1761
1983
  format_: Union[
1762
- str, mlrun.common.schemas.PipelinesFormat
1763
- ] = mlrun.common.schemas.PipelinesFormat.summary,
1984
+ str, mlrun.common.formatters.PipelineFormat
1985
+ ] = mlrun.common.formatters.PipelineFormat.summary,
1764
1986
  project: str = None,
1765
1987
  ):
1766
1988
  """Retrieve details of a specific pipeline using its run ID (as provided when the pipeline was executed)."""
@@ -1852,9 +2074,9 @@ class HTTPRunDB(RunDBInterface):
1852
2074
  project: str,
1853
2075
  name: str = None,
1854
2076
  tag: str = None,
1855
- entities: List[str] = None,
1856
- labels: List[str] = None,
1857
- ) -> List[dict]:
2077
+ entities: list[str] = None,
2078
+ labels: list[str] = None,
2079
+ ) -> list[dict]:
1858
2080
  """List feature-sets which contain specific features. This function may return multiple versions of the same
1859
2081
  feature-set if a specific tag is not requested. Note that the various filters of this function actually
1860
2082
  refer to the feature-set object containing the features, not to the features themselves.
@@ -1889,8 +2111,8 @@ class HTTPRunDB(RunDBInterface):
1889
2111
  project: str,
1890
2112
  name: str = None,
1891
2113
  tag: str = None,
1892
- labels: List[str] = None,
1893
- ) -> List[dict]:
2114
+ labels: list[str] = None,
2115
+ ) -> list[dict]:
1894
2116
  """Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
1895
2117
  to the :py:func:`~list_features` function, and uses the same logic. However, the entities are matched
1896
2118
  against the name rather than the features.
@@ -1934,9 +2156,9 @@ class HTTPRunDB(RunDBInterface):
1934
2156
  name: str = None,
1935
2157
  tag: str = None,
1936
2158
  state: str = None,
1937
- entities: List[str] = None,
1938
- features: List[str] = None,
1939
- labels: List[str] = None,
2159
+ entities: list[str] = None,
2160
+ features: list[str] = None,
2161
+ labels: list[str] = None,
1940
2162
  partition_by: Union[
1941
2163
  mlrun.common.schemas.FeatureStorePartitionByField, str
1942
2164
  ] = None,
@@ -1945,7 +2167,7 @@ class HTTPRunDB(RunDBInterface):
1945
2167
  partition_order: Union[
1946
2168
  mlrun.common.schemas.OrderType, str
1947
2169
  ] = mlrun.common.schemas.OrderType.desc,
1948
- ) -> List[FeatureSet]:
2170
+ ) -> list[FeatureSet]:
1949
2171
  """Retrieve a list of feature-sets matching the criteria provided.
1950
2172
 
1951
2173
  :param project: Project name.
@@ -2060,7 +2282,7 @@ class HTTPRunDB(RunDBInterface):
2060
2282
  not a full object.
2061
2283
  Example::
2062
2284
 
2063
- feature_set_update = {"status": {"processed" : True}}
2285
+ feature_set_update = {"status": {"processed": True}}
2064
2286
 
2065
2287
  Will apply the field ``status.processed`` to the existing object.
2066
2288
  :param project: Project which contains the modified object.
@@ -2155,7 +2377,7 @@ class HTTPRunDB(RunDBInterface):
2155
2377
  name: str = None,
2156
2378
  tag: str = None,
2157
2379
  state: str = None,
2158
- labels: List[str] = None,
2380
+ labels: list[str] = None,
2159
2381
  partition_by: Union[
2160
2382
  mlrun.common.schemas.FeatureStorePartitionByField, str
2161
2383
  ] = None,
@@ -2164,7 +2386,7 @@ class HTTPRunDB(RunDBInterface):
2164
2386
  partition_order: Union[
2165
2387
  mlrun.common.schemas.OrderType, str
2166
2388
  ] = mlrun.common.schemas.OrderType.desc,
2167
- ) -> List[FeatureVector]:
2389
+ ) -> list[FeatureVector]:
2168
2390
  """Retrieve a list of feature-vectors matching the criteria provided.
2169
2391
 
2170
2392
  :param project: Project name.
@@ -2366,7 +2588,7 @@ class HTTPRunDB(RunDBInterface):
2366
2588
 
2367
2589
  def tag_artifacts(
2368
2590
  self,
2369
- artifacts: Union[List[Artifact], List[dict], Artifact, dict],
2591
+ artifacts: Union[list[Artifact], list[dict], Artifact, dict],
2370
2592
  project: str,
2371
2593
  tag_name: str,
2372
2594
  replace: bool = False,
@@ -2402,11 +2624,11 @@ class HTTPRunDB(RunDBInterface):
2402
2624
  self,
2403
2625
  owner: str = None,
2404
2626
  format_: Union[
2405
- str, mlrun.common.schemas.ProjectsFormat
2406
- ] = mlrun.common.schemas.ProjectsFormat.name_only,
2407
- labels: List[str] = None,
2627
+ str, mlrun.common.formatters.ProjectFormat
2628
+ ] = mlrun.common.formatters.ProjectFormat.name_only,
2629
+ labels: list[str] = None,
2408
2630
  state: Union[str, mlrun.common.schemas.ProjectState] = None,
2409
- ) -> List[Union[mlrun.projects.MlrunProject, str]]:
2631
+ ) -> list[Union[mlrun.projects.MlrunProject, str]]:
2410
2632
  """Return a list of the existing projects, potentially filtered by specific criteria.
2411
2633
 
2412
2634
  :param owner: List only projects belonging to this specific owner.
@@ -2429,7 +2651,7 @@ class HTTPRunDB(RunDBInterface):
2429
2651
 
2430
2652
  error_message = f"Failed listing projects, query: {params}"
2431
2653
  response = self.api_call("GET", "projects", error_message, params=params)
2432
- if format_ == mlrun.common.schemas.ProjectsFormat.name_only:
2654
+ if format_ == mlrun.common.formatters.ProjectFormat.name_only:
2433
2655
  # projects is just a list of strings
2434
2656
  return response.json()["projects"]
2435
2657
 
@@ -2634,11 +2856,11 @@ class HTTPRunDB(RunDBInterface):
2634
2856
  :param secrets: A set of secret values to store.
2635
2857
  Example::
2636
2858
 
2637
- secrets = {'password': 'myPassw0rd', 'aws_key': '111222333'}
2859
+ secrets = {"password": "myPassw0rd", "aws_key": "111222333"}
2638
2860
  db.create_project_secrets(
2639
2861
  "project1",
2640
2862
  provider=mlrun.common.schemas.SecretProviderName.kubernetes,
2641
- secrets=secrets
2863
+ secrets=secrets,
2642
2864
  )
2643
2865
  """
2644
2866
  path = f"projects/{project}/secrets"
@@ -2661,7 +2883,7 @@ class HTTPRunDB(RunDBInterface):
2661
2883
  provider: Union[
2662
2884
  str, mlrun.common.schemas.SecretProviderName
2663
2885
  ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2664
- secrets: List[str] = None,
2886
+ secrets: list[str] = None,
2665
2887
  ) -> mlrun.common.schemas.SecretsData:
2666
2888
  """Retrieve project-context secrets from Vault.
2667
2889
 
@@ -2750,7 +2972,7 @@ class HTTPRunDB(RunDBInterface):
2750
2972
  provider: Union[
2751
2973
  str, mlrun.common.schemas.SecretProviderName
2752
2974
  ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2753
- secrets: List[str] = None,
2975
+ secrets: list[str] = None,
2754
2976
  ):
2755
2977
  """Delete project-context secrets from Kubernetes.
2756
2978
 
@@ -2907,13 +3129,13 @@ class HTTPRunDB(RunDBInterface):
2907
3129
  project: str,
2908
3130
  model: Optional[str] = None,
2909
3131
  function: Optional[str] = None,
2910
- labels: List[str] = None,
3132
+ labels: list[str] = None,
2911
3133
  start: str = "now-1h",
2912
3134
  end: str = "now",
2913
- metrics: Optional[List[str]] = None,
3135
+ metrics: Optional[list[str]] = None,
2914
3136
  top_level: bool = False,
2915
- uids: Optional[List[str]] = None,
2916
- ) -> List[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
3137
+ uids: Optional[list[str]] = None,
3138
+ ) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
2917
3139
  """
2918
3140
  Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
2919
3141
  model endpoint. This functions supports filtering by the following parameters:
@@ -2934,14 +3156,12 @@ class HTTPRunDB(RunDBInterface):
2934
3156
  :param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
2935
3157
  label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key")
2936
3158
  :param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
2937
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
2938
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2939
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
2940
- days), or 0 for the earliest time.
2941
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
2942
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2943
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
2944
- days), or 0 for the earliest time.
3159
+ :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3160
+ Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3161
+ `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3162
+ :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3163
+ Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3164
+ `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
2945
3165
  :param top_level: if true will return only routers and endpoint that are NOT children of any router
2946
3166
  :param uids: if passed will return a list `ModelEndpoint` object with uid in uids
2947
3167
  """
@@ -2981,7 +3201,7 @@ class HTTPRunDB(RunDBInterface):
2981
3201
  endpoint_id: str,
2982
3202
  start: Optional[str] = None,
2983
3203
  end: Optional[str] = None,
2984
- metrics: Optional[List[str]] = None,
3204
+ metrics: Optional[list[str]] = None,
2985
3205
  feature_analysis: bool = False,
2986
3206
  ) -> mlrun.model_monitoring.model_endpoint.ModelEndpoint:
2987
3207
  """
@@ -2990,13 +3210,13 @@ class HTTPRunDB(RunDBInterface):
2990
3210
  :param project: The name of the project
2991
3211
  :param endpoint_id: The unique id of the model endpoint.
2992
3212
  :param start: The start time of the metrics. Can be represented by a string containing an
2993
- RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2994
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
2995
- 0 for the earliest time.
3213
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time
3214
+ (`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
3215
+ `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
2996
3216
  :param end: The end time of the metrics. Can be represented by a string containing an
2997
- RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2998
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
2999
- 0 for the earliest time.
3217
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time
3218
+ (`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
3219
+ `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3000
3220
  :param metrics: A list of metrics to return for the model endpoint. There are pre-defined
3001
3221
  metrics for model endpoints such as predictions_per_second and
3002
3222
  latency_avg_5m but also custom metrics defined by the user. Please note that
@@ -3066,65 +3286,77 @@ class HTTPRunDB(RunDBInterface):
3066
3286
  params=attributes,
3067
3287
  )
3068
3288
 
3069
- def deploy_monitoring_batch_job(
3289
+ def update_model_monitoring_controller(
3070
3290
  self,
3071
- project: str = "",
3072
- default_batch_image: str = "mlrun/mlrun",
3073
- with_schedule: bool = False,
3074
- ):
3291
+ project: str,
3292
+ base_period: int = 10,
3293
+ image: str = "mlrun/mlrun",
3294
+ ) -> None:
3075
3295
  """
3076
- Submit model monitoring batch job. By default, submit only the batch job as ML function without scheduling.
3077
- To submit a scheduled job as well, please set with_schedule = True.
3296
+ Redeploy model monitoring application controller function.
3078
3297
 
3079
- :param project: Project name.
3080
- :param default_batch_image: The default image of the model monitoring batch job. By default, the image
3081
- is mlrun/mlrun.
3082
- :param with_schedule: If true, submit the model monitoring scheduled job as well.
3083
-
3084
-
3085
- :returns: model monitoring batch job as a dictionary. You can easily convert the returned function into a
3086
- runtime object by calling ~mlrun.new_function.
3298
+ :param project: Project name.
3299
+ :param base_period: The time period in minutes in which the model monitoring controller function
3300
+ triggers. By default, the base period is 10 minutes.
3301
+ :param image: The image of the model monitoring controller function.
3302
+ By default, the image is mlrun/mlrun.
3087
3303
  """
3304
+ self.api_call(
3305
+ method=mlrun.common.types.HTTPMethod.POST,
3306
+ path=f"projects/{project}/model-monitoring/model-monitoring-controller",
3307
+ params={
3308
+ "base_period": base_period,
3309
+ "image": image,
3310
+ },
3311
+ )
3088
3312
 
3089
- params = {
3090
- "default_batch_image": default_batch_image,
3091
- "with_schedule": with_schedule,
3092
- }
3093
- path = f"projects/{project}/jobs/batch-monitoring"
3094
-
3095
- resp = self.api_call(method="POST", path=path, params=params)
3096
- return resp.json()["func"]
3097
-
3098
- def create_model_monitoring_controller(
3313
+ def enable_model_monitoring(
3099
3314
  self,
3100
- project: str = "",
3101
- default_controller_image: str = "mlrun/mlrun",
3315
+ project: str,
3102
3316
  base_period: int = 10,
3103
- ):
3317
+ image: str = "mlrun/mlrun",
3318
+ deploy_histogram_data_drift_app: bool = True,
3319
+ ) -> None:
3320
+ """
3321
+ Deploy model monitoring application controller, writer and stream functions.
3322
+ While the main goal of the controller function is to handle the monitoring processing and triggering
3323
+ applications, the goal of the model monitoring writer function is to write all the monitoring
3324
+ application results to the databases.
3325
+ The stream function goal is to monitor the log of the data stream. It is triggered when a new log entry
3326
+ is detected. It processes the new events into statistics that are then written to statistics databases.
3327
+
3328
+ :param project: Project name.
3329
+ :param base_period: The time period in minutes in which the model monitoring controller function
3330
+ triggers. By default, the base period is 10 minutes.
3331
+ :param image: The image of the model monitoring controller, writer & monitoring
3332
+ stream functions, which are real time nuclio functions.
3333
+ By default, the image is mlrun/mlrun.
3334
+ :param deploy_histogram_data_drift_app: If true, deploy the default histogram-based data drift application.
3104
3335
  """
3105
- Submit model monitoring application controller job along with deploying the model monitoring writer function.
3106
- While the main goal of the controller job is to handle the monitoring processing and triggering applications,
3107
- the goal of the model monitoring writer function is to write all the monitoring application results to the
3108
- databases. Note that the default scheduling policy of the controller job is to run every 10 min.
3336
+ self.api_call(
3337
+ method=mlrun.common.types.HTTPMethod.POST,
3338
+ path=f"projects/{project}/model-monitoring/enable-model-monitoring",
3339
+ params={
3340
+ "base_period": base_period,
3341
+ "image": image,
3342
+ "deploy_histogram_data_drift_app": deploy_histogram_data_drift_app,
3343
+ },
3344
+ )
3109
3345
 
3110
- :param project: Project name.
3111
- :param default_controller_image: The default image of the model monitoring controller job. Note that the writer
3112
- function, which is a real time nuclio functino, will be deployed with the same
3113
- image. By default, the image is mlrun/mlrun.
3114
- :param base_period: Minutes to determine the frequency in which the model monitoring controller job
3115
- is running. By default, the base period is 5 minutes.
3116
- :returns: model monitoring controller job as a dictionary. You can easily convert the returned function into a
3117
- runtime object by calling ~mlrun.new_function.
3346
+ def deploy_histogram_data_drift_app(
3347
+ self, project: str, image: str = "mlrun/mlrun"
3348
+ ) -> None:
3118
3349
  """
3350
+ Deploy the histogram data drift application.
3119
3351
 
3120
- params = {
3121
- "default_controller_image": default_controller_image,
3122
- "base_period": base_period,
3123
- }
3124
- path = f"projects/{project}/jobs/model-monitoring-controller"
3125
-
3126
- resp = self.api_call(method="POST", path=path, params=params)
3127
- return resp.json()["func"]
3352
+ :param project: Project name.
3353
+ :param image: The image on which the application will run.
3354
+ """
3355
+ self.api_call(
3356
+ method=mlrun.common.types.HTTPMethod.POST,
3357
+ path=f"projects/{project}/model-monitoring/deploy-histogram-data-drift-app",
3358
+ params={"image": image},
3359
+ )
3128
3360
 
3129
3361
  def create_hub_source(
3130
3362
  self, source: Union[dict, mlrun.common.schemas.IndexedHubSource]
@@ -3155,8 +3387,10 @@ class HTTPRunDB(RunDBInterface):
3155
3387
  metadata=mlrun.common.schemas.HubObjectMetadata(
3156
3388
  name="priv", description="a private source"
3157
3389
  ),
3158
- spec=mlrun.common.schemas.HubSourceSpec(path="/local/path/to/source", channel="development")
3159
- )
3390
+ spec=mlrun.common.schemas.HubSourceSpec(
3391
+ path="/local/path/to/source", channel="development"
3392
+ ),
3393
+ ),
3160
3394
  )
3161
3395
  db.create_hub_source(private_source)
3162
3396
 
@@ -3170,9 +3404,9 @@ class HTTPRunDB(RunDBInterface):
3170
3404
  spec=mlrun.common.schemas.HubSourceSpec(
3171
3405
  path="/local/path/to/source/2",
3172
3406
  channel="development",
3173
- credentials={...}
3174
- )
3175
- )
3407
+ credentials={...},
3408
+ ),
3409
+ ),
3176
3410
  )
3177
3411
  db.create_hub_source(another_source)
3178
3412
 
@@ -3214,7 +3448,7 @@ class HTTPRunDB(RunDBInterface):
3214
3448
  item_name: Optional[str] = None,
3215
3449
  tag: Optional[str] = None,
3216
3450
  version: Optional[str] = None,
3217
- ) -> List[mlrun.common.schemas.hub.IndexedHubSource]:
3451
+ ) -> list[mlrun.common.schemas.hub.IndexedHubSource]:
3218
3452
  """
3219
3453
  List hub sources in the MLRun DB.
3220
3454
 
@@ -3364,20 +3598,72 @@ class HTTPRunDB(RunDBInterface):
3364
3598
  body=dict_to_json(authorization_verification_input.dict()),
3365
3599
  )
3366
3600
 
3367
- def list_api_gateways(self, project=None):
3601
+ def list_api_gateways(self, project=None) -> mlrun.common.schemas.APIGatewaysOutput:
3368
3602
  """
3369
3603
  Returns a list of Nuclio api gateways
3370
- :param project: optional str parameter to filter by project, if not passed, default Nuclio's value is taken
3604
+ :param project: optional str parameter to filter by project, if not passed, default project value is taken
3371
3605
 
3372
- :return: json with the list of Nuclio Api Gateways
3373
- (json example is here
3374
- https://github.com/nuclio/nuclio/blob/development/docs/reference/api/README.md#listing-all-api-gateways)
3606
+ :return: :py:class:`~mlrun.common.schemas.APIGateways`.
3375
3607
  """
3376
3608
  project = project or config.default_project
3377
3609
  error = "list api gateways"
3378
- endpoint_path = f"projects/{project}/nuclio/api-gateways"
3379
- resp = self.api_call("GET", endpoint_path, error)
3380
- return resp.json()
3610
+ endpoint_path = f"projects/{project}/api-gateways"
3611
+ response = self.api_call("GET", endpoint_path, error)
3612
+ return mlrun.common.schemas.APIGatewaysOutput(**response.json())
3613
+
3614
+ def get_api_gateway(self, name, project=None) -> mlrun.common.schemas.APIGateway:
3615
+ """
3616
+ Returns an API gateway
3617
+ :param name: API gateway name
3618
+ :param project: optional str parameter to filter by project, if not passed, default project value is taken
3619
+
3620
+ :return: :py:class:`~mlrun.common.schemas.APIGateway`.
3621
+ """
3622
+ project = project or config.default_project
3623
+ error = "get api gateway"
3624
+ endpoint_path = f"projects/{project}/api-gateways/{name}"
3625
+ response = self.api_call("GET", endpoint_path, error)
3626
+ return mlrun.common.schemas.APIGateway(**response.json())
3627
+
3628
+ def delete_api_gateway(self, name, project=None):
3629
+ """
3630
+ Deletes an API gateway
3631
+ :param name: API gateway name
3632
+ :param project: Project name
3633
+ """
3634
+ project = project or config.default_project
3635
+ error = "delete api gateway"
3636
+ endpoint_path = f"projects/{project}/api-gateways/{name}"
3637
+ self.api_call("DELETE", endpoint_path, error)
3638
+
3639
+ def store_api_gateway(
3640
+ self,
3641
+ api_gateway: Union[
3642
+ mlrun.common.schemas.APIGateway,
3643
+ mlrun.runtimes.nuclio.api_gateway.APIGateway,
3644
+ ],
3645
+ project: Optional[str] = None,
3646
+ ) -> mlrun.common.schemas.APIGateway:
3647
+ """
3648
+ Stores an API Gateway.
3649
+ :param api_gateway :py:class:`~mlrun.runtimes.nuclio.APIGateway`
3650
+ or :py:class:`~mlrun.common.schemas.APIGateway`: API Gateway entity.
3651
+ :param project: project name. Mandatory if api_gateway is mlrun.common.schemas.APIGateway.
3652
+
3653
+ :return: :py:class:`~mlrun.common.schemas.APIGateway`.
3654
+ """
3655
+
3656
+ if isinstance(api_gateway, mlrun.runtimes.nuclio.api_gateway.APIGateway):
3657
+ api_gateway = api_gateway.to_scheme()
3658
+ endpoint_path = f"projects/{project}/api-gateways/{api_gateway.metadata.name}"
3659
+ error = "store api gateways"
3660
+ response = self.api_call(
3661
+ "PUT",
3662
+ endpoint_path,
3663
+ error,
3664
+ json=api_gateway.dict(exclude_none=True),
3665
+ )
3666
+ return mlrun.common.schemas.APIGateway(**response.json())
3381
3667
 
3382
3668
  def trigger_migrations(self) -> Optional[mlrun.common.schemas.BackgroundTask]:
3383
3669
  """Trigger migrations (will do nothing if no migrations are needed) and wait for them to finish if actually
@@ -3400,7 +3686,7 @@ class HTTPRunDB(RunDBInterface):
3400
3686
  self,
3401
3687
  project: str,
3402
3688
  run_uid: str,
3403
- notifications: typing.List[mlrun.model.Notification] = None,
3689
+ notifications: list[mlrun.model.Notification] = None,
3404
3690
  ):
3405
3691
  """
3406
3692
  Set notifications on a run. This will override any existing notifications on the run.
@@ -3425,7 +3711,7 @@ class HTTPRunDB(RunDBInterface):
3425
3711
  self,
3426
3712
  project: str,
3427
3713
  schedule_name: str,
3428
- notifications: typing.List[mlrun.model.Notification] = None,
3714
+ notifications: list[mlrun.model.Notification] = None,
3429
3715
  ):
3430
3716
  """
3431
3717
  Set notifications on a schedule. This will override any existing notifications on the schedule.
@@ -3448,7 +3734,7 @@ class HTTPRunDB(RunDBInterface):
3448
3734
 
3449
3735
  def store_run_notifications(
3450
3736
  self,
3451
- notification_objects: typing.List[mlrun.model.Notification],
3737
+ notification_objects: list[mlrun.model.Notification],
3452
3738
  run_uid: str,
3453
3739
  project: str = None,
3454
3740
  mask_params: bool = True,
@@ -3460,6 +3746,16 @@ class HTTPRunDB(RunDBInterface):
3460
3746
  """
3461
3747
  pass
3462
3748
 
3749
+ def store_alert_notifications(
3750
+ self,
3751
+ session,
3752
+ notification_objects: list[mlrun.model.Notification],
3753
+ alert_id: str,
3754
+ project: str,
3755
+ mask_params: bool = True,
3756
+ ):
3757
+ pass
3758
+
3463
3759
  def submit_workflow(
3464
3760
  self,
3465
3761
  project: str,
@@ -3469,7 +3765,7 @@ class HTTPRunDB(RunDBInterface):
3469
3765
  mlrun.common.schemas.WorkflowSpec,
3470
3766
  dict,
3471
3767
  ],
3472
- arguments: Optional[Dict] = None,
3768
+ arguments: Optional[dict] = None,
3473
3769
  artifact_path: Optional[str] = None,
3474
3770
  source: Optional[str] = None,
3475
3771
  run_name: Optional[str] = None,
@@ -3562,7 +3858,7 @@ class HTTPRunDB(RunDBInterface):
3562
3858
  self,
3563
3859
  name: str,
3564
3860
  url: str,
3565
- secrets: Optional[Dict] = None,
3861
+ secrets: Optional[dict] = None,
3566
3862
  save_secrets: bool = True,
3567
3863
  ) -> str:
3568
3864
  """
@@ -3625,7 +3921,7 @@ class HTTPRunDB(RunDBInterface):
3625
3921
 
3626
3922
  def list_datastore_profiles(
3627
3923
  self, project: str
3628
- ) -> List[mlrun.common.schemas.DatastoreProfile]:
3924
+ ) -> list[mlrun.common.schemas.DatastoreProfile]:
3629
3925
  project = project or config.default_project
3630
3926
  _path = self._path_of("datastore-profiles", project)
3631
3927
 
@@ -3651,6 +3947,145 @@ class HTTPRunDB(RunDBInterface):
3651
3947
 
3652
3948
  self.api_call(method="PUT", path=_path, json=profile.dict())
3653
3949
 
3950
+ @staticmethod
3951
+ def warn_on_s3_and_ecr_permissions_conflict(func):
3952
+ is_s3_source = func.spec.build.source and func.spec.build.source.startswith(
3953
+ "s3://"
3954
+ )
3955
+ is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
3956
+ if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
3957
+ logger.warning(
3958
+ "Building a function image to ECR and loading an S3 source to the image may require conflicting access "
3959
+ "keys. Only the permissions granted to the platform's configured secret will take affect "
3960
+ "(see mlrun.mlconf.httpdb.builder.docker_registry_secret). "
3961
+ "In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
3962
+ source=func.spec.build.source,
3963
+ load_source_on_run=func.spec.build.load_source_on_run,
3964
+ default_docker_registry=config.httpdb.builder.docker_registry,
3965
+ )
3966
+
3967
+ def generate_event(
3968
+ self, name: str, event_data: Union[dict, mlrun.common.schemas.Event], project=""
3969
+ ):
3970
+ """
3971
+ Generate an event.
3972
+ :param name: The name of the event.
3973
+ :param event_data: The data of the event.
3974
+ :param project: The project that the event belongs to.
3975
+ """
3976
+ project = project or config.default_project
3977
+ endpoint_path = f"projects/{project}/events/{name}"
3978
+ error_message = f"post event {project}/events/{name}"
3979
+ if isinstance(event_data, mlrun.common.schemas.Event):
3980
+ event_data = event_data.dict()
3981
+ self.api_call(
3982
+ "POST", endpoint_path, error_message, body=dict_to_json(event_data)
3983
+ )
3984
+
3985
+ def store_alert_config(
3986
+ self,
3987
+ alert_name: str,
3988
+ alert_data: Union[dict, AlertConfig],
3989
+ project="",
3990
+ ) -> AlertConfig:
3991
+ """
3992
+ Create/modify an alert.
3993
+ :param alert_name: The name of the alert.
3994
+ :param alert_data: The data of the alert.
3995
+ :param project: the project that the alert belongs to.
3996
+ :return: The created/modified alert.
3997
+ """
3998
+ project = project or config.default_project
3999
+ endpoint_path = f"projects/{project}/alerts/{alert_name}"
4000
+ error_message = f"put alert {project}/alerts/{alert_name}"
4001
+ alert_instance = (
4002
+ alert_data
4003
+ if isinstance(alert_data, AlertConfig)
4004
+ else AlertConfig.from_dict(alert_data)
4005
+ )
4006
+ alert_instance.validate_required_fields()
4007
+
4008
+ alert_data = alert_instance.to_dict()
4009
+ body = _as_json(alert_data)
4010
+ response = self.api_call("PUT", endpoint_path, error_message, body=body)
4011
+ return AlertConfig.from_dict(response.json())
4012
+
4013
+ def get_alert_config(self, alert_name: str, project="") -> AlertConfig:
4014
+ """
4015
+ Retrieve an alert.
4016
+ :param alert_name: The name of the alert to retrieve.
4017
+ :param project: The project that the alert belongs to.
4018
+ :return: The alert object.
4019
+ """
4020
+ project = project or config.default_project
4021
+ endpoint_path = f"projects/{project}/alerts/{alert_name}"
4022
+ error_message = f"get alert {project}/alerts/{alert_name}"
4023
+ response = self.api_call("GET", endpoint_path, error_message)
4024
+ return AlertConfig.from_dict(response.json())
4025
+
4026
+ def list_alerts_configs(self, project="") -> list[AlertConfig]:
4027
+ """
4028
+ Retrieve list of alerts of a project.
4029
+ :param project: The project name.
4030
+ :return: All the alerts objects of the project.
4031
+ """
4032
+ project = project or config.default_project
4033
+ endpoint_path = f"projects/{project}/alerts"
4034
+ error_message = f"get alerts {project}/alerts"
4035
+ response = self.api_call("GET", endpoint_path, error_message).json()
4036
+ results = []
4037
+ for item in response:
4038
+ results.append(AlertConfig(**item))
4039
+ return results
4040
+
4041
+ def delete_alert_config(self, alert_name: str, project=""):
4042
+ """
4043
+ Delete an alert.
4044
+ :param alert_name: The name of the alert to delete.
4045
+ :param project: The project that the alert belongs to.
4046
+ """
4047
+ project = project or config.default_project
4048
+ endpoint_path = f"projects/{project}/alerts/{alert_name}"
4049
+ error_message = f"delete alert {project}/alerts/{alert_name}"
4050
+ self.api_call("DELETE", endpoint_path, error_message)
4051
+
4052
+ def reset_alert_config(self, alert_name: str, project=""):
4053
+ """
4054
+ Reset an alert.
4055
+ :param alert_name: The name of the alert to reset.
4056
+ :param project: The project that the alert belongs to.
4057
+ """
4058
+ project = project or config.default_project
4059
+ endpoint_path = f"projects/{project}/alerts/{alert_name}/reset"
4060
+ error_message = f"post alert {project}/alerts/{alert_name}/reset"
4061
+ self.api_call("POST", endpoint_path, error_message)
4062
+
4063
+ def get_alert_template(
4064
+ self, template_name: str
4065
+ ) -> mlrun.common.schemas.AlertTemplate:
4066
+ """
4067
+ Retrieve a specific alert template.
4068
+ :param template_name: The name of the template to retrieve.
4069
+ :return: The template object.
4070
+ """
4071
+ endpoint_path = f"alert-templates/{template_name}"
4072
+ error_message = f"get template alert-templates/{template_name}"
4073
+ response = self.api_call("GET", endpoint_path, error_message)
4074
+ return mlrun.common.schemas.AlertTemplate(**response.json())
4075
+
4076
+ def list_alert_templates(self) -> list[mlrun.common.schemas.AlertTemplate]:
4077
+ """
4078
+ Retrieve list of all alert templates.
4079
+ :return: All the alert template objects in the database.
4080
+ """
4081
+ endpoint_path = "alert-templates"
4082
+ error_message = "get templates /alert-templates"
4083
+ response = self.api_call("GET", endpoint_path, error_message).json()
4084
+ results = []
4085
+ for item in response:
4086
+ results.append(mlrun.common.schemas.AlertTemplate(**item))
4087
+ return results
4088
+
3654
4089
 
3655
4090
  def _as_json(obj):
3656
4091
  fn = getattr(obj, "to_json", None)