mlrun 1.8.0rc1__py3-none-any.whl → 1.8.0rc2__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 +5 -7
- mlrun/__main__.py +1 -1
- mlrun/common/formatters/project.py +9 -0
- mlrun/common/schemas/__init__.py +3 -0
- mlrun/common/schemas/alert.py +31 -18
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +7 -7
- mlrun/common/schemas/auth.py +6 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +2 -2
- mlrun/common/schemas/clusterization_spec.py +2 -2
- mlrun/common/schemas/common.py +5 -5
- mlrun/common/schemas/datastore_profile.py +1 -1
- mlrun/common/schemas/feature_store.py +9 -9
- mlrun/common/schemas/frontend_spec.py +4 -4
- mlrun/common/schemas/function.py +10 -10
- mlrun/common/schemas/hub.py +1 -1
- mlrun/common/schemas/k8s.py +3 -3
- mlrun/common/schemas/memory_reports.py +3 -3
- mlrun/common/schemas/model_monitoring/grafana.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoints.py +1 -1
- mlrun/common/schemas/notification.py +18 -3
- mlrun/common/schemas/object.py +1 -1
- mlrun/common/schemas/pagination.py +4 -4
- mlrun/common/schemas/partition.py +16 -1
- mlrun/common/schemas/pipeline.py +2 -2
- mlrun/common/schemas/project.py +22 -17
- mlrun/common/schemas/runs.py +2 -2
- mlrun/common/schemas/runtime_resource.py +5 -5
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/schemas/secret.py +1 -1
- mlrun/common/schemas/tag.py +3 -3
- mlrun/common/schemas/workflow.py +5 -5
- mlrun/config.py +22 -0
- mlrun/datastore/datastore_profile.py +19 -19
- mlrun/db/base.py +48 -6
- mlrun/db/httpdb.py +221 -9
- mlrun/db/nopdb.py +34 -5
- mlrun/model.py +2 -2
- mlrun/model_monitoring/applications/results.py +2 -2
- mlrun/model_monitoring/db/tsdb/base.py +2 -2
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +37 -13
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +32 -40
- mlrun/model_monitoring/helpers.py +4 -10
- mlrun/model_monitoring/stream_processing.py +14 -11
- mlrun/platforms/__init__.py +0 -13
- mlrun/projects/__init__.py +6 -1
- mlrun/projects/pipelines.py +184 -55
- mlrun/projects/project.py +95 -28
- mlrun/run.py +4 -1
- mlrun/runtimes/base.py +2 -1
- mlrun/runtimes/mounts.py +572 -0
- mlrun/runtimes/nuclio/function.py +1 -2
- mlrun/runtimes/pod.py +82 -18
- mlrun/runtimes/remotesparkjob.py +1 -1
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/utils/helpers.py +12 -2
- mlrun/utils/logger.py +2 -2
- mlrun/utils/notifications/notification/__init__.py +22 -19
- mlrun/utils/notifications/notification/base.py +12 -12
- mlrun/utils/notifications/notification/console.py +6 -6
- mlrun/utils/notifications/notification/git.py +6 -6
- mlrun/utils/notifications/notification/ipython.py +6 -6
- mlrun/utils/notifications/notification/mail.py +149 -0
- mlrun/utils/notifications/notification/slack.py +6 -6
- mlrun/utils/notifications/notification/webhook.py +6 -6
- mlrun/utils/notifications/notification_pusher.py +20 -12
- mlrun/utils/regex.py +2 -0
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/METADATA +190 -186
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/RECORD +76 -74
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/WHEEL +1 -1
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/LICENSE +0 -0
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
|
|
16
16
|
import typing
|
|
17
17
|
|
|
18
|
-
import pydantic
|
|
18
|
+
import pydantic.v1
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class MostCommonObjectTypesReport(pydantic.BaseModel):
|
|
21
|
+
class MostCommonObjectTypesReport(pydantic.v1.BaseModel):
|
|
22
22
|
object_types: list[tuple[str, int]]
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class ObjectTypeReport(pydantic.BaseModel):
|
|
25
|
+
class ObjectTypeReport(pydantic.v1.BaseModel):
|
|
26
26
|
object_type: str
|
|
27
27
|
sample_size: int
|
|
28
28
|
start_index: typing.Optional[int]
|
|
@@ -17,7 +17,7 @@ import json
|
|
|
17
17
|
from datetime import datetime
|
|
18
18
|
from typing import Any, NamedTuple, Optional, TypeVar
|
|
19
19
|
|
|
20
|
-
from pydantic import BaseModel, Extra, Field, constr, validator
|
|
20
|
+
from pydantic.v1 import BaseModel, Extra, Field, constr, validator
|
|
21
21
|
|
|
22
22
|
# TODO: remove the unused import below after `mlrun.datastore` and `mlrun.utils` usage is removed.
|
|
23
23
|
# At the moment `make lint` fails if this is removed.
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
import datetime
|
|
16
16
|
import enum
|
|
17
17
|
import typing
|
|
18
|
+
from typing import Optional
|
|
18
19
|
|
|
19
|
-
import pydantic
|
|
20
|
+
import pydantic.v1
|
|
20
21
|
|
|
21
22
|
import mlrun.common.types
|
|
22
23
|
|
|
@@ -45,6 +46,13 @@ class NotificationKind(mlrun.common.types.StrEnum):
|
|
|
45
46
|
slack: str = "slack"
|
|
46
47
|
"""**webhook** - The slack webhook to which to send the notification."""
|
|
47
48
|
|
|
49
|
+
mail: str = "mail"
|
|
50
|
+
"""
|
|
51
|
+
**email_addresses** - The target mails\n
|
|
52
|
+
**subject** - The subject of the mail\n
|
|
53
|
+
**body** - The body of the mail\n
|
|
54
|
+
"""
|
|
55
|
+
|
|
48
56
|
webhook: str = "webhook"
|
|
49
57
|
"""
|
|
50
58
|
**url** - The webhook url to which to send the notification.\n
|
|
@@ -86,7 +94,7 @@ class NotificationLimits(enum.Enum):
|
|
|
86
94
|
) # 900KB (k8s secret size limit is 1MB minus buffer for metadata)
|
|
87
95
|
|
|
88
96
|
|
|
89
|
-
class Notification(pydantic.BaseModel):
|
|
97
|
+
class Notification(pydantic.v1.BaseModel):
|
|
90
98
|
"""
|
|
91
99
|
Notification object schema
|
|
92
100
|
|
|
@@ -120,5 +128,12 @@ class Notification(pydantic.BaseModel):
|
|
|
120
128
|
reason: typing.Optional[str] = None
|
|
121
129
|
|
|
122
130
|
|
|
123
|
-
class SetNotificationRequest(pydantic.BaseModel):
|
|
131
|
+
class SetNotificationRequest(pydantic.v1.BaseModel):
|
|
124
132
|
notifications: list[Notification] = None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class NotificationState(pydantic.v1.BaseModel):
|
|
136
|
+
kind: str
|
|
137
|
+
err: Optional[
|
|
138
|
+
str
|
|
139
|
+
] # empty error means that the notifications were sent successfully
|
mlrun/common/schemas/object.py
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class PaginationInfo(pydantic.BaseModel):
|
|
20
|
+
class PaginationInfo(pydantic.v1.BaseModel):
|
|
21
21
|
class Config:
|
|
22
22
|
allow_population_by_field_name = True
|
|
23
23
|
|
|
24
24
|
page: typing.Optional[int]
|
|
25
|
-
page_size: typing.Optional[int] = pydantic.Field(alias="page-size")
|
|
26
|
-
page_token: typing.Optional[str] = pydantic.Field(alias="page-token")
|
|
25
|
+
page_size: typing.Optional[int] = pydantic.v1.Field(alias="page-size")
|
|
26
|
+
page_token: typing.Optional[str] = pydantic.v1.Field(alias="page-token")
|
|
@@ -30,6 +30,21 @@ class PartitionInterval(StrEnum):
|
|
|
30
30
|
def valid_intervals(cls) -> list:
|
|
31
31
|
return list(cls._value2member_map_.keys())
|
|
32
32
|
|
|
33
|
+
def as_duration(self) -> timedelta:
|
|
34
|
+
"""
|
|
35
|
+
Convert the partition interval to a duration-like timedelta.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
timedelta: A duration representing the partition interval.
|
|
39
|
+
"""
|
|
40
|
+
if self == PartitionInterval.DAY:
|
|
41
|
+
return timedelta(days=1)
|
|
42
|
+
elif self == PartitionInterval.MONTH:
|
|
43
|
+
# Approximate a month as 30 days
|
|
44
|
+
return timedelta(days=30)
|
|
45
|
+
elif self == PartitionInterval.YEARWEEK:
|
|
46
|
+
return timedelta(weeks=1)
|
|
47
|
+
|
|
33
48
|
@classmethod
|
|
34
49
|
def from_function(cls, partition_function: str):
|
|
35
50
|
"""
|
|
@@ -48,7 +63,7 @@ class PartitionInterval(StrEnum):
|
|
|
48
63
|
interval = partition_function_to_partitions_interval.get(partition_function)
|
|
49
64
|
if interval and cls.is_valid(interval):
|
|
50
65
|
return cls[interval]
|
|
51
|
-
|
|
66
|
+
raise KeyError(f"Partition function: {partition_function} isn't supported")
|
|
52
67
|
|
|
53
68
|
def get_partition_info(
|
|
54
69
|
self,
|
mlrun/common/schemas/pipeline.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
#
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
from deprecated import deprecated
|
|
19
19
|
|
|
20
20
|
import mlrun.common.types
|
|
@@ -39,7 +39,7 @@ class PipelinesPagination(str):
|
|
|
39
39
|
max_page_size = 200
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class PipelinesOutput(pydantic.BaseModel):
|
|
42
|
+
class PipelinesOutput(pydantic.v1.BaseModel):
|
|
43
43
|
# use the format query param to control what is returned
|
|
44
44
|
runs: list[typing.Union[dict, str]]
|
|
45
45
|
total_size: int
|
mlrun/common/schemas/project.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import datetime
|
|
16
16
|
import typing
|
|
17
17
|
|
|
18
|
-
import pydantic
|
|
18
|
+
import pydantic.v1
|
|
19
19
|
from deprecated import deprecated
|
|
20
20
|
|
|
21
21
|
import mlrun.common.types
|
|
@@ -40,14 +40,14 @@ class ProjectsFormat(mlrun.common.types.StrEnum):
|
|
|
40
40
|
leader = "leader"
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
class ProjectMetadata(pydantic.BaseModel):
|
|
43
|
+
class ProjectMetadata(pydantic.v1.BaseModel):
|
|
44
44
|
name: str
|
|
45
45
|
created: typing.Optional[datetime.datetime] = None
|
|
46
46
|
labels: typing.Optional[dict] = {}
|
|
47
47
|
annotations: typing.Optional[dict] = {}
|
|
48
48
|
|
|
49
49
|
class Config:
|
|
50
|
-
extra = pydantic.Extra.allow
|
|
50
|
+
extra = pydantic.v1.Extra.allow
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
class ProjectDesiredState(mlrun.common.types.StrEnum):
|
|
@@ -77,7 +77,7 @@ class ProjectStatus(ObjectStatus):
|
|
|
77
77
|
state: typing.Optional[ProjectState]
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
class ProjectSpec(pydantic.BaseModel):
|
|
80
|
+
class ProjectSpec(pydantic.v1.BaseModel):
|
|
81
81
|
description: typing.Optional[str] = None
|
|
82
82
|
owner: typing.Optional[str] = None
|
|
83
83
|
goals: typing.Optional[str] = None
|
|
@@ -97,10 +97,10 @@ class ProjectSpec(pydantic.BaseModel):
|
|
|
97
97
|
default_function_node_selector: typing.Optional[dict] = {}
|
|
98
98
|
|
|
99
99
|
class Config:
|
|
100
|
-
extra = pydantic.Extra.allow
|
|
100
|
+
extra = pydantic.v1.Extra.allow
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
class ProjectSpecOut(pydantic.BaseModel):
|
|
103
|
+
class ProjectSpecOut(pydantic.v1.BaseModel):
|
|
104
104
|
description: typing.Optional[str] = None
|
|
105
105
|
owner: typing.Optional[str] = None
|
|
106
106
|
goals: typing.Optional[str] = None
|
|
@@ -120,11 +120,11 @@ class ProjectSpecOut(pydantic.BaseModel):
|
|
|
120
120
|
default_function_node_selector: typing.Optional[dict] = {}
|
|
121
121
|
|
|
122
122
|
class Config:
|
|
123
|
-
extra = pydantic.Extra.allow
|
|
123
|
+
extra = pydantic.v1.Extra.allow
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
class Project(pydantic.BaseModel):
|
|
127
|
-
kind: ObjectKind = pydantic.Field(ObjectKind.project, const=True)
|
|
126
|
+
class Project(pydantic.v1.BaseModel):
|
|
127
|
+
kind: ObjectKind = pydantic.v1.Field(ObjectKind.project, const=True)
|
|
128
128
|
metadata: ProjectMetadata
|
|
129
129
|
spec: ProjectSpec = ProjectSpec()
|
|
130
130
|
status: ObjectStatus = ObjectStatus()
|
|
@@ -132,19 +132,19 @@ class Project(pydantic.BaseModel):
|
|
|
132
132
|
|
|
133
133
|
# The reason we have a different schema for the response model is that we don't want to validate project.spec.build in
|
|
134
134
|
# the response as the validation was added late and there may be corrupted values in the DB.
|
|
135
|
-
class ProjectOut(pydantic.BaseModel):
|
|
136
|
-
kind: ObjectKind = pydantic.Field(ObjectKind.project, const=True)
|
|
135
|
+
class ProjectOut(pydantic.v1.BaseModel):
|
|
136
|
+
kind: ObjectKind = pydantic.v1.Field(ObjectKind.project, const=True)
|
|
137
137
|
metadata: ProjectMetadata
|
|
138
138
|
spec: ProjectSpecOut = ProjectSpecOut()
|
|
139
139
|
status: ObjectStatus = ObjectStatus()
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
class ProjectOwner(pydantic.BaseModel):
|
|
142
|
+
class ProjectOwner(pydantic.v1.BaseModel):
|
|
143
143
|
username: str
|
|
144
144
|
access_key: str
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
class ProjectSummary(pydantic.BaseModel):
|
|
147
|
+
class ProjectSummary(pydantic.v1.BaseModel):
|
|
148
148
|
name: str
|
|
149
149
|
files_count: int = 0
|
|
150
150
|
feature_sets_count: int = 0
|
|
@@ -161,7 +161,7 @@ class ProjectSummary(pydantic.BaseModel):
|
|
|
161
161
|
updated: typing.Optional[datetime.datetime] = None
|
|
162
162
|
|
|
163
163
|
|
|
164
|
-
class IguazioProject(pydantic.BaseModel):
|
|
164
|
+
class IguazioProject(pydantic.v1.BaseModel):
|
|
165
165
|
data: dict
|
|
166
166
|
|
|
167
167
|
|
|
@@ -175,13 +175,18 @@ class IguazioProject(pydantic.BaseModel):
|
|
|
175
175
|
# to add a specific classes for them. it's frustrating but couldn't find other workaround, see:
|
|
176
176
|
# https://github.com/samuelcolvin/pydantic/issues/1423, https://github.com/samuelcolvin/pydantic/issues/619
|
|
177
177
|
ProjectOutput = typing.TypeVar(
|
|
178
|
-
"ProjectOutput",
|
|
178
|
+
"ProjectOutput",
|
|
179
|
+
ProjectOut,
|
|
180
|
+
str,
|
|
181
|
+
ProjectSummary,
|
|
182
|
+
IguazioProject,
|
|
183
|
+
tuple[str, datetime.datetime],
|
|
179
184
|
)
|
|
180
185
|
|
|
181
186
|
|
|
182
|
-
class ProjectsOutput(pydantic.BaseModel):
|
|
187
|
+
class ProjectsOutput(pydantic.v1.BaseModel):
|
|
183
188
|
projects: list[ProjectOutput]
|
|
184
189
|
|
|
185
190
|
|
|
186
|
-
class ProjectSummariesOutput(pydantic.BaseModel):
|
|
191
|
+
class ProjectSummariesOutput(pydantic.v1.BaseModel):
|
|
187
192
|
project_summaries: list[ProjectSummary]
|
mlrun/common/schemas/runs.py
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
from deprecated import deprecated
|
|
19
19
|
|
|
20
20
|
import mlrun.common.types
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class RunIdentifier(pydantic.BaseModel):
|
|
23
|
+
class RunIdentifier(pydantic.v1.BaseModel):
|
|
24
24
|
kind: typing.Literal["run"] = "run"
|
|
25
25
|
uid: typing.Optional[str]
|
|
26
26
|
iter: typing.Optional[int]
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
#
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
import mlrun.common.types
|
|
20
20
|
|
|
@@ -24,23 +24,23 @@ class ListRuntimeResourcesGroupByField(mlrun.common.types.StrEnum):
|
|
|
24
24
|
project = "project"
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class RuntimeResource(pydantic.BaseModel):
|
|
27
|
+
class RuntimeResource(pydantic.v1.BaseModel):
|
|
28
28
|
name: str
|
|
29
29
|
labels: dict[str, str] = {}
|
|
30
30
|
status: typing.Optional[dict]
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
class RuntimeResources(pydantic.BaseModel):
|
|
33
|
+
class RuntimeResources(pydantic.v1.BaseModel):
|
|
34
34
|
crd_resources: list[RuntimeResource] = []
|
|
35
35
|
pod_resources: list[RuntimeResource] = []
|
|
36
36
|
# only for dask runtime
|
|
37
37
|
service_resources: typing.Optional[list[RuntimeResource]] = None
|
|
38
38
|
|
|
39
39
|
class Config:
|
|
40
|
-
extra = pydantic.Extra.allow
|
|
40
|
+
extra = pydantic.v1.Extra.allow
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
class KindRuntimeResources(pydantic.BaseModel):
|
|
43
|
+
class KindRuntimeResources(pydantic.v1.BaseModel):
|
|
44
44
|
kind: str
|
|
45
45
|
resources: RuntimeResources
|
|
46
46
|
|
mlrun/common/schemas/schedule.py
CHANGED
mlrun/common/schemas/secret.py
CHANGED
mlrun/common/schemas/tag.py
CHANGED
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
15
|
|
|
16
|
-
import pydantic
|
|
16
|
+
import pydantic.v1
|
|
17
17
|
|
|
18
18
|
from .artifact import ArtifactIdentifier
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class Tag(pydantic.BaseModel):
|
|
21
|
+
class Tag(pydantic.v1.BaseModel):
|
|
22
22
|
name: str
|
|
23
23
|
project: str
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class TagObjects(pydantic.BaseModel):
|
|
26
|
+
class TagObjects(pydantic.v1.BaseModel):
|
|
27
27
|
"""Tag object"""
|
|
28
28
|
|
|
29
29
|
kind: str
|
mlrun/common/schemas/workflow.py
CHANGED
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
#
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
from mlrun.common.schemas.notification import Notification
|
|
20
20
|
from mlrun.common.schemas.schedule import ScheduleCronTrigger
|
|
21
21
|
from mlrun.common.types import StrEnum
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class WorkflowSpec(pydantic.BaseModel):
|
|
24
|
+
class WorkflowSpec(pydantic.v1.BaseModel):
|
|
25
25
|
name: str
|
|
26
26
|
engine: typing.Optional[str] = None
|
|
27
27
|
code: typing.Optional[str] = None
|
|
@@ -36,7 +36,7 @@ class WorkflowSpec(pydantic.BaseModel):
|
|
|
36
36
|
workflow_runner_node_selector: typing.Optional[dict[str, str]] = None
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
class WorkflowRequest(pydantic.BaseModel):
|
|
39
|
+
class WorkflowRequest(pydantic.v1.BaseModel):
|
|
40
40
|
spec: typing.Optional[WorkflowSpec] = None
|
|
41
41
|
arguments: typing.Optional[dict] = None
|
|
42
42
|
artifact_path: typing.Optional[str] = None
|
|
@@ -46,7 +46,7 @@ class WorkflowRequest(pydantic.BaseModel):
|
|
|
46
46
|
notifications: typing.Optional[list[Notification]] = None
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
class WorkflowResponse(pydantic.BaseModel):
|
|
49
|
+
class WorkflowResponse(pydantic.v1.BaseModel):
|
|
50
50
|
project: str = None
|
|
51
51
|
name: str = None
|
|
52
52
|
status: str = None
|
|
@@ -54,7 +54,7 @@ class WorkflowResponse(pydantic.BaseModel):
|
|
|
54
54
|
schedule: typing.Union[str, ScheduleCronTrigger] = None
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class GetWorkflowResponse(pydantic.BaseModel):
|
|
57
|
+
class GetWorkflowResponse(pydantic.v1.BaseModel):
|
|
58
58
|
workflow_id: str = None
|
|
59
59
|
|
|
60
60
|
|
mlrun/config.py
CHANGED
|
@@ -138,6 +138,9 @@ default_config = {
|
|
|
138
138
|
"object_retentions": {
|
|
139
139
|
"alert_activation": 14 * 7, # days
|
|
140
140
|
},
|
|
141
|
+
# A safety margin to account for delays
|
|
142
|
+
# This ensures that extra partitions are available beyond the specified retention period
|
|
143
|
+
"partitions_buffer_multiplier": 3,
|
|
141
144
|
# the grace period (in seconds) that will be given to runtime resources (after they're in terminal state)
|
|
142
145
|
# before deleting them (4 hours)
|
|
143
146
|
"runtime_resources_deletion_grace_period": "14400",
|
|
@@ -798,11 +801,30 @@ default_config = {
|
|
|
798
801
|
"max_allowed": 10000,
|
|
799
802
|
# maximum allowed value for count in criteria field inside AlertConfig
|
|
800
803
|
"max_criteria_count": 100,
|
|
804
|
+
# interval for periodic events generation job
|
|
805
|
+
"events_generation_interval": "30",
|
|
801
806
|
},
|
|
802
807
|
"auth_with_client_id": {
|
|
803
808
|
"enabled": False,
|
|
804
809
|
"request_timeout": 5,
|
|
805
810
|
},
|
|
811
|
+
"services": {
|
|
812
|
+
# The running service name. One of: "api", "alerts"
|
|
813
|
+
"service_name": "api",
|
|
814
|
+
"hydra": {
|
|
815
|
+
# Comma separated list of services to run on the instance.
|
|
816
|
+
# Currently, this is only considered when the service_name is "api".
|
|
817
|
+
# "*" starts all services on the same instance,
|
|
818
|
+
# other options are considered as running only the api service.
|
|
819
|
+
"services": "*",
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
"notifications": {
|
|
823
|
+
"smtp": {
|
|
824
|
+
"config_secret_name": "mlrun-smtp-config",
|
|
825
|
+
"refresh_interval": "30",
|
|
826
|
+
}
|
|
827
|
+
},
|
|
806
828
|
}
|
|
807
829
|
_is_running_as_api = None
|
|
808
830
|
|
|
@@ -19,7 +19,7 @@ import typing
|
|
|
19
19
|
import warnings
|
|
20
20
|
from urllib.parse import ParseResult, urlparse, urlunparse
|
|
21
21
|
|
|
22
|
-
import pydantic
|
|
22
|
+
import pydantic.v1
|
|
23
23
|
from mergedeep import merge
|
|
24
24
|
|
|
25
25
|
import mlrun
|
|
@@ -28,15 +28,15 @@ import mlrun.errors
|
|
|
28
28
|
from ..secrets import get_secret_or_env
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
class DatastoreProfile(pydantic.BaseModel):
|
|
31
|
+
class DatastoreProfile(pydantic.v1.BaseModel):
|
|
32
32
|
type: str
|
|
33
33
|
name: str
|
|
34
34
|
_private_attributes: list = ()
|
|
35
35
|
|
|
36
36
|
class Config:
|
|
37
|
-
extra = pydantic.Extra.forbid
|
|
37
|
+
extra = pydantic.v1.Extra.forbid
|
|
38
38
|
|
|
39
|
-
@pydantic.validator("name")
|
|
39
|
+
@pydantic.v1.validator("name")
|
|
40
40
|
@classmethod
|
|
41
41
|
def lower_case(cls, v):
|
|
42
42
|
return v.lower()
|
|
@@ -75,14 +75,14 @@ class TemporaryClientDatastoreProfiles(metaclass=mlrun.utils.singleton.Singleton
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
class DatastoreProfileBasic(DatastoreProfile):
|
|
78
|
-
type: str = pydantic.Field("basic")
|
|
78
|
+
type: str = pydantic.v1.Field("basic")
|
|
79
79
|
_private_attributes = "private"
|
|
80
80
|
public: str
|
|
81
81
|
private: typing.Optional[str] = None
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
class DatastoreProfileKafkaTarget(DatastoreProfile):
|
|
85
|
-
type: str = pydantic.Field("kafka_target")
|
|
85
|
+
type: str = pydantic.v1.Field("kafka_target")
|
|
86
86
|
_private_attributes = "kwargs_private"
|
|
87
87
|
bootstrap_servers: typing.Optional[str] = None
|
|
88
88
|
brokers: typing.Optional[str] = None
|
|
@@ -123,7 +123,7 @@ class DatastoreProfileKafkaTarget(DatastoreProfile):
|
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
class DatastoreProfileKafkaSource(DatastoreProfile):
|
|
126
|
-
type: str = pydantic.Field("kafka_source")
|
|
126
|
+
type: str = pydantic.v1.Field("kafka_source")
|
|
127
127
|
_private_attributes = ("kwargs_private", "sasl_user", "sasl_pass")
|
|
128
128
|
brokers: typing.Union[str, list[str]]
|
|
129
129
|
topics: typing.Union[str, list[str]]
|
|
@@ -162,7 +162,7 @@ class DatastoreProfileKafkaSource(DatastoreProfile):
|
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
class DatastoreProfileV3io(DatastoreProfile):
|
|
165
|
-
type: str = pydantic.Field("v3io")
|
|
165
|
+
type: str = pydantic.v1.Field("v3io")
|
|
166
166
|
v3io_access_key: typing.Optional[str] = None
|
|
167
167
|
_private_attributes = "v3io_access_key"
|
|
168
168
|
|
|
@@ -178,7 +178,7 @@ class DatastoreProfileV3io(DatastoreProfile):
|
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
class DatastoreProfileS3(DatastoreProfile):
|
|
181
|
-
type: str = pydantic.Field("s3")
|
|
181
|
+
type: str = pydantic.v1.Field("s3")
|
|
182
182
|
_private_attributes = ("access_key_id", "secret_key")
|
|
183
183
|
endpoint_url: typing.Optional[str] = None
|
|
184
184
|
force_non_anonymous: typing.Optional[str] = None
|
|
@@ -188,7 +188,7 @@ class DatastoreProfileS3(DatastoreProfile):
|
|
|
188
188
|
secret_key: typing.Optional[str] = None
|
|
189
189
|
bucket: typing.Optional[str] = None
|
|
190
190
|
|
|
191
|
-
@pydantic.validator("bucket")
|
|
191
|
+
@pydantic.v1.validator("bucket")
|
|
192
192
|
@classmethod
|
|
193
193
|
def check_bucket(cls, v):
|
|
194
194
|
if not v:
|
|
@@ -226,7 +226,7 @@ class DatastoreProfileS3(DatastoreProfile):
|
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
class DatastoreProfileRedis(DatastoreProfile):
|
|
229
|
-
type: str = pydantic.Field("redis")
|
|
229
|
+
type: str = pydantic.v1.Field("redis")
|
|
230
230
|
_private_attributes = ("username", "password")
|
|
231
231
|
endpoint_url: str
|
|
232
232
|
username: typing.Optional[str] = None
|
|
@@ -269,7 +269,7 @@ class DatastoreProfileRedis(DatastoreProfile):
|
|
|
269
269
|
|
|
270
270
|
|
|
271
271
|
class DatastoreProfileDBFS(DatastoreProfile):
|
|
272
|
-
type: str = pydantic.Field("dbfs")
|
|
272
|
+
type: str = pydantic.v1.Field("dbfs")
|
|
273
273
|
_private_attributes = ("token",)
|
|
274
274
|
endpoint_url: typing.Optional[str] = None # host
|
|
275
275
|
token: typing.Optional[str] = None
|
|
@@ -287,13 +287,13 @@ class DatastoreProfileDBFS(DatastoreProfile):
|
|
|
287
287
|
|
|
288
288
|
|
|
289
289
|
class DatastoreProfileGCS(DatastoreProfile):
|
|
290
|
-
type: str = pydantic.Field("gcs")
|
|
290
|
+
type: str = pydantic.v1.Field("gcs")
|
|
291
291
|
_private_attributes = ("gcp_credentials",)
|
|
292
292
|
credentials_path: typing.Optional[str] = None # path to file.
|
|
293
293
|
gcp_credentials: typing.Optional[typing.Union[str, dict]] = None
|
|
294
294
|
bucket: typing.Optional[str] = None
|
|
295
295
|
|
|
296
|
-
@pydantic.validator("bucket")
|
|
296
|
+
@pydantic.v1.validator("bucket")
|
|
297
297
|
@classmethod
|
|
298
298
|
def check_bucket(cls, v):
|
|
299
299
|
if not v:
|
|
@@ -304,7 +304,7 @@ class DatastoreProfileGCS(DatastoreProfile):
|
|
|
304
304
|
)
|
|
305
305
|
return v
|
|
306
306
|
|
|
307
|
-
@pydantic.validator("gcp_credentials", pre=True, always=True)
|
|
307
|
+
@pydantic.v1.validator("gcp_credentials", pre=True, always=True)
|
|
308
308
|
@classmethod
|
|
309
309
|
def convert_dict_to_json(cls, v):
|
|
310
310
|
if isinstance(v, dict):
|
|
@@ -332,7 +332,7 @@ class DatastoreProfileGCS(DatastoreProfile):
|
|
|
332
332
|
|
|
333
333
|
|
|
334
334
|
class DatastoreProfileAzureBlob(DatastoreProfile):
|
|
335
|
-
type: str = pydantic.Field("az")
|
|
335
|
+
type: str = pydantic.v1.Field("az")
|
|
336
336
|
_private_attributes = (
|
|
337
337
|
"connection_string",
|
|
338
338
|
"account_key",
|
|
@@ -350,7 +350,7 @@ class DatastoreProfileAzureBlob(DatastoreProfile):
|
|
|
350
350
|
credential: typing.Optional[str] = None
|
|
351
351
|
container: typing.Optional[str] = None
|
|
352
352
|
|
|
353
|
-
@pydantic.validator("container")
|
|
353
|
+
@pydantic.v1.validator("container")
|
|
354
354
|
@classmethod
|
|
355
355
|
def check_container(cls, v):
|
|
356
356
|
if not v:
|
|
@@ -392,7 +392,7 @@ class DatastoreProfileAzureBlob(DatastoreProfile):
|
|
|
392
392
|
|
|
393
393
|
|
|
394
394
|
class DatastoreProfileHdfs(DatastoreProfile):
|
|
395
|
-
type: str = pydantic.Field("hdfs")
|
|
395
|
+
type: str = pydantic.v1.Field("hdfs")
|
|
396
396
|
_private_attributes = "token"
|
|
397
397
|
host: typing.Optional[str] = None
|
|
398
398
|
port: typing.Optional[int] = None
|
|
@@ -415,7 +415,7 @@ class DatastoreProfileHdfs(DatastoreProfile):
|
|
|
415
415
|
return f"webhdfs://{self.host}:{self.http_port}{subpath}"
|
|
416
416
|
|
|
417
417
|
|
|
418
|
-
class DatastoreProfile2Json(pydantic.BaseModel):
|
|
418
|
+
class DatastoreProfile2Json(pydantic.v1.BaseModel):
|
|
419
419
|
@staticmethod
|
|
420
420
|
def _to_json(attributes):
|
|
421
421
|
# First, base64 encode the values
|