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

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

Potentially problematic release.


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

Files changed (291) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +26 -112
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +5 -4
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +46 -257
  8. mlrun/artifacts/dataset.py +11 -192
  9. mlrun/artifacts/manager.py +47 -48
  10. mlrun/artifacts/model.py +31 -159
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +69 -0
  13. mlrun/common/db/sql_session.py +2 -3
  14. mlrun/common/formatters/__init__.py +19 -0
  15. mlrun/common/formatters/artifact.py +21 -0
  16. mlrun/common/formatters/base.py +78 -0
  17. mlrun/common/formatters/function.py +41 -0
  18. mlrun/common/formatters/pipeline.py +53 -0
  19. mlrun/common/formatters/project.py +51 -0
  20. mlrun/common/helpers.py +1 -2
  21. mlrun/common/model_monitoring/helpers.py +9 -5
  22. mlrun/{runtimes → common/runtimes}/constants.py +37 -9
  23. mlrun/common/schemas/__init__.py +24 -4
  24. mlrun/common/schemas/alert.py +203 -0
  25. mlrun/common/schemas/api_gateway.py +148 -0
  26. mlrun/common/schemas/artifact.py +18 -8
  27. mlrun/common/schemas/auth.py +11 -5
  28. mlrun/common/schemas/background_task.py +1 -1
  29. mlrun/common/schemas/client_spec.py +4 -1
  30. mlrun/common/schemas/feature_store.py +16 -16
  31. mlrun/common/schemas/frontend_spec.py +8 -7
  32. mlrun/common/schemas/function.py +5 -1
  33. mlrun/common/schemas/hub.py +11 -18
  34. mlrun/common/schemas/memory_reports.py +2 -2
  35. mlrun/common/schemas/model_monitoring/__init__.py +18 -3
  36. mlrun/common/schemas/model_monitoring/constants.py +83 -26
  37. mlrun/common/schemas/model_monitoring/grafana.py +13 -9
  38. mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
  39. mlrun/common/schemas/notification.py +4 -4
  40. mlrun/common/schemas/object.py +2 -2
  41. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  42. mlrun/common/schemas/pipeline.py +1 -10
  43. mlrun/common/schemas/project.py +24 -23
  44. mlrun/common/schemas/runtime_resource.py +8 -12
  45. mlrun/common/schemas/schedule.py +3 -3
  46. mlrun/common/schemas/tag.py +1 -2
  47. mlrun/common/schemas/workflow.py +2 -2
  48. mlrun/common/types.py +7 -1
  49. mlrun/config.py +54 -17
  50. mlrun/data_types/to_pandas.py +10 -12
  51. mlrun/datastore/__init__.py +5 -8
  52. mlrun/datastore/alibaba_oss.py +130 -0
  53. mlrun/datastore/azure_blob.py +17 -5
  54. mlrun/datastore/base.py +62 -39
  55. mlrun/datastore/datastore.py +28 -9
  56. mlrun/datastore/datastore_profile.py +146 -20
  57. mlrun/datastore/filestore.py +0 -1
  58. mlrun/datastore/google_cloud_storage.py +6 -2
  59. mlrun/datastore/hdfs.py +56 -0
  60. mlrun/datastore/inmem.py +2 -2
  61. mlrun/datastore/redis.py +6 -2
  62. mlrun/datastore/s3.py +9 -0
  63. mlrun/datastore/snowflake_utils.py +43 -0
  64. mlrun/datastore/sources.py +201 -96
  65. mlrun/datastore/spark_utils.py +1 -2
  66. mlrun/datastore/store_resources.py +7 -7
  67. mlrun/datastore/targets.py +358 -104
  68. mlrun/datastore/utils.py +72 -58
  69. mlrun/datastore/v3io.py +5 -1
  70. mlrun/db/base.py +185 -35
  71. mlrun/db/factory.py +1 -1
  72. mlrun/db/httpdb.py +614 -179
  73. mlrun/db/nopdb.py +210 -26
  74. mlrun/errors.py +12 -1
  75. mlrun/execution.py +41 -24
  76. mlrun/feature_store/__init__.py +0 -2
  77. mlrun/feature_store/api.py +40 -72
  78. mlrun/feature_store/common.py +1 -1
  79. mlrun/feature_store/feature_set.py +76 -55
  80. mlrun/feature_store/feature_vector.py +28 -30
  81. mlrun/feature_store/ingestion.py +7 -6
  82. mlrun/feature_store/retrieval/base.py +16 -11
  83. mlrun/feature_store/retrieval/conversion.py +11 -13
  84. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  85. mlrun/feature_store/retrieval/job.py +9 -3
  86. mlrun/feature_store/retrieval/local_merger.py +2 -0
  87. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  88. mlrun/feature_store/steps.py +37 -34
  89. mlrun/features.py +9 -20
  90. mlrun/frameworks/_common/artifacts_library.py +9 -9
  91. mlrun/frameworks/_common/mlrun_interface.py +5 -5
  92. mlrun/frameworks/_common/model_handler.py +48 -48
  93. mlrun/frameworks/_common/plan.py +2 -3
  94. mlrun/frameworks/_common/producer.py +3 -4
  95. mlrun/frameworks/_common/utils.py +5 -5
  96. mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
  97. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
  98. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
  99. mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
  100. mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
  101. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
  102. mlrun/frameworks/_ml_common/model_handler.py +24 -24
  103. mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
  104. mlrun/frameworks/_ml_common/plan.py +1 -1
  105. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
  106. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
  107. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  108. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
  109. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  110. mlrun/frameworks/_ml_common/utils.py +4 -4
  111. mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
  112. mlrun/frameworks/huggingface/model_server.py +4 -4
  113. mlrun/frameworks/lgbm/__init__.py +33 -33
  114. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  115. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
  116. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
  117. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
  118. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
  119. mlrun/frameworks/lgbm/model_handler.py +10 -10
  120. mlrun/frameworks/lgbm/model_server.py +6 -6
  121. mlrun/frameworks/lgbm/utils.py +5 -5
  122. mlrun/frameworks/onnx/dataset.py +8 -8
  123. mlrun/frameworks/onnx/mlrun_interface.py +3 -3
  124. mlrun/frameworks/onnx/model_handler.py +6 -6
  125. mlrun/frameworks/onnx/model_server.py +7 -7
  126. mlrun/frameworks/parallel_coordinates.py +4 -3
  127. mlrun/frameworks/pytorch/__init__.py +18 -18
  128. mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
  129. mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
  130. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
  131. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
  132. mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
  133. mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
  134. mlrun/frameworks/pytorch/model_handler.py +17 -17
  135. mlrun/frameworks/pytorch/model_server.py +7 -7
  136. mlrun/frameworks/sklearn/__init__.py +13 -13
  137. mlrun/frameworks/sklearn/estimator.py +4 -4
  138. mlrun/frameworks/sklearn/metrics_library.py +14 -14
  139. mlrun/frameworks/sklearn/mlrun_interface.py +3 -6
  140. mlrun/frameworks/sklearn/model_handler.py +2 -2
  141. mlrun/frameworks/tf_keras/__init__.py +10 -7
  142. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
  143. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
  144. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
  145. mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
  146. mlrun/frameworks/tf_keras/model_handler.py +14 -14
  147. mlrun/frameworks/tf_keras/model_server.py +6 -6
  148. mlrun/frameworks/xgboost/__init__.py +13 -13
  149. mlrun/frameworks/xgboost/model_handler.py +6 -6
  150. mlrun/k8s_utils.py +14 -16
  151. mlrun/launcher/__init__.py +1 -1
  152. mlrun/launcher/base.py +16 -15
  153. mlrun/launcher/client.py +8 -6
  154. mlrun/launcher/factory.py +1 -1
  155. mlrun/launcher/local.py +17 -11
  156. mlrun/launcher/remote.py +16 -10
  157. mlrun/lists.py +7 -6
  158. mlrun/model.py +238 -73
  159. mlrun/model_monitoring/__init__.py +1 -1
  160. mlrun/model_monitoring/api.py +138 -315
  161. mlrun/model_monitoring/application.py +5 -296
  162. mlrun/model_monitoring/applications/__init__.py +24 -0
  163. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  164. mlrun/model_monitoring/applications/base.py +282 -0
  165. mlrun/model_monitoring/applications/context.py +214 -0
  166. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  167. mlrun/model_monitoring/applications/histogram_data_drift.py +349 -0
  168. mlrun/model_monitoring/applications/results.py +99 -0
  169. mlrun/model_monitoring/controller.py +104 -84
  170. mlrun/model_monitoring/controller_handler.py +13 -5
  171. mlrun/model_monitoring/db/__init__.py +18 -0
  172. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  173. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  174. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +64 -40
  175. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  176. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  177. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  178. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  179. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  180. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  181. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  182. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +310 -165
  183. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  184. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  185. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  186. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  187. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  188. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  189. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  190. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  191. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  192. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  193. mlrun/model_monitoring/evidently_application.py +6 -118
  194. mlrun/model_monitoring/features_drift_table.py +134 -106
  195. mlrun/model_monitoring/helpers.py +127 -28
  196. mlrun/model_monitoring/metrics/__init__.py +13 -0
  197. mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
  198. mlrun/model_monitoring/model_endpoint.py +3 -2
  199. mlrun/model_monitoring/prometheus.py +1 -4
  200. mlrun/model_monitoring/stream_processing.py +62 -231
  201. mlrun/model_monitoring/tracking_policy.py +9 -2
  202. mlrun/model_monitoring/writer.py +152 -124
  203. mlrun/package/__init__.py +6 -6
  204. mlrun/package/context_handler.py +5 -5
  205. mlrun/package/packager.py +7 -7
  206. mlrun/package/packagers/default_packager.py +6 -6
  207. mlrun/package/packagers/numpy_packagers.py +15 -15
  208. mlrun/package/packagers/pandas_packagers.py +5 -5
  209. mlrun/package/packagers/python_standard_library_packagers.py +10 -10
  210. mlrun/package/packagers_manager.py +19 -23
  211. mlrun/package/utils/_formatter.py +6 -6
  212. mlrun/package/utils/_pickler.py +2 -2
  213. mlrun/package/utils/_supported_format.py +4 -4
  214. mlrun/package/utils/log_hint_utils.py +2 -2
  215. mlrun/package/utils/type_hint_utils.py +4 -9
  216. mlrun/platforms/__init__.py +11 -10
  217. mlrun/platforms/iguazio.py +24 -203
  218. mlrun/projects/operations.py +35 -21
  219. mlrun/projects/pipelines.py +68 -99
  220. mlrun/projects/project.py +830 -266
  221. mlrun/render.py +3 -11
  222. mlrun/run.py +162 -166
  223. mlrun/runtimes/__init__.py +62 -7
  224. mlrun/runtimes/base.py +39 -32
  225. mlrun/runtimes/daskjob.py +8 -8
  226. mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
  227. mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
  228. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  229. mlrun/runtimes/funcdoc.py +0 -28
  230. mlrun/runtimes/function_reference.py +1 -1
  231. mlrun/runtimes/kubejob.py +28 -122
  232. mlrun/runtimes/local.py +6 -3
  233. mlrun/runtimes/mpijob/__init__.py +0 -20
  234. mlrun/runtimes/mpijob/abstract.py +9 -10
  235. mlrun/runtimes/mpijob/v1.py +1 -1
  236. mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
  237. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  238. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  239. mlrun/runtimes/nuclio/application/application.py +523 -0
  240. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  241. mlrun/runtimes/{function.py → nuclio/function.py} +112 -73
  242. mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
  243. mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
  244. mlrun/runtimes/pod.py +286 -88
  245. mlrun/runtimes/remotesparkjob.py +2 -2
  246. mlrun/runtimes/sparkjob/spark3job.py +51 -34
  247. mlrun/runtimes/utils.py +7 -75
  248. mlrun/secrets.py +9 -5
  249. mlrun/serving/remote.py +2 -7
  250. mlrun/serving/routers.py +13 -10
  251. mlrun/serving/server.py +22 -26
  252. mlrun/serving/states.py +99 -25
  253. mlrun/serving/utils.py +3 -3
  254. mlrun/serving/v1_serving.py +6 -7
  255. mlrun/serving/v2_serving.py +59 -20
  256. mlrun/track/tracker.py +2 -1
  257. mlrun/track/tracker_manager.py +3 -3
  258. mlrun/track/trackers/mlflow_tracker.py +1 -2
  259. mlrun/utils/async_http.py +5 -7
  260. mlrun/utils/azure_vault.py +1 -1
  261. mlrun/utils/clones.py +1 -2
  262. mlrun/utils/condition_evaluator.py +3 -3
  263. mlrun/utils/db.py +3 -3
  264. mlrun/utils/helpers.py +183 -197
  265. mlrun/utils/http.py +2 -5
  266. mlrun/utils/logger.py +76 -14
  267. mlrun/utils/notifications/notification/__init__.py +17 -12
  268. mlrun/utils/notifications/notification/base.py +14 -2
  269. mlrun/utils/notifications/notification/console.py +2 -0
  270. mlrun/utils/notifications/notification/git.py +3 -1
  271. mlrun/utils/notifications/notification/ipython.py +3 -1
  272. mlrun/utils/notifications/notification/slack.py +101 -21
  273. mlrun/utils/notifications/notification/webhook.py +11 -1
  274. mlrun/utils/notifications/notification_pusher.py +155 -30
  275. mlrun/utils/retryer.py +208 -0
  276. mlrun/utils/singleton.py +1 -1
  277. mlrun/utils/v3io_clients.py +2 -4
  278. mlrun/utils/version/version.json +2 -2
  279. mlrun/utils/version/version.py +2 -6
  280. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
  281. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  282. mlrun/kfpops.py +0 -868
  283. mlrun/model_monitoring/batch.py +0 -1095
  284. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  285. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
  286. mlrun/platforms/other.py +0 -306
  287. mlrun-1.6.4rc2.dist-info/RECORD +0 -314
  288. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  289. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
  290. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  291. {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
@@ -11,10 +11,10 @@
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
14
  import typing
16
15
 
17
16
  import kubernetes.client
17
+ from mlrun_pipelines.mounts import mount_v3io, mount_v3iod
18
18
 
19
19
  import mlrun.common.schemas.function
20
20
  import mlrun.errors
@@ -23,7 +23,6 @@ from mlrun.config import config
23
23
 
24
24
  from ...execution import MLClientCtx
25
25
  from ...model import RunObject
26
- from ...platforms.iguazio import mount_v3io, mount_v3iod
27
26
  from ...utils import update_in, verify_field_regex
28
27
  from ..kubejob import KubejobRuntime
29
28
  from ..pod import KubeResourceSpec
@@ -69,6 +68,48 @@ class Spark3JobSpec(KubeResourceSpec):
69
68
  "driver_cores",
70
69
  "executor_cores",
71
70
  ]
