mlrun 1.10.0rc40__py3-none-any.whl → 1.11.0rc16__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 (150) hide show
  1. mlrun/__init__.py +3 -2
  2. mlrun/__main__.py +0 -4
  3. mlrun/artifacts/dataset.py +2 -2
  4. mlrun/artifacts/plots.py +1 -1
  5. mlrun/{model_monitoring/db/tsdb/tdengine → auth}/__init__.py +2 -3
  6. mlrun/auth/nuclio.py +89 -0
  7. mlrun/auth/providers.py +429 -0
  8. mlrun/auth/utils.py +415 -0
  9. mlrun/common/constants.py +7 -0
  10. mlrun/common/model_monitoring/helpers.py +41 -4
  11. mlrun/common/runtimes/constants.py +28 -0
  12. mlrun/common/schemas/__init__.py +13 -3
  13. mlrun/common/schemas/alert.py +2 -2
  14. mlrun/common/schemas/api_gateway.py +3 -0
  15. mlrun/common/schemas/auth.py +10 -10
  16. mlrun/common/schemas/client_spec.py +4 -0
  17. mlrun/common/schemas/constants.py +25 -0
  18. mlrun/common/schemas/frontend_spec.py +1 -8
  19. mlrun/common/schemas/function.py +24 -0
  20. mlrun/common/schemas/hub.py +3 -2
  21. mlrun/common/schemas/model_monitoring/__init__.py +1 -1
  22. mlrun/common/schemas/model_monitoring/constants.py +2 -2
  23. mlrun/common/schemas/secret.py +17 -2
  24. mlrun/common/secrets.py +95 -1
  25. mlrun/common/types.py +10 -10
  26. mlrun/config.py +53 -15
  27. mlrun/data_types/infer.py +2 -2
  28. mlrun/datastore/__init__.py +2 -3
  29. mlrun/datastore/base.py +274 -10
  30. mlrun/datastore/datastore.py +1 -1
  31. mlrun/datastore/datastore_profile.py +49 -17
  32. mlrun/datastore/model_provider/huggingface_provider.py +6 -2
  33. mlrun/datastore/model_provider/model_provider.py +2 -2
  34. mlrun/datastore/model_provider/openai_provider.py +2 -2
  35. mlrun/datastore/s3.py +15 -16
  36. mlrun/datastore/sources.py +1 -1
  37. mlrun/datastore/store_resources.py +4 -4
  38. mlrun/datastore/storeytargets.py +16 -10
  39. mlrun/datastore/targets.py +1 -1
  40. mlrun/datastore/utils.py +16 -3
  41. mlrun/datastore/v3io.py +1 -1
  42. mlrun/db/base.py +36 -12
  43. mlrun/db/httpdb.py +316 -101
  44. mlrun/db/nopdb.py +29 -11
  45. mlrun/errors.py +4 -2
  46. mlrun/execution.py +11 -12
  47. mlrun/feature_store/api.py +1 -1
  48. mlrun/feature_store/common.py +1 -1
  49. mlrun/feature_store/feature_vector_utils.py +1 -1
  50. mlrun/feature_store/steps.py +8 -6
  51. mlrun/frameworks/_common/utils.py +3 -3
  52. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  53. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +2 -1
  54. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  55. mlrun/frameworks/_ml_common/utils.py +2 -1
  56. mlrun/frameworks/auto_mlrun/auto_mlrun.py +4 -3
  57. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +2 -1
  58. mlrun/frameworks/onnx/dataset.py +2 -1
  59. mlrun/frameworks/onnx/mlrun_interface.py +2 -1
  60. mlrun/frameworks/pytorch/callbacks/logging_callback.py +5 -4
  61. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +2 -1
  62. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +2 -1
  63. mlrun/frameworks/pytorch/utils.py +2 -1
  64. mlrun/frameworks/sklearn/metric.py +2 -1
  65. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +5 -4
  66. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +2 -1
  67. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +2 -1
  68. mlrun/hub/__init__.py +37 -0
  69. mlrun/hub/base.py +142 -0
  70. mlrun/hub/module.py +67 -76
  71. mlrun/hub/step.py +113 -0
  72. mlrun/launcher/base.py +2 -1
  73. mlrun/launcher/local.py +2 -1
  74. mlrun/model.py +12 -2
  75. mlrun/model_monitoring/__init__.py +0 -1
  76. mlrun/model_monitoring/api.py +2 -2
  77. mlrun/model_monitoring/applications/base.py +20 -6
  78. mlrun/model_monitoring/applications/context.py +1 -0
  79. mlrun/model_monitoring/controller.py +7 -17
  80. mlrun/model_monitoring/db/_schedules.py +2 -16
  81. mlrun/model_monitoring/db/_stats.py +2 -13
  82. mlrun/model_monitoring/db/tsdb/__init__.py +9 -7
  83. mlrun/model_monitoring/db/tsdb/base.py +2 -4
  84. mlrun/model_monitoring/db/tsdb/preaggregate.py +234 -0
  85. mlrun/model_monitoring/db/tsdb/stream_graph_steps.py +63 -0
  86. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_metrics_queries.py +414 -0
  87. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_predictions_queries.py +376 -0
  88. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_results_queries.py +590 -0
  89. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connection.py +434 -0
  90. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connector.py +541 -0
  91. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_operations.py +808 -0
  92. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_schema.py +502 -0
  93. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream.py +163 -0
  94. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream_graph_steps.py +60 -0
  95. mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_dataframe_processor.py +141 -0
  96. mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_query_builder.py +585 -0
  97. mlrun/model_monitoring/db/tsdb/timescaledb/writer_graph_steps.py +73 -0
  98. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +4 -6
  99. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +147 -79
  100. mlrun/model_monitoring/features_drift_table.py +2 -1
  101. mlrun/model_monitoring/helpers.py +2 -1
  102. mlrun/model_monitoring/stream_processing.py +18 -16
  103. mlrun/model_monitoring/writer.py +4 -3
  104. mlrun/package/__init__.py +2 -1
  105. mlrun/platforms/__init__.py +0 -44
  106. mlrun/platforms/iguazio.py +1 -1
  107. mlrun/projects/operations.py +11 -10
  108. mlrun/projects/project.py +81 -82
  109. mlrun/run.py +4 -7
  110. mlrun/runtimes/__init__.py +2 -204
  111. mlrun/runtimes/base.py +89 -21
  112. mlrun/runtimes/constants.py +225 -0
  113. mlrun/runtimes/daskjob.py +4 -2
  114. mlrun/runtimes/databricks_job/databricks_runtime.py +2 -1
  115. mlrun/runtimes/mounts.py +5 -0
  116. mlrun/runtimes/nuclio/__init__.py +12 -8
  117. mlrun/runtimes/nuclio/api_gateway.py +36 -6
  118. mlrun/runtimes/nuclio/application/application.py +200 -32
  119. mlrun/runtimes/nuclio/function.py +154 -49
  120. mlrun/runtimes/nuclio/serving.py +55 -42
  121. mlrun/runtimes/pod.py +59 -10
  122. mlrun/secrets.py +46 -2
  123. mlrun/serving/__init__.py +2 -0
  124. mlrun/serving/remote.py +5 -5
  125. mlrun/serving/routers.py +3 -3
  126. mlrun/serving/server.py +46 -43
  127. mlrun/serving/serving_wrapper.py +6 -2
  128. mlrun/serving/states.py +554 -207
  129. mlrun/serving/steps.py +1 -1
  130. mlrun/serving/system_steps.py +42 -33
  131. mlrun/track/trackers/mlflow_tracker.py +29 -31
  132. mlrun/utils/helpers.py +89 -16
  133. mlrun/utils/http.py +9 -2
  134. mlrun/utils/notifications/notification/git.py +1 -1
  135. mlrun/utils/notifications/notification/mail.py +39 -16
  136. mlrun/utils/notifications/notification_pusher.py +2 -2
  137. mlrun/utils/version/version.json +2 -2
  138. mlrun/utils/version/version.py +3 -4
  139. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/METADATA +39 -49
  140. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/RECORD +144 -130
  141. mlrun/db/auth_utils.py +0 -152
  142. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -343
  143. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +0 -75
  144. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +0 -281
  145. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +0 -1368
  146. mlrun/model_monitoring/db/tsdb/tdengine/writer_graph_steps.py +0 -51
  147. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/WHEEL +0 -0
  148. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/entry_points.txt +0 -0
  149. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/licenses/LICENSE +0 -0
  150. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/top_level.txt +0 -0
