mlrun 1.3.2rc1__py3-none-any.whl → 1.3.2rc2__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 (93) hide show
  1. mlrun/api/api/deps.py +14 -1
  2. mlrun/api/api/endpoints/frontend_spec.py +0 -2
  3. mlrun/api/api/endpoints/functions.py +15 -27
  4. mlrun/api/api/endpoints/grafana_proxy.py +435 -74
  5. mlrun/api/api/endpoints/healthz.py +5 -18
  6. mlrun/api/api/endpoints/model_endpoints.py +33 -37
  7. mlrun/api/api/utils.py +6 -13
  8. mlrun/api/crud/__init__.py +14 -16
  9. mlrun/api/crud/logs.py +5 -7
  10. mlrun/api/crud/model_monitoring/__init__.py +2 -2
  11. mlrun/api/crud/model_monitoring/model_endpoint_store.py +847 -0
  12. mlrun/api/crud/model_monitoring/model_endpoints.py +105 -328
  13. mlrun/api/crud/pipelines.py +2 -3
  14. mlrun/api/db/sqldb/models/models_mysql.py +52 -19
  15. mlrun/api/db/sqldb/models/models_sqlite.py +52 -19
  16. mlrun/api/db/sqldb/session.py +19 -26
  17. mlrun/api/schemas/__init__.py +2 -0
  18. mlrun/api/schemas/constants.py +0 -13
  19. mlrun/api/schemas/frontend_spec.py +0 -1
  20. mlrun/api/schemas/model_endpoints.py +38 -195
  21. mlrun/api/schemas/schedule.py +2 -2
  22. mlrun/api/utils/clients/log_collector.py +5 -0
  23. mlrun/builder.py +9 -41
  24. mlrun/config.py +1 -76
  25. mlrun/data_types/__init__.py +1 -6
  26. mlrun/data_types/data_types.py +1 -3
  27. mlrun/datastore/__init__.py +2 -9
  28. mlrun/datastore/sources.py +20 -25
  29. mlrun/datastore/store_resources.py +1 -1
  30. mlrun/datastore/targets.py +34 -67
  31. mlrun/datastore/utils.py +4 -26
  32. mlrun/db/base.py +2 -4
  33. mlrun/db/filedb.py +5 -13
  34. mlrun/db/httpdb.py +32 -64
  35. mlrun/db/sqldb.py +2 -4
  36. mlrun/errors.py +0 -5
  37. mlrun/execution.py +0 -2
  38. mlrun/feature_store/api.py +8 -24
  39. mlrun/feature_store/feature_set.py +6 -28
  40. mlrun/feature_store/feature_vector.py +0 -2
  41. mlrun/feature_store/ingestion.py +11 -8
  42. mlrun/feature_store/retrieval/base.py +43 -271
  43. mlrun/feature_store/retrieval/dask_merger.py +153 -55
  44. mlrun/feature_store/retrieval/job.py +3 -12
  45. mlrun/feature_store/retrieval/local_merger.py +130 -48
  46. mlrun/feature_store/retrieval/spark_merger.py +125 -126
  47. mlrun/features.py +2 -7
  48. mlrun/model_monitoring/constants.py +6 -48
  49. mlrun/model_monitoring/helpers.py +35 -118
  50. mlrun/model_monitoring/model_monitoring_batch.py +260 -293
  51. mlrun/model_monitoring/stream_processing_fs.py +253 -220
  52. mlrun/platforms/iguazio.py +0 -33
  53. mlrun/projects/project.py +72 -34
  54. mlrun/runtimes/base.py +0 -5
  55. mlrun/runtimes/daskjob.py +0 -2
  56. mlrun/runtimes/function.py +3 -29
  57. mlrun/runtimes/kubejob.py +15 -39
  58. mlrun/runtimes/local.py +45 -7
  59. mlrun/runtimes/mpijob/abstract.py +0 -2
  60. mlrun/runtimes/mpijob/v1.py +0 -2
  61. mlrun/runtimes/pod.py +0 -2
  62. mlrun/runtimes/remotesparkjob.py +0 -2
  63. mlrun/runtimes/serving.py +0 -6
  64. mlrun/runtimes/sparkjob/abstract.py +2 -39
  65. mlrun/runtimes/sparkjob/spark3job.py +0 -2
  66. mlrun/serving/__init__.py +1 -2
  67. mlrun/serving/routers.py +35 -35
  68. mlrun/serving/server.py +12 -22
  69. mlrun/serving/states.py +30 -162
  70. mlrun/serving/v2_serving.py +10 -13
  71. mlrun/utils/clones.py +1 -1
  72. mlrun/utils/model_monitoring.py +96 -122
  73. mlrun/utils/version/version.json +2 -2
  74. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/METADATA +27 -23
  75. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/RECORD +79 -92
  76. mlrun/api/crud/model_monitoring/grafana.py +0 -427
  77. mlrun/datastore/spark_udf.py +0 -40
  78. mlrun/model_monitoring/__init__.py +0 -44
  79. mlrun/model_monitoring/common.py +0 -112
  80. mlrun/model_monitoring/model_endpoint.py +0 -141
  81. mlrun/model_monitoring/stores/__init__.py +0 -106
  82. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +0 -448
  83. mlrun/model_monitoring/stores/model_endpoint_store.py +0 -147
  84. mlrun/model_monitoring/stores/models/__init__.py +0 -23
  85. mlrun/model_monitoring/stores/models/base.py +0 -18
  86. mlrun/model_monitoring/stores/models/mysql.py +0 -100
  87. mlrun/model_monitoring/stores/models/sqlite.py +0 -98
  88. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -375
  89. mlrun/utils/db.py +0 -52
  90. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/LICENSE +0 -0
  91. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/WHEEL +0 -0
  92. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/entry_points.txt +0 -0
  93. {mlrun-1.3.2rc1.dist-info → mlrun-1.3.2rc2.dist-info}/top_level.txt +0 -0
