mlrun 1.7.1rc4__py3-none-any.whl → 1.8.0rc8__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 (257) hide show
  1. mlrun/__init__.py +23 -21
  2. mlrun/__main__.py +3 -3
  3. mlrun/alerts/alert.py +148 -14
  4. mlrun/artifacts/__init__.py +1 -2
  5. mlrun/artifacts/base.py +46 -12
  6. mlrun/artifacts/dataset.py +16 -16
  7. mlrun/artifacts/document.py +334 -0
  8. mlrun/artifacts/manager.py +15 -13
  9. mlrun/artifacts/model.py +66 -53
  10. mlrun/common/constants.py +7 -0
  11. mlrun/common/formatters/__init__.py +1 -0
  12. mlrun/common/formatters/feature_set.py +1 -0
  13. mlrun/common/formatters/function.py +1 -0
  14. mlrun/{model_monitoring/db/stores/base/__init__.py → common/formatters/model_endpoint.py} +16 -1
  15. mlrun/common/formatters/pipeline.py +1 -2
  16. mlrun/common/formatters/project.py +9 -0
  17. mlrun/common/model_monitoring/__init__.py +0 -5
  18. mlrun/common/model_monitoring/helpers.py +1 -29
  19. mlrun/common/runtimes/constants.py +1 -2
  20. mlrun/common/schemas/__init__.py +6 -2
  21. mlrun/common/schemas/alert.py +111 -19
  22. mlrun/common/schemas/api_gateway.py +3 -3
  23. mlrun/common/schemas/artifact.py +11 -7
  24. mlrun/common/schemas/auth.py +6 -4
  25. mlrun/common/schemas/background_task.py +7 -7
  26. mlrun/common/schemas/client_spec.py +2 -3
  27. mlrun/common/schemas/clusterization_spec.py +2 -2
  28. mlrun/common/schemas/common.py +53 -3
  29. mlrun/common/schemas/constants.py +15 -0
  30. mlrun/common/schemas/datastore_profile.py +1 -1
  31. mlrun/common/schemas/feature_store.py +9 -9
  32. mlrun/common/schemas/frontend_spec.py +4 -4
  33. mlrun/common/schemas/function.py +10 -10
  34. mlrun/common/schemas/hub.py +1 -1
  35. mlrun/common/schemas/k8s.py +3 -3
  36. mlrun/common/schemas/memory_reports.py +3 -3
  37. mlrun/common/schemas/model_monitoring/__init__.py +2 -1
  38. mlrun/common/schemas/model_monitoring/constants.py +66 -14
  39. mlrun/common/schemas/model_monitoring/grafana.py +1 -1
  40. mlrun/common/schemas/model_monitoring/model_endpoints.py +91 -147
  41. mlrun/common/schemas/notification.py +24 -3
  42. mlrun/common/schemas/object.py +1 -1
  43. mlrun/common/schemas/pagination.py +4 -4
  44. mlrun/common/schemas/partition.py +137 -0
  45. mlrun/common/schemas/pipeline.py +2 -2
  46. mlrun/common/schemas/project.py +25 -17
  47. mlrun/common/schemas/runs.py +2 -2
  48. mlrun/common/schemas/runtime_resource.py +5 -5
  49. mlrun/common/schemas/schedule.py +1 -1
  50. mlrun/common/schemas/secret.py +1 -1
  51. mlrun/common/schemas/tag.py +3 -3
  52. mlrun/common/schemas/workflow.py +5 -5
  53. mlrun/config.py +67 -10
  54. mlrun/data_types/__init__.py +0 -2
  55. mlrun/data_types/infer.py +3 -1
  56. mlrun/data_types/spark.py +2 -1
  57. mlrun/datastore/__init__.py +0 -2
  58. mlrun/datastore/alibaba_oss.py +4 -1
  59. mlrun/datastore/azure_blob.py +4 -1
  60. mlrun/datastore/base.py +12 -4
  61. mlrun/datastore/datastore.py +9 -3
  62. mlrun/datastore/datastore_profile.py +79 -20
  63. mlrun/datastore/dbfs_store.py +4 -1
  64. mlrun/datastore/filestore.py +4 -1
  65. mlrun/datastore/google_cloud_storage.py +4 -1
  66. mlrun/datastore/hdfs.py +4 -1
  67. mlrun/datastore/inmem.py +4 -1
  68. mlrun/datastore/redis.py +4 -1
  69. mlrun/datastore/s3.py +4 -1
  70. mlrun/datastore/sources.py +52 -51
  71. mlrun/datastore/store_resources.py +0 -2
  72. mlrun/datastore/targets.py +21 -21
  73. mlrun/datastore/utils.py +2 -2
  74. mlrun/datastore/v3io.py +4 -1
  75. mlrun/datastore/vectorstore.py +194 -0
  76. mlrun/datastore/wasbfs/fs.py +13 -12
  77. mlrun/db/base.py +208 -82
  78. mlrun/db/factory.py +0 -3
  79. mlrun/db/httpdb.py +1237 -386
  80. mlrun/db/nopdb.py +201 -74
  81. mlrun/errors.py +2 -2
  82. mlrun/execution.py +136 -50
  83. mlrun/feature_store/__init__.py +0 -2
  84. mlrun/feature_store/api.py +41 -40
  85. mlrun/feature_store/common.py +9 -9
  86. mlrun/feature_store/feature_set.py +20 -18
  87. mlrun/feature_store/feature_vector.py +27 -24
  88. mlrun/feature_store/retrieval/base.py +14 -9
  89. mlrun/feature_store/retrieval/job.py +2 -1
  90. mlrun/feature_store/steps.py +2 -2
  91. mlrun/features.py +30 -13
  92. mlrun/frameworks/__init__.py +1 -2
  93. mlrun/frameworks/_common/__init__.py +1 -2
  94. mlrun/frameworks/_common/artifacts_library.py +2 -2
  95. mlrun/frameworks/_common/mlrun_interface.py +10 -6
  96. mlrun/frameworks/_common/model_handler.py +29 -27
  97. mlrun/frameworks/_common/producer.py +3 -1
  98. mlrun/frameworks/_dl_common/__init__.py +1 -2
  99. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
  100. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
  101. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
  102. mlrun/frameworks/_ml_common/__init__.py +1 -2
  103. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
  104. mlrun/frameworks/_ml_common/model_handler.py +21 -21
  105. mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
  106. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
  107. mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
  108. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
  109. mlrun/frameworks/auto_mlrun/__init__.py +1 -2
  110. mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
  111. mlrun/frameworks/huggingface/__init__.py +1 -2
  112. mlrun/frameworks/huggingface/model_server.py +9 -9
  113. mlrun/frameworks/lgbm/__init__.py +47 -44
  114. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
  115. mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
  116. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
  117. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
  118. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
  119. mlrun/frameworks/lgbm/model_handler.py +15 -11
  120. mlrun/frameworks/lgbm/model_server.py +11 -7
  121. mlrun/frameworks/lgbm/utils.py +2 -2
  122. mlrun/frameworks/onnx/__init__.py +1 -2
  123. mlrun/frameworks/onnx/dataset.py +3 -3
  124. mlrun/frameworks/onnx/mlrun_interface.py +2 -2
  125. mlrun/frameworks/onnx/model_handler.py +7 -5
  126. mlrun/frameworks/onnx/model_server.py +8 -6
  127. mlrun/frameworks/parallel_coordinates.py +11 -11
  128. mlrun/frameworks/pytorch/__init__.py +22 -23
  129. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
  130. mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
  131. mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
  132. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
  133. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
  134. mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
  135. mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
  136. mlrun/frameworks/pytorch/model_handler.py +21 -17
  137. mlrun/frameworks/pytorch/model_server.py +13 -9
  138. mlrun/frameworks/sklearn/__init__.py +19 -18
  139. mlrun/frameworks/sklearn/estimator.py +2 -2
  140. mlrun/frameworks/sklearn/metric.py +3 -3
  141. mlrun/frameworks/sklearn/metrics_library.py +8 -6
  142. mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
  143. mlrun/frameworks/sklearn/model_handler.py +4 -3
  144. mlrun/frameworks/tf_keras/__init__.py +11 -12
  145. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
  146. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
  147. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
  148. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
  149. mlrun/frameworks/tf_keras/model_handler.py +17 -13
  150. mlrun/frameworks/tf_keras/model_server.py +12 -8
  151. mlrun/frameworks/xgboost/__init__.py +19 -18
  152. mlrun/frameworks/xgboost/model_handler.py +13 -9
  153. mlrun/launcher/base.py +3 -4
  154. mlrun/launcher/local.py +1 -1
  155. mlrun/launcher/remote.py +1 -1
  156. mlrun/lists.py +4 -3
  157. mlrun/model.py +117 -46
  158. mlrun/model_monitoring/__init__.py +4 -4
  159. mlrun/model_monitoring/api.py +61 -59
  160. mlrun/model_monitoring/applications/_application_steps.py +17 -17
  161. mlrun/model_monitoring/applications/base.py +165 -6
  162. mlrun/model_monitoring/applications/context.py +88 -37
  163. mlrun/model_monitoring/applications/evidently_base.py +1 -2
  164. mlrun/model_monitoring/applications/histogram_data_drift.py +43 -21
  165. mlrun/model_monitoring/applications/results.py +55 -3
  166. mlrun/model_monitoring/controller.py +207 -239
  167. mlrun/model_monitoring/db/__init__.py +0 -2
  168. mlrun/model_monitoring/db/_schedules.py +156 -0
  169. mlrun/model_monitoring/db/_stats.py +189 -0
  170. mlrun/model_monitoring/db/tsdb/base.py +78 -25
  171. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +90 -16
  172. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
  173. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +279 -59
  174. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
  175. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +78 -17
  176. mlrun/model_monitoring/helpers.py +152 -49
  177. mlrun/model_monitoring/stream_processing.py +99 -283
  178. mlrun/model_monitoring/tracking_policy.py +10 -3
  179. mlrun/model_monitoring/writer.py +48 -36
  180. mlrun/package/__init__.py +3 -6
  181. mlrun/package/context_handler.py +1 -1
  182. mlrun/package/packager.py +12 -9
  183. mlrun/package/packagers/__init__.py +0 -2
  184. mlrun/package/packagers/default_packager.py +14 -11
  185. mlrun/package/packagers/numpy_packagers.py +16 -7
  186. mlrun/package/packagers/pandas_packagers.py +18 -18
  187. mlrun/package/packagers/python_standard_library_packagers.py +25 -11
  188. mlrun/package/packagers_manager.py +31 -14
  189. mlrun/package/utils/__init__.py +0 -3
  190. mlrun/package/utils/_pickler.py +6 -6
  191. mlrun/platforms/__init__.py +47 -16
  192. mlrun/platforms/iguazio.py +4 -1
  193. mlrun/projects/operations.py +27 -27
  194. mlrun/projects/pipelines.py +75 -38
  195. mlrun/projects/project.py +865 -206
  196. mlrun/run.py +53 -10
  197. mlrun/runtimes/__init__.py +1 -3
  198. mlrun/runtimes/base.py +15 -11
  199. mlrun/runtimes/daskjob.py +9 -9
  200. mlrun/runtimes/generators.py +2 -1
  201. mlrun/runtimes/kubejob.py +4 -5
  202. mlrun/runtimes/mounts.py +572 -0
  203. mlrun/runtimes/mpijob/__init__.py +0 -2
  204. mlrun/runtimes/mpijob/abstract.py +7 -6
  205. mlrun/runtimes/nuclio/api_gateway.py +7 -7
  206. mlrun/runtimes/nuclio/application/application.py +11 -11
  207. mlrun/runtimes/nuclio/function.py +19 -17
  208. mlrun/runtimes/nuclio/serving.py +18 -11
  209. mlrun/runtimes/pod.py +154 -45
  210. mlrun/runtimes/remotesparkjob.py +3 -2
  211. mlrun/runtimes/sparkjob/__init__.py +0 -2
  212. mlrun/runtimes/sparkjob/spark3job.py +21 -11
  213. mlrun/runtimes/utils.py +6 -5
  214. mlrun/serving/merger.py +6 -4
  215. mlrun/serving/remote.py +18 -17
  216. mlrun/serving/routers.py +185 -172
  217. mlrun/serving/server.py +7 -1
  218. mlrun/serving/states.py +97 -78
  219. mlrun/serving/utils.py +13 -2
  220. mlrun/serving/v1_serving.py +3 -2
  221. mlrun/serving/v2_serving.py +74 -65
  222. mlrun/track/__init__.py +1 -1
  223. mlrun/track/tracker.py +2 -2
  224. mlrun/track/trackers/mlflow_tracker.py +6 -5
  225. mlrun/utils/async_http.py +1 -1
  226. mlrun/utils/clones.py +1 -1
  227. mlrun/utils/helpers.py +66 -18
  228. mlrun/utils/logger.py +106 -4
  229. mlrun/utils/notifications/notification/__init__.py +22 -19
  230. mlrun/utils/notifications/notification/base.py +33 -14
  231. mlrun/utils/notifications/notification/console.py +6 -6
  232. mlrun/utils/notifications/notification/git.py +11 -11
  233. mlrun/utils/notifications/notification/ipython.py +10 -9
  234. mlrun/utils/notifications/notification/mail.py +176 -0
  235. mlrun/utils/notifications/notification/slack.py +6 -6
  236. mlrun/utils/notifications/notification/webhook.py +6 -6
  237. mlrun/utils/notifications/notification_pusher.py +86 -44
  238. mlrun/utils/regex.py +3 -1
  239. mlrun/utils/version/version.json +2 -2
  240. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/METADATA +191 -186
  241. mlrun-1.8.0rc8.dist-info/RECORD +347 -0
  242. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/WHEEL +1 -1
  243. mlrun/model_monitoring/db/stores/__init__.py +0 -136
  244. mlrun/model_monitoring/db/stores/base/store.py +0 -213
  245. mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
  246. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -71
  247. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -190
  248. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -103
  249. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -40
  250. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -659
  251. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
  252. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
  253. mlrun/model_monitoring/model_endpoint.py +0 -118
  254. mlrun-1.7.1rc4.dist-info/RECORD +0 -351
  255. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/LICENSE +0 -0
  256. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/entry_points.txt +0 -0
  257. {mlrun-1.7.1rc4.dist-info → mlrun-1.8.0rc8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,572 @@
1
+ # Copyright 2023 Iguazio
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import os
16
+ import typing
17
+ from collections import namedtuple
18
+
19
+ from mlrun.config import config
20
+ from mlrun.config import config as mlconf
21
+ from mlrun.errors import MLRunInvalidArgumentError
22
+ from mlrun.platforms.iguazio import v3io_to_vol
23
+ from mlrun.utils import logger
24
+
25
+ if typing.TYPE_CHECKING:
26
+ from mlrun.runtimes import KubeResource
27
+
28
+
29
+ VolumeMount = namedtuple("Mount", ["path", "sub_path"])
30
+
31
+
32
+ def v3io_cred(
33
+ api: str = "",
34
+ user: str = "",
35
+ access_key: str = "",
36
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
37
+ """
38
+ Modifier function to copy local v3io env vars to container
39
+
40
+ Usage::
41
+
42
+ train = train_op(...)
43
+ train.apply(use_v3io_cred())
44
+ """
45
+
46
+ def _use_v3io_cred(runtime: "KubeResource"):
47
+ web_api = api or os.environ.get("V3IO_API") or mlconf.v3io_api
48
+ _user = user or os.environ.get("V3IO_USERNAME")
49
+ _access_key = access_key or os.environ.get("V3IO_ACCESS_KEY")
50
+ v3io_framesd = mlconf.v3io_framesd or os.environ.get("V3IO_FRAMESD")
51
+
52
+ runtime.set_envs(
53
+ {
54
+ "V3IO_API": web_api,
55
+ "V3IO_USERNAME": _user,
56
+ "V3IO_ACCESS_KEY": _access_key,
57
+ "V3IO_FRAMESD": v3io_framesd,
58
+ },
59
+ )
60
+
61
+ return runtime
62
+
63
+ return _use_v3io_cred
64
+
65
+
66
+ def mount_v3io(
67
+ name: str = "v3io",
68
+ remote: str = "",
69
+ access_key: str = "",
70
+ user: str = "",
71
+ secret: typing.Optional[str] = None,
72
+ volume_mounts: typing.Optional[list[VolumeMount]] = None,
73
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
74
+ """Modifier function to apply to a Container Op to volume mount a v3io path
75
+
76
+ :param name: the volume name
77
+ :param remote: the v3io path to use for the volume (~/ prefix will be replaced with /users/<username>/)
78
+ :param access_key: the access key used to auth against v3io (default: V3IO_ACCESS_KEY env var)
79
+ :param user: the username used to auth against v3io (default: V3IO_USERNAME env var)
80
+ :param secret: k8s secret name for the username and access key
81
+ :param volume_mounts: list of VolumeMount; if empty, defaults to mounting /v3io and /User
82
+ """
83
+ volume_mounts, user = _enrich_and_validate_v3io_mounts(
84
+ remote=remote,
85
+ volume_mounts=volume_mounts,
86
+ user=user,
87
+ )
88
+
89
+ def _attach_volume_mounts_and_creds(runtime: "KubeResource"):
90
+ vol = v3io_to_vol(name, remote, access_key, user, secret=secret)
91
+ runtime.spec.with_volumes(vol)
92
+
93
+ for volume_mount in volume_mounts:
94
+ runtime.spec.with_volume_mounts(
95
+ {
96
+ "mountPath": volume_mount.path,
97
+ "name": name,
98
+ "subPath": volume_mount.sub_path,
99
+ }
100
+ )
101
+
102
+ if not secret:
103
+ runtime = v3io_cred(access_key=access_key, user=user)(runtime)
104
+ return runtime
105
+
106
+ return _attach_volume_mounts_and_creds
107
+
108
+
109
+ def mount_spark_conf() -> typing.Callable[["KubeResource"], "KubeResource"]:
110
+ """Modifier function to mount Spark configuration."""
111
+
112
+ def _mount_spark(runtime: "KubeResource"):
113
+ runtime.spec.with_volume_mounts(
114
+ {
115
+ "mountPath": "/etc/config/spark",
116
+ "name": "spark-master-config",
117
+ }
118
+ )
119
+ return runtime
120
+
121
+ return _mount_spark
122
+
123
+
124
+ def mount_v3iod(
125
+ namespace: str, v3io_config_configmap: str
126
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
127
+ """Modifier function to mount v3iod configuration."""
128
+
129
+ def _mount_v3iod(runtime: "KubeResource"):
130
+ def add_vol(name, mount_path, host_path):
131
+ runtime.spec.with_volumes(
132
+ {
133
+ "name": name,
134
+ "hostPath": {
135
+ "path": host_path,
136
+ "type": "",
137
+ },
138
+ }
139
+ )
140
+ runtime.spec.with_volume_mounts(
141
+ {
142
+ "mountPath": mount_path,
143
+ "name": name,
144
+ }
145
+ )
146
+
147
+ add_vol(
148
+ name="shm",
149
+ mount_path="/dev/shm",
150
+ host_path=f"/var/run/iguazio/dayman-shm/{namespace}",
151
+ )
152
+ add_vol(
153
+ name="v3iod-comm",
154
+ mount_path="/var/run/iguazio/dayman",
155
+ host_path="/var/run/iguazio/dayman/" + namespace,
156
+ )
157
+
158
+ # Add daemon-health and v3io-config volumes
159
+ runtime.spec.with_volumes(
160
+ [
161
+ {
162
+ "name": "daemon-health",
163
+ "emptyDir": {},
164
+ },
165
+ {
166
+ "name": "v3io-config",
167
+ "configMap": {
168
+ "name": v3io_config_configmap,
169
+ "defaultMode": 420,
170
+ },
171
+ },
172
+ ]
173
+ )
174
+
175
+ # Add volume mounts
176
+ runtime.spec.with_volume_mounts(
177
+ [
178
+ {
179
+ "mountPath": "/var/run/iguazio/daemon_health",
180
+ "name": "daemon-health",
181
+ },
182
+ {
183
+ "mountPath": "/etc/config/v3io",
184
+ "name": "v3io-config",
185
+ },
186
+ ]
187
+ )
188
+
189
+ # Add environment variables
190
+ runtime.set_envs(
191
+ {
192
+ "CURRENT_NODE_IP": {
193
+ "valueFrom": {
194
+ "fieldRef": {
195
+ "apiVersion": "v1",
196
+ "fieldPath": "status.hostIP",
197
+ }
198
+ },
199
+ },
200
+ "IGZ_DATA_CONFIG_FILE": "/igz/java/conf/v3io.conf",
201
+ }
202
+ )
203
+
204
+ return runtime
205
+
206
+ return _mount_v3iod
207
+
208
+
209
+ def mount_s3(
210
+ secret_name: typing.Optional[str] = None,
211
+ aws_access_key: str = "",
212
+ aws_secret_key: str = "",
213
+ endpoint_url: typing.Optional[str] = None,
214
+ prefix: str = "",
215
+ aws_region: typing.Optional[str] = None,
216
+ non_anonymous: bool = False,
217
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
218
+ """Modifier function to add s3 env vars or secrets to container
219
+
220
+ :param secret_name: Kubernetes secret name for credentials
221
+ :param aws_access_key: AWS_ACCESS_KEY_ID value (default: env variable)
222
+ :param aws_secret_key: AWS_SECRET_ACCESS_KEY value (default: env variable)
223
+ :param endpoint_url: s3 endpoint address (for non-AWS s3)
224
+ :param prefix: prefix to add before the env var name (for multiple s3 data stores)
225
+ :param aws_region: Amazon region
226
+ :param non_anonymous: use non-anonymous connection even if no credentials are provided
227
+ (for authenticating externally, such as through IAM instance-roles)
228
+
229
+ """
230
+
231
+ if secret_name and (aws_access_key or aws_secret_key):
232
+ raise MLRunInvalidArgumentError(
233
+ "Can use k8s_secret for credentials or specify them (aws_access_key, aws_secret_key) not both."
234
+ )
235
+
236
+ if not secret_name and (
237
+ aws_access_key
238
+ or os.environ.get(prefix + "AWS_ACCESS_KEY_ID")
239
+ or aws_secret_key
240
+ or os.environ.get(prefix + "AWS_SECRET_ACCESS_KEY")
241
+ ):
242
+ logger.warning(
243
+ "It is recommended to use k8s secret (specify secret_name), "
244
+ "specifying aws_access_key/aws_secret_key directly is unsafe."
245
+ )
246
+
247
+ def _use_s3_cred(runtime: "KubeResource"):
248
+ _access_key = aws_access_key or os.environ.get(prefix + "AWS_ACCESS_KEY_ID")
249
+ _secret_key = aws_secret_key or os.environ.get(prefix + "AWS_SECRET_ACCESS_KEY")
250
+ _endpoint_url = endpoint_url or os.environ.get(prefix + "S3_ENDPOINT_URL")
251
+
252
+ if _endpoint_url:
253
+ runtime.set_env(prefix + "S3_ENDPOINT_URL", _endpoint_url)
254
+ if aws_region:
255
+ runtime.set_env(prefix + "AWS_REGION", aws_region)
256
+ if non_anonymous:
257
+ runtime.set_env(prefix + "S3_NON_ANONYMOUS", "true")
258
+
259
+ if secret_name:
260
+ runtime.set_envs(
261
+ {
262
+ f"{prefix}AWS_ACCESS_KEY_ID": {
263
+ "valueFrom": {
264
+ "secretKeyRef": {
265
+ "name": secret_name,
266
+ "key": "AWS_ACCESS_KEY_ID",
267
+ }
268
+ }
269
+ },
270
+ f"{prefix}AWS_SECRET_ACCESS_KEY": {
271
+ "valueFrom": {
272
+ "secretKeyRef": {
273
+ "name": secret_name,
274
+ "key": "AWS_SECRET_ACCESS_KEY",
275
+ }
276
+ },
277
+ },
278
+ }
279
+ )
280
+ else:
281
+ runtime.set_envs(
282
+ {
283
+ f"{prefix}AWS_ACCESS_KEY_ID": _access_key,
284
+ f"{prefix}AWS_SECRET_ACCESS_KEY": _secret_key,
285
+ },
286
+ )
287
+
288
+ return runtime
289
+
290
+ return _use_s3_cred
291
+
292
+
293
+ def mount_pvc(
294
+ pvc_name: typing.Optional[str] = None,
295
+ volume_name: str = "pipeline",
296
+ volume_mount_path: str = "/mnt/pipeline",
297
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
298
+ """
299
+ Modifier function to mount a PVC volume in the container, simplifying volume and volume mount addition.
300
+
301
+ Usage::
302
+
303
+ train = train_op(...)
304
+ train.apply(mount_pvc("claim-name", "pipeline", "/mnt/pipeline"))
305
+ """
306
+ if not pvc_name:
307
+ # Try to get the PVC mount configuration from the environment variable
308
+ if "MLRUN_PVC_MOUNT" in os.environ:
309
+ mount = os.environ.get("MLRUN_PVC_MOUNT")
310
+ items = mount.split(":")
311
+ if len(items) != 2:
312
+ raise MLRunInvalidArgumentError(
313
+ "MLRUN_PVC_MOUNT should include <pvc-name>:<mount-path>"
314
+ )
315
+ pvc_name = items[0]
316
+ volume_mount_path = items[1]
317
+
318
+ if not pvc_name:
319
+ # The PVC name is still not set, raise an error
320
+ raise MLRunInvalidArgumentError(
321
+ "No PVC name: use the pvc_name parameter or configure the MLRUN_PVC_MOUNT environment variable"
322
+ )
323
+
324
+ def _mount_pvc(runtime: "KubeResource"):
325
+ local_pvc = {"claimName": pvc_name}
326
+
327
+ runtime.spec.with_volumes(
328
+ [
329
+ {
330
+ "name": volume_name,
331
+ "persistentVolumeClaim": local_pvc,
332
+ }
333
+ ]
334
+ )
335
+ runtime.spec.with_volume_mounts(
336
+ {
337
+ "mountPath": volume_mount_path,
338
+ "name": volume_name,
339
+ }
340
+ )
341
+
342
+ return runtime
343
+
344
+ return _mount_pvc
345
+
346
+
347
+ def auto_mount(
348
+ pvc_name: str = "",
349
+ volume_mount_path: str = "",
350
+ volume_name: typing.Optional[str] = None,
351
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
352
+ """Choose the mount based on env variables and params
353
+
354
+ Volume will be selected by the following order:
355
+ - k8s PVC volume when both pvc_name and volume_mount_path are set
356
+ - k8s PVC volume when env var is set: MLRUN_PVC_MOUNT=<pvc-name>:<mount-path>
357
+ - k8s PVC volume if it's configured as the auto mount type
358
+ - iguazio v3io volume when V3IO_ACCESS_KEY and V3IO_USERNAME env vars are set
359
+ """
360
+ if pvc_name and volume_mount_path:
361
+ return mount_pvc(
362
+ pvc_name=pvc_name,
363
+ volume_mount_path=volume_mount_path,
364
+ volume_name=volume_name or "shared-persistency",
365
+ )
366
+ if "MLRUN_PVC_MOUNT" in os.environ:
367
+ return mount_pvc(
368
+ volume_name=volume_name or "shared-persistency",
369
+ )
370
+ # In the case of CE when working remotely, no env variables will be defined but auto-mount
371
+ # parameters may still be declared - use them in that case.
372
+ if config.storage.auto_mount_type == "pvc":
373
+ return mount_pvc(**config.get_storage_auto_mount_params())
374
+ if "V3IO_ACCESS_KEY" in os.environ:
375
+ return mount_v3io(name=volume_name or "v3io")
376
+
377
+ raise ValueError("Failed to auto mount, need to set env vars")
378
+
379
+
380
+ def mount_secret(
381
+ secret_name: str,
382
+ mount_path: str,
383
+ volume_name: str = "secret",
384
+ items: typing.Optional[list[dict]] = None,
385
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
386
+ """
387
+ Modifier function to mount a Kubernetes secret as file(s).
388
+
389
+ :param secret_name: Kubernetes secret name
390
+ :param mount_path: Path inside the container to mount
391
+ :param volume_name: Unique volume name
392
+ :param items: If unspecified, each key-value pair in the Data field
393
+ of the referenced Secret will be projected into the
394
+ volume as a file whose name is the key and content is
395
+ the value.
396
+ If specified, the listed keys will be projected into
397
+ the specified paths, and unlisted keys will not be
398
+ present."""
399
+
400
+ def _mount_secret(runtime: "KubeResource"):
401
+ # Define the secret volume source
402
+ secret_volume_source = {
403
+ "secretName": secret_name,
404
+ "items": items,
405
+ }
406
+
407
+ # Add the secret volume
408
+ runtime.spec.with_volumes(
409
+ {
410
+ "name": volume_name,
411
+ "secret": secret_volume_source,
412
+ }
413
+ )
414
+
415
+ # Add the volume mount
416
+ runtime.spec.with_volume_mounts(
417
+ {
418
+ "mountPath": mount_path,
419
+ "name": volume_name,
420
+ }
421
+ )
422
+
423
+ return runtime
424
+
425
+ return _mount_secret
426
+
427
+
428
+ def mount_configmap(
429
+ configmap_name: str,
430
+ mount_path: str,
431
+ volume_name: str = "configmap",
432
+ items: typing.Optional[list[dict]] = None,
433
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
434
+ """
435
+ Modifier function to mount a Kubernetes ConfigMap as file(s).
436
+
437
+ :param configmap_name: Kubernetes ConfigMap name
438
+ :param mount_path: Path inside the container to mount
439
+ :param volume_name: Unique volume name
440
+ :param items: If unspecified, each key-value pair in the Data field
441
+ of the referenced Configmap will be projected into the
442
+ volume as a file whose name is the key and content is
443
+ the value.
444
+ If specified, the listed keys will be projected into
445
+ the specified paths, and unlisted keys will not be
446
+ present."""
447
+
448
+ def _mount_configmap(runtime: "KubeResource"):
449
+ # Construct the configMap dictionary
450
+ config_map_dict = {
451
+ "name": configmap_name,
452
+ }
453
+ if items is not None:
454
+ config_map_dict["items"] = items
455
+
456
+ vol = {
457
+ "name": volume_name,
458
+ "configMap": config_map_dict,
459
+ }
460
+
461
+ runtime.spec.with_volumes(vol)
462
+ runtime.spec.with_volume_mounts(
463
+ {
464
+ "mountPath": mount_path,
465
+ "name": volume_name,
466
+ }
467
+ )
468
+
469
+ return runtime
470
+
471
+ return _mount_configmap
472
+
473
+
474
+ def mount_hostpath(
475
+ host_path: str,
476
+ mount_path: str,
477
+ volume_name: str = "hostpath",
478
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
479
+ """
480
+ Modifier function to mount a host path inside a Kubernetes container.
481
+
482
+ :param host_path: Host path on the node to be mounted.
483
+ :param mount_path: Path inside the container where the volume will be mounted.
484
+ :param volume_name: Unique name for the volume.
485
+ """
486
+
487
+ def _mount_hostpath(runtime: "KubeResource") -> "KubeResource":
488
+ runtime.spec.with_volumes(
489
+ {
490
+ "name": volume_name,
491
+ "hostPath": {
492
+ "path": host_path,
493
+ "type": "",
494
+ },
495
+ }
496
+ )
497
+ runtime.spec.with_volume_mounts(
498
+ {
499
+ "mountPath": mount_path,
500
+ "name": volume_name,
501
+ }
502
+ )
503
+
504
+ return runtime
505
+
506
+ return _mount_hostpath
507
+
508
+
509
+ def set_env_variables(
510
+ env_vars_dict: typing.Optional[dict[str, str]] = None, **kwargs
511
+ ) -> typing.Callable[["KubeResource"], "KubeResource"]:
512
+ """
513
+ Modifier function to apply a set of environment variables to a runtime. Variables may be passed
514
+ as either a dictionary of name-value pairs, or as arguments to the function.
515
+ See `KubeResource.apply` for more information on modifiers.
516
+
517
+ Usage::
518
+
519
+ function.apply(set_env_variables({"ENV1": "value1", "ENV2": "value2"}))
520
+ or
521
+ function.apply(set_env_variables(ENV1=value1, ENV2=value2))
522
+
523
+ :param env_vars_dict: dictionary of environment variables
524
+ :param kwargs: environment variables passed as arguments
525
+ """
526
+
527
+ env_data = env_vars_dict.copy() if env_vars_dict else {}
528
+ for key, value in kwargs.items():
529
+ env_data[key] = value
530
+
531
+ def _set_env_variables(runtime: "KubeResource"):
532
+ runtime.set_envs(env_data)
533
+
534
+ return runtime
535
+
536
+ return _set_env_variables
537
+
538
+
539
+ def _enrich_and_validate_v3io_mounts(
540
+ remote: str = "",
541
+ volume_mounts: typing.Optional[list[VolumeMount]] = None,
542
+ user: str = "",
543
+ ) -> tuple[list[VolumeMount], str]:
544
+ if volume_mounts is None:
545
+ volume_mounts = []
546
+ if remote and not volume_mounts:
547
+ raise MLRunInvalidArgumentError(
548
+ "volume_mounts must be specified when remote is given"
549
+ )
550
+
551
+ # Empty remote & volume_mounts defaults are volume mounts of /v3io and /User
552
+ if not remote and not volume_mounts:
553
+ user = _resolve_mount_user(user)
554
+ if not user:
555
+ raise MLRunInvalidArgumentError(
556
+ "user name/env must be specified when using empty remote and volume_mounts"
557
+ )
558
+ volume_mounts = [
559
+ VolumeMount(path="/v3io", sub_path=""),
560
+ VolumeMount(path="/User", sub_path="users/" + user),
561
+ ]
562
+
563
+ if not isinstance(volume_mounts, list) and any(
564
+ [not isinstance(x, VolumeMount) for x in volume_mounts]
565
+ ):
566
+ raise TypeError("mounts should be a list of Mount")
567
+
568
+ return volume_mounts, user
569
+
570
+
571
+ def _resolve_mount_user(user: typing.Optional[str] = None):
572
+ return user or os.environ.get("V3IO_USERNAME")
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
16
-
17
15
  from dependency_injector import containers, providers
18
16
 
19
17
  from mlrun.config import config
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
  import abc
15
15
  import os
16
+ from typing import Optional
16
17
 
17
18
  from mlrun.config import config
18
19
  from mlrun.runtimes.kubejob import KubejobRuntime
@@ -117,7 +118,7 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
117
118
  return {}
118
119
 
119
120
  def with_tracing(
120
- self, log_file_path: str = None, enable_cycle_markers: bool = False
121
+ self, log_file_path: Optional[str] = None, enable_cycle_markers: bool = False
121
122
  ):
122
123
  """Add Horovod Timeline activity tracking to the job to analyse
123
124
  its performance.
@@ -149,11 +150,11 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
149
150
 
150
151
  def with_autotune(
151
152
  self,
152
- log_file_path: str = None,
153
- warmup_samples: int = None,
154
- steps_per_sample: int = None,
155
- bayes_opt_max_samples: int = None,
156
- gaussian_process_noise: float = None,
153
+ log_file_path: Optional[str] = None,
154
+ warmup_samples: Optional[int] = None,
155
+ steps_per_sample: Optional[int] = None,
156
+ bayes_opt_max_samples: Optional[int] = None,
157
+ gaussian_process_noise: Optional[float] = None,
157
158
  ):
158
159
  """Adds an Autotuner to help optimize Horovod's Parameters for better performance.
159
160
 
@@ -118,10 +118,10 @@ class APIGatewayMetadata(ModelObj):
118
118
  def __init__(
119
119
  self,
120
120
  name: str,
121
- namespace: str = None,
122
- labels: dict = None,
123
- annotations: dict = None,
124
- creation_timestamp: str = None,
121
+ namespace: Optional[str] = None,
122
+ labels: Optional[dict] = None,
123
+ annotations: Optional[dict] = None,
124
+ creation_timestamp: Optional[str] = None,
125
125
  ):
126
126
  """
127
127
  :param name: The name of the API gateway
@@ -169,9 +169,9 @@ class APIGatewaySpec(ModelObj):
169
169
  "mlrun.runtimes.nuclio.serving.ServingRuntime",
170
170
  "mlrun.runtimes.nuclio.application.ApplicationRuntime",
171
171
  ],
172
- project: str = None,
172
+ project: Optional[str] = None,
173
173
  description: str = "",
174
- host: str = None,
174
+ host: Optional[str] = None,
175
175
  path: str = "/",
176
176
  authentication: Optional[APIGatewayAuthenticator] = NoneAuth(),
177
177
  canary: Optional[list[int]] = None,
@@ -389,7 +389,7 @@ class APIGateway(ModelObj):
389
389
  def invoke(
390
390
  self,
391
391
  method="POST",
392
- headers: dict = None,
392
+ headers: Optional[dict] = None,
393
393
  credentials: Optional[tuple[str, str]] = None,
394
394
  path: Optional[str] = None,
395
395
  body: Optional[Union[str, bytes, dict]] = None,