mlrun 1.5.0rc1__py3-none-any.whl → 1.5.0rc2__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 (119) hide show
  1. mlrun/__init__.py +2 -35
  2. mlrun/__main__.py +1 -40
  3. mlrun/api/api/api.py +6 -0
  4. mlrun/api/api/endpoints/feature_store.py +0 -4
  5. mlrun/api/api/endpoints/files.py +14 -2
  6. mlrun/api/api/endpoints/functions.py +6 -1
  7. mlrun/api/api/endpoints/logs.py +17 -3
  8. mlrun/api/api/endpoints/pipelines.py +1 -5
  9. mlrun/api/api/endpoints/projects.py +88 -0
  10. mlrun/api/api/endpoints/runs.py +48 -6
  11. mlrun/api/api/endpoints/workflows.py +355 -0
  12. mlrun/api/api/utils.py +1 -1
  13. mlrun/api/crud/__init__.py +1 -0
  14. mlrun/api/crud/client_spec.py +3 -0
  15. mlrun/api/crud/model_monitoring/deployment.py +36 -7
  16. mlrun/api/crud/model_monitoring/grafana.py +1 -1
  17. mlrun/api/crud/model_monitoring/helpers.py +32 -2
  18. mlrun/api/crud/model_monitoring/model_endpoints.py +27 -5
  19. mlrun/api/crud/notifications.py +9 -4
  20. mlrun/api/crud/pipelines.py +4 -9
  21. mlrun/api/crud/runtime_resources.py +4 -3
  22. mlrun/api/crud/secrets.py +21 -0
  23. mlrun/api/crud/workflows.py +352 -0
  24. mlrun/api/db/base.py +16 -1
  25. mlrun/api/db/sqldb/db.py +97 -16
  26. mlrun/api/launcher.py +26 -7
  27. mlrun/api/main.py +3 -4
  28. mlrun/{mlutils → api/rundb}/__init__.py +2 -6
  29. mlrun/{db → api/rundb}/sqldb.py +35 -83
  30. mlrun/api/runtime_handlers/__init__.py +56 -0
  31. mlrun/api/runtime_handlers/base.py +1247 -0
  32. mlrun/api/runtime_handlers/daskjob.py +209 -0
  33. mlrun/api/runtime_handlers/kubejob.py +37 -0
  34. mlrun/api/runtime_handlers/mpijob.py +147 -0
  35. mlrun/api/runtime_handlers/remotesparkjob.py +29 -0
  36. mlrun/api/runtime_handlers/sparkjob.py +148 -0
  37. mlrun/api/utils/builder.py +1 -4
  38. mlrun/api/utils/clients/chief.py +14 -0
  39. mlrun/api/utils/scheduler.py +98 -15
  40. mlrun/api/utils/singletons/db.py +4 -0
  41. mlrun/artifacts/manager.py +1 -2
  42. mlrun/common/schemas/__init__.py +6 -0
  43. mlrun/common/schemas/auth.py +4 -1
  44. mlrun/common/schemas/client_spec.py +1 -1
  45. mlrun/common/schemas/model_monitoring/__init__.py +1 -0
  46. mlrun/common/schemas/model_monitoring/constants.py +11 -0
  47. mlrun/common/schemas/project.py +1 -0
  48. mlrun/common/schemas/runs.py +1 -8
  49. mlrun/common/schemas/schedule.py +1 -8
  50. mlrun/common/schemas/workflow.py +54 -0
  51. mlrun/config.py +42 -40
  52. mlrun/datastore/sources.py +1 -1
  53. mlrun/db/__init__.py +4 -68
  54. mlrun/db/base.py +12 -0
  55. mlrun/db/factory.py +65 -0
  56. mlrun/db/httpdb.py +175 -19
  57. mlrun/db/nopdb.py +4 -2
  58. mlrun/execution.py +4 -2
  59. mlrun/feature_store/__init__.py +1 -0
  60. mlrun/feature_store/api.py +1 -2
  61. mlrun/feature_store/feature_set.py +0 -10
  62. mlrun/feature_store/feature_vector.py +340 -2
  63. mlrun/feature_store/ingestion.py +5 -10
  64. mlrun/feature_store/retrieval/base.py +118 -104
  65. mlrun/feature_store/retrieval/dask_merger.py +17 -10
  66. mlrun/feature_store/retrieval/job.py +4 -1
  67. mlrun/feature_store/retrieval/local_merger.py +18 -18
  68. mlrun/feature_store/retrieval/spark_merger.py +21 -14
  69. mlrun/feature_store/retrieval/storey_merger.py +21 -15
  70. mlrun/kfpops.py +3 -9
  71. mlrun/launcher/base.py +3 -3
  72. mlrun/launcher/client.py +3 -2
  73. mlrun/launcher/factory.py +16 -13
  74. mlrun/lists.py +0 -11
  75. mlrun/model.py +9 -15
  76. mlrun/model_monitoring/helpers.py +15 -25
  77. mlrun/model_monitoring/model_monitoring_batch.py +72 -4
  78. mlrun/model_monitoring/prometheus.py +219 -0
  79. mlrun/model_monitoring/stores/__init__.py +15 -9
  80. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +3 -1
  81. mlrun/model_monitoring/stream_processing.py +181 -29
  82. mlrun/package/packager.py +6 -8
  83. mlrun/package/packagers/default_packager.py +121 -10
  84. mlrun/platforms/__init__.py +0 -2
  85. mlrun/platforms/iguazio.py +0 -56
  86. mlrun/projects/pipelines.py +57 -158
  87. mlrun/projects/project.py +6 -32
  88. mlrun/render.py +1 -1
  89. mlrun/run.py +2 -124
  90. mlrun/runtimes/__init__.py +6 -42
  91. mlrun/runtimes/base.py +26 -1241
  92. mlrun/runtimes/daskjob.py +2 -198
  93. mlrun/runtimes/function.py +16 -5
  94. mlrun/runtimes/kubejob.py +5 -29
  95. mlrun/runtimes/mpijob/__init__.py +2 -2
  96. mlrun/runtimes/mpijob/abstract.py +10 -1
  97. mlrun/runtimes/mpijob/v1.py +0 -76
  98. mlrun/runtimes/mpijob/v1alpha1.py +1 -74
  99. mlrun/runtimes/nuclio.py +3 -2
  100. mlrun/runtimes/pod.py +0 -10
  101. mlrun/runtimes/remotesparkjob.py +1 -15
  102. mlrun/runtimes/serving.py +1 -1
  103. mlrun/runtimes/sparkjob/__init__.py +0 -1
  104. mlrun/runtimes/sparkjob/abstract.py +4 -131
  105. mlrun/serving/states.py +1 -1
  106. mlrun/utils/db.py +0 -2
  107. mlrun/utils/helpers.py +19 -13
  108. mlrun/utils/notifications/notification_pusher.py +5 -25
  109. mlrun/utils/regex.py +7 -2
  110. mlrun/utils/version/version.json +2 -2
  111. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/METADATA +24 -23
  112. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/RECORD +116 -107
  113. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/WHEEL +1 -1
  114. mlrun/mlutils/data.py +0 -160
  115. mlrun/mlutils/models.py +0 -78
  116. mlrun/mlutils/plots.py +0 -902
  117. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/LICENSE +0 -0
  118. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/entry_points.txt +0 -0
  119. {mlrun-1.5.0rc1.dist-info → mlrun-1.5.0rc2.dist-info}/top_level.txt +0 -0
