mlrun 1.7.2rc3__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.2rc3.dist-info → mlrun-1.8.0.dist-info}/METADATA +81 -54
  260. mlrun-1.8.0.dist-info/RECORD +351 -0
  261. {mlrun-1.7.2rc3.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.2rc3.dist-info/RECORD +0 -351
  273. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0.dist-info}/entry_points.txt +0 -0
  274. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0.dist-info/licenses}/LICENSE +0 -0
  275. {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0.dist-info}/top_level.txt +0 -0
@@ -275,7 +275,7 @@ class ApplicationRuntime(RemoteRuntime):
275
275
  tag="",
276
276
  verbose=False,
277
277
  auth_info: schemas.AuthInfo = None,
278
- builder_env: dict = None,
278
+ builder_env: typing.Optional[dict] = None,
279
279
  force_build: bool = False,
280
280
  with_mlrun=None,
281
281
  skip_deployed=False,
@@ -367,7 +367,7 @@ class ApplicationRuntime(RemoteRuntime):
367
367
  source,
368
368
  workdir=None,
369
369
  pull_at_runtime: bool = False,
370
- target_dir: str = None,
370
+ target_dir: typing.Optional[str] = None,
371
371
  ):
372
372
  """load the code from git/tar/zip archive at build
373
373
 
@@ -426,12 +426,12 @@ class ApplicationRuntime(RemoteRuntime):
426
426
 
427
427
  def create_api_gateway(
428
428
  self,
429
- name: str = None,
430
- path: str = None,
429
+ name: typing.Optional[str] = None,
430
+ path: typing.Optional[str] = None,
431
431
  direct_port_access: bool = False,
432
432
  authentication_mode: schemas.APIGatewayAuthenticationMode = None,
433
- authentication_creds: tuple[str, str] = None,
434
- ssl_redirect: bool = None,
433
+ authentication_creds: typing.Optional[tuple[str, str]] = None,
434
+ ssl_redirect: typing.Optional[bool] = None,
435
435
  set_as_default: bool = False,
436
436
  gateway_timeout: typing.Optional[int] = None,
437
437
  ):
@@ -540,13 +540,12 @@ class ApplicationRuntime(RemoteRuntime):
540
540
  self,
541
541
  path: str = "",
542
542
  body: typing.Optional[typing.Union[str, bytes, dict]] = None,
543
- method: str = None,
544
- headers: dict = None,
545
- dashboard: str = "",
543
+ method: typing.Optional[str] = None,
544
+ headers: typing.Optional[dict] = None,
546
545
  force_external_address: bool = False,
547
546
  auth_info: schemas.AuthInfo = None,
548
- mock: bool = None,
549
- credentials: tuple[str, str] = None,
547
+ mock: typing.Optional[bool] = None,
548
+ credentials: typing.Optional[tuple[str, str]] = None,
550
549
  **http_client_kwargs,
551
550
  ):
552
551
  self._sync_api_gateway()
@@ -569,7 +568,6 @@ class ApplicationRuntime(RemoteRuntime):
569
568
  body,
570
569
  method,
571
570
  headers,
572
- dashboard,
573
571
  force_external_address,
574
572
  auth_info,
575
573
  mock,
@@ -653,7 +651,7 @@ class ApplicationRuntime(RemoteRuntime):
653
651
 
654
652
  def _build_application_image(
655
653
  self,
656
- builder_env: dict = None,
654
+ builder_env: typing.Optional[dict] = None,
657
655
  force_build: bool = False,
658
656
  watch=True,
659
657
  with_mlrun=None,
@@ -4,7 +4,7 @@
4
4
  // you may not use this file except in compliance with the License.
5
5
  // You may obtain a copy of the License at
6
6
  //
7
- // http://www.apache.org/licenses/LICENSE-2.0
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
8
  //
9
9
  // Unless required by applicable law or agreed to in writing, software
10
10
  // distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,82 +14,84 @@
14
14
  package main
15
15
 
16
16
  import (
17
- "bytes"
18
- "fmt"
19
- "net/http"
20
- "net/http/httptest"
21
- "net/http/httputil"
22
- "net/url"
23
- "os"
24
- "strings"
17
+ "bytes"
18
+ "fmt"
19
+ "net/http"
20
+ "net/http/httptest"
21
+ "net/http/httputil"
22
+ "net/url"
23
+ "os"
24
+ "strings"
25
25
 
26
- nuclio "github.com/nuclio/nuclio-sdk-go"
26
+ nuclio "github.com/nuclio/nuclio-sdk-go"
27
27
  )
28
28
 
29
29
  func Handler(context *nuclio.Context, event nuclio.Event) (interface{}, error) {
30
- reverseProxy := context.UserData.(map[string]interface{})["reverseProxy"].(*httputil.ReverseProxy)
31
- sidecarUrl := context.UserData.(map[string]interface{})["server"].(string)
30
+ reverseProxy := context.UserData.(map[string]interface{})["reverseProxy"].(*httputil.ReverseProxy)
31
+ sidecarUrl := context.UserData.(map[string]interface{})["server"].(string)
32
32
 
33
- // populate reverse proxy http request
34
- httpRequest, err := http.NewRequest(event.GetMethod(), event.GetPath(), bytes.NewReader(event.GetBody()))
35
- if err != nil {
36
- context.Logger.ErrorWith("Failed to create a reverse proxy request")
37
- return nil, err
38
- }
39
- for k, v := range event.GetHeaders() {
40
- httpRequest.Header[k] = []string{v.(string)}
41
- }
33
+ // populate reverse proxy http request
34
+ httpRequest, err := http.NewRequest(event.GetMethod(), event.GetPath(), bytes.NewReader(event.GetBody()))
35
+ if err != nil {
36
+ context.Logger.ErrorWith("Failed to create a reverse proxy request")
37
+ return nil, err
38
+ }
39
+ for k, v := range event.GetHeaders() {
40
+ httpRequest.Header[k] = []string{v.(string)}
41
+ }
42
42
 
43
- // populate query params
44
- query := httpRequest.URL.Query()
45
- for k, v := range event.GetFields() {
46
- query.Set(k, v.(string))
47
- }
48
- httpRequest.URL.RawQuery = query.Encode()
43
+ // populate query params
44
+ query := httpRequest.URL.Query()
45
+ for k, v := range event.GetFields() {
46
+ query.Set(k, v.(string))
47
+ }
48
+ httpRequest.URL.RawQuery = query.Encode()
49
49
 
50
- recorder := httptest.NewRecorder()
51
- reverseProxy.ServeHTTP(recorder, httpRequest)
50
+ recorder := httptest.NewRecorder()
51
+ reverseProxy.ServeHTTP(recorder, httpRequest)
52
52
 
53
- // send request to sidecar
54
- context.Logger.DebugWith("Forwarding request to sidecar", "sidecarUrl", sidecarUrl, "query", httpRequest.URL.Query())
55
- response := recorder.Result()
53
+ // send request to sidecar
54
+ context.Logger.DebugWith("Forwarding request to sidecar",
55
+ "sidecarUrl", sidecarUrl,
56
+ "method", event.GetMethod())
57
+ response := recorder.Result()
56
58
 
57
- headers := make(map[string]interface{})
58
- for key, value := range response.Header {
59
- headers[key] = value[0]
60
- }
59
+ headers := make(map[string]interface{})
60
+ for key, value := range response.Header {
61
+ headers[key] = value[0]
62
+ }
61
63
 
62
- // let the processor calculate the content length
63
- delete(headers, "Content-Length")
64
- return nuclio.Response{
65
- StatusCode: response.StatusCode,
66
- Body: recorder.Body.Bytes(),
67
- ContentType: response.Header.Get("Content-Type"),
68
- Headers: headers,
69
- }, nil
64
+ // let the processor calculate the content length
65
+ delete(headers, "Content-Length")
66
+ return nuclio.Response{
67
+ StatusCode: response.StatusCode,
68
+ Body: recorder.Body.Bytes(),
69
+ ContentType: response.Header.Get("Content-Type"),
70
+ Headers: headers,
71
+ }, nil
70
72
  }
71
73
 
72
74
  func InitContext(context *nuclio.Context) error {
73
- sidecarHost := os.Getenv("SIDECAR_HOST")
74
- sidecarPort := os.Getenv("SIDECAR_PORT")
75
- if sidecarHost == "" {
76
- sidecarHost = "http://localhost"
77
- } else if !strings.Contains(sidecarHost, "://") {
78
- sidecarHost = fmt.Sprintf("http://%s", sidecarHost)
79
- }
75
+ sidecarHost := os.Getenv("SIDECAR_HOST")
76
+ sidecarPort := os.Getenv("SIDECAR_PORT")
77
+ if sidecarHost == "" {
78
+ sidecarHost = "http://localhost"
79
+ } else if !strings.Contains(sidecarHost, "://") {
80
+ sidecarHost = fmt.Sprintf("http://%s", sidecarHost)
81
+ }
80
82
 
81
- // url for request forwarding
82
- sidecarUrl := fmt.Sprintf("%s:%s", sidecarHost, sidecarPort)
83
- parsedURL, err := url.Parse(sidecarUrl)
84
- if err != nil {
85
- context.Logger.ErrorWith("Failed to parse sidecar url", "sidecarUrl", sidecarUrl)
86
- return err
87
- }
88
- reverseProxy := httputil.NewSingleHostReverseProxy(parsedURL)
83
+ // url for request forwarding
84
+ sidecarUrl := fmt.Sprintf("%s:%s", sidecarHost, sidecarPort)
85
+ parsedURL, err := url.Parse(sidecarUrl)
86
+ if err != nil {
87
+ context.Logger.ErrorWith("Failed to parse sidecar url", "sidecarUrl", sidecarUrl)
88
+ return err
89
+ }
90
+ reverseProxy := httputil.NewSingleHostReverseProxy(parsedURL)
89
91
 
90
- context.UserData = map[string]interface{}{
91
- "server": sidecarUrl,
92
- "reverseProxy": reverseProxy,
93
- }
94
- return nil
92
+ context.UserData = map[string]interface{}{
93
+ "server": sidecarUrl,
94
+ "reverseProxy": reverseProxy,
95
+ }
96
+ return nil
95
97
  }
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import asyncio
16
+ import copy
16
17
  import json
17
18
  import typing
18
19
  import warnings
@@ -26,9 +27,6 @@ import requests
26
27
  import semver
27
28
  from aiohttp.client import ClientSession
28
29
  from kubernetes import client
29
- from mlrun_pipelines.common.mounts import VolumeMount
30
- from mlrun_pipelines.common.ops import deploy_op
31
- from mlrun_pipelines.mounts import mount_v3io, v3io_cred
32
30
  from nuclio.deploy import find_dashboard_url, get_deploy_status
33
31
  from nuclio.triggers import V3IOStreamTrigger
34
32
 
@@ -47,9 +45,24 @@ from mlrun.platforms.iguazio import (
47
45
  split_path,
48
46
  )
49
47
  from mlrun.runtimes.base import FunctionStatus, RunError
48
+ from mlrun.runtimes.mounts import VolumeMount, mount_v3io, v3io_cred
50
49
  from mlrun.runtimes.pod import KubeResource, KubeResourceSpec
51
50
  from mlrun.runtimes.utils import get_item_name, log_std
52
51
  from mlrun.utils import get_in, logger, update_in
52
+ from mlrun_pipelines.common.ops import deploy_op
53
+
54
+ SENSITIVE_PATHS_IN_TRIGGER_CONFIG = {
55
+ "password",
56
+ "secret",
57
+ "attributes/password",
58
+ "attributes/accesskeyid",
59
+ "attributes/secretaccesskey",
60
+ "attributes/cacert",
61
+ "attributes/accesskey",
62
+ "attributes/accesscertificate",
63
+ "attributes/sasl/password",
64
+ "attributes/sasl/oauth/clientsecret",
65
+ }
53
66
 
54
67
 
55
68
  def validate_nuclio_version_compatibility(*min_versions):
@@ -275,6 +288,37 @@ class RemoteRuntime(KubeResource):
275
288
  if self.metadata.tag:
276
289
  mlrun.utils.validate_tag_name(self.metadata.tag, "function.metadata.tag")
277
290
 
291
+ def mask_sensitive_data_in_config(self):
292
+ if not self.spec.config:
293
+ return {}
294
+
295
+ raw_config = copy.deepcopy(self.spec.config)
296
+
297
+ for key, value in self.spec.config.items():
298
+ if key.startswith("spec.triggers"):
299
+ trigger_name = key.split(".")[-1]
300
+
301
+ for path in SENSITIVE_PATHS_IN_TRIGGER_CONFIG:
302
+ # Handle nested keys
303
+ nested_keys = path.split("/")
304
+ target = value
305
+ for sub_key in nested_keys[:-1]:
306
+ target = target.get(sub_key, {})
307
+
308
+ last_key = nested_keys[-1]
309
+ if last_key in target:
310
+ sensitive_field = target[last_key]
311
+ if sensitive_field.startswith(
312
+ mlrun.model.Credentials.secret_reference_prefix
313
+ ):
314
+ # already masked
315
+ continue
316
+ target[last_key] = (
317
+ f"{mlrun.model.Credentials.secret_reference_prefix}/spec/triggers/{trigger_name}/{path}"
318
+ )
319
+
320
+ return raw_config
321
+
278
322
  def set_config(self, key, value):
279
323
  self.spec.config[key] = value
280
324
  return self
@@ -307,9 +351,12 @@ class RemoteRuntime(KubeResource):
307
351
  def _validate_triggers(self, spec):
308
352
  # ML-7763 / NUC-233
309
353
  min_nuclio_version = "1.13.12"
310
- if mlconf.nuclio_version and semver.VersionInfo.parse(
354
+ if (
311
355
  mlconf.nuclio_version
312
- ) < semver.VersionInfo.parse(min_nuclio_version):
356
+ and mlconf.nuclio_version != "unstable"
357
+ and semver.VersionInfo.parse(mlconf.nuclio_version)
358
+ < semver.VersionInfo.parse(min_nuclio_version)
359
+ ):
313
360
  explicit_ack_enabled = False
314
361
  num_triggers = 0
315
362
  trigger_name = spec.get("name", "UNKNOWN")
@@ -370,8 +417,9 @@ class RemoteRuntime(KubeResource):
370
417
  )
371
418
  """