71
+ _default_fields_to_strip = KubeResourceSpec._default_fields_to_strip + [
72
+ "driver_node_selector",
73
+ "executor_node_selector",
74
+ "driver_tolerations",
75
+ "executor_tolerations",
76
+ "driver_affinity",
77
+ "executor_affinity",
78
+ "driver_volume_mounts",
79
+ "executor_volume_mounts",
80
+ "driver_cores",
81
+ "executor_cores",
82
+ ]
83
+
84
+ __k8s_fields_to_serialize = [
85
+ "driver_volume_mounts",
86
+ "executor_volume_mounts",
87
+ "driver_node_selector",
88
+ "executor_node_selector",
89
+ "executor_affinity",
90
+ "executor_tolerations",
91
+ "driver_affinity",
92
+ "driver_tolerations",
93
+ ]
94
+ _k8s_fields_to_serialize = (
95
+ KubeResourceSpec._k8s_fields_to_serialize + __k8s_fields_to_serialize
96
+ )
97
+ _fields_to_serialize = (
98
+ KubeResourceSpec._fields_to_serialize + __k8s_fields_to_serialize
99
+ )
100
+ _fields_to_skip_validation = KubeResourceSpec._fields_to_skip_validation + [
101
+ # TODO: affinity, tolerations and node_selector are skipped due to preemption mode transitions.
102
+ # Preemption mode 'none' depends on the previous mode while the default mode may enrich these values.
103
+ # When we allow 'None' values for these attributes we get their true values and they will undo the default
104
+ # enrichment when creating the runtime from dict.
105
+ # The enrichment should move to the server side and then this can be removed.
106
+ "driver_node_selector",
107
+ "executor_node_selector",
108
+ "executor_affinity",
109
+ "executor_tolerations",
110
+ "driver_affinity",
111
+ "driver_tolerations",
112
+ ]
72
113
 