@@ -67,3 +67,7 @@ class ClientSpec(pydantic.v1.BaseModel):
67
67
  alerts_mode: typing.Optional[str]
68
68
  system_id: typing.Optional[str]
69
69
  model_endpoint_monitoring_store_prefixes: typing.Optional[dict[str, str]]
70
+ authentication_mode: typing.Optional[str]
71
+ # Iguazio V4 OAuth token provider configuration
72
+ oauth_internal_token_endpoint: typing.Optional[str]
73
+ oauth_external_token_endpoint: typing.Optional[str]
@@ -95,6 +95,21 @@ headers_prefix = "x-mlrun-"
95
95
 
96
96
  class HeaderNames:
97
97
  projects_role = "x-projects-role"
98
+ remote_user = "x-remote-user"
99
+ forwarded_host = "x-forwarded-host"
100
+ data_session_override = "x-data-session-override"
101
+ user_id = "x-user-id"
102
+ user_group_ids = "x-user-group-ids"
103
+ unix_uid = "x-unix-uid"
104
+ v3io_session_key = "x-v3io-session-key"
105
+ v3io_access_key = "x-v3io-access-key"
106
+ v3io_user_id = "x-v3io-user-id"
107
+ v3io_session_planes = "x-v3io-session-planes"
108
+ authorization = "authorization"
109
+ igz_authenticator_kind = "x-igz-authenticator-kind"
110
+ cookies = "cookies"
111
+ cookie = "cookie"
112
+ x_request_id = "x-request-id"
98
113
  patch_mode = f"{headers_prefix}patch-mode"