372
419
  self.spec.build.source = source
373
- # update handler in function_handler
374
- self.spec.function_handler = handler
420
+ # update handler in function_handler if needed
421
+ if handler:
422
+ self.spec.function_handler = handler
375
423
  if workdir:
376
424
  self.spec.workdir = workdir
377
425
  if runtime:
@@ -527,6 +575,13 @@ class RemoteRuntime(KubeResource):
527
575
  access_key = kwargs.pop("access_key", None)
528
576
  if not access_key:
529
577
  access_key = self._resolve_v3io_access_key()
578
+ engine = "sync"
579
+ explicit_ack_mode = kwargs.pop("explicit_ack_mode", None)
580
+ if self.spec and hasattr(self.spec, "graph"):
581
+ engine = getattr(self.spec.graph, "engine", None) or engine
582
+
583
+ if mlrun.mlconf.is_explicit_ack_enabled() and engine == "async":
584
+ explicit_ack_mode = explicit_ack_mode or "explicitOnly"
530
585
 
531
586
  self.add_trigger(
532
587
  name,
@@ -540,6 +595,7 @@ class RemoteRuntime(KubeResource):
540
595
  extra_attributes=extra_attributes,
541
596
  read_batch_size=256,
542
597
  access_key=access_key,
598
+ explicit_ack_mode=explicit_ack_mode,
543
599
  **kwargs,
544
600
  ),