@@ -47,9 +47,9 @@ class Pipelines(
47
47
  format_: mlrun.api.schemas.PipelinesFormat = mlrun.api.schemas.PipelinesFormat.metadata_only,
48
48
  page_size: typing.Optional[int] = None,
49
49
  ) -> typing.Tuple[int, typing.Optional[int], typing.List[dict]]:
50
- if project != "*" and (page_token or page_size):
50
+ if project != "*" and (page_token or page_size or sort_by):
51
51
  raise mlrun.errors.MLRunInvalidArgumentError(
52
- "Filtering by project can not be used together with pagination"
52
+ "Filtering by project can not be used together with pagination, or sorting"
53
53
  )
54
54
  if format_ == mlrun.api.schemas.PipelinesFormat.summary:
55
55
  # we don't support summary format in list pipelines since the returned runs doesn't include the workflow
@@ -73,7 +73,6 @@ class Pipelines(
73
73
  response = kfp_client._run_api.list_runs(
74
74
  page_token=page_token,
75
75
  page_size=mlrun.api.schemas.PipelinesPagination.max_page_size,
76
- sort_by=sort_by,
77
76
  filter=filter_ if page_token == "" else "",
78
77
  )
79
78
  run_dicts.extend([run.to_dict() for run in response.runs or []])
@@ -30,9 +30,8 @@ from sqlalchemy import (
30
30
  UniqueConstraint,
31
31
  )
32
32
  from sqlalchemy.ext.declarative import declarative_base
33
- from sqlalchemy.orm import relationship
33
+ from sqlalchemy.orm import class_mapper, relationship
34
34
 
35
- import mlrun.utils.db
36
35
  from mlrun.api import schemas
37
36
  from mlrun.api.utils.db.sql_collation import SQLCollationUtil
38
37
 
@@ -41,8 +40,42 @@ NULL = None # Avoid flake8 issuing warnings when comparing in filter
41
40
  run_time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
42
41
 
43
42
 
43
+ class BaseModel:
44
+ def to_dict(self, exclude=None):
45
+ """
46
+ NOTE - this function (currently) does not handle serializing relationships
47
+ """
48
+ exclude = exclude or []
49
+ mapper = class_mapper(self.__class__)
50
+ columns = [column.key for column in mapper.columns if column.key not in exclude]
51
+ get_key_value = (
52
+ lambda c: (c, getattr(self, c).isoformat())
53
+ if isinstance(getattr(self, c), datetime)
54
+ else (c, getattr(self, c))
55
+ )
56
+ return dict(map(get_key_value, columns))
57
+
58
+
59
+ class HasStruct(BaseModel):
60
+ @property
61
+ def struct(self):
62
+ return pickle.loads(self.body)
63
+
64
+ @struct.setter
65
+ def struct(self, value):
66
+ self.body = pickle.dumps(value)
67
+
68
+ def to_dict(self, exclude=None):
69
+ """
70
+ NOTE - this function (currently) does not handle serializing relationships
71
+ """
72
+ exclude = exclude or []
73
+ exclude.append("body")
74
+ return super().to_dict(exclude)
75
+
76
+
44
77
  def make_label(table):
45
- class Label(Base, mlrun.utils.db.BaseModel):
78
+ class Label(Base, BaseModel):
46
79
  __tablename__ = f"{table}_labels"
47
80
  __table_args__ = (
48
81
  UniqueConstraint("name", "parent", name=f"_{table}_labels_uc"),
@@ -57,7 +90,7 @@ def make_label(table):
57
90
 
58
91
 
59
92
  def make_tag(table):
60
- class Tag(Base, mlrun.utils.db.BaseModel):
93
+ class Tag(Base, BaseModel):
61
94
  __tablename__ = f"{table}_tags"
62
95
  __table_args__ = (
63
96
  UniqueConstraint("project", "name", "obj_id", name=f"_{table}_tags_uc"),
@@ -74,7 +107,7 @@ def make_tag(table):
74
107
  # TODO: don't want to refactor everything in one PR so splitting this function to 2 versions - eventually only this one
75
108
  # should be used
76
109
  def make_tag_v2(table):
77
- class Tag(Base, mlrun.utils.db.BaseModel):
110
+ class Tag(Base, BaseModel):
78
111
  __tablename__ = f"{table}_tags"
79
112
  __table_args__ = (
80
113
  UniqueConstraint("project", "name", "obj_name", name=f"_{table}_tags_uc"),
@@ -93,7 +126,7 @@ def make_tag_v2(table):
93
126
  with warnings.catch_warnings():
94
127
  warnings.simplefilter("ignore")
95
128
 
96
- class Artifact(Base, mlrun.utils.db.HasStruct):
129
+ class Artifact(Base, HasStruct):
97
130
  __tablename__ = "artifacts"
98
131
  __table_args__ = (
99
132
  UniqueConstraint("uid", "project", "key", name="_artifacts_uc"),
@@ -116,7 +149,7 @@ with warnings.catch_warnings():
116
149
  def get_identifier_string(self) -> str:
117
150
  return f"{self.project}/{self.key}/{self.uid}"
118
151
 
119
- class Function(Base, mlrun.utils.db.HasStruct):
152
+ class Function(Base, HasStruct):
120
153
  __tablename__ = "functions"
121
154
  __table_args__ = (
122
155
  UniqueConstraint("name", "project", "uid", name="_functions_uc"),
@@ -139,7 +172,7 @@ with warnings.catch_warnings():
139
172
  def get_identifier_string(self) -> str:
140
173
  return f"{self.project}/{self.name}/{self.uid}"
141
174
 
142
- class Log(Base, mlrun.utils.db.BaseModel):
175
+ class Log(Base, BaseModel):
143
176
  __tablename__ = "logs"
144
177
 
145
178
  id = Column(Integer, primary_key=True)
@@ -151,7 +184,7 @@ with warnings.catch_warnings():
151
184
  def get_identifier_string(self) -> str:
152
185
  return f"{self.project}/{self.uid}"
153
186
 
154
- class Run(Base, mlrun.utils.db.HasStruct):
187
+ class Run(Base, HasStruct):
155
188
  __tablename__ = "runs"
156
189
  __table_args__ = (
157
190
  UniqueConstraint("uid", "project", "iteration", name="_runs_uc"),
@@ -186,7 +219,7 @@ with warnings.catch_warnings():
186
219
  def get_identifier_string(self) -> str:
187
220
  return f"{self.project}/{self.uid}/{self.iteration}"
188
221
 
189
- class BackgroundTask(Base, mlrun.utils.db.BaseModel):
222
+ class BackgroundTask(Base, BaseModel):
190
223
  __tablename__ = "background_tasks"
191
224
  __table_args__ = (
192
225
  UniqueConstraint("name", "project", name="_background_tasks_uc"),
@@ -210,7 +243,7 @@ with warnings.catch_warnings():
210
243
  state = Column(String(255, collation=SQLCollationUtil.collation()))
211
244
  timeout = Column(Integer)
212
245
 
213
- class Schedule(Base, mlrun.utils.db.BaseModel):
246
+ class Schedule(Base, BaseModel):
214
247
  __tablename__ = "schedules_v2"
215
248
  __table_args__ = (UniqueConstraint("project", "name", name="_schedules_v2_uc"),)
216
249
 
@@ -262,14 +295,14 @@ with warnings.catch_warnings():
262
295
  Column("user_id", Integer, ForeignKey("users.id")),
263
296
  )
264
297
 
265
- class User(Base, mlrun.utils.db.BaseModel):
298
+ class User(Base, BaseModel):
266
299
  __tablename__ = "users"
267
300
  __table_args__ = (UniqueConstraint("name", name="_users_uc"),)
268
301
 
269
302
  id = Column(Integer, primary_key=True)
270
303
  name = Column(String(255, collation=SQLCollationUtil.collation()))
271
304
 
272
- class Project(Base, mlrun.utils.db.BaseModel):
305
+ class Project(Base, BaseModel):
273
306
  __tablename__ = "projects"
274
307
  # For now since we use project name a lot
275
308
  __table_args__ = (UniqueConstraint("name", name="_projects_uc"),)
@@ -305,7 +338,7 @@ with warnings.catch_warnings():
305
338
  def full_object(self, value):
306
339
  self._full_object = pickle.dumps(value)
307
340
 
308
- class Feature(Base, mlrun.utils.db.BaseModel):
341
+ class Feature(Base, BaseModel):
309
342
  __tablename__ = "features"
310
343
  id = Column(Integer, primary_key=True)
311
344
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -319,7 +352,7 @@ with warnings.catch_warnings():
319
352
  def get_identifier_string(self) -> str:
320
353
  return f"{self.project}/{self.name}"
321
354
 
322
- class Entity(Base, mlrun.utils.db.BaseModel):
355
+ class Entity(Base, BaseModel):
323
356
  __tablename__ = "entities"
324
357
  id = Column(Integer, primary_key=True)
325
358
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -333,7 +366,7 @@ with warnings.catch_warnings():
333
366
  def get_identifier_string(self) -> str:
334
367
  return f"{self.project}/{self.name}"
335
368
 
336
- class FeatureSet(Base, mlrun.utils.db.BaseModel):
369
+ class FeatureSet(Base, BaseModel):
337
370
  __tablename__ = "feature_sets"
338
371
  __table_args__ = (
339
372
  UniqueConstraint("name", "project", "uid", name="_feature_set_uc"),
@@ -377,7 +410,7 @@ with warnings.catch_warnings():
377
410
  # TODO - convert to pickle, to avoid issues with non-json serializable fields such as datetime
378
411
  self._full_object = json.dumps(value, default=str)
379
412
 
380
- class FeatureVector(Base, mlrun.utils.db.BaseModel):
413
+ class FeatureVector(Base, BaseModel):
381
414
  __tablename__ = "feature_vectors"
382
415
  __table_args__ = (
383
416
  UniqueConstraint("name", "project", "uid", name="_feature_vectors_uc"),
@@ -418,7 +451,7 @@ with warnings.catch_warnings():
418
451
  # TODO - convert to pickle, to avoid issues with non-json serializable fields such as datetime
419
452
  self._full_object = json.dumps(value, default=str)
420
453
 
421
- class MarketplaceSource(Base, mlrun.utils.db.BaseModel):
454
+ class MarketplaceSource(Base, BaseModel):
422
455
  __tablename__ = "marketplace_sources"
423
456
  __table_args__ = (UniqueConstraint("name", name="_marketplace_sources_uc"),)
424
457
 
@@ -449,7 +482,7 @@ with warnings.catch_warnings():
449
482
  # TODO - convert to pickle, to avoid issues with non-json serializable fields such as datetime
450
483
  self._full_object = json.dumps(value, default=str)
451
484
 
452
- class DataVersion(Base, mlrun.utils.db.BaseModel):
485
+ class DataVersion(Base, BaseModel):
453
486
  __tablename__ = "data_versions"
454
487
  __table_args__ = (UniqueConstraint("version", name="_versions_uc"),)
455
488
 
@@ -31,9 +31,8 @@ from sqlalchemy import (
31
31
  UniqueConstraint,
32
32
  )
33
33
  from sqlalchemy.ext.declarative import declarative_base
34
- from sqlalchemy.orm import relationship
34
+ from sqlalchemy.orm import class_mapper, relationship
35
35
 
36
- import mlrun.utils.db
37
36
  from mlrun.api import schemas
38
37
  from mlrun.api.utils.db.sql_collation import SQLCollationUtil
39
38
 
@@ -42,8 +41,42 @@ NULL = None # Avoid flake8 issuing warnings when comparing in filter
42
41
  run_time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
43
42
 
44
43
 
44
+ class BaseModel:
45
+ def to_dict(self, exclude=None):
46
+ """
47
+ NOTE - this function (currently) does not handle serializing relationships
48
+ """
49
+ exclude = exclude or []
50
+ mapper = class_mapper(self.__class__)
51
+ columns = [column.key for column in mapper.columns if column.key not in exclude]
52
+ get_key_value = (
53
+ lambda c: (c, getattr(self, c).isoformat())
54
+ if isinstance(getattr(self, c), datetime)
55
+ else (c, getattr(self, c))
56
+ )
57
+ return dict(map(get_key_value, columns))
58
+
59
+
60
+ class HasStruct(BaseModel):
61
+ @property
62
+ def struct(self):
63
+ return pickle.loads(self.body)
64
+
65
+ @struct.setter
66
+ def struct(self, value):
67
+ self.body = pickle.dumps(value)
68
+
69
+ def to_dict(self, exclude=None):
70
+ """
71
+ NOTE - this function (currently) does not handle serializing relationships
72
+ """
73
+ exclude = exclude or []
74
+ exclude.append("body")
75
+ return super().to_dict(exclude)
76
+
77
+
45
78
  def make_label(table):
46
- class Label(Base, mlrun.utils.db.BaseModel):
79
+ class Label(Base, BaseModel):
47
80
  __tablename__ = f"{table}_labels"
48
81
  __table_args__ = (
49
82
  UniqueConstraint("name", "parent", name=f"_{table}_labels_uc"),
@@ -58,7 +91,7 @@ def make_label(table):
58
91
 
59
92
 
60
93
  def make_tag(table):
61
- class Tag(Base, mlrun.utils.db.BaseModel):
94
+ class Tag(Base, BaseModel):
62
95
  __tablename__ = f"{table}_tags"
63
96
  __table_args__ = (
64
97
  UniqueConstraint("project", "name", "obj_id", name=f"_{table}_tags_uc"),
@@ -75,7 +108,7 @@ def make_tag(table):
75
108
  # TODO: don't want to refactor everything in one PR so splitting this function to 2 versions - eventually only this one
76
109
  # should be used
77
110
  def make_tag_v2(table):
78
- class Tag(Base, mlrun.utils.db.BaseModel):
111
+ class Tag(Base, BaseModel):
79
112
  __tablename__ = f"{table}_tags"
80
113
  __table_args__ = (
81
114
  UniqueConstraint("project", "name", "obj_name", name=f"_{table}_tags_uc"),
@@ -97,7 +130,7 @@ def make_tag_v2(table):
97
130
  with warnings.catch_warnings():
98
131
  warnings.simplefilter("ignore")
99
132
 
100
- class Artifact(Base, mlrun.utils.db.HasStruct):
133
+ class Artifact(Base, HasStruct):
101
134
  __tablename__ = "artifacts"
102
135
  __table_args__ = (
103
136
  UniqueConstraint("uid", "project", "key", name="_artifacts_uc"),
@@ -118,7 +151,7 @@ with warnings.catch_warnings():
118
151
  def get_identifier_string(self) -> str:
119
152
  return f"{self.project}/{self.key}/{self.uid}"
120
153
 
121
- class Function(Base, mlrun.utils.db.HasStruct):
154
+ class Function(Base, HasStruct):
122
155
  __tablename__ = "functions"
123
156
  __table_args__ = (
124
157
  UniqueConstraint("name", "project", "uid", name="_functions_uc"),
@@ -139,7 +172,7 @@ with warnings.catch_warnings():
139
172
  def get_identifier_string(self) -> str:
140
173
  return f"{self.project}/{self.name}/{self.uid}"
141
174
 
142
- class Log(Base, mlrun.utils.db.BaseModel):
175
+ class Log(Base, BaseModel):
143
176
  __tablename__ = "logs"
144
177
 
145
178
  id = Column(Integer, primary_key=True)
@@ -151,7 +184,7 @@ with warnings.catch_warnings():
151
184
  def get_identifier_string(self) -> str:
152
185
  return f"{self.project}/{self.uid}"
153
186
 
154
- class Run(Base, mlrun.utils.db.HasStruct):
187
+ class Run(Base, HasStruct):
155
188
  __tablename__ = "runs"
156
189
  __table_args__ = (
157
190
  UniqueConstraint("uid", "project", "iteration", name="_runs_uc"),
@@ -182,7 +215,7 @@ with warnings.catch_warnings():
182
215
  def get_identifier_string(self) -> str:
183
216
  return f"{self.project}/{self.uid}/{self.iteration}"
184
217
 
185
- class BackgroundTask(Base, mlrun.utils.db.BaseModel):
218
+ class BackgroundTask(Base, BaseModel):
186
219
  __tablename__ = "background_tasks"
187
220
  __table_args__ = (
188
221
  UniqueConstraint("name", "project", name="_background_tasks_uc"),
@@ -200,7 +233,7 @@ with warnings.catch_warnings():
200
233
  state = Column(String(255, collation=SQLCollationUtil.collation()))
201
234
  timeout = Column(Integer)
202
235
 
203
- class Schedule(Base, mlrun.utils.db.BaseModel):
236
+ class Schedule(Base, BaseModel):
204
237
  __tablename__ = "schedules_v2"
205
238
  __table_args__ = (UniqueConstraint("project", "name", name="_schedules_v2_uc"),)
206
239
 
@@ -252,14 +285,14 @@ with warnings.catch_warnings():
252
285
  Column("user_id", Integer, ForeignKey("users.id")),
253
286
  )
254
287
 
255
- class User(Base, mlrun.utils.db.BaseModel):
288
+ class User(Base, BaseModel):
256
289
  __tablename__ = "users"
257
290
  __table_args__ = (UniqueConstraint("name", name="_users_uc"),)
258
291
 
259
292
  id = Column(Integer, primary_key=True)
260
293
  name = Column(String(255, collation=SQLCollationUtil.collation()))
261
294
 
262
- class Project(Base, mlrun.utils.db.BaseModel):
295
+ class Project(Base, BaseModel):
263
296
  __tablename__ = "projects"
264
297
  # For now since we use project name a lot
265
298
  __table_args__ = (UniqueConstraint("name", name="_projects_uc"),)
@@ -293,7 +326,7 @@ with warnings.catch_warnings():
293
326
  def full_object(self, value):
294
327
  self._full_object = pickle.dumps(value)
295
328
 
296
- class Feature(Base, mlrun.utils.db.BaseModel):
329
+ class Feature(Base, BaseModel):
297
330
  __tablename__ = "features"
298
331
  id = Column(Integer, primary_key=True)
299
332
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -307,7 +340,7 @@ with warnings.catch_warnings():
307
340
  def get_identifier_string(self) -> str:
308
341
  return f"{self.project}/{self.name}"
309
342
 
310
- class Entity(Base, mlrun.utils.db.BaseModel):
343
+ class Entity(Base, BaseModel):
311
344
  __tablename__ = "entities"
312
345
  id = Column(Integer, primary_key=True)
313
346
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -321,7 +354,7 @@ with warnings.catch_warnings():
321
354
  def get_identifier_string(self) -> str:
322
355
  return f"{self.project}/{self.name}"
323
356
 
324
- class FeatureSet(Base, mlrun.utils.db.BaseModel):
357
+ class FeatureSet(Base, BaseModel):
325
358
  __tablename__ = "feature_sets"
326
359
  __table_args__ = (
327
360
  UniqueConstraint("name", "project", "uid", name="_feature_set_uc"),
@@ -357,7 +390,7 @@ with warnings.catch_warnings():
357
390
  def full_object(self, value):
358
391
  self._full_object = json.dumps(value, default=str)
359
392
 
360
- class FeatureVector(Base, mlrun.utils.db.BaseModel):
393
+ class FeatureVector(Base, BaseModel):
361
394
  __tablename__ = "feature_vectors"
362
395
  __table_args__ = (
363
396
  UniqueConstraint("name", "project", "uid", name="_feature_vectors_uc"),
@@ -390,7 +423,7 @@ with warnings.catch_warnings():
390
423
  def full_object(self, value):
391
424
  self._full_object = json.dumps(value, default=str)
392
425
 
393
- class MarketplaceSource(Base, mlrun.utils.db.BaseModel):
426
+ class MarketplaceSource(Base, BaseModel):
394
427
  __tablename__ = "marketplace_sources"
395
428
  __table_args__ = (UniqueConstraint("name", name="_marketplace_sources_uc"),)
396
429
 
@@ -414,7 +447,7 @@ with warnings.catch_warnings():
414
447
  def full_object(self, value):
415
448
  self._full_object = json.dumps(value, default=str)
416
449
 
417
- class DataVersion(Base, mlrun.utils.db.BaseModel):
450
+ class DataVersion(Base, BaseModel):
418
451
  __tablename__ = "data_versions"
419
452
  __table_args__ = (UniqueConstraint("version", name="_versions_uc"),)
420
453
 
@@ -12,9 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  #
15
-
16
- import typing
17
-
18
15
  from sqlalchemy import create_engine
19
16
  from sqlalchemy.engine import Engine
20
17
  from sqlalchemy.orm import Session
@@ -22,38 +19,35 @@ from sqlalchemy.orm import sessionmaker as SessionMaker
22
19
 
23
20
  from mlrun.config import config
24
21
 
25
- # TODO: wrap the following functions in a singleton class
26
- _engines: typing.Dict[str, Engine] = {}
27
- _session_makers: typing.Dict[str, SessionMaker] = {}
22
+ engine: Engine = None
23
+ _session_maker: SessionMaker = None
28
24
 
29
25
 
30
26
  # doing lazy load to allow tests to initialize the engine
31
- def get_engine(dsn=None) -> Engine:
32
- global _engines
33
- dsn = dsn or config.httpdb.dsn
34
- if dsn not in _engines:
35
- _init_engine(dsn=dsn)
36
- return _engines[dsn]
27
+ def get_engine() -> Engine:
28
+ global engine
29
+ if engine is None:
30
+ _init_engine()
31
+ return engine
37
32
 
38
33
 
39
- def create_session(dsn=None) -> Session:
40
- session_maker = _get_session_maker(dsn=dsn)
34
+ def create_session() -> Session:
35
+ session_maker = _get_session_maker()
41
36
  return session_maker()
42
37
 
43
38
 
44
39
  # doing lazy load to allow tests to initialize the engine
45
- def _get_session_maker(dsn) -> SessionMaker:
46
- global _session_makers
47
- dsn = dsn or config.httpdb.dsn
48
- if dsn not in _session_makers:
49
- _init_session_maker(dsn=dsn)
50
- return _session_makers[dsn]
40
+ def _get_session_maker() -> SessionMaker:
41
+ global _session_maker
42
+ if _session_maker is None:
43
+ _init_session_maker()
44
+ return _session_maker
51
45
 
52
46
 
53
47
  # TODO: we accept the dsn here to enable tests to override it, the "right" thing will be that config will be easily
54
48
  # overridable by tests (today when you import the config it is already being initialized.. should be lazy load)
55
49
  def _init_engine(dsn=None):
56
- global _engines
50
+ global engine
57
51
  dsn = dsn or config.httpdb.dsn
58
52
  kwargs = {}
59
53
  if "mysql" in dsn:
@@ -68,10 +62,9 @@ def _init_engine(dsn=None):
68
62
  "max_overflow": max_overflow,
69
63
  }
70
64
  engine = create_engine(dsn, **kwargs)
71
- _engines[dsn] = engine
72
- _init_session_maker(dsn=dsn)
65
+ _init_session_maker()
73
66
 
74
67
 
75
- def _init_session_maker(dsn):
76
- global _session_makers
77
- _session_makers[dsn] = SessionMaker(bind=get_engine(dsn=dsn))
68
+ def _init_session_maker():
69
+ global _session_maker
70
+ _session_maker = SessionMaker(bind=get_engine())
@@ -100,11 +100,13 @@ from .model_endpoints import (
100
100
  GrafanaStringColumn,
101
101
  GrafanaTable,
102
102
  GrafanaTimeSeriesTarget,
103
+ Metric,
103
104
  ModelEndpoint,
104
105
  ModelEndpointList,
105
106
  ModelEndpointMetadata,
106
107
  ModelEndpointSpec,
107
108
  ModelEndpointStatus,
109
+ ModelMonitoringMode,
108
110
  ModelMonitoringStoreKinds,
109
111
  )
110
112
  from .object import ObjectKind, ObjectMetadata, ObjectSpec, ObjectStatus
@@ -170,19 +170,6 @@ class APIStates:
170
170
  def terminal_states():
171
171
  return [APIStates.online, APIStates.offline]
172
172
 
173
- @staticmethod
174
- def description(state: str):
175
- return {
176
- APIStates.online: "API is online",
177
- APIStates.waiting_for_migrations: "API is waiting for migrations to be triggered. "
178
- "Send POST request to /api/operations/migrations to trigger it",
179
- APIStates.migrations_in_progress: "Migrations are in progress",
180
- APIStates.migrations_failed: "Migrations failed, API can't be started",
181
- APIStates.migrations_completed: "Migrations completed, API is waiting to become online",
182
- APIStates.offline: "API is offline",
183
- APIStates.waiting_for_chief: "API is waiting for chief to be ready",
184
- }.get(state, f"Unknown API state '{state}'")
185
-
186
173
 
187
174
  class ClusterizationRole:
188
175
  chief = "chief"
@@ -67,7 +67,6 @@ class FrontendSpec(pydantic.BaseModel):
67
67
  default_function_pod_resources: Resources = Resources()
68
68
  default_function_preemption_mode: str
69
69
  feature_store_data_prefixes: typing.Optional[typing.Dict[str, str]]
70
- allowed_artifact_path_prefixes_list: typing.List[str]
71
70
 
72
71
  # ce_mode is deprecated, we will use the full ce config instead and ce_mode will be removed in 1.6.0
73
72
  ce_mode: typing.Optional[str]