99
114
  deletion_strategy = f"{headers_prefix}deletion-strategy"
100
115
  secret_store_token = f"{headers_prefix}secret-store-token"
@@ -106,6 +121,16 @@ class HeaderNames:
106
121
  ui_clear_cache = f"{headers_prefix}ui-clear-cache"
107
122
 
108
123
 
124
+ class AuthorizationHeaderPrefixes:
125
+ basic = "Basic "
126
+ bearer = "Bearer "
127
+
128
+
129
+ class CookieNames:
130
+ oauth2_proxy = "_oauth2_proxy"
131
+ iguazio = "session"
132
+
133
+
109
134
  class FeatureStorePartitionByField(mlrun.common.types.StrEnum):
110
135
  name = "name" # Supported for feature-store objects
111
136
 
@@ -31,13 +31,6 @@ class PreemptionNodesFeatureFlag(mlrun.common.types.StrEnum):
31
31
  disabled = "disabled"
32
32
 
33
33
 
34
- class AuthenticationFeatureFlag(mlrun.common.types.StrEnum):
35
- none = "none"
36
- basic = "basic"
37
- bearer = "bearer"
38
- iguazio = "iguazio"
39
-
40
-
41
34
  class NuclioStreamsFeatureFlag(mlrun.common.types.StrEnum):
42
35
  enabled = "enabled"
43
36
  disabled = "disabled"
@@ -45,7 +38,7 @@ class NuclioStreamsFeatureFlag(mlrun.common.types.StrEnum):
45
38
 
46
39
  class FeatureFlags(pydantic.v1.BaseModel):
47
40
  project_membership: ProjectMembershipFeatureFlag
48
- authentication: AuthenticationFeatureFlag
41
+ authentication: mlrun.common.types.AuthenticationMode
49
42
  nuclio_streams: NuclioStreamsFeatureFlag
50
43
  preemption_nodes: PreemptionNodesFeatureFlag
51
44
 