545
601
  )
@@ -554,7 +610,7 @@ class RemoteRuntime(KubeResource):
554
610
  tag="",
555
611
  verbose=False,
556
612
  auth_info: AuthInfo = None,
557
- builder_env: dict = None,
613
+ builder_env: typing.Optional[dict] = None,
558
614
  force_build: bool = False,
559
615
  ):
560
616
  """Deploy the nuclio function to the cluster
@@ -567,9 +623,9 @@ class RemoteRuntime(KubeResource):
567
623
  :param force_build: set True for force building the image
568
624
  """
569
625
  if auth_info:
570
- # TODO: remove in 1.9.0
626
+ # TODO: remove in 1.10.0
571
627
  warnings.warn(
572
- "'auth_info' is deprecated for nuclio runtimes in 1.7.0 and will be removed in 1.9.0",
628
+ "'auth_info' is deprecated for nuclio runtimes in 1.7.0 and will be removed in 1.10.0",
573
629
  FutureWarning,
574
630
  )
575
631
 
@@ -600,6 +656,18 @@ class RemoteRuntime(KubeResource):
600
656
  # when a function is deployed, we wait for it to be ready by default
601
657
  # this also means that the function object will be updated with the function status
602
658
  self._wait_for_function_deployment(db, verbose=verbose)