73
114
  def __init__(
74
115
  self,
@@ -189,26 +230,8 @@ class Spark3JobSpec(KubeResourceSpec):
189
230
  self.driver_cores = driver_cores
190
231
  self.executor_cores = executor_cores
191
232
 
192
- def to_dict(self, fields=None, exclude=None):
193
- exclude = exclude or []
194
- _exclude = [
195
- "affinity",
196
- "tolerations",
197
- "security_context",
198
- "executor_affinity",
199
- "executor_tolerations",
200
- "driver_affinity",
201
- "driver_tolerations",
202
- ]
203
- struct = super().to_dict(fields, exclude=list(set(exclude + _exclude)))
204
- api = kubernetes.client.ApiClient()
205
- for field in _exclude:
206
- if field not in exclude:
207
- struct[field] = api.sanitize_for_serialization(getattr(self, field))
208
- return struct
209
-
210
233
  @property
211
- def executor_tolerations(self) -> typing.List[kubernetes.client.V1Toleration]:
234
+ def executor_tolerations(self) -> list[kubernetes.client.V1Toleration]:
212
235
  return self._executor_tolerations
213
236
 
214
237
  @executor_tolerations.setter
@@ -220,7 +243,7 @@ class Spark3JobSpec(KubeResourceSpec):
220
243
  )