mlrun/api/launcher.py CHANGED
@@ -13,6 +13,8 @@
13
13
  # limitations under the License.
14
14
  from typing import Dict, List, Optional, Union
15
15
 
16
+ from dependency_injector import containers, providers
17
+
16
18
  import mlrun.api.crud
17
19
  import mlrun.common.db.sql_session
18
20
  import mlrun.common.schemas.schedule
@@ -26,20 +28,25 @@ import mlrun.runtimes.utils
26
28
  import mlrun.utils
27
29
  import mlrun.utils.regex
28
30
 
29
-
30
- def initialize_launcher():
31
- """Set the factory custom launcher to the server side launcher"""
32
- mlrun.launcher.factory.LauncherFactory().set_launcher(ServerSideLauncher)
31
+ # must be at the bottom to avoid circular import conflicts and can't use 'from' notation because unit tests mock this
32
+ import mlrun.api.api.utils # isort:skip
33
33
 
34
34
 
35
35
  class ServerSideLauncher(launcher.BaseLauncher):
36
- def __init__(self, local: bool = False, **kwargs):
36
+ def __init__(
37
+ self,
38
+ local: bool = False,
39
+ auth_info: Optional[mlrun.common.schemas.AuthInfo] = None,
40
+ **kwargs,
41
+ ):
37
42
  super().__init__(**kwargs)