@@ -140,3 +140,27 @@ class Function(pydantic.v1.BaseModel):
140
140
 
141
141
  class Config:
142
142
  extra = pydantic.v1.Extra.allow
143
+
144
+
145
+ class BatchingSpec(pydantic.v1.BaseModel):
146
+ # Set to True to enable batching
147
+ enabled: bool
148
+ # Maximal events to batch together. Default size is 10.
149
+ batch_size: typing.Optional[int]
150
+ # The maximum amount of time to wait before processing the batch. Default timeout is 1s.
151
+ # Once this time passes, the batch is processed even if it hasn’t reached the full batch size.
152
+ timeout: typing.Optional[str]
153
+
154
+ def get_nuclio_batch_config(self):
155
+ if not self.enabled:
156
+ return None
157
+
158
+ config = {"mode": "enable"}
159
+
160
+ if self.batch_size:
161
+ config["batchSize"] = self.batch_size
162
+
163
+ if self.timeout:
164
+ config["timeout"] = self.timeout
165
+
166
+ return config
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from datetime import datetime, timezone
15
+ from datetime import UTC, datetime
16
16
  from typing import Optional
17
17
 
18
18
  import deepdiff
@@ -40,6 +40,7 @@ class HubObjectMetadata(BaseModel):
40
40
  class HubSourceType(mlrun.common.types.StrEnum):
41
41
  functions = "functions"
42
42
  modules = "modules"
43
+ steps = "steps"
43
44
 
44
45
 
45
46
  # Sources-related objects
@@ -66,7 +67,7 @@ class HubSource(BaseModel):
66
67
  if not mlrun.mlconf.hub.default_source.create:
67
68
  return None
68
69
 