659
+ # check if there are any background tasks related to creating model endpoints
660
+ model_endpoints_creation_background_tasks = (
661
+ mlrun.common.schemas.BackgroundTaskList(
662
+ **data.pop("background_tasks", {"background_tasks": []})
663
+ ).background_tasks
664
+ )
665
+ if model_endpoints_creation_background_tasks:
666
+ self._check_model_endpoint_task_state(
667
+ db=db,
668
+ background_task=model_endpoints_creation_background_tasks[0],
669
+ wait_for_completion=False,
670
+ )
603
671
 
604
672
  return self._enrich_command_from_status()
605
673
 
@@ -693,7 +761,9 @@ class RemoteRuntime(KubeResource):
693
761
  super().with_priority_class(name)
694
762
 
695
763
  def with_service_type(
696
- self, service_type: str, add_templated_ingress_host_mode: str = None
764
+ self,
765
+ service_type: str,
766
+ add_templated_ingress_host_mode: typing.Optional[str] = None,
697
767
  ):
698
768
  """
699
769
  Enables to control the service type of the pod and the addition of templated ingress host
@@ -741,45 +811,10 @@ class RemoteRuntime(KubeResource):
741
811
 
742
812
  def _get_state(
743
813
  self,
744
- dashboard="",
745
814
  last_log_timestamp=0,
746
815
  verbose=False,
747
816
  raise_on_exception=True,
748
- resolve_address=True,
749
- auth_info: AuthInfo = None,
750
817
  ) -> tuple[str, str, typing.Optional[float]]:
751
- if dashboard:
752
- (
753
- state,
754
- address,
755
- name,
756
- last_log_timestamp,
757
- text,
758
- function_status,
759
- ) = get_nuclio_deploy_status(
760
- self.metadata.name,
761
- self.metadata.project,
762
- self.metadata.tag,
763
- dashboard,
764
- last_log_timestamp=last_log_timestamp,
765
- verbose=verbose,
766
- resolve_address=resolve_address,
767
- auth_info=auth_info,
768
- )
769
- self.status.internal_invocation_urls = function_status.get(
770
- "internalInvocationUrls", []
771
- )
772
- self.status.external_invocation_urls = function_status.get(
773
- "externalInvocationUrls", []
774
- )
775
- self.status.state = state
776
- self.status.nuclio_name = name
777
- self.status.container_image = function_status.get("containerImage", "")
778
- if address:
779
- self.status.address = address
780
- self.spec.command = f"http://{address}"
781
- return state, text, last_log_timestamp
782
-
783
818
  try:
784
819
  text, last_log_timestamp = self._get_db().get_nuclio_deploy_status(
785
820
  self, last_log_timestamp=last_log_timestamp, verbose=verbose
@@ -887,13 +922,12 @@ class RemoteRuntime(KubeResource):
887
922
  def invoke(
888
923
  self,
889
924
  path: str,
890
- body: typing.Union[str, bytes, dict] = None,
891
- method: str = None,
892
- headers: dict = None,
893
- dashboard: str = "",
925
+ body: typing.Optional[typing.Union[str, bytes, dict]] = None,
926
+ method: typing.Optional[str] = None,
927
+ headers: typing.Optional[dict] = None,
894
928
  force_external_address: bool = False,
895
929
  auth_info: AuthInfo = None,
896
- mock: bool = None,
930
+ mock: typing.Optional[bool] = None,
897
931
  **http_client_kwargs,
898
932
  ):
899
933
  """Invoke the remote (live) function and return the results