221
244
 
222
245
  @property
223
- def driver_tolerations(self) -> typing.List[kubernetes.client.V1Toleration]:
246
+ def driver_tolerations(self) -> list[kubernetes.client.V1Toleration]:
224
247
  return self._driver_tolerations
225
248
 
226
249
  @driver_tolerations.setter
@@ -461,11 +484,9 @@ class Spark3Runtime(KubejobRuntime):
461
484
  def with_node_selection(
462
485
  self,
463
486
  node_name: typing.Optional[str] = None,
464
- node_selector: typing.Optional[typing.Dict[str, str]] = None,
487
+ node_selector: typing.Optional[dict[str, str]] = None,
465
488
  affinity: typing.Optional[kubernetes.client.V1Affinity] = None,
466
- tolerations: typing.Optional[
467
- typing.List[kubernetes.client.V1Toleration]
468
- ] = None,
489
+ tolerations: typing.Optional[list[kubernetes.client.V1Toleration]] = None,
469
490
  ):
470
491
  if node_name:
471
492
  raise NotImplementedError(
@@ -495,11 +516,9 @@ class Spark3Runtime(KubejobRuntime):
495
516
  def with_driver_node_selection(
496
517
  self,
497
518
  node_name: typing.Optional[str] = None,
498
- node_selector: typing.Optional[typing.Dict[str, str]] = None,
519
+ node_selector: typing.Optional[dict[str, str]] = None,
499
520
  affinity: typing.Optional[kubernetes.client.V1Affinity] = None,
500
- tolerations: typing.Optional[
501
- typing.List[kubernetes.client.V1Toleration]
502
- ] = None,
521
+ tolerations: typing.Optional[list[kubernetes.client.V1Toleration]] = None,
503
522
  ):
504
523
  """
505
524
  Enables control of which k8s node the spark executor will run on.
@@ -528,11 +547,9 @@ class Spark3Runtime(KubejobRuntime):
528
547
  def with_executor_node_selection(
529
548
  self,
530
549
  node_name: typing.Optional[str] = None,
531
- node_selector: typing.Optional[typing.Dict[str, str]] = None,
550
+ node_selector: typing.Optional[dict[str, str]] = None,
532
551
  affinity: typing.Optional[kubernetes.client.V1Affinity] = None,
533
- tolerations: typing.Optional[
534
- typing.List[kubernetes.client.V1Toleration]
535
- ] = None,
552
+ tolerations: typing.Optional[list[kubernetes.client.V1Toleration]] = None,
536
553
  ):
537
554
  """
538
555
  Enables control of which k8s node the spark executor will run on.
mlrun/runtimes/utils.py CHANGED
@@ -16,22 +16,21 @@ import hashlib
16
16
  import json
17
17
  import os
18
18
  import re
19
- import typing
20
19
  from io import StringIO
21
20
  from sys import stderr
22
21
 
23
22
  import pandas as pd
24
- from kubernetes import client
25
23
 
26
24
  import mlrun
27
25
  import mlrun.common.constants
26
+ import mlrun.common.constants as mlrun_constants
28
27
  import mlrun.common.schemas
29
28
  import mlrun.utils.regex
30
29
  from mlrun.artifacts import TableArtifact
30
+ from mlrun.common.runtimes.constants import RunLabels
31
31
  from mlrun.config import config
32
32
  from mlrun.errors import err_to_str
33
33
  from mlrun.frameworks.parallel_coordinates import gen_pcp_plot
34
- from mlrun.runtimes.constants import RunLabels
35
34
  from mlrun.runtimes.generators import selector
36
35
  from mlrun.utils import get_in, helpers, logger, verify_field_regex
37
36
 
@@ -40,9 +39,6 @@ class RunError(Exception):
40
39
  pass
41
40
 
42
41
 
43
- mlrun_key = "mlrun/"
44
-
45
-
46
42
  class _ContextStore:
47
43
  def __init__(self):
48
44
  self._context = None
@@ -281,43 +277,6 @@ def get_item_name(item, attr="name"):
281
277
  return getattr(item, attr, None)
282
278
 
283
279
 
284
- def apply_kfp(modify, cop, runtime):
285
- modify(cop)
286
-
287
- # Have to do it here to avoid circular dependencies
288
- from .pod import AutoMountType
289
-
290
- if AutoMountType.is_auto_modifier(modify):
291
- runtime.spec.disable_auto_mount = True
292
-
293
- api = client.ApiClient()
294
- for k, v in cop.pod_labels.items():
295
- runtime.metadata.labels[k] = v
296
- for k, v in cop.pod_annotations.items():
297
- runtime.metadata.annotations[k] = v
298
- if cop.container.env:
299
- env_names = [
300
- e.name if hasattr(e, "name") else e["name"] for e in runtime.spec.env
301
- ]
302
- for e in api.sanitize_for_serialization(cop.container.env):
303
- name = e["name"]
304
- if name in env_names:
305
- runtime.spec.env[env_names.index(name)] = e
306
- else:
307
- runtime.spec.env.append(e)
308
- env_names.append(name)
309
- cop.container.env.clear()
310
-
311
- if cop.volumes and cop.container.volume_mounts:
312
- vols = api.sanitize_for_serialization(cop.volumes)
313
- mounts = api.sanitize_for_serialization(cop.container.volume_mounts)
314
- runtime.spec.update_vols_and_mounts(vols, mounts)
315
- cop.volumes.clear()
316
- cop.container.volume_mounts.clear()
317
-
318
- return runtime
319
-
320
-
321
280
  def verify_limits(
322
281
  resources_field_name,
323
282
  mem=None,
@@ -411,41 +370,13 @@ def generate_resources(mem=None, cpu=None, gpus=None, gpu_type="nvidia.com/gpu")
411
370
 
412
371
 
413
372
  def get_func_selector(project, name=None, tag=None):
414
- s = [f"{mlrun_key}project={project}"]
373
+ s = [f"{mlrun_constants.MLRunInternalLabels.project}={project}"]
415
374
  if name:
416
- s.append(f"{mlrun_key}function={name}")
417
- s.append(f"{mlrun_key}tag={tag or 'latest'}")
375
+ s.append(f"{mlrun_constants.MLRunInternalLabels.function}={name}")
376
+ s.append(f"{mlrun_constants.MLRunInternalLabels.tag}={tag or 'latest'}")
418
377
  return s
419
378
 
420
379
 
421
- class k8s_resource:
422
- kind = ""
423
- per_run = False
424
- per_function = False
425
- k8client = None
426
-
427
- def deploy_function(self, function):
428
- pass
429
-
430
- def release_function(self, function):
431
- pass
432
-
433
- def submit_run(self, function, runobj):
434
- pass
435
-
436
- def get_object(self, name, namespace=None):
437
- return None
438
-
439
- def get_status(self, name, namespace=None):
440
- return None
441
-
442
- def del_object(self, name, namespace=None):
443
- pass
444
-
445
- def get_pods(self, name, namespace=None, master=False):
446
- return {}
447
-
448
-
449
380
  def enrich_function_from_dict(function, function_dict):
450
381
  override_function = mlrun.new_function(runtime=function_dict, kind=function.kind)
451
382
  for attribute in [
@@ -501,10 +432,11 @@ def enrich_function_from_dict(function, function_dict):
501
432
 
502
433
  def enrich_run_labels(
503
434
  labels: dict,
504
- labels_to_enrich: typing.List[RunLabels] = None,
435
+ labels_to_enrich: list[RunLabels] = None,
505
436
  ):
506
437
  labels_enrichment = {
507
438
  RunLabels.owner: os.environ.get("V3IO_USERNAME") or getpass.getuser(),
439
+ # TODO: remove this in 1.9.0
508
440
  RunLabels.v3io_user: os.environ.get("V3IO_USERNAME"),
509
441
  }
510
442
  labels_to_enrich = labels_to_enrich or RunLabels.all()
mlrun/secrets.py CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  from ast import literal_eval
16
16
  from os import environ, getenv
17
- from typing import Callable, Dict, Optional, Union
17
+ from typing import Callable, Optional, Union
18
18
 
19
19
  from .utils import AzureVaultStore, list2dict
20
20
 
@@ -148,7 +148,7 @@ class SecretsStore:
148
148
 
149
149
  def get_secret_or_env(
150
150
  key: str,
151
- secret_provider: Union[Dict, SecretsStore, Callable, None] = None,
151
+ secret_provider: Union[dict, SecretsStore, Callable, None] = None,
152
152
  default: Optional[str] = None,
153
153
  prefix: Optional[str] = None,
154
154
  ) -> str:
@@ -163,15 +163,19 @@ def get_secret_or_env(
163
163
 
164
164
  Example::
165
165
 
166
- secrets = { "KEY1": "VALUE1" }
166
+ secrets = {"KEY1": "VALUE1"}
167
167
  secret = get_secret_or_env("KEY1", secret_provider=secrets)
168
168
 
169
+
169
170
  # Using a function to retrieve a secret
170
171
  def my_secret_provider(key):
171
172
  # some internal logic to retrieve secret
172
173
  return value
173
174
 
174
- secret = get_secret_or_env("KEY1", secret_provider=my_secret_provider, default="TOO-MANY-SECRETS")
175
+
176
+ secret = get_secret_or_env(
177
+ "KEY1", secret_provider=my_secret_provider, default="TOO-MANY-SECRETS"
178
+ )
175
179
 
176
180
  :param key: Secret key to look for
177
181
  :param secret_provider: Dictionary, callable or `SecretsStore` to extract the secret value from. If using a
@@ -185,7 +189,7 @@ def get_secret_or_env(
185
189
 
186
190
  value = None
187
191
  if secret_provider:
188
- if isinstance(secret_provider, (Dict, SecretsStore)):
192
+ if isinstance(secret_provider, (dict, SecretsStore)):
189
193
  value = secret_provider.get(key)
190
194
  else:
191
195
  value = secret_provider(key)
mlrun/serving/remote.py CHANGED
@@ -37,8 +37,6 @@ default_backoff_factor = 1
37
37
 
38
38
 
39
39
  class RemoteStep(storey.SendToHttp):
40
- """class for calling remote endpoints"""
41
-
42
40
  def __init__(
43
41
  self,
44
42
  url: str,
@@ -174,8 +172,7 @@ class RemoteStep(storey.SendToHttp):
174
172
  if not self._session:
175
173
  self._session = mlrun.utils.HTTPSessionWithRetry(
176
174
  self.retries,
177
- self.backoff_factor
178
- or mlrun.config.config.http_retry_defaults.backoff_factor,
175
+ self.backoff_factor or mlrun.mlconf.http_retry_defaults.backoff_factor,
179
176
  retry_on_exception=False,
180
177
  retry_on_status=self.retries > 0,
181
178
  retry_on_post=True,
@@ -187,7 +184,7 @@ class RemoteStep(storey.SendToHttp):
187
184
  resp = self._session.request(
188
185
  method,
189
186
  url,
190
- verify=mlrun.config.config.httpdb.http.verify,
187
+ verify=mlrun.mlconf.httpdb.http.verify,
191
188
  headers=headers,
192
189
  data=body,
193
190
  timeout=self.timeout,
@@ -242,8 +239,6 @@ class RemoteStep(storey.SendToHttp):
242
239
 
243
240
 
244
241
  class BatchHttpRequests(_ConcurrentJobExecution):
245
- """class for calling remote endpoints in parallel"""
246
-
247
242
  def __init__(
248
243
  self,
249
244
  url: str = None,
mlrun/serving/routers.py CHANGED
@@ -20,7 +20,7 @@ import traceback
20
20
  import typing
21
21
  from enum import Enum
22
22
  from io import BytesIO
23
- from typing import Dict, List, Union
23
+ from typing import Union
24
24
 
25
25
  import numpy
26
26
  import numpy as np
@@ -28,6 +28,7 @@ import numpy as np
28
28
  import mlrun
29
29
  import mlrun.common.model_monitoring
30
30
  import mlrun.common.schemas.model_monitoring
31
+ from mlrun.errors import err_to_str
31
32
  from mlrun.utils import logger, now_date
32
33
 
33
34
  from ..common.helpers import parse_versioned_object_uri
@@ -271,7 +272,9 @@ class ParallelRun(BaseModelRouter):
271
272
  fn = mlrun.new_function("parallel", kind="serving")
272
273
  graph = fn.set_topology(
273
274
  "router",
274
- mlrun.serving.routers.ParallelRun(extend_event=True, executor_type=executor),
275
+ mlrun.serving.routers.ParallelRun(
276
+ extend_event=True, executor_type=executor
277
+ ),
275
278
  )
276
279
  graph.add_route("child1", class_name="Cls1")
277
280
  graph.add_route("child2", class_name="Cls2", my_arg={"c": 7})
@@ -485,7 +488,7 @@ class VotingEnsemble(ParallelRun):
485
488
  url_prefix: str = None,
486
489
  health_prefix: str = None,
487
490
  vote_type: str = None,
488
- weights: Dict[str, float] = None,
491
+ weights: dict[str, float] = None,
489
492
  executor_type: Union[ParallelRunnerModes, str] = ParallelRunnerModes.thread,
490
493
  format_response_with_col_name_flag: bool = False,
491
494
  prediction_col_name: str = "prediction",
@@ -703,7 +706,7 @@ class VotingEnsemble(ParallelRun):
703
706
  )
704
707
  return model, None, subpath
705
708
 
706
- def _majority_vote(self, all_predictions: List[List[int]], weights: List[float]):
709
+ def _majority_vote(self, all_predictions: list[list[int]], weights: list[float]):
707
710
  """
708
711
  Returns most predicted class for each event
709
712
 
@@ -727,7 +730,7 @@ class VotingEnsemble(ParallelRun):
727
730
  weighted_res = one_hot_representation @ weights
728
731
  return np.argmax(weighted_res, axis=1).tolist()
729
732
 
730
- def _mean_vote(self, all_predictions: List[List[float]], weights: List[float]):
733
+ def _mean_vote(self, all_predictions: list[list[float]], weights: list[float]):
731
734
  """
732
735
  Returns weighted mean of the predictions
733
736
 
@@ -741,7 +744,7 @@ class VotingEnsemble(ParallelRun):
741
744
  def _is_int(self, value):
742
745
  return float(value).is_integer()
743
746
 
744
- def logic(self, predictions: List[List[Union[int, float]]], weights: List[float]):
747
+ def logic(self, predictions: list[list[Union[int, float]]], weights: list[float]):
745
748
  """
746
749
  Returns the final prediction of all the models after applying the desire logic
747
750
 
@@ -957,7 +960,7 @@ class VotingEnsemble(ParallelRun):
957
960
  raise Exception('Expected "inputs" to be a list')
958
961
  return request
959
962
 
960
- def _normalize_weights(self, weights_dict: Dict[str, float]):
963
+ def _normalize_weights(self, weights_dict: dict[str, float]):
961
964
  """
962
965
  Normalized all the weights such that abs(weights_sum - 1.0) <= 0.001
963
966
  and adding 0 weight to all the routes that doesn't appear in the dict.
@@ -1013,7 +1016,7 @@ def _init_endpoint_record(
1013
1016
  graph_server.function_uri
1014
1017
  )
1015
1018
  except Exception as e:
1016
- logger.error("Failed to parse function URI", exc=e)
1019
+ logger.error("Failed to parse function URI", exc=err_to_str(e))
1017
1020
  return None
1018
1021
 
1019
1022
  # Generating version model value based on the model name and model version
@@ -1089,12 +1092,12 @@ def _init_endpoint_record(
1089
1092
  except Exception as exc:
1090
1093
  logger.warning(
1091
1094
  "Failed creating model endpoint record",
1092
- exc=exc,
1095
+ exc=err_to_str(exc),
1093
1096
  traceback=traceback.format_exc(),
1094
1097
  )
1095
1098
 
1096
1099
  except Exception as e:
1097
- logger.error("Failed to retrieve model endpoint object", exc=e)
1100
+ logger.error("Failed to retrieve model endpoint object", exc=err_to_str(e))
1098
1101
 
1099
1102
  return endpoint_uid
1100
1103
 
mlrun/serving/server.py CHANGED
@@ -23,6 +23,7 @@ import uuid
23
23
  from typing import Optional, Union
24
24
 
25
25
  import mlrun
26
+ import mlrun.common.constants
26
27
  import mlrun.common.helpers
27
28
  import mlrun.model_monitoring
28
29
  from mlrun.config import config
@@ -52,7 +53,7 @@ class _StreamContext:
52
53
  Initialize _StreamContext object.
53
54
  :param enabled: A boolean indication for applying the stream context
54
55
  :param parameters: Dictionary of optional parameters, such as `log_stream` and `stream_args`. Note that these
55
- parameters might be relevant to the output source such as `kafka_bootstrap_servers` if
56
+ parameters might be relevant to the output source such as `kafka_brokers` if
56
57
  the output source is from type Kafka.
57
58
  :param function_uri: Full value of the function uri, usually it's <project-name>/<function-name>
58
59
  """
@@ -188,11 +189,6 @@ class GraphServer(ModelObj):
188
189
 
189
190
  def init_object(self, namespace):
190
191
  self.graph.init_object(self.context, namespace, self.load_mode, reset=True)
191
- return (
192
- v2_serving_async_handler
193
- if config.datastore.async_source_mode == "enabled"
194
- else v2_serving_handler
195
- )
196
192
 
197
193
  def test(
198
194
  self,
@@ -310,17 +306,14 @@ class GraphServer(ModelObj):
310
306
 
311
307
  def wait_for_completion(self):
312
308
  """wait for async operation to complete"""
313
- self.graph.wait_for_completion()
309
+ return self.graph.wait_for_completion()
314
310
 
315
311
 
316
312
  def v2_serving_init(context, namespace=None):
317
313
  """hook for nuclio init_context()"""
318
314
 
319
- data = os.environ.get("SERVING_SPEC_ENV", "")
320
- if not data:
321
- raise MLRunInvalidArgumentError("failed to find spec env var")
322
- spec = json.loads(data)
323
315
  context.logger.info("Initializing server from spec")
316
+ spec = mlrun.utils.get_serving_spec()
324
317
  server = GraphServer.from_dict(spec)
325
318
  if config.log_level.lower() == "debug":
326
319
  server.verbose = True
@@ -334,11 +327,18 @@ def v2_serving_init(context, namespace=None):
334
327
  context.logger.info_with(
335
328
  "Initializing states", namespace=namespace or get_caller_globals()
336
329
  )
337
- server.init_states(context, namespace or get_caller_globals())
330
+ kwargs = {}
331
+ if hasattr(context, "is_mock"):
332
+ kwargs["is_mock"] = context.is_mock
333
+ server.init_states(
334
+ context,
335
+ namespace or get_caller_globals(),
336
+ **kwargs,
337
+ )
338
338
  context.logger.info("Initializing graph steps")
339
- serving_handler = server.init_object(namespace or get_caller_globals())
339
+ server.init_object(namespace or get_caller_globals())
340
340
  # set the handler hook to point to our handler
341
- setattr(context, "mlrun_handler", serving_handler)
341
+ setattr(context, "mlrun_handler", v2_serving_handler)
342
342
  setattr(context, "_server", server)
343
343
  context.logger.info_with("Serving was initialized", verbose=server.verbose)
344
344
  if server.verbose:
@@ -351,7 +351,7 @@ def v2_serving_init(context, namespace=None):
351
351
  "Setting termination callback to terminate graph on worker shutdown"
352
352
  )
353
353
 
354
- def termination_callback():
354
+ async def termination_callback():
355
355
  context.logger.info("Termination callback called")
356
356
  server.wait_for_completion()
357
357
  context.logger.info("Termination of async flow is completed")
@@ -363,7 +363,7 @@ def v2_serving_init(context, namespace=None):
363
363
  "Setting drain callback to terminate and restart the graph on a drain event (such as rebalancing)"
364
364
  )
365
365
 
366
- def drain_callback():
366
+ async def drain_callback():
367
367
  context.logger.info("Drain callback called")
368
368
  server.wait_for_completion()
369
369
  context.logger.info(
@@ -386,13 +386,8 @@ def v2_serving_handler(context, event, get_body=False):
386
386
  return context._server.run(event, context, get_body)
387
387
 
388
388
 
389
- async def v2_serving_async_handler(context, event, get_body=False):
390
- """hook for nuclio handler()"""
391
- return await context._server.run(event, context, get_body)
392
-
393
-
394
389
  def create_graph_server(
395
- parameters={},
390
+ parameters=None,
396
391
  load_mode=None,
397
392
  graph=None,
398
393
  verbose=False,
@@ -408,6 +403,7 @@ def create_graph_server(
408
403
  server.graph.add_route("my", class_name=MyModelClass, model_path="{path}", z=100)
409
404
  print(server.test("/v2/models/my/infer", testdata))
410
405
  """
406
+ parameters = parameters or {}
411
407
  server = GraphServer(graph, parameters, load_mode, verbose=verbose, **kwargs)
412
408
  server.set_current_function(
413
409
  current_function or os.environ.get("SERVING_CURRENT_FUNCTION", "")
@@ -415,7 +411,7 @@ def create_graph_server(
415
411
  return server
416
412
 
417
413
 
418
- class MockTrigger(object):
414
+ class MockTrigger:
419
415
  """mock nuclio event trigger"""
420
416
 
421
417
  def __init__(self, kind="", name=""):
@@ -423,7 +419,7 @@ class MockTrigger(object):
423
419
  self.name = name
424
420
 
425
421
 
426
- class MockEvent(object):
422
+ class MockEvent:
427
423
  """mock basic nuclio event object"""
428
424
 
429
425
  def __init__(
@@ -456,7 +452,7 @@ class MockEvent(object):
456
452
  return f"Event(id={self.id}, body={self.body}, method={self.method}, path={self.path}{error})"
457
453
 
458
454
 
459
- class Response(object):
455
+ class Response:
460
456
  def __init__(self, headers=None, body=None, content_type=None, status_code=200):
461
457
  self.headers = headers or {}
462
458
  self.body = body
@@ -563,7 +559,7 @@ class GraphContext:
563
559
  _,
564
560
  _,
565
561
  function_status,
566
- ) = mlrun.runtimes.function.get_nuclio_deploy_status(name, project, tag)
562
+ ) = mlrun.runtimes.nuclio.function.get_nuclio_deploy_status(name, project, tag)
567
563
 
568
564
  if state in ["error", "unhealthy"]:
569
565
  raise ValueError(