wandb 0.19.9__py3-none-musllinux_1_2_aarch64.whl → 0.19.11__py3-none-musllinux_1_2_aarch64.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.
- wandb/__init__.py +1 -1
- wandb/__init__.pyi +6 -3
- wandb/_pydantic/__init__.py +14 -8
- wandb/_pydantic/base.py +51 -36
- wandb/_pydantic/utils.py +73 -0
- wandb/_pydantic/v1_compat.py +79 -57
- wandb/apis/public/__init__.py +2 -2
- wandb/apis/public/api.py +684 -4
- wandb/apis/public/artifacts.py +377 -677
- wandb/apis/public/automations.py +69 -0
- wandb/apis/public/integrations.py +180 -0
- wandb/apis/public/projects.py +29 -0
- wandb/apis/public/registries/__init__.py +0 -0
- wandb/apis/public/registries/_freezable_list.py +179 -0
- wandb/apis/public/{registries.py → registries/registries_search.py} +22 -129
- wandb/apis/public/registries/registry.py +357 -0
- wandb/apis/public/registries/utils.py +140 -0
- wandb/apis/public/runs.py +58 -56
- wandb/apis/public/utils.py +107 -1
- wandb/automations/__init__.py +73 -0
- wandb/automations/_filters/__init__.py +40 -0
- wandb/automations/_filters/expressions.py +181 -0
- wandb/automations/_filters/operators.py +258 -0
- wandb/automations/_filters/run_metrics.py +332 -0
- wandb/automations/_generated/__init__.py +177 -0
- wandb/automations/_generated/create_automation.py +17 -0
- wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
- wandb/automations/_generated/delete_automation.py +17 -0
- wandb/automations/_generated/enums.py +33 -0
- wandb/automations/_generated/fragments.py +358 -0
- wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
- wandb/automations/_generated/get_automations.py +24 -0
- wandb/automations/_generated/get_automations_by_entity.py +26 -0
- wandb/automations/_generated/input_types.py +104 -0
- wandb/automations/_generated/integrations_by_entity.py +22 -0
- wandb/automations/_generated/operations.py +647 -0
- wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
- wandb/automations/_generated/update_automation.py +17 -0
- wandb/automations/_utils.py +237 -0
- wandb/automations/_validators.py +165 -0
- wandb/automations/actions.py +220 -0
- wandb/automations/automations.py +87 -0
- wandb/automations/events.py +287 -0
- wandb/automations/integrations.py +45 -0
- wandb/automations/scopes.py +78 -0
- wandb/beta/workflows.py +9 -10
- wandb/bin/gpu_stats +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +3 -3
- wandb/env.py +11 -0
- wandb/integration/keras/keras.py +2 -1
- wandb/integration/langchain/wandb_tracer.py +2 -1
- wandb/jupyter.py +137 -118
- wandb/old/settings.py +4 -1
- wandb/old/summary.py +0 -2
- wandb/proto/v3/wandb_internal_pb2.py +297 -292
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v4/wandb_internal_pb2.py +292 -292
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_internal_pb2.py +292 -292
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v6/wandb_base_pb2.py +41 -0
- wandb/proto/v6/wandb_internal_pb2.py +393 -0
- wandb/proto/v6/wandb_server_pb2.py +78 -0
- wandb/proto/v6/wandb_settings_pb2.py +58 -0
- wandb/proto/v6/wandb_telemetry_pb2.py +52 -0
- wandb/proto/wandb_base_pb2.py +2 -0
- wandb/proto/wandb_deprecated.py +8 -0
- wandb/proto/wandb_internal_pb2.py +3 -1
- wandb/proto/wandb_server_pb2.py +2 -0
- wandb/proto/wandb_settings_pb2.py +2 -0
- wandb/proto/wandb_telemetry_pb2.py +2 -0
- wandb/sdk/artifacts/_generated/__init__.py +289 -0
- wandb/sdk/artifacts/_generated/add_aliases.py +21 -0
- wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_version_files.py +36 -0
- wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +36 -0
- wandb/sdk/artifacts/_generated/delete_aliases.py +21 -0
- wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +25 -0
- wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_generated/enums.py +17 -0
- wandb/sdk/artifacts/_generated/fetch_linked_artifacts.py +67 -0
- wandb/sdk/artifacts/_generated/fragments.py +221 -0
- wandb/sdk/artifacts/_generated/input_types.py +28 -0
- wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
- wandb/sdk/artifacts/_generated/operations.py +611 -0
- wandb/sdk/artifacts/_generated/project_artifact_collection.py +101 -0
- wandb/sdk/artifacts/_generated/project_artifact_collections.py +33 -0
- wandb/sdk/artifacts/_generated/project_artifact_type.py +24 -0
- wandb/sdk/artifacts/_generated/project_artifact_types.py +24 -0
- wandb/sdk/artifacts/_generated/project_artifacts.py +42 -0
- wandb/sdk/artifacts/_generated/run_input_artifacts.py +51 -0
- wandb/sdk/artifacts/_generated/run_output_artifacts.py +51 -0
- wandb/sdk/artifacts/_generated/update_artifact.py +26 -0
- wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_graphql_fragments.py +57 -79
- wandb/sdk/artifacts/_validators.py +120 -1
- wandb/sdk/artifacts/artifact.py +419 -215
- wandb/sdk/artifacts/artifact_file_cache.py +4 -6
- wandb/sdk/artifacts/artifact_manifest_entry.py +13 -3
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +182 -1
- wandb/sdk/artifacts/storage_policy.py +3 -0
- wandb/sdk/data_types/base_types/media.py +2 -3
- wandb/sdk/data_types/base_types/wb_value.py +34 -11
- wandb/sdk/data_types/html.py +36 -9
- wandb/sdk/data_types/image.py +12 -12
- wandb/sdk/data_types/table.py +5 -0
- wandb/sdk/data_types/trace_tree.py +2 -0
- wandb/sdk/data_types/utils.py +1 -1
- wandb/sdk/data_types/video.py +59 -57
- wandb/sdk/interface/interface.py +4 -3
- wandb/sdk/internal/internal_api.py +21 -31
- wandb/sdk/internal/profiler.py +6 -5
- wandb/sdk/internal/run.py +13 -6
- wandb/sdk/internal/sender.py +5 -2
- wandb/sdk/launch/sweeps/utils.py +8 -0
- wandb/sdk/lib/apikey.py +25 -4
- wandb/sdk/lib/asyncio_compat.py +1 -1
- wandb/sdk/lib/deprecate.py +13 -22
- wandb/sdk/lib/disabled.py +2 -1
- wandb/sdk/lib/printer.py +37 -8
- wandb/sdk/lib/printer_asyncio.py +46 -0
- wandb/sdk/lib/redirect.py +10 -5
- wandb/sdk/projects/_generated/__init__.py +47 -0
- wandb/sdk/projects/_generated/delete_project.py +22 -0
- wandb/sdk/projects/_generated/enums.py +4 -0
- wandb/sdk/projects/_generated/fetch_registry.py +22 -0
- wandb/sdk/projects/_generated/fragments.py +41 -0
- wandb/sdk/projects/_generated/input_types.py +13 -0
- wandb/sdk/projects/_generated/operations.py +88 -0
- wandb/sdk/projects/_generated/rename_project.py +27 -0
- wandb/sdk/projects/_generated/upsert_registry_project.py +27 -0
- wandb/sdk/service/server_sock.py +19 -14
- wandb/sdk/service/service.py +18 -8
- wandb/sdk/service/streams.py +5 -0
- wandb/sdk/verify/verify.py +6 -3
- wandb/sdk/wandb_init.py +217 -70
- wandb/sdk/wandb_login.py +13 -4
- wandb/sdk/wandb_run.py +419 -295
- wandb/sdk/wandb_settings.py +27 -10
- wandb/sdk/wandb_setup.py +61 -0
- wandb/util.py +33 -29
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/METADATA +5 -5
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/RECORD +153 -83
- wandb/_globals.py +0 -19
- wandb/sdk/internal/_generated/base.py +0 -226
- wandb/sdk/internal/_generated/typing_compat.py +0 -14
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/WHEEL +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,332 @@
|
|
1
|
+
# ruff: noqa: UP007
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from abc import ABC, abstractmethod
|
6
|
+
from typing import TYPE_CHECKING, Any, Final, Literal, Optional, Union, overload
|
7
|
+
|
8
|
+
from pydantic import (
|
9
|
+
Field,
|
10
|
+
PositiveFloat,
|
11
|
+
PositiveInt,
|
12
|
+
StrictFloat,
|
13
|
+
StrictInt,
|
14
|
+
field_validator,
|
15
|
+
)
|
16
|
+
from typing_extensions import Annotated, TypeAlias, override
|
17
|
+
|
18
|
+
from wandb._pydantic import GQLBase
|
19
|
+
from wandb.automations._validators import LenientStrEnum
|
20
|
+
|
21
|
+
from .expressions import FilterExpr
|
22
|
+
from .operators import BaseOp, RichReprResult
|
23
|
+
|
24
|
+
if TYPE_CHECKING:
|
25
|
+
from wandb.automations.events import RunMetricFilter
|
26
|
+
|
27
|
+
# Maps MongoDB comparison operators -> Python literal (str) representations
|
28
|
+
MONGO2PY_OPS: Final[dict[str, str]] = {
|
29
|
+
"$eq": "==",
|
30
|
+
"$ne": "!=",
|
31
|
+
"$gt": ">",
|
32
|
+
"$lt": "<",
|
33
|
+
"$gte": ">=",
|
34
|
+
"$lte": "<=",
|
35
|
+
}
|
36
|
+
# Reverse mapping from Python literal (str) -> MongoDB operator key
|
37
|
+
PY2MONGO_OPS: Final[dict[str, str]] = {v: k for k, v in MONGO2PY_OPS.items()}
|
38
|
+
|
39
|
+
# Type hint for positive numbers (int or float)
|
40
|
+
PosNum: TypeAlias = Union[PositiveInt, PositiveFloat]
|
41
|
+
|
42
|
+
|
43
|
+
class Agg(LenientStrEnum): # from: Aggregation
|
44
|
+
"""Supported run metric aggregation operations."""
|
45
|
+
|
46
|
+
MAX = "MAX"
|
47
|
+
MIN = "MIN"
|
48
|
+
AVERAGE = "AVERAGE"
|
49
|
+
|
50
|
+
# Shorter aliases for convenience
|
51
|
+
AVG = AVERAGE
|
52
|
+
|
53
|
+
|
54
|
+
class ChangeType(LenientStrEnum): # from: RunMetricChangeType
|
55
|
+
"""Describes the metric change as absolute (arithmetic difference) or relative (decimal percentage)."""
|
56
|
+
|
57
|
+
ABSOLUTE = "ABSOLUTE"
|
58
|
+
RELATIVE = "RELATIVE"
|
59
|
+
|
60
|
+
# Shorter aliases for convenience
|
61
|
+
ABS = ABSOLUTE
|
62
|
+
REL = RELATIVE
|
63
|
+
|
64
|
+
|
65
|
+
class ChangeDir(LenientStrEnum): # from: RunMetricChangeDirection
|
66
|
+
"""Describes the direction of the metric change."""
|
67
|
+
|
68
|
+
INCREASE = "INCREASE"
|
69
|
+
DECREASE = "DECREASE"
|
70
|
+
ANY = "ANY"
|
71
|
+
|
72
|
+
# Shorter aliases for convenience
|
73
|
+
INC = INCREASE
|
74
|
+
DEC = DECREASE
|
75
|
+
|
76
|
+
|
77
|
+
class BaseMetricFilter(GQLBase, ABC, extra="forbid"):
|
78
|
+
name: str
|
79
|
+
"""Name of the observed metric."""
|
80
|
+
|
81
|
+
agg: Optional[Agg]
|
82
|
+
"""Aggregate operation, if any, to apply over the window size."""
|
83
|
+
|
84
|
+
window: PositiveInt
|
85
|
+
"""Size of the window over which the metric is aggregated (ignored if `agg is None`)."""
|
86
|
+
|
87
|
+
# ------------------------------------------------------------------------------
|
88
|
+
cmp: Optional[str]
|
89
|
+
"""Comparison between the metric expression (left) vs. the threshold or target value (right)."""
|
90
|
+
|
91
|
+
# ------------------------------------------------------------------------------
|
92
|
+
threshold: Union[StrictInt, StrictFloat]
|
93
|
+
"""Threshold value to compare against."""
|
94
|
+
|
95
|
+
def __and__(self, other: Any) -> RunMetricFilter:
|
96
|
+
"""Implements `(metric_filter & run_filter) -> RunMetricFilter`."""
|
97
|
+
from wandb.automations.events import RunMetricFilter
|
98
|
+
|
99
|
+
if isinstance(run_filter := other, (BaseOp, FilterExpr)):
|
100
|
+
# Assume `other` is a run filter, and we are building a RunMetricEvent.
|
101
|
+
# For the metric filter, delegate to the inner validator(s) to further wrap/nest as appropriate.
|
102
|
+
return RunMetricFilter(run=run_filter, metric=self)
|
103
|
+
return NotImplemented
|
104
|
+
|
105
|
+
def __rand__(self, other: BaseOp | FilterExpr) -> RunMetricFilter:
|
106
|
+
"""Ensures `&` is commutative: `(run_filter & metric_filter) == (metric_filter & run_filter)`."""
|
107
|
+
return self.__and__(other)
|
108
|
+
|
109
|
+
@abstractmethod
|
110
|
+
def __repr__(self) -> str:
|
111
|
+
"""The text representation of the metric filter."""
|
112
|
+
raise NotImplementedError
|
113
|
+
|
114
|
+
@override
|
115
|
+
def __rich_repr__(self) -> RichReprResult: # type: ignore[override]
|
116
|
+
"""The representation of the metric filter when using `rich` for pretty-printing."""
|
117
|
+
# See: https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol
|
118
|
+
yield None, repr(self)
|
119
|
+
|
120
|
+
|
121
|
+
class MetricThresholdFilter(BaseMetricFilter): # from: RunMetricThresholdFilter
|
122
|
+
"""Defines a filter that compares a run metric against a user-defined threshold value."""
|
123
|
+
|
124
|
+
name: str
|
125
|
+
agg: Annotated[Optional[Agg], Field(alias="agg_op")] = None
|
126
|
+
window: Annotated[PositiveInt, Field(alias="window_size")] = 1
|
127
|
+
|
128
|
+
cmp: Annotated[Literal["$gte", "$gt", "$lt", "$lte"], Field(alias="cmp_op")]
|
129
|
+
"""Comparison operator used to compare the metric value (left) vs. the threshold value (right)."""
|
130
|
+
|
131
|
+
threshold: Union[StrictInt, StrictFloat]
|
132
|
+
|
133
|
+
@field_validator("cmp", mode="before")
|
134
|
+
def _validate_cmp(cls, v: Any) -> Any:
|
135
|
+
# Be helpful: e.g. ">" -> "$gt"
|
136
|
+
return PY2MONGO_OPS.get(v.strip(), v) if isinstance(v, str) else v
|
137
|
+
|
138
|
+
def __repr__(self) -> str:
|
139
|
+
metric = f"{self.agg.value}({self.name})" if self.agg else self.name
|
140
|
+
op = MONGO2PY_OPS.get(self.cmp, self.cmp)
|
141
|
+
return repr(rf"{metric} {op} {self.threshold}")
|
142
|
+
|
143
|
+
|
144
|
+
class MetricChangeFilter(BaseMetricFilter): # from: RunMetricChangeFilter
|
145
|
+
"""Defines a filter that compares a change in a run metric against a user-defined threshold.
|
146
|
+
|
147
|
+
The change is calculated over "tumbling" windows, i.e. the difference
|
148
|
+
between the current window and the non-overlapping prior window.
|
149
|
+
"""
|
150
|
+
|
151
|
+
name: str
|
152
|
+
agg: Annotated[Optional[Agg], Field(alias="agg_op")] = None
|
153
|
+
window: Annotated[PositiveInt, Field(alias="current_window_size")] = 1
|
154
|
+
|
155
|
+
# `prior_window` is only for `RUN_METRIC_CHANGE` events
|
156
|
+
prior_window: Annotated[
|
157
|
+
PositiveInt,
|
158
|
+
# By default, set `window -> prior_window` if the latter wasn't provided.
|
159
|
+
Field(alias="prior_window_size", default_factory=lambda data: data["window"]),
|
160
|
+
]
|
161
|
+
"""Size of the prior window over which the metric is aggregated (ignored if `agg is None`).
|
162
|
+
|
163
|
+
If omitted, defaults to the size of the current window.
|
164
|
+
"""
|
165
|
+
|
166
|
+
# ------------------------------------------------------------------------------
|
167
|
+
# NOTE:
|
168
|
+
# - The "comparison" operator isn't actually part of the backend schema,
|
169
|
+
# but it's defined here for consistency -- and ignored otherwise.
|
170
|
+
# - In the backend, it's effectively "$gte" or "$lte", depending on the sign
|
171
|
+
# (change_dir), though again, this is not explicit in the schema.
|
172
|
+
cmp: Annotated[None, Field(frozen=True, exclude=True, repr=False)] = None
|
173
|
+
"""Ignored."""
|
174
|
+
|
175
|
+
# ------------------------------------------------------------------------------
|
176
|
+
change_type: Annotated[ChangeType, Field(alias="change_type")]
|
177
|
+
change_dir: Annotated[ChangeDir, Field(alias="change_dir")]
|
178
|
+
threshold: Annotated[PosNum, Field(alias="change_amount")]
|
179
|
+
|
180
|
+
def __repr__(self) -> str:
|
181
|
+
metric = f"{self.agg.value}({self.name})" if self.agg else self.name
|
182
|
+
verb = (
|
183
|
+
"changes"
|
184
|
+
if (self.change_dir is ChangeDir.ANY)
|
185
|
+
else f"{self.change_dir.value.lower()}s"
|
186
|
+
)
|
187
|
+
|
188
|
+
fmt_spec = ".2%" if (self.change_type is ChangeType.REL) else ""
|
189
|
+
amt = f"{self.threshold:{fmt_spec}}"
|
190
|
+
return repr(rf"{metric} {verb} {amt}")
|
191
|
+
|
192
|
+
|
193
|
+
class BaseMetricOperand(GQLBase, extra="forbid"):
|
194
|
+
def gt(self, value: int | float, /) -> MetricThresholdFilter:
|
195
|
+
"""Defines a `MetricThresholdFilter` that observes for `metric_expr > threshold`."""
|
196
|
+
return self > value
|
197
|
+
|
198
|
+
def lt(self, value: int | float, /) -> MetricThresholdFilter:
|
199
|
+
"""Defines a `MetricThresholdFilter` that observes for `metric_expr < threshold`."""
|
200
|
+
return self < value
|
201
|
+
|
202
|
+
def gte(self, value: int | float, /) -> MetricThresholdFilter:
|
203
|
+
"""Defines a `MetricThresholdFilter` that observes for `metric_expr >= threshold`."""
|
204
|
+
return self >= value
|
205
|
+
|
206
|
+
def lte(self, value: int | float, /) -> MetricThresholdFilter:
|
207
|
+
"""Defines a `MetricThresholdFilter` that observes for `metric_expr <= threshold`."""
|
208
|
+
return self <= value
|
209
|
+
|
210
|
+
# Overloads to implement:
|
211
|
+
# - `(metric_operand > threshold) -> MetricThresholdFilter`
|
212
|
+
# - `(metric_operand < threshold) -> MetricThresholdFilter`
|
213
|
+
# - `(metric_operand >= threshold) -> MetricThresholdFilter`
|
214
|
+
# - `(metric_operand <= threshold) -> MetricThresholdFilter`
|
215
|
+
def __gt__(self, other: Any) -> MetricThresholdFilter:
|
216
|
+
if isinstance(other, (int, float)):
|
217
|
+
return MetricThresholdFilter(**dict(self), cmp="$gt", threshold=other)
|
218
|
+
return NotImplemented
|
219
|
+
|
220
|
+
def __lt__(self, other: Any) -> MetricThresholdFilter:
|
221
|
+
if isinstance(other, (int, float)):
|
222
|
+
return MetricThresholdFilter(**dict(self), cmp="$lt", threshold=other)
|
223
|
+
return NotImplemented
|
224
|
+
|
225
|
+
def __ge__(self, other: Any) -> MetricThresholdFilter:
|
226
|
+
if isinstance(other, (int, float)):
|
227
|
+
return MetricThresholdFilter(**dict(self), cmp="$gte", threshold=other)
|
228
|
+
return NotImplemented
|
229
|
+
|
230
|
+
def __le__(self, other: Any) -> MetricThresholdFilter:
|
231
|
+
if isinstance(other, (int, float)):
|
232
|
+
return MetricThresholdFilter(**dict(self), cmp="$lte", threshold=other)
|
233
|
+
return NotImplemented
|
234
|
+
|
235
|
+
@overload
|
236
|
+
def changes_by(self, *, diff: PosNum, frac: None) -> MetricChangeFilter: ...
|
237
|
+
@overload
|
238
|
+
def changes_by(self, *, diff: None, frac: PosNum) -> MetricChangeFilter: ...
|
239
|
+
@overload # NOTE: This overload is for internal use only.
|
240
|
+
def changes_by(
|
241
|
+
self, *, diff: PosNum | None, frac: PosNum | None, _dir: ChangeDir
|
242
|
+
) -> MetricChangeFilter: ...
|
243
|
+
def changes_by(
|
244
|
+
self,
|
245
|
+
*,
|
246
|
+
diff: PosNum | None = None,
|
247
|
+
frac: PosNum | None = None,
|
248
|
+
_dir: ChangeDir = ChangeDir.ANY,
|
249
|
+
) -> MetricChangeFilter:
|
250
|
+
"""Defines a filter that observes for any change (increase OR decrease) in a run metric.
|
251
|
+
|
252
|
+
Exactly one of the keyword arguments `frac` or `diff` must be provided.
|
253
|
+
|
254
|
+
Args:
|
255
|
+
diff:
|
256
|
+
If given, the arithmetic difference that must be observed
|
257
|
+
in the metric. Must be a positive number.
|
258
|
+
frac:
|
259
|
+
If given, the fractional (relative) change that must be observed
|
260
|
+
in the metric. Must be a positive number. E.g. `frac=0.1`
|
261
|
+
denotes a 10% relative increase OR decrease.
|
262
|
+
"""
|
263
|
+
# Enforce mutually exclusive keyword args
|
264
|
+
if (frac is None) is (diff is None):
|
265
|
+
raise ValueError("Must provide exactly one of `frac` or `diff`")
|
266
|
+
|
267
|
+
# Enforce positive values
|
268
|
+
if (frac is not None) and (frac <= 0):
|
269
|
+
raise ValueError(f"Expected positive quantity, got: {frac=}")
|
270
|
+
if (diff is not None) and (diff <= 0):
|
271
|
+
raise ValueError(f"Expected positive quantity, got: {diff=}")
|
272
|
+
|
273
|
+
if diff is None:
|
274
|
+
change_kws = dict(change_type=ChangeType.REL, threshold=frac)
|
275
|
+
return MetricChangeFilter(**dict(self), change_dir=_dir, **change_kws)
|
276
|
+
else:
|
277
|
+
change_kws = dict(change_type=ChangeType.ABS, threshold=diff)
|
278
|
+
return MetricChangeFilter(**dict(self), change_dir=_dir, **change_kws)
|
279
|
+
|
280
|
+
@overload
|
281
|
+
def increases_by(self, *, diff: PosNum, frac: None) -> MetricChangeFilter: ...
|
282
|
+
@overload
|
283
|
+
def increases_by(self, *, diff: None, frac: PosNum) -> MetricChangeFilter: ...
|
284
|
+
def increases_by(
|
285
|
+
self, *, diff: PosNum | None = None, frac: PosNum | None = None
|
286
|
+
) -> MetricChangeFilter:
|
287
|
+
"""Defines a filter that observes for an increase in the numerical value of a run metric.
|
288
|
+
|
289
|
+
Arguments are the same as for `.changes_by()`.
|
290
|
+
"""
|
291
|
+
return self.changes_by(diff=diff, frac=frac, _dir=ChangeDir.INC)
|
292
|
+
|
293
|
+
@overload
|
294
|
+
def decreases_by(self, *, diff: PosNum, frac: None) -> MetricChangeFilter: ...
|
295
|
+
@overload
|
296
|
+
def decreases_by(self, *, diff: None, frac: PosNum) -> MetricChangeFilter: ...
|
297
|
+
def decreases_by(
|
298
|
+
self, *, diff: PosNum | None = None, frac: PosNum | None = None
|
299
|
+
) -> MetricChangeFilter:
|
300
|
+
"""Defines a filter that observes for a decrease in the numerical value of a run metric.
|
301
|
+
|
302
|
+
Arguments are the same as for `.changes_by()`.
|
303
|
+
"""
|
304
|
+
return self.changes_by(diff=diff, frac=frac, _dir=ChangeDir.DEC)
|
305
|
+
|
306
|
+
|
307
|
+
class MetricVal(BaseMetricOperand):
|
308
|
+
"""Represents a single, unaggregated metric value when defining a metric filter."""
|
309
|
+
|
310
|
+
name: str
|
311
|
+
|
312
|
+
# Allow users to convert this single-value metric into an aggregated metric expression.
|
313
|
+
def max(self, window: int) -> MetricAgg:
|
314
|
+
return MetricAgg(name=self.name, agg=Agg.MAX, window=window)
|
315
|
+
|
316
|
+
def min(self, window: int) -> MetricAgg:
|
317
|
+
return MetricAgg(name=self.name, agg=Agg.MIN, window=window)
|
318
|
+
|
319
|
+
def avg(self, window: int) -> MetricAgg:
|
320
|
+
return MetricAgg(name=self.name, agg=Agg.AVG, window=window)
|
321
|
+
|
322
|
+
# Aliased method for users familiar with e.g. torch/tf/numpy/pandas/polars/etc.
|
323
|
+
def mean(self, window: int) -> MetricAgg:
|
324
|
+
return self.avg(window=window)
|
325
|
+
|
326
|
+
|
327
|
+
class MetricAgg(BaseMetricOperand):
|
328
|
+
"""Represents an aggregated metric value when defining a metric filter."""
|
329
|
+
|
330
|
+
name: str
|
331
|
+
agg: Annotated[Agg, Field(alias="agg_op")]
|
332
|
+
window: Annotated[PositiveInt, Field(alias="window_size")]
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
|
3
|
+
from .create_automation import CreateAutomation
|
4
|
+
from .create_generic_webhook_integration import (
|
5
|
+
CreateGenericWebhookIntegration,
|
6
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegration,
|
7
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationGenericWebhookIntegration,
|
8
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationIntegration,
|
9
|
+
)
|
10
|
+
from .delete_automation import DeleteAutomation
|
11
|
+
from .enums import (
|
12
|
+
AlertSeverity,
|
13
|
+
EventTriggeringConditionType,
|
14
|
+
TriggeredActionType,
|
15
|
+
TriggerScopeType,
|
16
|
+
)
|
17
|
+
from .fragments import (
|
18
|
+
ArtifactPortfolioScopeFields,
|
19
|
+
ArtifactSequenceScopeFields,
|
20
|
+
FilterEventFields,
|
21
|
+
GenericWebhookActionFields,
|
22
|
+
GenericWebhookActionFieldsIntegrationGenericWebhookIntegration,
|
23
|
+
GenericWebhookActionFieldsIntegrationIntegration,
|
24
|
+
GenericWebhookIntegrationConnectionFields,
|
25
|
+
GenericWebhookIntegrationConnectionFieldsEdges,
|
26
|
+
GenericWebhookIntegrationConnectionFieldsEdgesNodeGenericWebhookIntegration,
|
27
|
+
GenericWebhookIntegrationConnectionFieldsEdgesNodeIntegration,
|
28
|
+
GenericWebhookIntegrationFields,
|
29
|
+
IntegrationConnectionFields,
|
30
|
+
IntegrationConnectionFieldsEdges,
|
31
|
+
IntegrationConnectionFieldsEdgesNodeGenericWebhookIntegration,
|
32
|
+
IntegrationConnectionFieldsEdgesNodeIntegration,
|
33
|
+
IntegrationConnectionFieldsEdgesNodeSlackIntegration,
|
34
|
+
NoOpActionFields,
|
35
|
+
NotificationActionFields,
|
36
|
+
NotificationActionFieldsIntegrationIntegration,
|
37
|
+
NotificationActionFieldsIntegrationSlackIntegration,
|
38
|
+
PageInfoFields,
|
39
|
+
ProjectConnectionFields,
|
40
|
+
ProjectConnectionFieldsEdges,
|
41
|
+
ProjectConnectionFieldsEdgesNode,
|
42
|
+
ProjectScopeFields,
|
43
|
+
QueueJobActionFields,
|
44
|
+
QueueJobActionFieldsQueue,
|
45
|
+
SlackIntegrationConnectionFields,
|
46
|
+
SlackIntegrationConnectionFieldsEdges,
|
47
|
+
SlackIntegrationConnectionFieldsEdgesNodeIntegration,
|
48
|
+
SlackIntegrationConnectionFieldsEdgesNodeSlackIntegration,
|
49
|
+
SlackIntegrationFields,
|
50
|
+
TriggerFields,
|
51
|
+
TriggerFieldsActionGenericWebhookTriggeredAction,
|
52
|
+
TriggerFieldsActionNoOpTriggeredAction,
|
53
|
+
TriggerFieldsActionNotificationTriggeredAction,
|
54
|
+
TriggerFieldsActionQueueJobTriggeredAction,
|
55
|
+
TriggerFieldsEventFilterEventTriggeringCondition,
|
56
|
+
TriggerFieldsScopeArtifactPortfolio,
|
57
|
+
TriggerFieldsScopeArtifactSequence,
|
58
|
+
TriggerFieldsScopeProject,
|
59
|
+
)
|
60
|
+
from .generic_webhook_integrations_by_entity import (
|
61
|
+
GenericWebhookIntegrationsByEntity,
|
62
|
+
GenericWebhookIntegrationsByEntityEntity,
|
63
|
+
)
|
64
|
+
from .get_automations import GetAutomations, GetAutomationsSearchScope
|
65
|
+
from .get_automations_by_entity import (
|
66
|
+
GetAutomationsByEntity,
|
67
|
+
GetAutomationsByEntitySearchScope,
|
68
|
+
)
|
69
|
+
from .input_types import (
|
70
|
+
CreateFilterTriggerInput,
|
71
|
+
CreateGenericWebhookIntegrationInput,
|
72
|
+
GenericWebhookActionInput,
|
73
|
+
NoOpTriggeredActionInput,
|
74
|
+
NotificationActionInput,
|
75
|
+
QueueJobActionInput,
|
76
|
+
TriggeredActionConfig,
|
77
|
+
UpdateFilterTriggerInput,
|
78
|
+
)
|
79
|
+
from .integrations_by_entity import IntegrationsByEntity, IntegrationsByEntityEntity
|
80
|
+
from .operations import (
|
81
|
+
CREATE_AUTOMATION_GQL,
|
82
|
+
CREATE_GENERIC_WEBHOOK_INTEGRATION_GQL,
|
83
|
+
DELETE_AUTOMATION_GQL,
|
84
|
+
GENERIC_WEBHOOK_INTEGRATIONS_BY_ENTITY_GQL,
|
85
|
+
GET_AUTOMATIONS_BY_ENTITY_GQL,
|
86
|
+
GET_AUTOMATIONS_GQL,
|
87
|
+
INTEGRATIONS_BY_ENTITY_GQL,
|
88
|
+
SLACK_INTEGRATIONS_BY_ENTITY_GQL,
|
89
|
+
UPDATE_AUTOMATION_GQL,
|
90
|
+
)
|
91
|
+
from .slack_integrations_by_entity import (
|
92
|
+
SlackIntegrationsByEntity,
|
93
|
+
SlackIntegrationsByEntityEntity,
|
94
|
+
)
|
95
|
+
from .update_automation import UpdateAutomation
|
96
|
+
|
97
|
+
__all__ = [
|
98
|
+
"CREATE_AUTOMATION_GQL",
|
99
|
+
"CREATE_GENERIC_WEBHOOK_INTEGRATION_GQL",
|
100
|
+
"DELETE_AUTOMATION_GQL",
|
101
|
+
"GENERIC_WEBHOOK_INTEGRATIONS_BY_ENTITY_GQL",
|
102
|
+
"GET_AUTOMATIONS_BY_ENTITY_GQL",
|
103
|
+
"GET_AUTOMATIONS_GQL",
|
104
|
+
"INTEGRATIONS_BY_ENTITY_GQL",
|
105
|
+
"SLACK_INTEGRATIONS_BY_ENTITY_GQL",
|
106
|
+
"UPDATE_AUTOMATION_GQL",
|
107
|
+
"GetAutomations",
|
108
|
+
"GetAutomationsSearchScope",
|
109
|
+
"GetAutomationsByEntity",
|
110
|
+
"GetAutomationsByEntitySearchScope",
|
111
|
+
"CreateAutomation",
|
112
|
+
"UpdateAutomation",
|
113
|
+
"DeleteAutomation",
|
114
|
+
"IntegrationsByEntity",
|
115
|
+
"IntegrationsByEntityEntity",
|
116
|
+
"SlackIntegrationsByEntity",
|
117
|
+
"SlackIntegrationsByEntityEntity",
|
118
|
+
"GenericWebhookIntegrationsByEntity",
|
119
|
+
"GenericWebhookIntegrationsByEntityEntity",
|
120
|
+
"CreateGenericWebhookIntegration",
|
121
|
+
"CreateGenericWebhookIntegrationCreateGenericWebhookIntegration",
|
122
|
+
"CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationGenericWebhookIntegration",
|
123
|
+
"CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationIntegration",
|
124
|
+
"CreateFilterTriggerInput",
|
125
|
+
"CreateGenericWebhookIntegrationInput",
|
126
|
+
"GenericWebhookActionInput",
|
127
|
+
"NoOpTriggeredActionInput",
|
128
|
+
"NotificationActionInput",
|
129
|
+
"QueueJobActionInput",
|
130
|
+
"TriggeredActionConfig",
|
131
|
+
"UpdateFilterTriggerInput",
|
132
|
+
"ArtifactPortfolioScopeFields",
|
133
|
+
"ArtifactSequenceScopeFields",
|
134
|
+
"FilterEventFields",
|
135
|
+
"GenericWebhookActionFields",
|
136
|
+
"GenericWebhookActionFieldsIntegrationGenericWebhookIntegration",
|
137
|
+
"GenericWebhookActionFieldsIntegrationIntegration",
|
138
|
+
"GenericWebhookIntegrationConnectionFields",
|
139
|
+
"GenericWebhookIntegrationConnectionFieldsEdges",
|
140
|
+
"GenericWebhookIntegrationConnectionFieldsEdgesNodeGenericWebhookIntegration",
|
141
|
+
"GenericWebhookIntegrationConnectionFieldsEdgesNodeIntegration",
|
142
|
+
"GenericWebhookIntegrationFields",
|
143
|
+
"IntegrationConnectionFields",
|
144
|
+
"IntegrationConnectionFieldsEdges",
|
145
|
+
"IntegrationConnectionFieldsEdgesNodeGenericWebhookIntegration",
|
146
|
+
"IntegrationConnectionFieldsEdgesNodeIntegration",
|
147
|
+
"IntegrationConnectionFieldsEdgesNodeSlackIntegration",
|
148
|
+
"NoOpActionFields",
|
149
|
+
"NotificationActionFields",
|
150
|
+
"NotificationActionFieldsIntegrationIntegration",
|
151
|
+
"NotificationActionFieldsIntegrationSlackIntegration",
|
152
|
+
"PageInfoFields",
|
153
|
+
"ProjectConnectionFields",
|
154
|
+
"ProjectConnectionFieldsEdges",
|
155
|
+
"ProjectConnectionFieldsEdgesNode",
|
156
|
+
"ProjectScopeFields",
|
157
|
+
"QueueJobActionFields",
|
158
|
+
"QueueJobActionFieldsQueue",
|
159
|
+
"SlackIntegrationConnectionFields",
|
160
|
+
"SlackIntegrationConnectionFieldsEdges",
|
161
|
+
"SlackIntegrationConnectionFieldsEdgesNodeIntegration",
|
162
|
+
"SlackIntegrationConnectionFieldsEdgesNodeSlackIntegration",
|
163
|
+
"SlackIntegrationFields",
|
164
|
+
"TriggerFields",
|
165
|
+
"TriggerFieldsActionGenericWebhookTriggeredAction",
|
166
|
+
"TriggerFieldsActionNoOpTriggeredAction",
|
167
|
+
"TriggerFieldsActionNotificationTriggeredAction",
|
168
|
+
"TriggerFieldsActionQueueJobTriggeredAction",
|
169
|
+
"TriggerFieldsEventFilterEventTriggeringCondition",
|
170
|
+
"TriggerFieldsScopeArtifactPortfolio",
|
171
|
+
"TriggerFieldsScopeArtifactSequence",
|
172
|
+
"TriggerFieldsScopeProject",
|
173
|
+
"AlertSeverity",
|
174
|
+
"EventTriggeringConditionType",
|
175
|
+
"TriggerScopeType",
|
176
|
+
"TriggeredActionType",
|
177
|
+
]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/automations/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
from wandb._pydantic import GQLBase
|
9
|
+
|
10
|
+
from .fragments import CreateAutomationResult
|
11
|
+
|
12
|
+
|
13
|
+
class CreateAutomation(GQLBase):
|
14
|
+
result: Optional[CreateAutomationResult]
|
15
|
+
|
16
|
+
|
17
|
+
CreateAutomation.model_rebuild()
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/automations/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Literal, Optional, Union
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase, Typename
|
11
|
+
|
12
|
+
from .fragments import GenericWebhookIntegrationFields
|
13
|
+
|
14
|
+
|
15
|
+
class CreateGenericWebhookIntegration(GQLBase):
|
16
|
+
create_generic_webhook_integration: Optional[
|
17
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegration
|
18
|
+
] = Field(alias="createGenericWebhookIntegration")
|
19
|
+
|
20
|
+
|
21
|
+
class CreateGenericWebhookIntegrationCreateGenericWebhookIntegration(GQLBase):
|
22
|
+
integration: Union[
|
23
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationIntegration,
|
24
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationGenericWebhookIntegration,
|
25
|
+
] = Field(discriminator="typename__")
|
26
|
+
|
27
|
+
|
28
|
+
class CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationIntegration(
|
29
|
+
GQLBase
|
30
|
+
):
|
31
|
+
typename__: Typename[
|
32
|
+
Literal["GitHubOAuthIntegration", "Integration", "SlackIntegration"]
|
33
|
+
]
|
34
|
+
|
35
|
+
|
36
|
+
class CreateGenericWebhookIntegrationCreateGenericWebhookIntegrationIntegrationGenericWebhookIntegration(
|
37
|
+
GenericWebhookIntegrationFields
|
38
|
+
):
|
39
|
+
typename__: Typename[Literal["GenericWebhookIntegration"]]
|
40
|
+
|
41
|
+
|
42
|
+
CreateGenericWebhookIntegration.model_rebuild()
|
43
|
+
CreateGenericWebhookIntegrationCreateGenericWebhookIntegration.model_rebuild()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/automations/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
from wandb._pydantic import GQLBase
|
9
|
+
|
10
|
+
from .fragments import DeleteAutomationResult
|
11
|
+
|
12
|
+
|
13
|
+
class DeleteAutomation(GQLBase):
|
14
|
+
result: Optional[DeleteAutomationResult]
|
15
|
+
|
16
|
+
|
17
|
+
DeleteAutomation.model_rebuild()
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: core/api/graphql/schemas/schema-latest.graphql
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from enum import Enum
|
7
|
+
|
8
|
+
|
9
|
+
class EventTriggeringConditionType(str, Enum):
|
10
|
+
CREATE_ARTIFACT = "CREATE_ARTIFACT"
|
11
|
+
UPDATE_ARTIFACT_ALIAS = "UPDATE_ARTIFACT_ALIAS"
|
12
|
+
ADD_ARTIFACT_ALIAS = "ADD_ARTIFACT_ALIAS"
|
13
|
+
LINK_MODEL = "LINK_MODEL"
|
14
|
+
RUN_METRIC = "RUN_METRIC"
|
15
|
+
RUN_METRIC_CHANGE = "RUN_METRIC_CHANGE"
|
16
|
+
|
17
|
+
|
18
|
+
class TriggerScopeType(str, Enum):
|
19
|
+
PROJECT = "PROJECT"
|
20
|
+
ARTIFACT_COLLECTION = "ARTIFACT_COLLECTION"
|
21
|
+
|
22
|
+
|
23
|
+
class AlertSeverity(str, Enum):
|
24
|
+
INFO = "INFO"
|
25
|
+
WARN = "WARN"
|
26
|
+
ERROR = "ERROR"
|
27
|
+
|
28
|
+
|
29
|
+
class TriggeredActionType(str, Enum):
|
30
|
+
QUEUE_JOB = "QUEUE_JOB"
|
31
|
+
NOTIFICATION = "NOTIFICATION"
|
32
|
+
GENERIC_WEBHOOK = "GENERIC_WEBHOOK"
|
33
|
+
NO_OP = "NO_OP"
|