@@ -906,7 +940,6 @@ class RemoteRuntime(KubeResource):
906
940
  :param body: request body (str, bytes or a dict for json requests)
907
941
  :param method: HTTP method (GET, PUT, ..)
908
942
  :param headers: key/value dict with http headers
909
- :param dashboard: nuclio dashboard address (deprecated)
910
943
  :param force_external_address: use the external ingress URL
911
944
  :param auth_info: service AuthInfo
912
945
  :param mock: use mock server vs a real Nuclio function (for local simulations)
@@ -914,14 +947,6 @@ class RemoteRuntime(KubeResource):
914
947
  see this link for more information:
915
948
  https://requests.readthedocs.io/en/latest/api/#requests.request
916
949
  """
917
- if dashboard:
918
- # TODO: remove in 1.8.0
919
- warnings.warn(
920
- "'dashboard' parameter is no longer supported on client side, "
921
- "it is being configured through the MLRun API. It will be removed in 1.8.0.",
922
- FutureWarning,
923
- )
924
-
925
950
  if not method:
926
951
  method = "POST" if body else "GET"
927
952
 
@@ -951,7 +976,7 @@ class RemoteRuntime(KubeResource):
951
976
  "so function can not be invoked via http. Either enable default http trigger creation or "
952
977
  "create custom http trigger"
953
978
  )
954
- state, _, _ = self._get_state(dashboard, auth_info=auth_info)
979
+ state, _, _ = self._get_state()
955
980
  if state not in ["ready", "scaledToZero"]:
956
981
  logger.warning(f"Function is in the {state} state")
957
982
  if not self.status.address:
@@ -975,7 +1000,7 @@ class RemoteRuntime(KubeResource):
975
1000
  else:
976
1001
  http_client_kwargs["json"] = body
977
1002
  try:
978
- logger.info("Invoking function", method=method, path=path)
1003
+ logger.debug("Invoking function", method=method, path=path)
979
1004
  if not getattr(self, "_http_session", None):
980
1005
  self._http_session = requests.Session()
981
1006
  resp = self._http_session.request(
@@ -995,14 +1020,15 @@ class RemoteRuntime(KubeResource):
995
1020
 
996
1021
  def with_sidecar(
997
1022
  self,
998
- name: str = None,
999
- image: str = None,
1023
+ name: typing.Optional[str] = None,
1024
+ image: typing.Optional[str] = None,
1000
1025
  ports: typing.Optional[typing.Union[int, list[int]]] = None,
1001
1026
  command: typing.Optional[str] = None,
1002
1027
  args: typing.Optional[list[str]] = None,
1003
1028
  ):
1004
1029
  """
