mlrun 1.7.2rc4__py3-none-any.whl → 1.8.0__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 (275) hide show
  1. mlrun/__init__.py +26 -22
  2. mlrun/__main__.py +15 -16
  3. mlrun/alerts/alert.py +150 -15
  4. mlrun/api/schemas/__init__.py +1 -9
  5. mlrun/artifacts/__init__.py +2 -3
  6. mlrun/artifacts/base.py +62 -19
  7. mlrun/artifacts/dataset.py +17 -17
  8. mlrun/artifacts/document.py +454 -0
  9. mlrun/artifacts/manager.py +28 -18
  10. mlrun/artifacts/model.py +91 -59
  11. mlrun/artifacts/plots.py +2 -2
  12. mlrun/common/constants.py +8 -0
  13. mlrun/common/formatters/__init__.py +1 -0
  14. mlrun/common/formatters/artifact.py +1 -1
  15. mlrun/common/formatters/feature_set.py +2 -0
  16. mlrun/common/formatters/function.py +1 -0
  17. mlrun/{model_monitoring/db/stores/v3io_kv/__init__.py → common/formatters/model_endpoint.py} +17 -0
  18. mlrun/common/formatters/pipeline.py +1 -2
  19. mlrun/common/formatters/project.py +9 -0
  20. mlrun/common/model_monitoring/__init__.py +0 -5
  21. mlrun/common/model_monitoring/helpers.py +12 -62
  22. mlrun/common/runtimes/constants.py +25 -4
  23. mlrun/common/schemas/__init__.py +9 -5
  24. mlrun/common/schemas/alert.py +114 -19
  25. mlrun/common/schemas/api_gateway.py +3 -3
  26. mlrun/common/schemas/artifact.py +22 -9
  27. mlrun/common/schemas/auth.py +8 -4
  28. mlrun/common/schemas/background_task.py +7 -7
  29. mlrun/common/schemas/client_spec.py +4 -4
  30. mlrun/common/schemas/clusterization_spec.py +2 -2
  31. mlrun/common/schemas/common.py +53 -3
  32. mlrun/common/schemas/constants.py +15 -0
  33. mlrun/common/schemas/datastore_profile.py +1 -1
  34. mlrun/common/schemas/feature_store.py +9 -9
  35. mlrun/common/schemas/frontend_spec.py +4 -4
  36. mlrun/common/schemas/function.py +10 -10
  37. mlrun/common/schemas/hub.py +1 -1
  38. mlrun/common/schemas/k8s.py +3 -3
  39. mlrun/common/schemas/memory_reports.py +3 -3
  40. mlrun/common/schemas/model_monitoring/__init__.py +4 -8
  41. mlrun/common/schemas/model_monitoring/constants.py +127 -46
  42. mlrun/common/schemas/model_monitoring/grafana.py +18 -12
  43. mlrun/common/schemas/model_monitoring/model_endpoints.py +154 -160
  44. mlrun/common/schemas/notification.py +24 -3
  45. mlrun/common/schemas/object.py +1 -1
  46. mlrun/common/schemas/pagination.py +4 -4
  47. mlrun/common/schemas/partition.py +142 -0
  48. mlrun/common/schemas/pipeline.py +3 -3
  49. mlrun/common/schemas/project.py +26 -18
  50. mlrun/common/schemas/runs.py +3 -3
  51. mlrun/common/schemas/runtime_resource.py +5 -5
  52. mlrun/common/schemas/schedule.py +1 -1
  53. mlrun/common/schemas/secret.py +1 -1
  54. mlrun/{model_monitoring/db/stores/sqldb/__init__.py → common/schemas/serving.py} +10 -1
  55. mlrun/common/schemas/tag.py +3 -3
  56. mlrun/common/schemas/workflow.py +6 -5
  57. mlrun/common/types.py +1 -0
  58. mlrun/config.py +157 -89
  59. mlrun/data_types/__init__.py +5 -3
  60. mlrun/data_types/infer.py +13 -3
  61. mlrun/data_types/spark.py +2 -1
  62. mlrun/datastore/__init__.py +59 -18
  63. mlrun/datastore/alibaba_oss.py +4 -1
  64. mlrun/datastore/azure_blob.py +4 -1
  65. mlrun/datastore/base.py +19 -24
  66. mlrun/datastore/datastore.py +10 -4
  67. mlrun/datastore/datastore_profile.py +178 -45
  68. mlrun/datastore/dbfs_store.py +4 -1
  69. mlrun/datastore/filestore.py +4 -1
  70. mlrun/datastore/google_cloud_storage.py +4 -1
  71. mlrun/datastore/hdfs.py +4 -1
  72. mlrun/datastore/inmem.py +4 -1
  73. mlrun/datastore/redis.py +4 -1
  74. mlrun/datastore/s3.py +14 -3
  75. mlrun/datastore/sources.py +89 -92
  76. mlrun/datastore/store_resources.py +7 -4
  77. mlrun/datastore/storeytargets.py +51 -16
  78. mlrun/datastore/targets.py +38 -31
  79. mlrun/datastore/utils.py +87 -4
  80. mlrun/datastore/v3io.py +4 -1
  81. mlrun/datastore/vectorstore.py +291 -0
  82. mlrun/datastore/wasbfs/fs.py +13 -12
  83. mlrun/db/base.py +286 -100
  84. mlrun/db/httpdb.py +1562 -490
  85. mlrun/db/nopdb.py +250 -83
  86. mlrun/errors.py +6 -2
  87. mlrun/execution.py +194 -50
  88. mlrun/feature_store/__init__.py +2 -10
  89. mlrun/feature_store/api.py +20 -458
  90. mlrun/feature_store/common.py +9 -9
  91. mlrun/feature_store/feature_set.py +20 -18
  92. mlrun/feature_store/feature_vector.py +105 -479
  93. mlrun/feature_store/feature_vector_utils.py +466 -0
  94. mlrun/feature_store/retrieval/base.py +15 -11
  95. mlrun/feature_store/retrieval/job.py +2 -1
  96. mlrun/feature_store/retrieval/storey_merger.py +1 -1
  97. mlrun/feature_store/steps.py +3 -3
  98. mlrun/features.py +30 -13
  99. mlrun/frameworks/__init__.py +1 -2
  100. mlrun/frameworks/_common/__init__.py +1 -2
  101. mlrun/frameworks/_common/artifacts_library.py +2 -2
  102. mlrun/frameworks/_common/mlrun_interface.py +10 -6
  103. mlrun/frameworks/_common/model_handler.py +31 -31
  104. mlrun/frameworks/_common/producer.py +3 -1
  105. mlrun/frameworks/_dl_common/__init__.py +1 -2
  106. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
  107. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
  108. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
  109. mlrun/frameworks/_ml_common/__init__.py +1 -2
  110. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
  111. mlrun/frameworks/_ml_common/model_handler.py +21 -21
  112. mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
  113. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
  114. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  115. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  116. mlrun/frameworks/auto_mlrun/__init__.py +1 -2
  117. mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
  118. mlrun/frameworks/huggingface/__init__.py +1 -2
  119. mlrun/frameworks/huggingface/model_server.py +9 -9
  120. mlrun/frameworks/lgbm/__init__.py +47 -44
  121. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
  122. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
  123. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
  124. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
  125. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
  126. mlrun/frameworks/lgbm/model_handler.py +15 -11
  127. mlrun/frameworks/lgbm/model_server.py +11 -7
  128. mlrun/frameworks/lgbm/utils.py +2 -2
  129. mlrun/frameworks/onnx/__init__.py +1 -2
  130. mlrun/frameworks/onnx/dataset.py +3 -3
  131. mlrun/frameworks/onnx/mlrun_interface.py +2 -2
  132. mlrun/frameworks/onnx/model_handler.py +7 -5
  133. mlrun/frameworks/onnx/model_server.py +8 -6
  134. mlrun/frameworks/parallel_coordinates.py +11 -11
  135. mlrun/frameworks/pytorch/__init__.py +22 -23
  136. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
  137. mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
  138. mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
  139. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
  140. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
  141. mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
  142. mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
  143. mlrun/frameworks/pytorch/model_handler.py +21 -17
  144. mlrun/frameworks/pytorch/model_server.py +13 -9
  145. mlrun/frameworks/sklearn/__init__.py +19 -18
  146. mlrun/frameworks/sklearn/estimator.py +2 -2
  147. mlrun/frameworks/sklearn/metric.py +3 -3
  148. mlrun/frameworks/sklearn/metrics_library.py +8 -6
  149. mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
  150. mlrun/frameworks/sklearn/model_handler.py +4 -3
  151. mlrun/frameworks/tf_keras/__init__.py +11 -12
  152. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
  153. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
  154. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
  155. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
  156. mlrun/frameworks/tf_keras/model_handler.py +17 -13
  157. mlrun/frameworks/tf_keras/model_server.py +12 -8
  158. mlrun/frameworks/xgboost/__init__.py +19 -18
  159. mlrun/frameworks/xgboost/model_handler.py +13 -9
  160. mlrun/k8s_utils.py +2 -5
  161. mlrun/launcher/base.py +3 -4
  162. mlrun/launcher/client.py +2 -2
  163. mlrun/launcher/local.py +6 -2
  164. mlrun/launcher/remote.py +1 -1
  165. mlrun/lists.py +8 -4
  166. mlrun/model.py +132 -46
  167. mlrun/model_monitoring/__init__.py +3 -5
  168. mlrun/model_monitoring/api.py +113 -98
  169. mlrun/model_monitoring/applications/__init__.py +0 -5
  170. mlrun/model_monitoring/applications/_application_steps.py +81 -50
  171. mlrun/model_monitoring/applications/base.py +467 -14
  172. mlrun/model_monitoring/applications/context.py +212 -134
  173. mlrun/model_monitoring/{db/stores/base → applications/evidently}/__init__.py +6 -2
  174. mlrun/model_monitoring/applications/evidently/base.py +146 -0
  175. mlrun/model_monitoring/applications/histogram_data_drift.py +89 -56
  176. mlrun/model_monitoring/applications/results.py +67 -15
  177. mlrun/model_monitoring/controller.py +701 -315
  178. mlrun/model_monitoring/db/__init__.py +0 -2
  179. mlrun/model_monitoring/db/_schedules.py +242 -0
  180. mlrun/model_monitoring/db/_stats.py +189 -0
  181. mlrun/model_monitoring/db/tsdb/__init__.py +33 -22
  182. mlrun/model_monitoring/db/tsdb/base.py +243 -49
  183. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +76 -36
  184. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
  185. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +213 -0
  186. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +534 -88
  187. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
  188. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +436 -106
  189. mlrun/model_monitoring/helpers.py +356 -114
  190. mlrun/model_monitoring/stream_processing.py +190 -345
  191. mlrun/model_monitoring/tracking_policy.py +11 -4
  192. mlrun/model_monitoring/writer.py +49 -90
  193. mlrun/package/__init__.py +3 -6
  194. mlrun/package/context_handler.py +2 -2
  195. mlrun/package/packager.py +12 -9
  196. mlrun/package/packagers/__init__.py +0 -2
  197. mlrun/package/packagers/default_packager.py +14 -11
  198. mlrun/package/packagers/numpy_packagers.py +16 -7
  199. mlrun/package/packagers/pandas_packagers.py +18 -18
  200. mlrun/package/packagers/python_standard_library_packagers.py +25 -11
  201. mlrun/package/packagers_manager.py +35 -32
  202. mlrun/package/utils/__init__.py +0 -3
  203. mlrun/package/utils/_pickler.py +6 -6
  204. mlrun/platforms/__init__.py +47 -16
  205. mlrun/platforms/iguazio.py +4 -1
  206. mlrun/projects/operations.py +30 -30
  207. mlrun/projects/pipelines.py +116 -47
  208. mlrun/projects/project.py +1292 -329
  209. mlrun/render.py +5 -9
  210. mlrun/run.py +57 -14
  211. mlrun/runtimes/__init__.py +1 -3
  212. mlrun/runtimes/base.py +30 -22
  213. mlrun/runtimes/daskjob.py +9 -9
  214. mlrun/runtimes/databricks_job/databricks_runtime.py +6 -5
  215. mlrun/runtimes/function_reference.py +5 -2
  216. mlrun/runtimes/generators.py +3 -2
  217. mlrun/runtimes/kubejob.py +6 -7
  218. mlrun/runtimes/mounts.py +574 -0
  219. mlrun/runtimes/mpijob/__init__.py +0 -2
  220. mlrun/runtimes/mpijob/abstract.py +7 -6
  221. mlrun/runtimes/nuclio/api_gateway.py +7 -7
  222. mlrun/runtimes/nuclio/application/application.py +11 -13
  223. mlrun/runtimes/nuclio/application/reverse_proxy.go +66 -64
  224. mlrun/runtimes/nuclio/function.py +127 -70
  225. mlrun/runtimes/nuclio/serving.py +105 -37
  226. mlrun/runtimes/pod.py +159 -54
  227. mlrun/runtimes/remotesparkjob.py +3 -2
  228. mlrun/runtimes/sparkjob/__init__.py +0 -2
  229. mlrun/runtimes/sparkjob/spark3job.py +22 -12
  230. mlrun/runtimes/utils.py +7 -6
  231. mlrun/secrets.py +2 -2
  232. mlrun/serving/__init__.py +8 -0
  233. mlrun/serving/merger.py +7 -5
  234. mlrun/serving/remote.py +35 -22
  235. mlrun/serving/routers.py +186 -240
  236. mlrun/serving/server.py +41 -10
  237. mlrun/serving/states.py +432 -118
  238. mlrun/serving/utils.py +13 -2
  239. mlrun/serving/v1_serving.py +3 -2
  240. mlrun/serving/v2_serving.py +161 -203
  241. mlrun/track/__init__.py +1 -1
  242. mlrun/track/tracker.py +2 -2
  243. mlrun/track/trackers/mlflow_tracker.py +6 -5
  244. mlrun/utils/async_http.py +35 -22
  245. mlrun/utils/clones.py +7 -4
  246. mlrun/utils/helpers.py +511 -58
  247. mlrun/utils/logger.py +119 -13
  248. mlrun/utils/notifications/notification/__init__.py +22 -19
  249. mlrun/utils/notifications/notification/base.py +39 -15
  250. mlrun/utils/notifications/notification/console.py +6 -6
  251. mlrun/utils/notifications/notification/git.py +11 -11
  252. mlrun/utils/notifications/notification/ipython.py +10 -9
  253. mlrun/utils/notifications/notification/mail.py +176 -0
  254. mlrun/utils/notifications/notification/slack.py +16 -8
  255. mlrun/utils/notifications/notification/webhook.py +24 -8
  256. mlrun/utils/notifications/notification_pusher.py +191 -200
  257. mlrun/utils/regex.py +12 -2
  258. mlrun/utils/version/version.json +2 -2
  259. {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/METADATA +69 -54
  260. mlrun-1.8.0.dist-info/RECORD +351 -0
  261. {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/WHEEL +1 -1
  262. mlrun/model_monitoring/applications/evidently_base.py +0 -137
  263. mlrun/model_monitoring/db/stores/__init__.py +0 -136
  264. mlrun/model_monitoring/db/stores/base/store.py +0 -213
  265. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -71
  266. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -190
  267. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -103
  268. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -40
  269. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -659
  270. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
  271. mlrun/model_monitoring/model_endpoint.py +0 -118
  272. mlrun-1.7.2rc4.dist-info/RECORD +0 -351
  273. {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/entry_points.txt +0 -0
  274. {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info/licenses}/LICENSE +0 -0
  275. {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/top_level.txt +0 -0
@@ -11,9 +11,8 @@
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
- from typing import Union
14
+
15
+ from typing import Optional, Union
17
16
 
18
17
  import xgboost as xgb
19
18
 
@@ -34,26 +33,28 @@ def apply_mlrun(
34
33
  model: xgb.XGBModel = None,
35
34
  model_name: str = "model",
36
35
  tag: str = "",
37
- model_path: str = None,
38
- modules_map: Union[dict[str, Union[None, str, list[str]]], str] = None,
39
- custom_objects_map: Union[dict[str, Union[str, list[str]]], str] = None,
40
- custom_objects_directory: str = None,
36
+ model_path: Optional[str] = None,
37
+ modules_map: Optional[Union[dict[str, Union[None, str, list[str]]], str]] = None,
38
+ custom_objects_map: Optional[Union[dict[str, Union[str, list[str]]], str]] = None,
39
+ custom_objects_directory: Optional[str] = None,
41
40
  context: mlrun.MLClientCtx = None,
42
- artifacts: Union[list[MLPlan], list[str], dict[str, dict]] = None,
43
- metrics: Union[
44
- list[Metric],
45
- list[XGBoostTypes.MetricEntryType],
46
- dict[str, XGBoostTypes.MetricEntryType],
41
+ artifacts: Optional[Union[list[MLPlan], list[str], dict[str, dict]]] = None,
42
+ metrics: Optional[
43
+ Union[
44
+ list[Metric],
45
+ list[XGBoostTypes.MetricEntryType],
46
+ dict[str, XGBoostTypes.MetricEntryType],
47
+ ]
47
48
  ] = None,
48
49
  x_test: XGBoostTypes.DatasetType = None,
49
50
  y_test: XGBoostTypes.DatasetType = None,
50
51
  sample_set: Union[XGBoostTypes.DatasetType, mlrun.DataItem, str] = None,
51
- y_columns: Union[list[str], list[int]] = None,
52
- feature_vector: str = None,
53
- feature_weights: list[float] = None,
54
- labels: dict[str, Union[str, int, float]] = None,
55
- parameters: dict[str, Union[str, int, float]] = None,
56
- extra_data: dict[str, XGBoostTypes.ExtraDataType] = None,
52
+ y_columns: Optional[Union[list[str], list[int]]] = None,
53
+ feature_vector: Optional[str] = None,
54
+ feature_weights: Optional[list[float]] = None,
55
+ labels: Optional[dict[str, Union[str, int, float]]] = None,
56
+ parameters: Optional[dict[str, Union[str, int, float]]] = None,
57
+ extra_data: Optional[dict[str, XGBoostTypes.ExtraDataType]] = None,
57
58
  auto_log: bool = True,
58
59
  **kwargs,
59
60
  ) -> XGBoostModelHandler:
@@ -14,7 +14,7 @@
14
14
  #
15
15
  import os
16
16
  import pickle
17
- from typing import Union
17
+ from typing import Optional, Union
18
18
 
19
19
  import cloudpickle
20
20
 
@@ -45,11 +45,15 @@ class XGBoostModelHandler(MLModelHandler):
45
45
  def __init__(
46
46
  self,
47
47
  model: XGBoostTypes.ModelType = None,
48
- model_path: str = None,
49
- model_name: str = None,
50
- modules_map: Union[dict[str, Union[None, str, list[str]]], str] = None,
51
- custom_objects_map: Union[dict[str, Union[str, list[str]]], str] = None,
52
- custom_objects_directory: str = None,
48
+ model_path: Optional[str] = None,
49
+ model_name: Optional[str] = None,
50
+ modules_map: Optional[
51
+ Union[dict[str, Union[None, str, list[str]]], str]
52
+ ] = None,
53
+ custom_objects_map: Optional[
54
+ Union[dict[str, Union[str, list[str]]], str]
55
+ ] = None,
56
+ custom_objects_directory: Optional[str] = None,
53
57
  context: mlrun.MLClientCtx = None,
54
58
  model_format: str = ModelFormats.PKL,
55
59
  **kwargs,
@@ -152,7 +156,7 @@ class XGBoostModelHandler(MLModelHandler):
152
156
  )
153
157
 
154
158
  @without_mlrun_interface(interface=XGBModelMLRunInterface)
155
- def save(self, output_path: str = None, **kwargs):
159
+ def save(self, output_path: Optional[str] = None, **kwargs):
156
160
  """
157
161
  Save the handled model at the given output path. If a MLRun context is available, the saved model files will be
158
162
  logged and returned as artifacts.
@@ -186,10 +190,10 @@ class XGBoostModelHandler(MLModelHandler):
186
190
 
187
191
  def to_onnx(
188
192
  self,
189
- model_name: str = None,
193
+ model_name: Optional[str] = None,
190
194
  optimize: bool = True,
191
195
  input_sample: XGBoostTypes = None,
192
- log: bool = None,
196
+ log: Optional[bool] = None,
193
197
  ):
194
198
  """
195
199
  Convert the model in this handler to an ONNX model. The inputs names are optional, they do not change the
mlrun/k8s_utils.py CHANGED
@@ -142,6 +142,7 @@ def verify_label_key(key: str, allow_k8s_prefix: bool = False):
142
142
  if not key:
143
143
  raise mlrun.errors.MLRunInvalidArgumentError("label key cannot be empty")
144
144
 
145
+ prefix = ""
145
146
  parts = key.split("/")
146
147
  if len(parts) == 1:
147
148
  name = parts[0]
@@ -180,11 +181,7 @@ def verify_label_key(key: str, allow_k8s_prefix: bool = False):
180
181
 
181
182
  # Allow the use of Kubernetes reserved prefixes ('k8s.io/' or 'kubernetes.io/')
182
183
  # only when setting node selectors, not when adding new labels.
183
- if (
184
- key.startswith("k8s.io/")
185
- or key.startswith("kubernetes.io/")
186
- and not allow_k8s_prefix
187
- ):
184
+ if not allow_k8s_prefix and prefix in {"k8s.io", "kubernetes.io"}:
188
185
  raise mlrun.errors.MLRunInvalidArgumentError(
189
186
  "Labels cannot start with 'k8s.io/' or 'kubernetes.io/'"
190
187
  )
mlrun/launcher/base.py CHANGED
@@ -18,8 +18,6 @@ import os
18
18
  import uuid
19
19
  from typing import Any, Callable, Optional, Union
20
20
 
21
- import mlrun_pipelines.common.ops
22
-
23
21
  import mlrun.common.schemas
24
22
  import mlrun.config
25
23
  import mlrun.errors
@@ -27,6 +25,7 @@ import mlrun.lists
27
25
  import mlrun.model
28
26
  import mlrun.runtimes
29
27
  import mlrun.utils.regex
28
+ import mlrun_pipelines.common.ops
30
29
  from mlrun.utils import logger
31
30
 
32
31
  run_modes = ["pass"]
@@ -62,7 +61,7 @@ class BaseLauncher(abc.ABC):
62
61
  schedule: Optional[
63
62
  Union[str, mlrun.common.schemas.schedule.ScheduleCronTrigger]
64
63
  ] = None,
65
- hyperparams: dict[str, list] = None,
64
+ hyperparams: Optional[dict[str, list]] = None,
66
65
  hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
67
66
  verbose: Optional[bool] = None,
68
67
  scrape_metrics: Optional[bool] = None,
@@ -238,7 +237,7 @@ class BaseLauncher(abc.ABC):
238
237
  out_path=None,
239
238
  artifact_path=None,
240
239
  workdir=None,
241
- notifications: list[mlrun.model.Notification] = None,
240
+ notifications: Optional[list[mlrun.model.Notification]] = None,
242
241
  state_thresholds: Optional[dict[str, int]] = None,
243
242
  ):
244
243
  run.spec.handler = (
mlrun/launcher/client.py CHANGED
@@ -134,7 +134,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
134
134
  if mlrun.utils.is_jupyter and mlrun.mlconf.ipython_widget:
135
135
  results_tbl.show()
136
136
  print()
137
- ui_url = mlrun.utils.get_ui_url(project, uid)
137
+ ui_url = mlrun.utils.get_run_url(project, uid=uid, name=run.metadata.name)
138
138
  if ui_url:
139
139
  ui_url = f' or <a href="{ui_url}" target="_blank">click here</a> to open in UI'
140
140
  IPython.display.display(
@@ -150,6 +150,6 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
150
150
  mlrun.utils.logger.info(
151
151
  "To track results use the CLI", info_cmd=info_cmd, logs_cmd=logs_cmd
152
152
  )
153
- ui_url = mlrun.utils.get_ui_url(project, uid)
153
+ ui_url = mlrun.utils.get_run_url(project, uid=uid, name=run.metadata.name)
154
154
  if ui_url:
155
155
  mlrun.utils.logger.info("Or click for UI", ui_url=ui_url)
mlrun/launcher/local.py CHANGED
@@ -59,7 +59,7 @@ class ClientLocalLauncher(launcher.ClientBaseLauncher):
59
59
  schedule: Optional[
60
60
  Union[str, mlrun.common.schemas.schedule.ScheduleCronTrigger]
61
61
  ] = None,
62
- hyperparams: dict[str, list] = None,
62
+ hyperparams: Optional[dict[str, list]] = None,
63
63
  hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
64
64
  verbose: Optional[bool] = None,
65
65
  scrape_metrics: Optional[bool] = None,
@@ -281,5 +281,9 @@ class ClientLocalLauncher(launcher.ClientBaseLauncher):
281
281
  # once the run is completed, and we can just push the notifications.
282
282
  # Only push from jupyter, not from the CLI.
283
283
  # "handler" and "dask" kinds are special cases of local runs which don't set local=True
284
- if self._is_run_local or runtime.kind in ["handler", "dask"]:
284
+ if self._is_run_local or runtime.kind in ["handler"]:
285
285
  mlrun.utils.notifications.NotificationPusher([runobj]).push()
286
+ elif runtime.kind in ["dask"]:
287
+ runtime._get_db().push_run_notifications(
288
+ uid=runobj.metadata.uid, project=runobj.metadata.project
289
+ )
mlrun/launcher/remote.py CHANGED
@@ -49,7 +49,7 @@ class ClientRemoteLauncher(launcher.ClientBaseLauncher):
49
49
  schedule: Optional[
50
50
  Union[str, mlrun.common.schemas.schedule.ScheduleCronTrigger]
51
51
  ] = None,
52
- hyperparams: dict[str, list] = None,
52
+ hyperparams: Optional[dict[str, list]] = None,
53
53
  hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
54
54
  verbose: Optional[bool] = None,
55
55
  scrape_metrics: Optional[bool] = None,
mlrun/lists.py CHANGED
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  from copy import copy
15
+ from typing import Optional
15
16
 
16
17
  import pandas as pd
17
18
 
@@ -28,6 +29,7 @@ list_header = [
28
29
  "uid",
29
30
  "iter",
30
31
  "start",
32
+ "end",
31
33
  "state",
32
34
  "kind",
33
35
  "name",
@@ -57,6 +59,7 @@ class RunList(list):
57
59
  get_in(run, "metadata.uid", ""),
58
60
  get_in(run, "metadata.iteration", ""),
59
61
  get_in(run, "status.start_time", ""),
62
+ get_in(run, "status.end_time", ""),
60
63
  get_in(run, "status.state", ""),
61
64
  get_in(run, "step_kind", get_in(run, "kind", "")),
62
65
  get_in(run, "metadata.name", ""),
@@ -102,7 +105,8 @@ class RunList(list):
102
105
  return self._df
103
106
  rows = self.to_rows(extend_iterations=extend_iterations)
104
107
  df = pd.DataFrame(rows[1:], columns=rows[0]) # .set_index('iter')
105
- df["start"] = pd.to_datetime(df["start"])
108
+ for time_column in ["start", "end"]:
109
+ df[time_column] = pd.to_datetime(df[time_column])
106
110
 
107
111
  if flat:
108
112
  df = flatten(df, "labels")
@@ -129,11 +133,11 @@ class RunList(list):
129
133
  def compare(
130
134
  self,
131
135
  hide_identical: bool = True,
132
- exclude: list = None,
133
- show: bool = None,
136
+ exclude: Optional[list] = None,
137
+ show: Optional[bool] = None,
134
138
  extend_iterations=True,
135
139
  filename=None,
136
- colorscale: str = None,
140
+ colorscale: Optional[str] = None,
137
141
  ):
138
142
  """return/show parallel coordinates plot + table to compare between the list of runs
139
143
 
mlrun/model.py CHANGED
@@ -24,7 +24,7 @@ from datetime import datetime
24
24
  from os import environ
25
25
  from typing import Any, Optional, Union
26
26
 
27
- import pydantic.error_wrappers
27
+ import pydantic.v1.error_wrappers
28
28
 
29
29
  import mlrun
30
30
  import mlrun.common.constants as mlrun_constants
@@ -74,7 +74,10 @@ class ModelObj:
74
74
 
75
75
  @mlrun.utils.filter_warnings("ignore", FutureWarning)
76
76
  def to_dict(
77
- self, fields: list = None, exclude: list = None, strip: bool = False
77
+ self,
78
+ fields: Optional[list] = None,
79
+ exclude: Optional[list] = None,
80
+ strip: bool = False,
78
81
  ) -> dict:
79
82
  """
80
83
  Convert the object to a dict
@@ -114,6 +117,8 @@ class ModelObj:
114
117
  # If one of the attributes is a third party object that has to_dict method (such as k8s objects), then
115
118
  # add it to the object's _fields_to_serialize attribute and handle it in the _serialize_field method.
116
119
  if hasattr(field_value, "to_dict"):
120
+ # TODO: Allow passing fields to exclude from the parent object to the child object
121
+ # e.g.: run.to_dict(exclude=["status.artifacts"])
117
122
  field_value = field_value.to_dict(strip=strip)
118
123
  if self._is_valid_field_value_for_serialization(
119
124
  field_name, field_value, strip
@@ -141,7 +146,7 @@ class ModelObj:
141
146
  self._apply_enrichment_before_to_dict_completion(struct, strip=strip)
142
147
  return struct
143
148
 
144
- def _resolve_initial_to_dict_fields(self, fields: list = None) -> list:
149
+ def _resolve_initial_to_dict_fields(self, fields: Optional[list] = None) -> list:
145
150
  """
146
151
  Resolve fields to be used in to_dict method.
147
152
  If fields is None, use `_dict_fields` attribute of the object.
@@ -184,7 +189,7 @@ class ModelObj:
184
189
  self,
185
190
  struct: dict,
186
191
  method: typing.Callable,
187
- fields: typing.Union[list, set] = None,
192
+ fields: Optional[typing.Union[list, set]] = None,
188
193
  strip: bool = False,
189
194
  ) -> dict:
190
195
  for field_name in fields:
@@ -196,14 +201,14 @@ class ModelObj:
196
201
  return struct
197
202
 
198
203
  def _serialize_field(
199
- self, struct: dict, field_name: str = None, strip: bool = False
204
+ self, struct: dict, field_name: Optional[str] = None, strip: bool = False
200
205
  ) -> typing.Any:
201
206
  # We pull the field from self and not from struct because it was excluded from the struct when looping over
202
207
  # the fields to save.
203
208
  return getattr(self, field_name, None)
204
209
 
205
210
  def _enrich_field(
206
- self, struct: dict, field_name: str = None, strip: bool = False
211
+ self, struct: dict, field_name: Optional[str] = None, strip: bool = False
207
212
  ) -> typing.Any:
208
213
  # We first try to pull from struct because the field might have been already serialized and if not,
209
214
  # we pull from self
@@ -215,7 +220,9 @@ class ModelObj:
215
220
  return struct
216
221
 
217
222
  @classmethod
218
- def from_dict(cls, struct=None, fields=None, deprecated_fields: dict = None):
223
+ def from_dict(
224
+ cls, struct=None, fields=None, deprecated_fields: Optional[dict] = None
225
+ ):
219
226
  """create an object from a python dictionary"""
220
227
  struct = {} if struct is None else struct
221
228
  deprecated_fields = deprecated_fields or {}
@@ -423,6 +430,19 @@ class ObjectList:
423
430
  self._children[child_obj.name] = child_obj
424
431
  return child_obj
425
432
 
433
+ def move_to_end(self, child, last=True):
434
+ self._children.move_to_end(child, last)
435
+
436
+ def update_list(self, object_list: "ObjectList", push_at_start: bool = False):
437
+ if push_at_start:
438
+ self._children = OrderedDict(
439
+ list(object_list._children.items()) + list(self._children.items())
440
+ )
441
+ else:
442
+ self._children = OrderedDict(
443
+ list(self._children.items()) + list(object_list._children.items())
444
+ )
445
+
426
446
 
427
447
  class Credentials(ModelObj):
428
448
  generate_access_key = "$generate"
@@ -430,7 +450,7 @@ class Credentials(ModelObj):
430
450
 
431
451
  def __init__(
432
452
  self,
433
- access_key: str = None,
453
+ access_key: Optional[str] = None,
434
454
  ):
435
455
  self.access_key = access_key
436
456
 
@@ -438,6 +458,7 @@ class Credentials(ModelObj):
438
458
  class BaseMetadata(ModelObj):
439
459
  _default_fields_to_strip = ModelObj._default_fields_to_strip + [
440
460
  "hash",
461
+ "uid",
441
462
  # Below are environment specific fields, no need to keep when stripping
442
463
  "namespace",
443
464
  "project",
@@ -460,10 +481,12 @@ class BaseMetadata(ModelObj):
460
481
  categories=None,
461
482
  updated=None,
462
483
  credentials=None,
484
+ uid=None,
463
485
  ):
464
486
  self.name = name
465
487
  self.tag = tag
466
488
  self.hash = hash
489
+ self.uid = uid
467
490
  self.namespace = namespace
468
491
  self.project = project or ""
469
492
  self.labels = labels or {}
@@ -500,7 +523,7 @@ class ImageBuilder(ModelObj):
500
523
  origin_filename=None,
501
524
  with_mlrun=None,
502
525
  auto_build=None,
503
- requirements: list = None,
526
+ requirements: Optional[list] = None,
504
527
  extra_args=None,
505
528
  builder_env=None,
506
529
  source_code_target_dir=None,
@@ -549,7 +572,7 @@ class ImageBuilder(ModelObj):
549
572
  self,
550
573
  image="",
551
574
  base_image=None,
552
- commands: list = None,
575
+ commands: Optional[list] = None,
553
576
  secret=None,
554
577
  source=None,
555
578
  extra=None,
@@ -734,7 +757,7 @@ class Notification(ModelObj):
734
757
  def validate_notification(self):
735
758
  try:
736
759
  mlrun.common.schemas.notification.Notification(**self.to_dict())
737
- except pydantic.error_wrappers.ValidationError as exc:
760
+ except pydantic.v1.error_wrappers.ValidationError as exc:
738
761
  raise mlrun.errors.MLRunInvalidArgumentError(
739
762
  "Invalid notification object"
740
763
  ) from exc
@@ -750,14 +773,14 @@ class Notification(ModelObj):
750
773
  "Notification params size exceeds max size of 1 MB"
751
774
  )
752
775
 
753
- def validate_notification_params(self):
754
- notification_class = mlrun.utils.notifications.NotificationTypes(
755
- self.kind
756
- ).get_notification()
757
-
776
+ def validate_notification_params(self, default_notification_params=None):
777
+ default_notification_params = default_notification_params or {}
778
+ notification_type = mlrun.utils.notifications.NotificationTypes(self.kind)
779
+ notification_class = notification_type.get_notification()
758
780
  secret_params = self.secret_params or {}
759
781
  params = self.params or {}
760
-
782
+ default_params = default_notification_params.get(notification_type, {})
783
+ params = notification_class.enrich_default_params(params, default_params)
761
784
  # if the secret_params are already masked - no need to validate
762
785
  params_secret = secret_params.get("secret", "")
763
786
  if params_secret:
@@ -973,7 +996,7 @@ class RunSpec(ModelObj):
973
996
  self.node_selector = node_selector or {}
974
997
 
975
998
  def _serialize_field(
976
- self, struct: dict, field_name: str = None, strip: bool = False
999
+ self, struct: dict, field_name: Optional[str] = None, strip: bool = False
977
1000
  ) -> Optional[str]:
978
1001
  # We pull the field from self and not from struct because it was excluded from the struct
979
1002
  if field_name == "handler":
@@ -1262,6 +1285,8 @@ class RunSpec(ModelObj):
1262
1285
  class RunStatus(ModelObj):
1263
1286
  """Run status"""
1264
1287
 
1288
+ _default_fields_to_strip = ModelObj._default_fields_to_strip + ["artifacts"]
1289
+
1265
1290
  def __init__(
1266
1291
  self,
1267
1292
  state=None,
@@ -1272,12 +1297,13 @@ class RunStatus(ModelObj):
1272
1297
  results=None,
1273
1298
  artifacts=None,
1274
1299
  start_time=None,
1300
+ end_time=None,
1275
1301
  last_update=None,
1276
1302
  iterations=None,
1277
1303
  ui_url=None,
1278
- reason: str = None,
1279
- notifications: dict[str, Notification] = None,
1280
- artifact_uris: dict[str, str] = None,
1304
+ reason: Optional[str] = None,
1305
+ notifications: Optional[dict[str, Notification]] = None,
1306
+ artifact_uris: Optional[dict[str, str]] = None,
1281
1307
  ):
1282
1308
  self.state = state or "created"
1283
1309
  self.status_text = status_text
@@ -1285,15 +1311,68 @@ class RunStatus(ModelObj):
1285
1311
  self.host = host
1286
1312
  self.commit = commit
1287
1313
  self.results = results
1288
- self.artifacts = artifacts
1314
+ self._artifacts = artifacts
1289
1315
  self.start_time = start_time
1316
+ self.end_time = end_time
1290
1317
  self.last_update = last_update
1291
1318
  self.iterations = iterations
1292
1319
  self.ui_url = ui_url
1293
1320
  self.reason = reason
1294
1321
  self.notifications = notifications or {}
1295
1322
  # Artifact key -> URI mapping, since the full artifacts are not stored in the runs DB table
1296
- self.artifact_uris = artifact_uris or {}
1323
+ self._artifact_uris = artifact_uris or {}
1324
+
1325
+ @classmethod
1326
+ def from_dict(
1327
+ cls, struct=None, fields=None, deprecated_fields: Optional[dict] = None
1328
+ ):
1329
+ deprecated_fields = {
1330
+ # Set artifacts as deprecated for lazy loading
1331
+ "artifacts": "artifact_uris"
1332
+ }
1333
+ return super().from_dict(
1334
+ struct, fields=fields, deprecated_fields=deprecated_fields
1335
+ )
1336
+
1337
+ @property
1338
+ def artifacts(self):
1339
+ """
1340
+ Artifacts are lazy loaded to reduce memory consumption.
1341
+ We keep artifact_uris (key -> store URI dictionary) to be able to get the run artifacts easily.
1342
+ If the artifact is not already in the cache, we get it from the store (DB).
1343
+ :return: List of artifact dictionaries
1344
+ """
1345
+ self._artifacts = self._artifacts or []
1346
+ existing_artifact_keys = {
1347
+ artifact["metadata"]["key"] for artifact in self._artifacts
1348
+ }
1349
+ for key, uri in self.artifact_uris.items():
1350
+ if key not in existing_artifact_keys:
1351
+ artifact = mlrun.datastore.get_store_resource(uri)
1352
+ self._artifacts.append(artifact.to_dict())
1353
+ return self._artifacts
1354
+
1355
+ @artifacts.setter
1356
+ def artifacts(self, artifacts):
1357
+ self._artifacts = artifacts
1358
+
1359
+ @property
1360
+ def artifact_uris(self):
1361
+ return self._artifact_uris
1362
+
1363
+ @artifact_uris.setter
1364
+ def artifact_uris(self, artifact_uris):
1365
+ resolved_artifact_uris = {}
1366
+ if isinstance(artifact_uris, list):
1367
+ # artifact_uris is the deprecated list of artifacts - convert to new form
1368
+ for artifact in artifact_uris:
1369
+ if isinstance(artifact, dict):
1370
+ artifact = mlrun.artifacts.dict_to_artifact(artifact)
1371
+ resolved_artifact_uris[artifact.key] = artifact.uri
1372
+ else:
1373
+ resolved_artifact_uris = artifact_uris
1374
+
1375
+ self._artifact_uris = resolved_artifact_uris
1297
1376
 
1298
1377
  def is_failed(self) -> Optional[bool]:
1299
1378
  """
@@ -1601,7 +1680,7 @@ class RunObject(RunTemplate):
1601
1680
 
1602
1681
  return outputs
1603
1682
 
1604
- def artifact(self, key: str) -> "mlrun.DataItem":
1683
+ def artifact(self, key: str) -> typing.Optional["mlrun.DataItem"]:
1605
1684
  """Return artifact DataItem by key.
1606
1685
 
1607
1686
  This method waits for the outputs to complete, searches for the artifact matching the given key,
@@ -1644,7 +1723,7 @@ class RunObject(RunTemplate):
1644
1723
  :param key: The key of the artifact to retrieve.
1645
1724
  :return: The last artifact DataItem with the given key, or None if no such artifact is found.
1646
1725
  """
1647
- if not self.status.artifacts:
1726
+ if not self.status.artifacts and not self.status.artifact_uris:
1648
1727
  return None
1649
1728
 
1650
1729
  # Collect artifacts that match the key
@@ -1655,7 +1734,12 @@ class RunObject(RunTemplate):
1655
1734
  ]
1656
1735
 
1657
1736
  if not matching_artifacts:
1658
- return None
1737
+ if key not in self.status.artifact_uris:
1738
+ return None
1739
+
1740
+ # Get artifact by store URI sanity (should have been enriched by now in status.artifacts property)
1741
+ artifact_uri = self.status.artifact_uris[key]
1742
+ return mlrun.datastore.get_store_resource(artifact_uri)
1659
1743
 
1660
1744
  # Sort matching artifacts by creation date in ascending order.
1661
1745
  # The last element in the list will be the one created most recently.
@@ -1870,7 +1954,7 @@ class EntrypointParam(ModelObj):
1870
1954
  default=None,
1871
1955
  doc="",
1872
1956
  required=None,
1873
- choices: list = None,
1957
+ choices: Optional[list] = None,
1874
1958
  ):
1875
1959
  self.name = name
1876
1960
  self.type = type
@@ -2065,12 +2149,12 @@ class DataSource(ModelObj):
2065
2149
 
2066
2150
  def __init__(
2067
2151
  self,
2068
- name: str = None,
2069
- path: str = None,
2070
- attributes: dict[str, object] = None,
2071
- key_field: str = None,
2072
- time_field: str = None,
2073
- schedule: str = None,
2152
+ name: Optional[str] = None,
2153
+ path: Optional[str] = None,
2154
+ attributes: Optional[dict[str, object]] = None,
2155
+ key_field: Optional[str] = None,
2156
+ time_field: Optional[str] = None,
2157
+ schedule: Optional[str] = None,
2074
2158
  start_time: Optional[Union[datetime, str]] = None,
2075
2159
  end_time: Optional[Union[datetime, str]] = None,
2076
2160
  ):
@@ -2092,7 +2176,7 @@ class DataSource(ModelObj):
2092
2176
  self._secrets = secrets
2093
2177
 
2094
2178
  def _serialize_field(
2095
- self, struct: dict, field_name: str = None, strip: bool = False
2179
+ self, struct: dict, field_name: Optional[str] = None, strip: bool = False
2096
2180
  ) -> typing.Any:
2097
2181
  value = super()._serialize_field(struct, field_name, strip)
2098
2182
  # We pull the field from self and not from struct because it was excluded from the struct when looping over
@@ -2124,7 +2208,9 @@ class DataTargetBase(ModelObj):
2124
2208
  ]
2125
2209
 
2126
2210
  @classmethod
2127
- def from_dict(cls, struct=None, fields=None, deprecated_fields: dict = None):
2211
+ def from_dict(
2212
+ cls, struct=None, fields=None, deprecated_fields: Optional[dict] = None
2213
+ ):
2128
2214
  return super().from_dict(struct, fields=fields)
2129
2215
 
2130
2216
  def get_path(self):
@@ -2140,10 +2226,10 @@ class DataTargetBase(ModelObj):
2140
2226
 
2141
2227
  def __init__(
2142
2228
  self,
2143
- kind: str = None,
2229
+ kind: Optional[str] = None,
2144
2230
  name: str = "",
2145
2231
  path=None,
2146
- attributes: dict[str, str] = None,
2232
+ attributes: Optional[dict[str, str]] = None,
2147
2233
  after_step=None,
2148
2234
  partitioned: bool = False,
2149
2235
  key_bucketing_number: Optional[int] = None,
@@ -2151,8 +2237,8 @@ class DataTargetBase(ModelObj):
2151
2237
  time_partitioning_granularity: Optional[str] = None,
2152
2238
  max_events: Optional[int] = None,
2153
2239
  flush_after_seconds: Optional[int] = None,
2154
- storage_options: dict[str, str] = None,
2155
- schema: dict[str, Any] = None,
2240
+ storage_options: Optional[dict[str, str]] = None,
2241
+ schema: Optional[dict[str, Any]] = None,
2156
2242
  credentials_prefix=None,
2157
2243
  ):
2158
2244
  self.name = name
@@ -2208,7 +2294,7 @@ class DataTarget(DataTargetBase):
2208
2294
 
2209
2295
  def __init__(
2210
2296
  self,
2211
- kind: str = None,
2297
+ kind: Optional[str] = None,
2212
2298
  name: str = "",
2213
2299
  path=None,
2214
2300
  online=None,
@@ -2237,12 +2323,12 @@ class DataTarget(DataTargetBase):
2237
2323
  class VersionedObjMetadata(ModelObj):
2238
2324
  def __init__(
2239
2325
  self,
2240
- name: str = None,
2241
- tag: str = None,
2242
- uid: str = None,
2243
- project: str = None,
2244
- labels: dict[str, str] = None,
2245
- annotations: dict[str, str] = None,
2326
+ name: Optional[str] = None,
2327
+ tag: Optional[str] = None,
2328
+ uid: Optional[str] = None,
2329
+ project: Optional[str] = None,
2330
+ labels: Optional[dict[str, str]] = None,
2331
+ annotations: Optional[dict[str, str]] = None,
2246
2332
  updated=None,
2247
2333
  ):
2248
2334
  self.name = name
@@ -11,11 +11,9 @@
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
14
 
18
- from .db import get_store_object, get_tsdb_connector
15
+ from mlrun.common.schemas import ModelEndpoint, ModelEndpointList
16
+
17
+ from .db import get_tsdb_connector
19
18
  from .helpers import get_stream_path
20
- from .model_endpoint import ModelEndpoint
21
19
  from .tracking_policy import TrackingPolicy