69
- now = datetime.now(timezone.utc)
70
+ now = datetime.now(UTC)
70
71
  hub_metadata = HubObjectMetadata(
71
72
  name=mlrun.mlconf.hub.default_source.name,
72
73
  description=mlrun.mlconf.hub.default_source.description,
@@ -40,7 +40,7 @@ from .constants import (
40
40
  ResultStatusApp,
41
41
  SpecialApps,
42
42
  StreamProcessingEvent,
43
- TDEngineSuperTables,
43
+ TimescaleDBTables,
44
44
  TSDBTarget,
45
45
  V3IOTSDBTables,
46
46
  VersionedModel,
@@ -274,7 +274,7 @@ class EventKeyMetrics:
274
274
 
275
275
  class TSDBTarget(MonitoringStrEnum):
276
276
  V3IO_TSDB = "v3io-tsdb"
277
- TDEngine = "tdengine"
277
+ TimescaleDB = "postgresql"
278
278
 
279
279
 
280
280
  class ProjectSecretKeys:
@@ -353,7 +353,7 @@ class V3IOTSDBTables(MonitoringStrEnum):
353
353
  PREDICTIONS = "predictions"
354
354
 
355
355
 
356
- class TDEngineSuperTables(MonitoringStrEnum):
356
+ class TimescaleDBTables(MonitoringStrEnum):
357
357
  APP_RESULTS = "app_results"
358
358
  METRICS = "metrics"
359
359
  PREDICTIONS = "predictions"
@@ -49,5 +49,20 @@ class SecretKeysData(BaseModel):
49
49
  secret_keys: Optional[list] = []
50
50
 
51
51
 
52
- class UserSecretCreationRequest(SecretsData):
53
- user: str
52
+ class SecretToken(BaseModel):
53
+ name: str
54
+ token: str
55
+
56
+
57
+ class StoreSecretTokensResponse(BaseModel):
58
+ created_tokens: list[str] = []
59
+ updated_tokens: list[str] = []
60
+
61
+
62
+ class SecretTokenInfo(BaseModel):
63
+ name: str
64
+ expiration: int
65
+
66
+
67
+ class ListSecretTokensResponse(BaseModel):
68
+ secret_tokens: list[SecretTokenInfo]
mlrun/common/secrets.py CHANGED
@@ -11,10 +11,32 @@
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
-
14
+ import re
15
+ import typing
15
16
  from abc import ABC, abstractmethod
16
17
 
17
18
  import mlrun.common.schemas
19
+ from mlrun.config import config as mlconf
20
+
21
+ _AUTH_SECRET_NAME_TEMPLATE = re.escape(
22
+ mlconf.secret_stores.kubernetes.auth_secret_name.format(
23
+ hashed_access_key="",
24
+ )
25
+ )
26
+ AUTH_SECRET_PATTERN = re.compile(f"^{_AUTH_SECRET_NAME_TEMPLATE}.*")
27
+
28
+
29
+ def validate_not_forbidden_secret(secret_name: str) -> None:
30
+ """
31
+ Forbid client-supplied references to internal MLRun auth/project secrets.
32
+ No-op when running inside the API server (API enrichments are allowed).
33
+ """
34
+ if not secret_name or mlrun.config.is_running_as_api():
35
+ return
36
+ if AUTH_SECRET_PATTERN.match(secret_name):
37
+ raise mlrun.errors.MLRunInvalidArgumentError(
38
+ f"Forbidden secret '{secret_name}' matches MLRun auth-secret pattern."
39
+ )
18
40
 
19
41
 
20
42
  class SecretProviderInterface(ABC):
@@ -54,6 +76,44 @@ class SecretProviderInterface(ABC):
54
76
  def get_secret_data(self, secret_name, namespace=""):
55
77
  pass
56
78
 
79
+ @abstractmethod
80
+ def store_user_token_secret(
81
+ self,
82
+ username: str,
83
+ token_name: str,
84
+ token: str,
85
+ expiration: int,
86
+ force: bool = False,
87
+ namespace: typing.Optional[str] = None,
88
+ ) -> typing.Optional[mlrun.common.schemas.SecretEventActions]:
89
+ pass
90
+
91
+ @abstractmethod
92
+ def get_user_token_secret_value(
93
+ self,
94
+ username: str,
95
+ token_name: str,
96
+ namespace: typing.Optional[str] = None,
97
+ ) -> str:
98
+ pass
99
+
100
+ @abstractmethod
101
+ def list_user_token_secrets(
102
+ self,
103
+ username: str,
104
+ namespace: typing.Optional[str] = None,
105
+ ) -> list[mlrun.common.schemas.SecretTokenInfo]:
106
+ pass
107
+
108
+ @abstractmethod
109
+ def delete_user_token_secret(
110
+ self,
111
+ username: str,
112
+ token_name: str,
113
+ namespace: typing.Optional[str] = None,
114
+ ) -> None:
115
+ pass
116
+
57
117
 
58
118
  class InMemorySecretProvider(SecretProviderInterface):
59
119
  def __init__(self):
@@ -130,6 +190,40 @@ class InMemorySecretProvider(SecretProviderInterface):
130
190
  def get_secret_data(self, secret_name, namespace=""):
131
191
  return self.secrets_map[secret_name]
132
192
 
193
+ def store_user_token_secret(
194
+ self,
195
+ username: str,
196
+ token_name: str,
197
+ token: str,
198
+ expiration: int,
199
+ force: bool = False,
200
+ namespace: typing.Optional[str] = None,
201
+ ) -> typing.Optional[mlrun.common.schemas.SecretEventActions]:
202
+ raise NotImplementedError()
203
+
204
+ def get_user_token_secret_value(
205
+ self,
206
+ username: str,
207
+ token_name: str,
208
+ namespace: typing.Optional[str] = None,
209
+ ) -> str:
210
+ raise NotImplementedError()
211
+
212
+ def list_user_token_secrets(
213
+ self,
214
+ username: str,
215
+ namespace: typing.Optional[str] = None,
216
+ ) -> list[mlrun.common.schemas.SecretTokenInfo]:
217
+ raise NotImplementedError()
218
+
219
+ def delete_user_token_secret(
220
+ self,
221
+ username: str,
222
+ token_name: str,
223
+ namespace: typing.Optional[str] = None,
224
+ ) -> None:
225
+ raise NotImplementedError()
226
+
133
227
  @staticmethod
134
228
  def _generate_auth_secret_data(username: str, access_key: str):
135
229
  return {
mlrun/common/types.py CHANGED
@@ -14,18 +14,10 @@
14
14
 
15
15
  import enum
16
16
 
17
+ # Alias to Python's built-in StrEnum (Python 3.11+)
18
+ StrEnum = enum.StrEnum
17
19
 
18
- # TODO: From python 3.11 StrEnum is built-in and this will not be needed
19
- class StrEnum(str, enum.Enum):
20
- def __str__(self):
21
- return self.value
22
20
 
23
- def __repr__(self):
24
- return self.value
25
-
26
-
27
- # Partial backport from Python 3.11
28
- # https://docs.python.org/3/library/http.html#http.HTTPMethod
29
21
  class HTTPMethod(StrEnum):
30
22
  GET = "GET"
31
23
  POST = "POST"
@@ -37,3 +29,11 @@ class HTTPMethod(StrEnum):
37
29
  class Operation(StrEnum):
38
30
  ADD = "add"
39
31
  REMOVE = "remove"
32
+
33
+
34
+ class AuthenticationMode(StrEnum):
35
+ NONE = "none"
36
+ BASIC = "basic"
37
+ BEARER = "bearer"
38
+ IGUAZIO = "iguazio"
39
+ IGUAZIO_V4 = "iguazio-v4"
mlrun/config.py CHANGED
@@ -40,6 +40,7 @@ import yaml
40
40
 
41
41
  import mlrun.common.constants
42
42
  import mlrun.common.schemas
43
+ import mlrun.common.types
43
44
  import mlrun.errors
44
45
 
45
46
  env_prefix = "MLRUN_"
@@ -66,7 +67,6 @@ default_config = {
66
67
  "nuclio_version": "",
67
68
  "default_nuclio_runtime": "python:3.11",
68
69
  "nest_asyncio_enabled": "", # enable import of nest_asyncio for corner cases with old jupyter, set "1"
69
- "ui_url": "", # remote/external mlrun UI url (for hyperlinks) (This is deprecated in favor of the ui block)
70
70
  "remote_host": "",
71
71
  "api_base_version": "v1",
72
72
  "version": "", # will be set to current version
@@ -85,7 +85,9 @@ default_config = {
85
85
  "kfp_image": "mlrun/mlrun-kfp", # image to use for KFP runner
86
86
  "dask_kfp_image": "mlrun/mlrun", # image to use for dask KFP runner
87
87
  "igz_version": "", # the version of the iguazio system the API is running on
88
- "iguazio_api_url": "", # the url to iguazio api
88
+ "iguazio_api_url": "", # the url to iguazio api (internal / external access with priority to internal)
89
+ "iguazio_api_url_ingress": "", # the url to iguazio api ingress (for external access)
90
+ "iguazio_api_ssl_verify": True, # verify ssl certificate of iguazio api
89
91
  "spark_app_image": "", # image to use for spark operator app runtime
90
92
  "spark_app_image_tag": "", # image tag to use for spark operator app runtime
91
93
  "spark_history_server_path": "", # spark logs directory for spark history server
@@ -422,11 +424,17 @@ default_config = {
422
424
  "allow_local_run": False,
423
425
  },
424
426
  "authentication": {
425
- "mode": "none", # one of none, basic, bearer, iguazio
427
+ "mode": "none", # one of none, basic, bearer, iguazio, iguazio-v4
426
428
  "basic": {"username": "", "password": ""},
427
429
  "bearer": {"token": ""},
428
430
  "iguazio": {
429
431
  "session_verification_endpoint": "data_sessions/verifications/app_service",
432
+ "authentication_endpoint": "api/v1/authentication/refresh-access-token",
433
+ },
434
+ "service_account": {
435
+ # the following are the default values for k8s service accounts, but may be changed per deployment
436
+ "token_expiration_seconds": 600,
437
+ "token_path": "/var/run/secrets/kubernetes.io/serviceaccount/token",
430
438
  },
431
439
  },
432
440
  "nuclio": {
@@ -481,6 +489,10 @@ default_config = {
481
489
  },
482
490
  "authorization": {
483
491
  "mode": "none", # one of none, opa
492
+ "namespaces": {
493
+ "resources": "",
494
+ "mgmt": "mgmt",
495
+ },
484
496
  "opa": {
485
497
  "address": "",
486
498
  "request_timeout": 10,
@@ -653,7 +665,7 @@ default_config = {
653
665
  "writer_graph": {
654
666
  "max_events": 1000,
655
667
  "flush_after_seconds": 30,
656
- "writer_version": "v1", # v1 is the sync version while v2 is async
668
+ "writer_version": "v2", # v1 is the sync version while v2 is async
657
669
  "parquet_batching_max_events": 10,
658
670
  "parquet_batching_timeout_secs": 30,
659
671
  },
@@ -670,6 +682,15 @@ default_config = {
670
682
  "parquet_batching_max_events": 10_000,
671
683
  "parquet_batching_timeout_secs": timedelta(minutes=1).total_seconds(),
672
684
  "model_endpoint_creation_check_period": 15,
685
+ # TSDB (TimescaleDB) configuration
686
+ "tsdb": {
687
+ # When True, automatically create/generate database name using system_id if not explicitly
688
+ # specified in the connection string. When False, use the database from connection string as-is.
689
+ "auto_create_database": True,
690
+ # Connection pool timeout in seconds. This is the maximum time to wait for a connection
691
+ # from the pool before raising an error.
692
+ "connection_pool_timeout": 120,
693
+ },
673
694
  },
674
695
  "secret_stores": {
675
696
  # Use only in testing scenarios (such as integration tests) to avoid using k8s for secrets (will use in-memory
@@ -725,7 +746,7 @@ default_config = {
725
746
  # Set false to avoid creating a global source (for example in a dark site)
726
747
  "create": True,
727
748
  "name": "default",
728
- "description": "MLRun global function hub",
749
+ "description": "MLRun hub",
729
750
  "url": "https://mlrun.github.io/marketplace",
730
751
  "channel": "master",
731
752
  },
@@ -868,6 +889,19 @@ default_config = {
868
889
  "enabled": False,
869
890
  "request_timeout": 5,
870
891
  },
892
+ "auth_with_oauth_token": {
893
+ "enabled": False,
894
+ "request_timeout": 5,
895
+ "refresh_threshold": 0.75,
896
+ # Default is empty. automatically set based on configuration (end client vs jupyter vs runtime, etc)
897
+ # can be set manually set using envvars
898
+ "token_file": "",
899
+ # Default is empty because if set, searches for the specific token name in the file, if empty, it will look
900
+ # for a token named "default", if "default" does not exist, it will use the first token in the file
901
+ "token_name": "",
902
+ },
903
+ # a runtime computed value. Do not set it manually.
904
+ "auth_token_endpoint": "",
871
905
  "services": {
872
906
  # The running service name. One of: "api", "alerts"
873
907
  "service_name": "api",
@@ -965,7 +999,7 @@ class Config:
965
999
  try:
966
1000
  config_value.update(value)
967
1001
  except AttributeError as exc:
968
- if not isinstance(config_value, (dict, Config)):
1002
+ if not isinstance(config_value, dict | Config):
969
1003
  raise ValueError(
970
1004
  f"Can not update `{key}` config. "
971
1005
  f"Expected a configuration but received {type(value)}"
@@ -1280,10 +1314,7 @@ class Config:
1280
1314
 
1281
1315
  @staticmethod
1282
1316
  def resolve_ui_url():
1283
- # ui_url is deprecated in favor of the ui.url (we created the ui block)
1284
- # since the config class is used in a "recursive" way, we can't use property like we used in other places
1285
- # since the property will need to be url, which exists in other structs as well
1286
- return config.ui.url or config.ui_url
1317
+ return config.ui.url
1287
1318
 
1288
1319
  def is_api_running_on_k8s(self):
1289
1320
  # determine if the API service is attached to K8s cluster
@@ -1403,6 +1434,18 @@ class Config:
1403
1434
  ver in mlrun.mlconf.ce.mode for ver in ["lite", "full"]
1404
1435
  )
1405
1436
 
1437
+ def is_iguazio_mode(self):
1438
+ return (
1439
+ mlrun.mlconf.httpdb.authentication.mode
1440
+ == mlrun.common.types.AuthenticationMode.IGUAZIO
1441
+ )
1442
+
1443
+ def is_iguazio_v4_mode(self):
1444
+ return (
1445
+ config.httpdb.authentication.mode
1446
+ == mlrun.common.types.AuthenticationMode.IGUAZIO_V4
1447
+ )
1448
+
1406
1449
  def is_explicit_ack_enabled(self) -> bool:
1407
1450
  return self.httpdb.nuclio.explicit_ack == "enabled" and (
1408
1451
  not self.nuclio_version
@@ -1570,7 +1613,6 @@ def read_env(env=None, prefix=env_prefix):
1570
1613
  "https://mlrun-api.", "https://framesd."
1571
1614
  )
1572
1615
 
1573
- uisvc = env.get("MLRUN_UI_SERVICE_HOST")
1574
1616
  igz_domain = env.get("IGZ_NAMESPACE_DOMAIN")
1575
1617
 
1576
1618
  # workaround to try and detect IGZ domain
@@ -1596,10 +1638,6 @@ def read_env(env=None, prefix=env_prefix):
1596
1638
  if config.get("nuclio_dashboard_url") == "disabled":
1597
1639
  config["nuclio_dashboard_url"] = ""
1598
1640
 
1599
- if uisvc and not config.get("ui_url"):
1600
- if igz_domain:
1601
- config["ui_url"] = f"https://mlrun-ui.{igz_domain}"
1602
-
1603
1641
  if log_level := config.get("log_level"):
1604
1642
  import mlrun.utils.logger
1605
1643
 
mlrun/data_types/infer.py CHANGED
@@ -134,9 +134,9 @@ def get_df_stats(df, options, num_bins=None, sample_size=None):
134
134
  for col, values in df.describe(include="all", **kwargs).items():
135
135
  stats_dict = {}
136
136
  for stat, val in values.dropna().items():
137
- if isinstance(val, (float, np.floating, np.float64)):
137
+ if isinstance(val, float | np.floating | np.float64):
138
138
  stats_dict[stat] = float(val)
139
- elif isinstance(val, (int, np.integer, np.int64)):
139
+ elif isinstance(val, int | np.integer | np.int64):
140
140
  # boolean values are considered subclass of int
141
141
  if isinstance(val, bool):
142
142
  stats_dict[stat] = bool(val)
@@ -59,7 +59,6 @@ from ..utils import logger
59
59
  from .base import DataItem
60
60
  from .datastore import StoreManager, in_memory_store, uri_to_ipython
61
61
  from .dbfs_store import DatabricksFileBugFixed, DatabricksFileSystemDisableCache
62
- from .s3 import parse_s3_bucket_and_key
63
62
  from .sources import (
64
63
  BigQuerySource,
65
64
  CSVSource,
@@ -75,7 +74,7 @@ from .store_resources import (
75
74
  parse_store_uri,
76
75
  )
77
76
  from .targets import CSVTarget, NoSqlTarget, ParquetTarget, StreamTarget
78
- from .utils import get_kafka_brokers_from_dict, parse_kafka_url
77
+ from .utils import get_kafka_brokers_from_dict, parse_kafka_url, parse_s3_bucket_and_key
79
78
 
80
79
  store_manager = StoreManager()
81
80
 
@@ -123,7 +122,7 @@ def get_stream_pusher(stream_path: str, **kwargs):
123
122
  )
124
123
  if isinstance(
125
124
  datastore_profile,
126
- (DatastoreProfileKafkaStream, DatastoreProfileKafkaTarget),
125
+ DatastoreProfileKafkaStream | DatastoreProfileKafkaTarget,
127
126
  ):
128
127
  attributes = datastore_profile.attributes()
129
128
  brokers = attributes.pop("brokers", None)