38
43
  if local:
39
44
  raise mlrun.errors.MLRunInternalServerError(
40
45
  "Launch of local run inside the server is not allowed"
41
46
  )
42
47
 
48
+ self._auth_info = auth_info
49
+
43
50
  def launch(
44
51
  self,
45
52
  runtime: mlrun.runtimes.BaseRuntime,
@@ -158,15 +165,21 @@ class ServerSideLauncher(launcher.BaseLauncher):
158
165
 
159
166
  return self._wrap_run_result(runtime, result, run, err=last_err)
160
167
 
161
- @staticmethod
162
168
  def enrich_runtime(
163
- runtime: "mlrun.runtimes.base.BaseRuntime", project_name: Optional[str] = ""
169
+ self,
170
+ runtime: "mlrun.runtimes.base.BaseRuntime",
171
+ project_name: Optional[str] = "",
164
172
  ):
165
173
  """
166
174
  Enrich the runtime object with the project spec and metadata.
167
175
  This is done only on the server side, since it's the source of truth for the project, and we want to keep the
168
176
  client side enrichment as minimal as possible.
169
177
  """
178
+ if self._auth_info:
179
+ mlrun.api.api.utils.apply_enrichment_and_validation_on_function(
180
+ runtime, self._auth_info
181
+ )
182
+
170
183
  # ensure the runtime has a project before we enrich it with the project's spec
171
184
  runtime.metadata.project = (
172
185
  project_name
@@ -207,3 +220,9 @@ class ServerSideLauncher(launcher.BaseLauncher):
207
220
  struct, runtime.metadata.name, runtime.metadata.project, versioned=True
208
221
  )
209
222
  run.spec.function = runtime._function_uri(hash_key=hash_key)
223
+
224
+
225
+ # Once this file is imported it will set the container server side launcher
226
+ @containers.override(mlrun.launcher.factory.LauncherContainer)
227
+ class ServerSideLauncherContainer(containers.DeclarativeContainer):
228
+ server_side_launcher = providers.Factory(ServerSideLauncher)
mlrun/api/main.py CHANGED
@@ -36,8 +36,8 @@ import mlrun.utils.version
36
36
  from mlrun.api.api.api import api_router
37
37
  from mlrun.api.db.session import close_session, create_session
38
38
  from mlrun.api.initial_data import init_data
39
- from mlrun.api.launcher import initialize_launcher
40
39
  from mlrun.api.middlewares import init_middlewares
40
+ from mlrun.api.runtime_handlers import get_runtime_handler
41
41
  from mlrun.api.utils.periodic import (
42
42
  cancel_all_periodic_functions,
43
43
  cancel_periodic_function,
@@ -53,7 +53,7 @@ from mlrun.api.utils.singletons.project_member import (
53
53
  from mlrun.api.utils.singletons.scheduler import get_scheduler, initialize_scheduler
54
54
  from mlrun.config import config
55
55
  from mlrun.errors import err_to_str
56
- from mlrun.runtimes import RuntimeClassMode, RuntimeKinds, get_runtime_handler
56
+ from mlrun.runtimes import RuntimeClassMode, RuntimeKinds
57
57
  from mlrun.utils import logger
58
58
 
59
59
  API_PREFIX = "/api"
@@ -141,7 +141,6 @@ async def startup_event():
141
141
 
142
142
  initialize_logs_dir()
143
143
  initialize_db()
144
- initialize_launcher()
145
144
 
146
145
  if (
147
146
  config.httpdb.clusterization.worker.sync_with_chief.mode
@@ -618,7 +617,7 @@ def _push_terminal_run_notifications(db: mlrun.api.db.base.DBInterface, db_sessi
618
617
  logger.debug(
619
618
  "Got terminal runs with configured notifications", runs_amount=len(runs)
620
619
  )
621
- mlrun.utils.notifications.NotificationPusher(unmasked_runs).push(db)
620
+ mlrun.utils.notifications.NotificationPusher(unmasked_runs).push()
622
621
 
623
622
  _last_notification_push_time = now
624
623
 
@@ -1,17 +1,13 @@
1
- # Copyright 2023 Iguazio
1
+ # Copyright 2023 MLRun Authors
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
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
- #
15
- # flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
16
- # for backwards compatibility
17
- from ..utils.helpers import create_class, create_function
@@ -15,24 +15,27 @@
15
15
  import datetime
16
16
  from typing import List, Optional, Union
17
17
 
18
+ from dependency_injector import containers, providers
19
+
20
+ import mlrun.api.crud
18
21
  import mlrun.common.schemas
22
+ import mlrun.db.factory
19
23
  import mlrun.model_monitoring.model_endpoint
20
24
  from mlrun.api.db.base import DBError
21
- from mlrun.api.db.sqldb.db import SQLDB as SQLAPIDB
25
+ from mlrun.api.db.sqldb.db import SQLDB
22
26
  from mlrun.common.db.sql_session import create_session
27
+ from mlrun.db import RunDBInterface
23
28
 
24
29
  # This class is a proxy for the real implementation that sits under mlrun.api.db.sqldb
25
30
  # The runtime objects (which manages the resources that do the real logic, like Nuclio functions, Dask jobs, etc...)
26
- # require a RunDB to manage their state, when a user run them locally this db will either be the
27
- # local filedb or the remote httpdb (we decided that we don't want to support SQLDB as an optional RunDB).
31
+ # require a RunDB to manage their state, when a user run them locally this db will be a remote httpdb.
28
32
  # When the user submits something to run (task, function etc...) this runtime managers actually runs inside the api
29
33
  # service, in order to prevent the api from calling itself several times for each submission request (since the runDB
30
34
  # will be httpdb to that same api service) we have this class which is kind of a proxy between the RunDB interface to
31
35
  # the api service's DB interface
32
- from .base import RunDBError, RunDBInterface
33
36
 
34
37
 
35
- class SQLDB(RunDBInterface):
38
+ class SQLRunDB(RunDBInterface):
36
39
  def __init__(
37
40
  self,
38
41
  dsn,
@@ -45,12 +48,10 @@ class SQLDB(RunDBInterface):
45
48
  def connect(self, secrets=None):
46
49
  if not self.session:
47
50
  self.session = create_session()
48
- self.db = SQLAPIDB(self.dsn)
51
+ self.db = SQLDB(self.dsn)
49
52
  return self
50
53
 
51
54
  def store_log(self, uid, project="", body=b"", append=False):
52
- import mlrun.api.crud
53
-
54
55
  return self._transform_db_error(
55
56
  mlrun.api.crud.Logs().store_log,
56
57
  body,
@@ -71,8 +72,6 @@ class SQLDB(RunDBInterface):
71
72
  )
72
73
 
73
74
  def store_run(self, struct, uid, project="", iter=0):
74
- import mlrun.api.crud
75
-
76
75
  return self._transform_db_error(
77
76
  mlrun.api.crud.Runs().store_run,
78
77
  self.session,
@@ -83,8 +82,6 @@ class SQLDB(RunDBInterface):
83
82
  )
84
83
 
85
84
  def update_run(self, updates: dict, uid, project="", iter=0):
86
- import mlrun.api.crud
87
-
88
85
  return self._transform_db_error(
89
86
  mlrun.api.crud.Runs().update_run,
90
87
  self.session,
@@ -98,8 +95,6 @@ class SQLDB(RunDBInterface):
98
95
  raise NotImplementedError()
99
96
 
100
97
  def read_run(self, uid, project=None, iter=None):
101
- import mlrun.api.crud
102
-
103
98
  return self._transform_db_error(
104
99
  mlrun.api.crud.Runs().get_run,
105
100
  self.session,
@@ -131,8 +126,6 @@ class SQLDB(RunDBInterface):
131
126
  max_partitions: int = 0,
132
127
  with_notifications: bool = False,
133
128
  ):
134
- import mlrun.api.crud
135
-
136
129
  return self._transform_db_error(
137
130
  mlrun.api.crud.Runs().list_runs,
138
131
  self.session,
@@ -157,8 +150,6 @@ class SQLDB(RunDBInterface):
157
150
  )
158
151
 
159
152
  def del_run(self, uid, project=None, iter=None):
160
- import mlrun.api.crud
161
-
162
153
  return self._transform_db_error(
163
154
  mlrun.api.crud.Runs().delete_run,
164
155
  self.session,
@@ -168,8 +159,6 @@ class SQLDB(RunDBInterface):
168
159
  )
169
160
 
170
161
  def del_runs(self, name=None, project=None, labels=None, state=None, days_ago=0):
171
- import mlrun.api.crud
172
-
173
162
  return self._transform_db_error(
174
163
  mlrun.api.crud.Runs().delete_runs,
175
164
  self.session,
@@ -181,8 +170,6 @@ class SQLDB(RunDBInterface):
181
170
  )
182
171
 
183
172
  def store_artifact(self, key, artifact, uid, iter=None, tag="", project=""):
184
- import mlrun.api.crud
185
-
186
173
  return self._transform_db_error(
187
174
  mlrun.api.crud.Artifacts().store_artifact,
188
175
  self.session,
@@ -195,8 +182,6 @@ class SQLDB(RunDBInterface):
195
182
  )
196
183
 
197
184
  def read_artifact(self, key, tag="", iter=None, project=""):
198
- import mlrun.api.crud
199
-
200
185
  return self._transform_db_error(
201
186
  mlrun.api.crud.Artifacts().get_artifact,
202
187
  self.session,
@@ -219,8 +204,6 @@ class SQLDB(RunDBInterface):
219
204
  kind: str = None,
220
205
  category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
221
206
  ):
222
- import mlrun.api.crud
223
-
224
207
  if category and isinstance(category, str):
225
208
  category = mlrun.common.schemas.ArtifactCategories(category)
226
209
 
@@ -240,8 +223,6 @@ class SQLDB(RunDBInterface):
240
223
  )
241
224
 
242
225
  def del_artifact(self, key, tag="", project=""):
243
- import mlrun.api.crud
244
-
245
226
  return self._transform_db_error(
246
227
  mlrun.api.crud.Artifacts().delete_artifact,
247
228
  self.session,
@@ -251,8 +232,6 @@ class SQLDB(RunDBInterface):
251
232
  )
252
233
 
253
234
  def del_artifacts(self, name="", project="", tag="", labels=None):
254
- import mlrun.api.crud
255
-
256
235
  return self._transform_db_error(
257
236
  mlrun.api.crud.Artifacts().delete_artifacts,
258
237
  self.session,
@@ -263,8 +242,6 @@ class SQLDB(RunDBInterface):
263
242
  )
264
243
 
265
244
  def store_function(self, function, name, project="", tag="", versioned=False):
266
- import mlrun.api.crud
267
-
268
245
  return self._transform_db_error(
269
246
  mlrun.api.crud.Functions().store_function,
270
247
  self.session,
@@ -276,8 +253,6 @@ class SQLDB(RunDBInterface):
276
253
  )
277
254
 
278
255
  def get_function(self, name, project="", tag="", hash_key=""):
279
- import mlrun.api.crud
280
-
281
256
  return self._transform_db_error(
282
257
  mlrun.api.crud.Functions().get_function,
283
258
  self.session,
@@ -288,8 +263,6 @@ class SQLDB(RunDBInterface):
288
263
  )
289
264
 
290
265
  def delete_function(self, name: str, project: str = ""):
291
- import mlrun.api.crud
292
-
293
266
  return self._transform_db_error(
294
267
  mlrun.api.crud.Functions().delete_function,
295
268
  self.session,
@@ -298,8 +271,6 @@ class SQLDB(RunDBInterface):
298
271
  )
299
272
 
300
273
  def list_functions(self, name=None, project=None, tag=None, labels=None):
301
- import mlrun.api.crud
302
-
303
274
  return self._transform_db_error(
304
275
  mlrun.api.crud.Functions().list_functions,
305
276
  db_session=self.session,
@@ -325,8 +296,6 @@ class SQLDB(RunDBInterface):
325
296
  tag_objects: mlrun.common.schemas.TagObjects,
326
297
  replace: bool = False,
327
298
  ):
328
- import mlrun.api.crud
329
-
330
299
  if replace:
331
300
  return self._transform_db_error(
332
301
  mlrun.api.crud.Tags().overwrite_object_tags_with_tag,
@@ -350,8 +319,6 @@ class SQLDB(RunDBInterface):
350
319
  tag_name: str,
351
320
  tag_objects: mlrun.common.schemas.TagObjects,
352
321
  ):
353
- import mlrun.api.crud
354
-
355
322
  return self._transform_db_error(
356
323
  mlrun.api.crud.Tags().delete_tag_from_objects,
357
324
  self.session,
@@ -399,8 +366,6 @@ class SQLDB(RunDBInterface):
399
366
  name: str,
400
367
  project: mlrun.common.schemas.Project,
401
368
  ) -> mlrun.common.schemas.Project:
402
- import mlrun.api.crud
403
-
404
369
  if isinstance(project, dict):
405
370
  project = mlrun.common.schemas.Project(**project)
406
371
 
@@ -417,8 +382,6 @@ class SQLDB(RunDBInterface):
417
382
  project: dict,
418
383
  patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
419
384
  ) -> mlrun.common.schemas.Project:
420
- import mlrun.api.crud
421
-
422
385
  return self._transform_db_error(
423
386
  mlrun.api.crud.Projects().patch_project,
424
387
  self.session,
@@ -431,8 +394,6 @@ class SQLDB(RunDBInterface):
431
394
  self,
432
395
  project: mlrun.common.schemas.Project,
433
396
  ) -> mlrun.common.schemas.Project:
434
- import mlrun.api.crud
435
-
436
397
  return self._transform_db_error(
437
398
  mlrun.api.crud.Projects().create_project,
438
399
  self.session,
@@ -444,8 +405,6 @@ class SQLDB(RunDBInterface):
444
405
  name: str,
445
406
  deletion_strategy: mlrun.common.schemas.DeletionStrategy = mlrun.common.schemas.DeletionStrategy.default(),
446
407
  ):
447
- import mlrun.api.crud
448
-
449
408
  return self._transform_db_error(
450
409
  mlrun.api.crud.Projects().delete_project,
451
410
  self.session,
@@ -456,8 +415,6 @@ class SQLDB(RunDBInterface):
456
415
  def get_project(
457
416
  self, name: str = None, project_id: int = None
458
417
  ) -> mlrun.common.schemas.Project:
459
- import mlrun.api.crud
460
-
461
418
  return self._transform_db_error(
462
419
  mlrun.api.crud.Projects().get_project,
463
420
  self.session,
@@ -471,8 +428,6 @@ class SQLDB(RunDBInterface):
471
428
  labels: List[str] = None,
472
429
  state: mlrun.common.schemas.ProjectState = None,
473
430
  ) -> mlrun.common.schemas.ProjectsOutput:
474
- import mlrun.api.crud
475
-
476
431
  return self._transform_db_error(
477
432
  mlrun.api.crud.Projects().list_projects,
478
433
  self.session,
@@ -487,11 +442,9 @@ class SQLDB(RunDBInterface):
487
442
  try:
488
443
  return func(*args, **kwargs)
489
444
  except DBError as exc:
490
- raise RunDBError(exc.args)
445
+ raise mlrun.db.RunDBError(exc.args)
491
446
 
492
447
  def create_feature_set(self, feature_set, project="", versioned=True):
493
- import mlrun.api.crud
494
-
495
448
  return self._transform_db_error(
496
449
  mlrun.api.crud.FeatureStore().create_feature_set,
497
450
  self.session,
@@ -503,8 +456,6 @@ class SQLDB(RunDBInterface):
503
456
  def get_feature_set(
504
457
  self, name: str, project: str = "", tag: str = None, uid: str = None
505
458
  ):
506
- import mlrun.api.crud
507
-
508
459
  feature_set = self._transform_db_error(
509
460
  mlrun.api.crud.FeatureStore().get_feature_set,
510
461
  self.session,
@@ -523,8 +474,6 @@ class SQLDB(RunDBInterface):
523
474
  entities: List[str] = None,
524
475
  labels: List[str] = None,
525
476
  ):
526
- import mlrun.api.crud
527
-
528
477
  return self._transform_db_error(
529
478
  mlrun.api.crud.FeatureStore().list_features,
530
479
  self.session,
@@ -542,8 +491,6 @@ class SQLDB(RunDBInterface):
542
491
  tag: str = None,
543
492
  labels: List[str] = None,
544
493
  ):
545
- import mlrun.api.crud
546
-
547
494
  return self._transform_db_error(
548
495
  mlrun.api.crud.FeatureStore().list_entities,
549
496
  self.session,
@@ -567,8 +514,6 @@ class SQLDB(RunDBInterface):
567
514
  partition_sort_by: mlrun.common.schemas.SortField = None,
568
515
  partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
569
516
  ):
570
- import mlrun.api.crud
571
-
572
517
  return self._transform_db_error(
573
518
  mlrun.api.crud.FeatureStore().list_feature_sets,
574
519
  self.session,
@@ -594,8 +539,6 @@ class SQLDB(RunDBInterface):
594
539
  uid=None,
595
540
  versioned=True,
596
541
  ):
597
- import mlrun.api.crud
598
-
599
542
  if isinstance(feature_set, dict):
600
543
  feature_set = mlrun.common.schemas.FeatureSet(**feature_set)
601
544
 
@@ -615,8 +558,6 @@ class SQLDB(RunDBInterface):
615
558
  def patch_feature_set(
616
559
  self, name, feature_set, project="", tag=None, uid=None, patch_mode="replace"
617
560
  ):
618
- import mlrun.api.crud
619
-
620
561
  return self._transform_db_error(
621
562
  mlrun.api.crud.FeatureStore().patch_feature_set,
622
563
  self.session,
@@ -629,8 +570,6 @@ class SQLDB(RunDBInterface):
629
570
  )
630
571
 
631
572
  def delete_feature_set(self, name, project="", tag=None, uid=None):
632
- import mlrun.api.crud
633
-
634
573
  return self._transform_db_error(
635
574
  mlrun.api.crud.FeatureStore().delete_feature_set,
636
575
  self.session,
@@ -641,8 +580,6 @@ class SQLDB(RunDBInterface):
641
580
  )
642
581
 
643
582
  def create_feature_vector(self, feature_vector, project="", versioned=True):
644
- import mlrun.api.crud
645
-
646
583
  return self._transform_db_error(
647
584
  mlrun.api.crud.FeatureStore().create_feature_vector,
648
585
  self.session,
@@ -654,8 +591,6 @@ class SQLDB(RunDBInterface):
654
591
  def get_feature_vector(
655
592
  self, name: str, project: str = "", tag: str = None, uid: str = None
656
593
  ):
657
- import mlrun.api.crud
658
-
659
594
  return self._transform_db_error(
660
595
  mlrun.api.crud.FeatureStore().get_feature_vector,
661
596
  self.session,
@@ -677,8 +612,6 @@ class SQLDB(RunDBInterface):
677
612
  partition_sort_by: mlrun.common.schemas.SortField = None,
678
613
  partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
679
614
  ):
680
- import mlrun.api.crud
681
-
682
615
  return self._transform_db_error(
683
616
  mlrun.api.crud.FeatureStore().list_feature_vectors,
684
617
  self.session,
@@ -702,8 +635,6 @@ class SQLDB(RunDBInterface):
702
635
  uid=None,
703
636
  versioned=True,
704
637
  ):
705
- import mlrun.api.crud
706
-
707
638
  return self._transform_db_error(
708
639
  mlrun.api.crud.FeatureStore().store_feature_vector,
709
640
  self.session,
@@ -724,8 +655,6 @@ class SQLDB(RunDBInterface):
724
655
  uid=None,
725
656
  patch_mode="replace",
726
657
  ):
727
- import mlrun.api.crud
728
-
729
658
  return self._transform_db_error(
730
659
  mlrun.api.crud.FeatureStore().patch_feature_vector,
731
660
  self.session,
@@ -738,8 +667,6 @@ class SQLDB(RunDBInterface):
738
667
  )
739
668
 
740
669
  def delete_feature_vector(self, name, project="", tag=None, uid=None):
741
- import mlrun.api.crud
742
-
743
670
  return self._transform_db_error(
744
671
  mlrun.api.crud.FeatureStore().delete_feature_vector,
745
672
  self.session,
@@ -749,6 +676,22 @@ class SQLDB(RunDBInterface):
749
676
  uid,
750
677
  )
751
678
 
679
+ def store_run_notifications(
680
+ self,
681
+ notification_objects: List[mlrun.model.Notification],
682
+ run_uid: str,
683
+ project: str = None,
684
+ mask_params: bool = True,
685
+ ):
686
+ return self._transform_db_error(
687
+ mlrun.api.crud.Notifications().store_run_notifications,
688
+ self.session,
689
+ notification_objects,
690
+ run_uid,
691
+ project,
692
+ mask_params,
693
+ )
694
+
752
695
  def list_pipelines(
753
696
  self,
754
697
  project: str,
@@ -909,3 +852,12 @@ class SQLDB(RunDBInterface):
909
852
  # on server side authorization is done in endpoint anyway, so for server side we can "pass" on check
910
853
  # done from ingest()
911
854
  pass
855
+
856
+ def watch_log(self, uid, project="", watch=True, offset=0):
857
+ raise NotImplementedError("Watching logs is not supported on the server")
858
+
859
+
860
+ # Once this file is imported it will override the default RunDB implementation (RunDBContainer)
861
+ @containers.override(mlrun.db.factory.RunDBContainer)
862
+ class SQLRunDBContainer(containers.DeclarativeContainer):
863
+ run_db = providers.Factory(SQLRunDB)
@@ -0,0 +1,56 @@
1
+ # Copyright 2023 Iguazio
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ from mlrun.api.runtime_handlers.base import BaseRuntimeHandler
16
+ from mlrun.api.runtime_handlers.daskjob import DaskRuntimeHandler
17
+ from mlrun.api.runtime_handlers.kubejob import KubeRuntimeHandler
18
+ from mlrun.api.runtime_handlers.mpijob import (
19
+ MpiV1Alpha1RuntimeHandler,
20
+ MpiV1RuntimeHandler,
21
+ )
22
+ from mlrun.api.runtime_handlers.remotesparkjob import RemoteSparkRuntimeHandler
23
+ from mlrun.api.runtime_handlers.sparkjob import SparkRuntimeHandler
24
+ from mlrun.runtimes import MPIJobCRDVersions, RuntimeKinds, resolve_mpijob_crd_version
25
+
26
+ runtime_handler_instances_cache = {}
27
+
28
+
29
+ def get_runtime_handler(kind: str) -> BaseRuntimeHandler:
30
+ global runtime_handler_instances_cache
31
+ if kind == RuntimeKinds.mpijob:
32
+ # TODO: split resolve_mpijob_crd_version to client and server side
33
+ mpijob_crd_version = resolve_mpijob_crd_version()
34
+ crd_version_to_runtime_handler_class = {
35
+ MPIJobCRDVersions.v1alpha1: MpiV1Alpha1RuntimeHandler,
36
+ MPIJobCRDVersions.v1: MpiV1RuntimeHandler,
37
+ }
38
+ runtime_handler_class = crd_version_to_runtime_handler_class[mpijob_crd_version]
39
+ if not runtime_handler_instances_cache.setdefault(RuntimeKinds.mpijob, {}).get(
40
+ mpijob_crd_version
41
+ ):
42
+ runtime_handler_instances_cache[RuntimeKinds.mpijob][
43
+ mpijob_crd_version
44
+ ] = runtime_handler_class()
45
+ return runtime_handler_instances_cache[RuntimeKinds.mpijob][mpijob_crd_version]
46
+
47
+ kind_runtime_handler_map = {
48
+ RuntimeKinds.dask: DaskRuntimeHandler,
49
+ RuntimeKinds.spark: SparkRuntimeHandler,
50
+ RuntimeKinds.remotespark: RemoteSparkRuntimeHandler,
51
+ RuntimeKinds.job: KubeRuntimeHandler,
52
+ }
53
+ runtime_handler_class = kind_runtime_handler_map[kind]
54
+ if not runtime_handler_instances_cache.get(kind):
55
+ runtime_handler_instances_cache[kind] = runtime_handler_class()
56
+ return runtime_handler_instances_cache[kind]