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.
- mlrun/__init__.py +3 -2
- mlrun/__main__.py +0 -4
- mlrun/artifacts/dataset.py +2 -2
- mlrun/artifacts/plots.py +1 -1
- mlrun/{model_monitoring/db/tsdb/tdengine → auth}/__init__.py +2 -3
- mlrun/auth/nuclio.py +89 -0
- mlrun/auth/providers.py +429 -0
- mlrun/auth/utils.py +415 -0
- mlrun/common/constants.py +7 -0
- mlrun/common/model_monitoring/helpers.py +41 -4
- mlrun/common/runtimes/constants.py +28 -0
- mlrun/common/schemas/__init__.py +13 -3
- mlrun/common/schemas/alert.py +2 -2
- mlrun/common/schemas/api_gateway.py +3 -0
- mlrun/common/schemas/auth.py +10 -10
- mlrun/common/schemas/client_spec.py +4 -0
- mlrun/common/schemas/constants.py +25 -0
- mlrun/common/schemas/frontend_spec.py +1 -8
- mlrun/common/schemas/function.py +24 -0
- mlrun/common/schemas/hub.py +3 -2
- mlrun/common/schemas/model_monitoring/__init__.py +1 -1
- mlrun/common/schemas/model_monitoring/constants.py +2 -2
- mlrun/common/schemas/secret.py +17 -2
- mlrun/common/secrets.py +95 -1
- mlrun/common/types.py +10 -10
- mlrun/config.py +53 -15
- mlrun/data_types/infer.py +2 -2
- mlrun/datastore/__init__.py +2 -3
- mlrun/datastore/base.py +274 -10
- mlrun/datastore/datastore.py +1 -1
- mlrun/datastore/datastore_profile.py +49 -17
- mlrun/datastore/model_provider/huggingface_provider.py +6 -2
- mlrun/datastore/model_provider/model_provider.py +2 -2
- mlrun/datastore/model_provider/openai_provider.py +2 -2
- mlrun/datastore/s3.py +15 -16
- mlrun/datastore/sources.py +1 -1
- mlrun/datastore/store_resources.py +4 -4
- mlrun/datastore/storeytargets.py +16 -10
- mlrun/datastore/targets.py +1 -1
- mlrun/datastore/utils.py +16 -3
- mlrun/datastore/v3io.py +1 -1
- mlrun/db/base.py +36 -12
- mlrun/db/httpdb.py +316 -101
- mlrun/db/nopdb.py +29 -11
- mlrun/errors.py +4 -2
- mlrun/execution.py +11 -12
- mlrun/feature_store/api.py +1 -1
- mlrun/feature_store/common.py +1 -1
- mlrun/feature_store/feature_vector_utils.py +1 -1
- mlrun/feature_store/steps.py +8 -6
- mlrun/frameworks/_common/utils.py +3 -3
- mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +2 -1
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_ml_common/utils.py +2 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +4 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +2 -1
- mlrun/frameworks/onnx/dataset.py +2 -1
- mlrun/frameworks/onnx/mlrun_interface.py +2 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +5 -4
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +2 -1
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +2 -1
- mlrun/frameworks/pytorch/utils.py +2 -1
- mlrun/frameworks/sklearn/metric.py +2 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +5 -4
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +2 -1
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +2 -1
- mlrun/hub/__init__.py +37 -0
- mlrun/hub/base.py +142 -0
- mlrun/hub/module.py +67 -76
- mlrun/hub/step.py +113 -0
- mlrun/launcher/base.py +2 -1
- mlrun/launcher/local.py +2 -1
- mlrun/model.py +12 -2
- mlrun/model_monitoring/__init__.py +0 -1
- mlrun/model_monitoring/api.py +2 -2
- mlrun/model_monitoring/applications/base.py +20 -6
- mlrun/model_monitoring/applications/context.py +1 -0
- mlrun/model_monitoring/controller.py +7 -17
- mlrun/model_monitoring/db/_schedules.py +2 -16
- mlrun/model_monitoring/db/_stats.py +2 -13
- mlrun/model_monitoring/db/tsdb/__init__.py +9 -7
- mlrun/model_monitoring/db/tsdb/base.py +2 -4
- mlrun/model_monitoring/db/tsdb/preaggregate.py +234 -0
- mlrun/model_monitoring/db/tsdb/stream_graph_steps.py +63 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_metrics_queries.py +414 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_predictions_queries.py +376 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_results_queries.py +590 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connection.py +434 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connector.py +541 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_operations.py +808 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_schema.py +502 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream.py +163 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream_graph_steps.py +60 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_dataframe_processor.py +141 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_query_builder.py +585 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/writer_graph_steps.py +73 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +4 -6
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +147 -79
- mlrun/model_monitoring/features_drift_table.py +2 -1
- mlrun/model_monitoring/helpers.py +2 -1
- mlrun/model_monitoring/stream_processing.py +18 -16
- mlrun/model_monitoring/writer.py +4 -3
- mlrun/package/__init__.py +2 -1
- mlrun/platforms/__init__.py +0 -44
- mlrun/platforms/iguazio.py +1 -1
- mlrun/projects/operations.py +11 -10
- mlrun/projects/project.py +81 -82
- mlrun/run.py +4 -7
- mlrun/runtimes/__init__.py +2 -204
- mlrun/runtimes/base.py +89 -21
- mlrun/runtimes/constants.py +225 -0
- mlrun/runtimes/daskjob.py +4 -2
- mlrun/runtimes/databricks_job/databricks_runtime.py +2 -1
- mlrun/runtimes/mounts.py +5 -0
- mlrun/runtimes/nuclio/__init__.py +12 -8
- mlrun/runtimes/nuclio/api_gateway.py +36 -6
- mlrun/runtimes/nuclio/application/application.py +200 -32
- mlrun/runtimes/nuclio/function.py +154 -49
- mlrun/runtimes/nuclio/serving.py +55 -42
- mlrun/runtimes/pod.py +59 -10
- mlrun/secrets.py +46 -2
- mlrun/serving/__init__.py +2 -0
- mlrun/serving/remote.py +5 -5
- mlrun/serving/routers.py +3 -3
- mlrun/serving/server.py +46 -43
- mlrun/serving/serving_wrapper.py +6 -2
- mlrun/serving/states.py +554 -207
- mlrun/serving/steps.py +1 -1
- mlrun/serving/system_steps.py +42 -33
- mlrun/track/trackers/mlflow_tracker.py +29 -31
- mlrun/utils/helpers.py +89 -16
- mlrun/utils/http.py +9 -2
- mlrun/utils/notifications/notification/git.py +1 -1
- mlrun/utils/notifications/notification/mail.py +39 -16
- mlrun/utils/notifications/notification_pusher.py +2 -2
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +3 -4
- {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/METADATA +39 -49
- {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/RECORD +144 -130
- mlrun/db/auth_utils.py +0 -152
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -343
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +0 -75
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +0 -281
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +0 -1368
- mlrun/model_monitoring/db/tsdb/tdengine/writer_graph_steps.py +0 -51
- {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/WHEEL +0 -0
- {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/entry_points.txt +0 -0
- {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/licenses/LICENSE +0 -0
- {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:
|
|
41
|
+
authentication: mlrun.common.types.AuthenticationMode
|
|
49
42
|
nuclio_streams: NuclioStreamsFeatureFlag
|
|
50
43
|
preemption_nodes: PreemptionNodesFeatureFlag
|
|
51
44
|
|
mlrun/common/schemas/function.py
CHANGED
|
@@ -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
|
mlrun/common/schemas/hub.py
CHANGED
|
@@ -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
|
|
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(
|
|
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,
|
|
@@ -274,7 +274,7 @@ class EventKeyMetrics:
|
|
|
274
274
|
|
|
275
275
|
class TSDBTarget(MonitoringStrEnum):
|
|
276
276
|
V3IO_TSDB = "v3io-tsdb"
|
|
277
|
-
|
|
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
|
|
356
|
+
class TimescaleDBTables(MonitoringStrEnum):
|
|
357
357
|
APP_RESULTS = "app_results"
|
|
358
358
|
METRICS = "metrics"
|
|
359
359
|
PREDICTIONS = "predictions"
|
mlrun/common/schemas/secret.py
CHANGED
|
@@ -49,5 +49,20 @@ class SecretKeysData(BaseModel):
|
|
|
49
49
|
secret_keys: Optional[list] = []
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
class
|
|
53
|
-
|
|
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": "
|
|
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
|
|
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,
|
|
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
|
-
|
|
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,
|
|
137
|
+
if isinstance(val, float | np.floating | np.float64):
|
|
138
138
|
stats_dict[stat] = float(val)
|
|
139
|
-
elif isinstance(val,
|
|
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)
|
mlrun/datastore/__init__.py
CHANGED
|
@@ -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
|
-
|
|
125
|
+
DatastoreProfileKafkaStream | DatastoreProfileKafkaTarget,
|
|
127
126
|
):
|
|
128
127
|
attributes = datastore_profile.attributes()
|
|
129
128
|
brokers = attributes.pop("brokers", None)
|