1005
1030
  Add a sidecar container to the function pod
1031
+
1006
1032
  :param name: Sidecar container name.
1007
1033
  :param image: Sidecar container image.
1008
1034
  :param ports: Sidecar container ports to expose. Can be a single port or a list of ports.
@@ -1192,9 +1218,6 @@ class RemoteRuntime(KubeResource):
1192
1218
  return results
1193
1219
 
1194
1220
  def _resolve_invocation_url(self, path, force_external_address):
1195
- if not path.startswith("/") and path != "":
1196
- path = f"/{path}"
1197
-
1198
1221
  # internal / external invocation urls is a nuclio >= 1.6.x feature
1199
1222
  # try to infer the invocation url from the internal and if not exists, use external.
1200
1223
  # $$$$ we do not want to use the external invocation url (e.g.: ingress, nodePort, etc.)
@@ -1203,12 +1226,16 @@ class RemoteRuntime(KubeResource):
1203
1226
  and self.status.internal_invocation_urls
1204
1227
  and mlrun.k8s_utils.is_running_inside_kubernetes_cluster()
1205
1228
  ):
1206
- return f"http://{self.status.internal_invocation_urls[0]}{path}"
1229
+ return mlrun.utils.helpers.join_urls(
1230
+ f"http://{self.status.internal_invocation_urls[0]}", path
1231
+ )
1207
1232
 
