mlrun 1.7.0rc20__py3-none-any.whl → 1.7.0rc28__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/__main__.py +10 -8
- mlrun/alerts/alert.py +55 -18
- mlrun/api/schemas/__init__.py +3 -3
- mlrun/artifacts/manager.py +26 -0
- mlrun/common/constants.py +3 -2
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/artifact.py +26 -3
- mlrun/common/formatters/base.py +44 -9
- mlrun/common/formatters/function.py +12 -7
- mlrun/common/formatters/run.py +26 -0
- mlrun/common/helpers.py +11 -0
- mlrun/common/schemas/__init__.py +4 -0
- mlrun/common/schemas/alert.py +5 -9
- mlrun/common/schemas/api_gateway.py +64 -16
- mlrun/common/schemas/artifact.py +11 -0
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +58 -28
- mlrun/common/schemas/model_monitoring/constants.py +21 -12
- mlrun/common/schemas/model_monitoring/model_endpoints.py +0 -12
- mlrun/common/schemas/pipeline.py +16 -0
- mlrun/common/schemas/project.py +17 -0
- mlrun/common/schemas/runs.py +17 -0
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/types.py +6 -0
- mlrun/config.py +17 -25
- mlrun/datastore/azure_blob.py +2 -1
- mlrun/datastore/datastore.py +3 -3
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/snowflake_utils.py +3 -1
- mlrun/datastore/sources.py +26 -11
- mlrun/datastore/store_resources.py +2 -0
- mlrun/datastore/targets.py +68 -16
- mlrun/db/base.py +83 -2
- mlrun/db/httpdb.py +280 -63
- mlrun/db/nopdb.py +60 -3
- mlrun/errors.py +5 -3
- mlrun/execution.py +28 -13
- mlrun/feature_store/feature_vector.py +8 -0
- mlrun/feature_store/retrieval/spark_merger.py +13 -2
- mlrun/launcher/local.py +4 -0
- mlrun/launcher/remote.py +1 -0
- mlrun/model.py +32 -3
- mlrun/model_monitoring/api.py +7 -52
- mlrun/model_monitoring/applications/base.py +5 -7
- mlrun/model_monitoring/applications/histogram_data_drift.py +1 -1
- mlrun/model_monitoring/db/stores/__init__.py +37 -24
- mlrun/model_monitoring/db/stores/base/store.py +40 -1
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +42 -87
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +27 -35
- mlrun/model_monitoring/db/tsdb/__init__.py +15 -15
- mlrun/model_monitoring/db/tsdb/base.py +1 -14
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +22 -18
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +86 -56
- mlrun/model_monitoring/helpers.py +34 -9
- mlrun/model_monitoring/stream_processing.py +12 -11
- mlrun/model_monitoring/writer.py +11 -11
- mlrun/projects/operations.py +5 -0
- mlrun/projects/pipelines.py +35 -21
- mlrun/projects/project.py +216 -107
- mlrun/render.py +10 -5
- mlrun/run.py +15 -5
- mlrun/runtimes/__init__.py +2 -0
- mlrun/runtimes/base.py +17 -4
- mlrun/runtimes/daskjob.py +8 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
- mlrun/runtimes/local.py +23 -4
- mlrun/runtimes/nuclio/application/application.py +0 -2
- mlrun/runtimes/nuclio/function.py +31 -2
- mlrun/runtimes/nuclio/serving.py +9 -6
- mlrun/runtimes/pod.py +5 -29
- mlrun/runtimes/remotesparkjob.py +8 -2
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/routers.py +75 -59
- mlrun/serving/server.py +11 -0
- mlrun/serving/states.py +80 -8
- mlrun/serving/utils.py +19 -11
- mlrun/serving/v2_serving.py +66 -39
- mlrun/utils/helpers.py +91 -11
- mlrun/utils/logger.py +36 -2
- mlrun/utils/notifications/notification/base.py +43 -7
- mlrun/utils/notifications/notification/git.py +21 -0
- mlrun/utils/notifications/notification/slack.py +9 -14
- mlrun/utils/notifications/notification/webhook.py +41 -1
- mlrun/utils/notifications/notification_pusher.py +3 -9
- mlrun/utils/regex.py +9 -0
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/METADATA +16 -9
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/RECORD +92 -91
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/WHEEL +1 -1
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
#
|
|
15
15
|
from typing import Optional
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
import pydantic
|
|
18
18
|
|
|
19
19
|
from .auth import AuthorizationResourceTypes, Credentials
|
|
20
20
|
from .object import (
|
|
@@ -27,32 +27,42 @@ from .object import (
|
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
class
|
|
30
|
+
class FeatureStoreBaseModel(pydantic.BaseModel):
|
|
31
|
+
"""
|
|
32
|
+
Intermediate base class, in order to override pydantic's configuration, as per
|
|
33
|
+
https://docs.pydantic.dev/1.10/usage/model_config/#change-behaviour-globally
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
class Config:
|
|
37
|
+
copy_on_model_validation = "none"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Feature(FeatureStoreBaseModel):
|
|
31
41
|
name: str
|
|
32
42
|
value_type: str
|
|
33
43
|
labels: Optional[dict] = {}
|
|
34
44
|
|
|
35
45
|
class Config:
|
|
36
|
-
extra = Extra.allow
|
|
46
|
+
extra = pydantic.Extra.allow
|
|
37
47
|
|
|
38
48
|
|
|
39
|
-
class Entity(
|
|
49
|
+
class Entity(FeatureStoreBaseModel):
|
|
40
50
|
name: str
|
|
41
51
|
value_type: str
|
|
42
52
|
labels: Optional[dict] = {}
|
|
43
53
|
|
|
44
54
|
class Config:
|
|
45
|
-
extra = Extra.allow
|
|
55
|
+
extra = pydantic.Extra.allow
|
|
46
56
|
|
|
47
57
|
|
|
48
58
|
class FeatureSetSpec(ObjectSpec):
|
|
49
59
|
entities: list[Entity] = []
|
|
50
60
|
features: list[Feature] = []
|
|
51
|
-
engine: Optional[str] = Field(default="storey")
|
|
61
|
+
engine: Optional[str] = pydantic.Field(default="storey")
|
|
52
62
|
|
|
53
63
|
|
|
54
|
-
class FeatureSet(
|
|
55
|
-
kind: ObjectKind = Field(ObjectKind.feature_set, const=True)
|
|
64
|
+
class FeatureSet(FeatureStoreBaseModel):
|
|
65
|
+
kind: ObjectKind = pydantic.Field(ObjectKind.feature_set, const=True)
|
|
56
66
|
metadata: ObjectMetadata
|
|
57
67
|
spec: FeatureSetSpec
|
|
58
68
|
status: ObjectStatus
|
|
@@ -62,7 +72,7 @@ class FeatureSet(BaseModel):
|
|
|
62
72
|
return AuthorizationResourceTypes.feature_set
|
|
63
73
|
|
|
64
74
|
|
|
65
|
-
class EntityRecord(
|
|
75
|
+
class EntityRecord(FeatureStoreBaseModel):
|
|
66
76
|
name: str
|
|
67
77
|
value_type: str
|
|
68
78
|
labels: list[LabelRecord]
|
|
@@ -71,7 +81,7 @@ class EntityRecord(BaseModel):
|
|
|
71
81
|
orm_mode = True
|
|
72
82
|
|
|
73
83
|
|
|
74
|
-
class FeatureRecord(
|
|
84
|
+
class FeatureRecord(FeatureStoreBaseModel):
|
|
75
85
|
name: str
|
|
76
86
|
value_type: str
|
|
77
87
|
labels: list[LabelRecord]
|
|
@@ -88,44 +98,64 @@ class FeatureSetRecord(ObjectRecord):
|
|
|
88
98
|
orm_mode = True
|
|
89
99
|
|
|
90
100
|
|
|
91
|
-
class FeatureSetsOutput(
|
|
101
|
+
class FeatureSetsOutput(FeatureStoreBaseModel):
|
|
92
102
|
feature_sets: list[FeatureSet]
|
|
93
103
|
|
|
94
104
|
|
|
95
|
-
class FeatureSetsTagsOutput(
|
|
105
|
+
class FeatureSetsTagsOutput(FeatureStoreBaseModel):
|
|
96
106
|
tags: list[str] = []
|
|
97
107
|
|
|
98
108
|
|
|
99
|
-
class FeatureSetDigestSpec(
|
|
109
|
+
class FeatureSetDigestSpec(FeatureStoreBaseModel):
|
|
100
110
|
entities: list[Entity]
|
|
101
111
|
features: list[Feature]
|
|
102
112
|
|
|
103
113
|
|
|
104
|
-
class FeatureSetDigestOutput(
|
|
114
|
+
class FeatureSetDigestOutput(FeatureStoreBaseModel):
|
|
105
115
|
metadata: ObjectMetadata
|
|
106
116
|
spec: FeatureSetDigestSpec
|
|
107
117
|
|
|
108
118
|
|
|
109
|
-
class
|
|
119
|
+
class FeatureSetDigestSpecV2(FeatureStoreBaseModel):
|
|
120
|
+
entities: list[Entity]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class FeatureSetDigestOutputV2(FeatureStoreBaseModel):
|
|
124
|
+
feature_set_index: int
|
|
125
|
+
metadata: ObjectMetadata
|
|
126
|
+
spec: FeatureSetDigestSpecV2
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class FeatureListOutput(FeatureStoreBaseModel):
|
|
110
130
|
feature: Feature
|
|
111
131
|
feature_set_digest: FeatureSetDigestOutput
|
|
112
132
|
|
|
113
133
|
|
|
114
|
-
class FeaturesOutput(
|
|
134
|
+
class FeaturesOutput(FeatureStoreBaseModel):
|
|
115
135
|
features: list[FeatureListOutput]
|
|
116
136
|
|
|
117
137
|
|
|
118
|
-
class
|
|
138
|
+
class FeaturesOutputV2(FeatureStoreBaseModel):
|
|
139
|
+
features: list[Feature]
|
|
140
|
+
feature_set_digests: list[FeatureSetDigestOutputV2]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class EntityListOutput(FeatureStoreBaseModel):
|
|
119
144
|
entity: Entity
|
|
120
145
|
feature_set_digest: FeatureSetDigestOutput
|
|
121
146
|
|
|
122
147
|
|
|
123
|
-
class
|
|
148
|
+
class EntitiesOutputV2(FeatureStoreBaseModel):
|
|
149
|
+
entities: list[Entity]
|
|
150
|
+
feature_set_digests: list[FeatureSetDigestOutputV2]
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class EntitiesOutput(FeatureStoreBaseModel):
|
|
124
154
|
entities: list[EntityListOutput]
|
|
125
155
|
|
|
126
156
|
|
|
127
|
-
class FeatureVector(
|
|
128
|
-
kind: ObjectKind = Field(ObjectKind.feature_vector, const=True)
|
|
157
|
+
class FeatureVector(FeatureStoreBaseModel):
|
|
158
|
+
kind: ObjectKind = pydantic.Field(ObjectKind.feature_vector, const=True)
|
|
129
159
|
metadata: ObjectMetadata
|
|
130
160
|
spec: ObjectSpec
|
|
131
161
|
status: ObjectStatus
|
|
@@ -139,39 +169,39 @@ class FeatureVectorRecord(ObjectRecord):
|
|
|
139
169
|
pass
|
|
140
170
|
|
|
141
171
|
|
|
142
|
-
class FeatureVectorsOutput(
|
|
172
|
+
class FeatureVectorsOutput(FeatureStoreBaseModel):
|
|
143
173
|
feature_vectors: list[FeatureVector]
|
|
144
174
|
|
|
145
175
|
|
|
146
|
-
class FeatureVectorsTagsOutput(
|
|
176
|
+
class FeatureVectorsTagsOutput(FeatureStoreBaseModel):
|
|
147
177
|
tags: list[str] = []
|
|
148
178
|
|
|
149
179
|
|
|
150
|
-
class DataSource(
|
|
180
|
+
class DataSource(FeatureStoreBaseModel):
|
|
151
181
|
kind: str
|
|
152
182
|
name: str
|
|
153
183
|
path: str
|
|
154
184
|
|
|
155
185
|
class Config:
|
|
156
|
-
extra = Extra.allow
|
|
186
|
+
extra = pydantic.Extra.allow
|
|
157
187
|
|
|
158
188
|
|
|
159
|
-
class DataTarget(
|
|
189
|
+
class DataTarget(FeatureStoreBaseModel):
|
|
160
190
|
kind: str
|
|
161
191
|
name: str
|
|
162
192
|
path: Optional[str]
|
|
163
193
|
|
|
164
194
|
class Config:
|
|
165
|
-
extra = Extra.allow
|
|
195
|
+
extra = pydantic.Extra.allow
|
|
166
196
|
|
|
167
197
|
|
|
168
|
-
class FeatureSetIngestInput(
|
|
198
|
+
class FeatureSetIngestInput(FeatureStoreBaseModel):
|
|
169
199
|
source: Optional[DataSource]
|
|
170
200
|
targets: Optional[list[DataTarget]]
|
|
171
201
|
infer_options: Optional[int]
|
|
172
202
|
credentials: Credentials = Credentials()
|
|
173
203
|
|
|
174
204
|
|
|
175
|
-
class FeatureSetIngestOutput(
|
|
205
|
+
class FeatureSetIngestOutput(FeatureStoreBaseModel):
|
|
176
206
|
feature_set: FeatureSet
|
|
177
207
|
run_object: dict
|
|
@@ -78,8 +78,6 @@ class EventFieldType:
|
|
|
78
78
|
FEATURE_SET_URI = "monitoring_feature_set_uri"
|
|
79
79
|
ALGORITHM = "algorithm"
|
|
80
80
|
VALUE = "value"
|
|
81
|
-
DRIFT_DETECTED_THRESHOLD = "drift_detected_threshold"
|
|
82
|
-
POSSIBLE_DRIFT_THRESHOLD = "possible_drift_threshold"
|
|
83
81
|
SAMPLE_PARQUET_PATH = "sample_parquet_path"
|
|
84
82
|
TIME = "time"
|
|
85
83
|
TABLE_COLUMN = "table_column"
|
|
@@ -158,19 +156,36 @@ class EventKeyMetrics:
|
|
|
158
156
|
REAL_TIME = "real_time"
|
|
159
157
|
|
|
160
158
|
|
|
161
|
-
class ModelEndpointTarget:
|
|
159
|
+
class ModelEndpointTarget(MonitoringStrEnum):
|
|
162
160
|
V3IO_NOSQL = "v3io-nosql"
|
|
163
161
|
SQL = "sql"
|
|
164
162
|
|
|
165
163
|
|
|
164
|
+
class StreamKind(MonitoringStrEnum):
|
|
165
|
+
V3IO_STREAM = "v3io_stream"
|
|
166
|
+
KAFKA = "kafka"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class TSDBTarget(MonitoringStrEnum):
|
|
170
|
+
V3IO_TSDB = "v3io-tsdb"
|
|
171
|
+
TDEngine = "tdengine"
|
|
172
|
+
PROMETHEUS = "prometheus"
|
|
173
|
+
|
|
174
|
+
|
|
166
175
|
class ProjectSecretKeys:
|
|
167
176
|
ENDPOINT_STORE_CONNECTION = "MODEL_MONITORING_ENDPOINT_STORE_CONNECTION"
|
|
168
177
|
ACCESS_KEY = "MODEL_MONITORING_ACCESS_KEY"
|
|
169
|
-
PIPELINES_ACCESS_KEY = "MODEL_MONITORING_PIPELINES_ACCESS_KEY"
|
|
170
|
-
KAFKA_BROKERS = "KAFKA_BROKERS"
|
|
171
178
|
STREAM_PATH = "STREAM_PATH"
|
|
172
179
|
TSDB_CONNECTION = "TSDB_CONNECTION"
|
|
173
180
|
|
|
181
|
+
@classmethod
|
|
182
|
+
def mandatory_secrets(cls):
|
|
183
|
+
return [
|
|
184
|
+
cls.ENDPOINT_STORE_CONNECTION,
|
|
185
|
+
cls.STREAM_PATH,
|
|
186
|
+
cls.TSDB_CONNECTION,
|
|
187
|
+
]
|
|
188
|
+
|
|
174
189
|
|
|
175
190
|
class ModelMonitoringStoreKinds:
|
|
176
191
|
ENDPOINTS = "endpoints"
|
|
@@ -318,7 +333,7 @@ class ResultKindApp(Enum):
|
|
|
318
333
|
concept_drift = 1
|
|
319
334
|
model_performance = 2
|
|
320
335
|
system_performance = 3
|
|
321
|
-
|
|
336
|
+
mm_app_anomaly = 4
|
|
322
337
|
|
|
323
338
|
|
|
324
339
|
class ResultStatusApp(IntEnum):
|
|
@@ -344,12 +359,6 @@ class ControllerPolicy:
|
|
|
344
359
|
BASE_PERIOD = "base_period"
|
|
345
360
|
|
|
346
361
|
|
|
347
|
-
class TSDBTarget:
|
|
348
|
-
V3IO_TSDB = "v3io-tsdb"
|
|
349
|
-
TDEngine = "tdengine"
|
|
350
|
-
PROMETHEUS = "prometheus"
|
|
351
|
-
|
|
352
|
-
|
|
353
362
|
class HistogramDataDriftApplicationConstants:
|
|
354
363
|
NAME = "histogram-data-drift"
|
|
355
364
|
GENERAL_RESULT_NAME = "general_drift"
|
|
@@ -103,18 +103,6 @@ class ModelEndpointSpec(ObjectSpec):
|
|
|
103
103
|
json_parse_values=json_parse_values,
|
|
104
104
|
)
|
|
105
105
|
|
|
106
|
-
@validator("monitor_configuration")
|
|
107
|
-
@classmethod
|
|
108
|
-
def set_name(cls, monitor_configuration):
|
|
109
|
-
return monitor_configuration or {
|
|
110
|
-
EventFieldType.DRIFT_DETECTED_THRESHOLD: (
|
|
111
|
-
mlrun.mlconf.model_endpoint_monitoring.drift_thresholds.default.drift_detected
|
|
112
|
-
),
|
|
113
|
-
EventFieldType.POSSIBLE_DRIFT_THRESHOLD: (
|
|
114
|
-
mlrun.mlconf.model_endpoint_monitoring.drift_thresholds.default.possible_drift
|
|
115
|
-
),
|
|
116
|
-
}
|
|
117
|
-
|
|
118
106
|
@validator("model_uri")
|
|
119
107
|
@classmethod
|
|
120
108
|
def validate_model_uri(cls, model_uri):
|
mlrun/common/schemas/pipeline.py
CHANGED
|
@@ -15,6 +15,22 @@
|
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
17
|
import pydantic
|
|
18
|
+
from deprecated import deprecated
|
|
19
|
+
|
|
20
|
+
import mlrun.common.types
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@deprecated(
|
|
24
|
+
version="1.7.0",
|
|
25
|
+
reason="mlrun.common.schemas.PipelinesFormat is deprecated and will be removed in 1.9.0. "
|
|
26
|
+
"Use mlrun.common.formatters.PipelineFormat instead.",
|
|
27
|
+
category=FutureWarning,
|
|
28
|
+
)
|
|
29
|
+
class PipelinesFormat(mlrun.common.types.StrEnum):
|
|
30
|
+
full = "full"
|
|
31
|
+
metadata_only = "metadata_only"
|
|
32
|
+
summary = "summary"
|
|
33
|
+
name_only = "name_only"
|
|
18
34
|
|
|
19
35
|
|
|
20
36
|
class PipelinesPagination(str):
|
mlrun/common/schemas/project.py
CHANGED
|
@@ -16,6 +16,7 @@ import datetime
|
|
|
16
16
|
import typing
|
|
17
17
|
|
|
18
18
|
import pydantic
|
|
19
|
+
from deprecated import deprecated
|
|
19
20
|
|
|
20
21
|
import mlrun.common.types
|
|
21
22
|
|
|
@@ -23,6 +24,22 @@ from .common import ImageBuilder
|
|
|
23
24
|
from .object import ObjectKind, ObjectStatus
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
@deprecated(
|
|
28
|
+
version="1.7.0",
|
|
29
|
+
reason="mlrun.common.schemas.ProjectsFormat is deprecated and will be removed in 1.9.0. "
|
|
30
|
+
"Use mlrun.common.formatters.ProjectFormat instead.",
|
|
31
|
+
category=FutureWarning,
|
|
32
|
+
)
|
|
33
|
+
class ProjectsFormat(mlrun.common.types.StrEnum):
|
|
34
|
+
full = "full"
|
|
35
|
+
name_only = "name_only"
|
|
36
|
+
# minimal format removes large fields from the response (e.g. functions, workflows, artifacts)
|
|
37
|
+
# and is used for faster response times (in the UI)
|
|
38
|
+
minimal = "minimal"
|
|
39
|
+
# internal - allowed only in follower mode, only for the leader for upgrade purposes
|
|
40
|
+
leader = "leader"
|
|
41
|
+
|
|
42
|
+
|
|
26
43
|
class ProjectMetadata(pydantic.BaseModel):
|
|
27
44
|
name: str
|
|
28
45
|
created: typing.Optional[datetime.datetime] = None
|
mlrun/common/schemas/runs.py
CHANGED
|
@@ -15,9 +15,26 @@
|
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
17
|
import pydantic
|
|
18
|
+
from deprecated import deprecated
|
|
19
|
+
|
|
20
|
+
import mlrun.common.types
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
class RunIdentifier(pydantic.BaseModel):
|
|
21
24
|
kind: typing.Literal["run"] = "run"
|
|
22
25
|
uid: typing.Optional[str]
|
|
23
26
|
iter: typing.Optional[int]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@deprecated(
|
|
30
|
+
version="1.7.0",
|
|
31
|
+
reason="mlrun.common.schemas.RunsFormat is deprecated and will be removed in 1.9.0. "
|
|
32
|
+
"Use mlrun.common.formatters.RunFormat instead.",
|
|
33
|
+
category=FutureWarning,
|
|
34
|
+
)
|
|
35
|
+
class RunsFormat(mlrun.common.types.StrEnum):
|
|
36
|
+
# No enrichment, data is pulled as-is from the database.
|
|
37
|
+
standard = "standard"
|
|
38
|
+
|
|
39
|
+
# Performs run enrichment, including the run's artifacts. Only available for the `get` run API.
|
|
40
|
+
full = "full"
|
mlrun/common/schemas/schedule.py
CHANGED
|
@@ -96,7 +96,7 @@ class ScheduleUpdate(BaseModel):
|
|
|
96
96
|
scheduled_object: Optional[Any]
|
|
97
97
|
cron_trigger: Optional[Union[str, ScheduleCronTrigger]]
|
|
98
98
|
desired_state: Optional[str]
|
|
99
|
-
labels: Optional[dict] =
|
|
99
|
+
labels: Optional[dict] = None
|
|
100
100
|
concurrency_limit: Optional[int]
|
|
101
101
|
credentials: Credentials = Credentials()
|
|
102
102
|
|
mlrun/common/types.py
CHANGED
mlrun/config.py
CHANGED
|
@@ -229,6 +229,9 @@ default_config = {
|
|
|
229
229
|
"executing": "24h",
|
|
230
230
|
}
|
|
231
231
|
},
|
|
232
|
+
# When the module is reloaded, the maximum depth recursion configuration for the recursive reload
|
|
233
|
+
# function is used to prevent infinite loop
|
|
234
|
+
"reload_max_recursion_depth": 100,
|
|
232
235
|
},
|
|
233
236
|
"databricks": {
|
|
234
237
|
"artifact_directory_path": "/mlrun_databricks_runtime/artifacts_dictionaries"
|
|
@@ -501,13 +504,12 @@ default_config = {
|
|
|
501
504
|
"model_endpoint_monitoring": {
|
|
502
505
|
"serving_stream_args": {"shard_count": 1, "retention_period_hours": 24},
|
|
503
506
|
"application_stream_args": {"shard_count": 1, "retention_period_hours": 24},
|
|
504
|
-
"drift_thresholds": {"default": {"possible_drift": 0.5, "drift_detected": 0.7}},
|
|
505
507
|
# Store prefixes are used to handle model monitoring storing policies based on project and kind, such as events,
|
|
506
508
|
# stream, and endpoints.
|
|
507
509
|
"store_prefixes": {
|
|
508
510
|
"default": "v3io:///users/pipelines/{project}/model-endpoints/{kind}",
|
|
509
511
|
"user_space": "v3io:///projects/{project}/model-endpoints/{kind}",
|
|
510
|
-
"stream": "",
|
|
512
|
+
"stream": "", # TODO: Delete in 1.9.0
|
|
511
513
|
"monitoring_application": "v3io:///users/pipelines/{project}/monitoring-apps/",
|
|
512
514
|
},
|
|
513
515
|
# Offline storage path can be either relative or a full path. This path is used for general offline data
|
|
@@ -520,11 +522,12 @@ default_config = {
|
|
|
520
522
|
"parquet_batching_max_events": 10_000,
|
|
521
523
|
"parquet_batching_timeout_secs": timedelta(minutes=1).total_seconds(),
|
|
522
524
|
# See mlrun.model_monitoring.db.stores.ObjectStoreFactory for available options
|
|
523
|
-
"store_type": "v3io-nosql",
|
|
525
|
+
"store_type": "v3io-nosql", # TODO: Delete in 1.9.0
|
|
524
526
|
"endpoint_store_connection": "",
|
|
525
527
|
# See mlrun.model_monitoring.db.tsdb.ObjectTSDBFactory for available options
|
|
526
|
-
"tsdb_connector_type": "v3io-tsdb",
|
|
527
528
|
"tsdb_connection": "",
|
|
529
|
+
# See mlrun.common.schemas.model_monitoring.constants.StreamKind for available options
|
|
530
|
+
"stream_connection": "",
|
|
528
531
|
},
|
|
529
532
|
"secret_stores": {
|
|
530
533
|
# Use only in testing scenarios (such as integration tests) to avoid using k8s for secrets (will use in-memory
|
|
@@ -657,7 +660,9 @@ default_config = {
|
|
|
657
660
|
"failed_runs_grace_period": 3600,
|
|
658
661
|
"verbose": True,
|
|
659
662
|
# the number of workers which will be used to trigger the start log collection
|
|
660
|
-
"concurrent_start_logs_workers":
|
|
663
|
+
"concurrent_start_logs_workers": 50,
|
|
664
|
+
# the number of runs for which to start logs on api startup
|
|
665
|
+
"start_logs_startup_run_limit": 150,
|
|
661
666
|
# the time in hours in which to start log collection from.
|
|
662
667
|
# after upgrade, we might have runs which completed in the mean time or still in non-terminal state and
|
|
663
668
|
# we want to collect their logs in the new log collection method (sidecar)
|
|
@@ -701,7 +706,12 @@ default_config = {
|
|
|
701
706
|
"grafana_url": "",
|
|
702
707
|
"alerts": {
|
|
703
708
|
# supported modes: "enabled", "disabled".
|
|
704
|
-
"mode": "enabled"
|
|
709
|
+
"mode": "enabled",
|
|
710
|
+
# maximum number of alerts we allow to be configured.
|
|
711
|
+
# user will get an error when exceeding this
|
|
712
|
+
"max_allowed": 10000,
|
|
713
|
+
# maximum allowed value for count in criteria field inside AlertConfig
|
|
714
|
+
"max_criteria_count": 100,
|
|
705
715
|
},
|
|
706
716
|
"auth_with_client_id": {
|
|
707
717
|
"enabled": False,
|
|
@@ -806,6 +816,7 @@ class Config:
|
|
|
806
816
|
):
|
|
807
817
|
"""
|
|
808
818
|
decodes and loads the config attribute to expected type
|
|
819
|
+
|
|
809
820
|
:param attribute_path: the path in the default_config e.g. preemptible_nodes.node_selector
|
|
810
821
|
:param expected_type: the object type valid values are : `dict`, `list` etc...
|
|
811
822
|
:return: the expected type instance
|
|
@@ -931,24 +942,6 @@ class Config:
|
|
|
931
942
|
f"is not allowed for iguazio version: {igz_version} < 3.5.1"
|
|
932
943
|
)
|
|
933
944
|
|
|
934
|
-
def resolve_kfp_url(self, namespace=None):
|
|
935
|
-
if config.kfp_url:
|
|
936
|
-
return config.kfp_url
|
|
937
|
-
igz_version = self.get_parsed_igz_version()
|
|
938
|
-
# TODO: When Iguazio 3.4 will deprecate we can remove this line
|
|
939
|
-
if igz_version and igz_version <= semver.VersionInfo.parse("3.6.0-b1"):
|
|
940
|
-
if namespace is None:
|
|
941
|
-
if not config.namespace:
|
|
942
|
-
raise mlrun.errors.MLRunNotFoundError(
|
|
943
|
-
"For KubeFlow Pipelines to function, a namespace must be configured"
|
|
944
|
-
)
|
|
945
|
-
namespace = config.namespace
|
|
946
|
-
# When instead of host we provided namespace we tackled this issue
|
|
947
|
-
# https://github.com/canonical/bundle-kubeflow/issues/412
|
|
948
|
-
# TODO: When we'll move to kfp 1.4.0 (server side) it should be resolved
|
|
949
|
-
return f"http://ml-pipeline.{namespace}.svc.cluster.local:8888"
|
|
950
|
-
return None
|
|
951
|
-
|
|
952
945
|
def resolve_chief_api_url(self) -> str:
|
|
953
946
|
if self.httpdb.clusterization.chief.url:
|
|
954
947
|
return self.httpdb.clusterization.chief.url
|
|
@@ -1129,7 +1122,6 @@ class Config:
|
|
|
1129
1122
|
if store_prefix_dict.get(kind):
|
|
1130
1123
|
# Target exist in store prefix and has a valid string value
|
|
1131
1124
|
return store_prefix_dict[kind].format(project=project, **kwargs)
|
|
1132
|
-
|
|
1133
1125
|
if (
|
|
1134
1126
|
function_name
|
|
1135
1127
|
and function_name
|
mlrun/datastore/azure_blob.py
CHANGED
mlrun/datastore/datastore.py
CHANGED
|
@@ -21,7 +21,7 @@ from mlrun.datastore.datastore_profile import datastore_profile_read
|
|
|
21
21
|
from mlrun.errors import err_to_str
|
|
22
22
|
from mlrun.utils.helpers import get_local_file_schema
|
|
23
23
|
|
|
24
|
-
from ..utils import DB_SCHEMA,
|
|
24
|
+
from ..utils import DB_SCHEMA, RunKeys
|
|
25
25
|
from .base import DataItem, DataStore, HttpStore
|
|
26
26
|
from .filestore import FileStore
|
|
27
27
|
from .inmem import InMemoryStore
|
|
@@ -133,7 +133,7 @@ class StoreManager:
|
|
|
133
133
|
return self._db
|
|
134
134
|
|
|
135
135
|
def from_dict(self, struct: dict):
|
|
136
|
-
stor_list = struct.get(
|
|
136
|
+
stor_list = struct.get(RunKeys.data_stores)
|
|
137
137
|
if stor_list and isinstance(stor_list, list):
|
|
138
138
|
for stor in stor_list:
|
|
139
139
|
schema, endpoint, parsed_url = parse_url(stor.get("url"))
|
|
@@ -145,7 +145,7 @@ class StoreManager:
|
|
|
145
145
|
self._stores[stor["name"]] = new_stor
|
|
146
146
|
|
|
147
147
|
def to_dict(self, struct):
|
|
148
|
-
struct[
|
|
148
|
+
struct[RunKeys.data_stores] = [
|
|
149
149
|
stor.to_dict() for stor in self._stores.values() if stor.from_spec
|
|
150
150
|
]
|
|
151
151
|
|
|
@@ -55,8 +55,12 @@ class GoogleCloudStorageStore(DataStore):
|
|
|
55
55
|
) or self._get_secret_or_env("GOOGLE_APPLICATION_CREDENTIALS")
|
|
56
56
|
if credentials:
|
|
57
57
|
try:
|
|
58
|
-
# Try to handle credentials as a json connection string
|
|
59
|
-
token =
|
|
58
|
+
# Try to handle credentials as a json connection string or do nothing if already a dict
|
|
59
|
+
token = (
|
|
60
|
+
credentials
|
|
61
|
+
if isinstance(credentials, dict)
|
|
62
|
+
else json.loads(credentials)
|
|
63
|
+
)
|
|
60
64
|
except json.JSONDecodeError:
|
|
61
65
|
# If it's not json, handle it as a filename
|
|
62
66
|
token = credentials
|
|
@@ -30,13 +30,15 @@ def get_snowflake_password():
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def get_snowflake_spark_options(attributes):
|
|
33
|
+
if not attributes:
|
|
34
|
+
return {}
|
|
33
35
|
return {
|
|
34
36
|
"format": "net.snowflake.spark.snowflake",
|
|
35
37
|
"sfURL": attributes.get("url"),
|
|
36
38
|
"sfUser": attributes.get("user"),
|
|
37
39
|
"sfPassword": get_snowflake_password(),
|
|
38
40
|
"sfDatabase": attributes.get("database"),
|
|
39
|
-
"sfSchema": attributes.get("
|
|
41
|
+
"sfSchema": attributes.get("db_schema"),
|
|
40
42
|
"sfWarehouse": attributes.get("warehouse"),
|
|
41
43
|
"application": "iguazio_platform",
|
|
42
44
|
"TIMESTAMP_TYPE_MAPPING": "TIMESTAMP_LTZ",
|
mlrun/datastore/sources.py
CHANGED
|
@@ -747,7 +747,7 @@ class SnowflakeSource(BaseSourceDriver):
|
|
|
747
747
|
url="...",
|
|
748
748
|
user="...",
|
|
749
749
|
database="...",
|
|
750
|
-
|
|
750
|
+
db_schema="...",
|
|
751
751
|
warehouse="...",
|
|
752
752
|
)
|
|
753
753
|
|
|
@@ -762,7 +762,8 @@ class SnowflakeSource(BaseSourceDriver):
|
|
|
762
762
|
:parameter url: URL of the snowflake cluster
|
|
763
763
|
:parameter user: snowflake user
|
|
764
764
|
:parameter database: snowflake database
|
|
765
|
-
:parameter schema: snowflake schema
|
|
765
|
+
:parameter schema: snowflake schema - deprecated, use db_schema
|
|
766
|
+
:parameter db_schema: snowflake schema
|
|
766
767
|
:parameter warehouse: snowflake warehouse
|
|
767
768
|
"""
|
|
768
769
|
|
|
@@ -774,6 +775,7 @@ class SnowflakeSource(BaseSourceDriver):
|
|
|
774
775
|
self,
|
|
775
776
|
name: str = "",
|
|
776
777
|
key_field: str = None,
|
|
778
|
+
attributes: dict[str, object] = None,
|
|
777
779
|
time_field: str = None,
|
|
778
780
|
schedule: str = None,
|
|
779
781
|
start_time=None,
|
|
@@ -783,21 +785,34 @@ class SnowflakeSource(BaseSourceDriver):
|
|
|
783
785
|
user: str = None,
|
|
784
786
|
database: str = None,
|
|
785
787
|
schema: str = None,
|
|
788
|
+
db_schema: str = None,
|
|
786
789
|
warehouse: str = None,
|
|
787
790
|
**kwargs,
|
|
788
791
|
):
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
792
|
+
# TODO: Remove in 1.9.0
|
|
793
|
+
if schema:
|
|
794
|
+
warnings.warn(
|
|
795
|
+
"schema is deprecated in 1.7.0, and will be removed in 1.9.0, please use db_schema"
|
|
796
|
+
)
|
|
797
|
+
db_schema = db_schema or schema # TODO: Remove in 1.9.0
|
|
798
|
+
|
|
799
|
+
attributes = attributes or {}
|
|
800
|
+
if url:
|
|
801
|
+
attributes["url"] = url
|
|
802
|
+
if user:
|
|
803
|
+
attributes["user"] = user
|
|
804
|
+
if database:
|
|
805
|
+
attributes["database"] = database
|
|
806
|
+
if db_schema:
|
|
807
|
+
attributes["db_schema"] = db_schema
|
|
808
|
+
if warehouse:
|
|
809
|
+
attributes["warehouse"] = warehouse
|
|
810
|
+
if query:
|
|
811
|
+
attributes["query"] = query
|
|
797
812
|
|
|
798
813
|
super().__init__(
|
|
799
814
|
name,
|
|
800
|
-
attributes=
|
|
815
|
+
attributes=attributes,
|
|
801
816
|
key_field=key_field,
|
|
802
817
|
time_field=time_field,
|
|
803
818
|
schedule=schedule,
|