1208
1233
  if self.status.external_invocation_urls:
1209
- return f"http://{self.status.external_invocation_urls[0]}{path}"
1234
+ return mlrun.utils.helpers.join_urls(
1235
+ f"http://{self.status.external_invocation_urls[0]}", path
1236
+ )
1210
1237
  else:
1211
- return f"http://{self.status.address}{path}"
1238
+ return mlrun.utils.helpers.join_urls(f"http://{self.status.address}", path)
1212
1239
 
1213
1240
  def _update_credentials_from_remote_build(self, remote_data):
1214
1241
  self.metadata.credentials = remote_data.get("metadata", {}).get(
@@ -1244,6 +1271,9 @@ class RemoteRuntime(KubeResource):
1244
1271
  if remote_env.get("name") in credentials_env_var_names:
1245
1272
  new_env.append(remote_env)
1246
1273
 
1274
+ # update nuclio-specific credentials
1275
+ self.mask_sensitive_data_in_config()
1276
+
1247
1277
  self.spec.env = new_env
1248
1278
 
1249
1279
  def _set_as_mock(self, enable):
@@ -1283,6 +1313,33 @@ class RemoteRuntime(KubeResource):
1283
1313
  return mlrun.model.Credentials.generate_access_key
1284
1314
  return None
1285
1315
 
1316
+ def _check_model_endpoint_task_state(
1317
+ self,
1318
+ db: mlrun.db.RunDBInterface,
1319
+ background_task: mlrun.common.schemas.BackgroundTask,
1320
+ wait_for_completion: bool,
1321
+ ):
1322
+ if wait_for_completion:
1323
+ background_task = db._wait_for_background_task_to_reach_terminal_state(
1324
+ name=background_task.metadata.name, project=self.metadata.project
1325
+ )
1326
+ else:
1327
+ background_task = db.get_project_background_task(
1328
+ project=self.metadata.project, name=background_task.metadata.name
1329
+ )
1330
+ if (
1331
+ background_task.status.state
1332
+ in mlrun.common.schemas.BackgroundTaskState.terminal_states()
1333
+ ):
1334
+ logger.info(
1335
+ f"Model endpoint creation task completed with state {background_task.status.state}"
1336
+ )
1337
+ else:
1338
+ logger.warning(
1339
+ f"Model endpoint creation task is still running with state {background_task.status.state}"
1340
+ f"You can use the serving function, but it won't be monitored for the next few minutes"
1341
+ )
1342
+
1286
1343
 
1287
1344
  def parse_logs(logs):
1288
1345
  logs = json.loads(logs)