wandb 0.19.8__py3-none-macosx_11_0_arm64.whl → 0.19.10__py3-none-macosx_11_0_arm64.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 +5 -1
- wandb/__init__.pyi +15 -8
- wandb/_pydantic/__init__.py +30 -0
- wandb/_pydantic/base.py +148 -0
- wandb/_pydantic/utils.py +66 -0
- wandb/_pydantic/v1_compat.py +284 -0
- wandb/apis/paginator.py +82 -38
- wandb/apis/public/__init__.py +2 -2
- wandb/apis/public/api.py +111 -53
- wandb/apis/public/artifacts.py +387 -639
- wandb/apis/public/automations.py +69 -0
- wandb/apis/public/files.py +2 -2
- wandb/apis/public/integrations.py +168 -0
- wandb/apis/public/projects.py +32 -2
- wandb/apis/public/reports.py +2 -2
- wandb/apis/public/runs.py +19 -11
- wandb/apis/public/utils.py +107 -1
- wandb/automations/__init__.py +81 -0
- wandb/automations/_filters/__init__.py +40 -0
- wandb/automations/_filters/expressions.py +179 -0
- wandb/automations/_filters/operators.py +267 -0
- wandb/automations/_filters/run_metrics.py +183 -0
- wandb/automations/_generated/__init__.py +184 -0
- wandb/automations/_generated/create_filter_trigger.py +21 -0
- wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
- wandb/automations/_generated/delete_trigger.py +19 -0
- wandb/automations/_generated/enums.py +33 -0
- wandb/automations/_generated/fragments.py +343 -0
- wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
- wandb/automations/_generated/get_triggers.py +24 -0
- wandb/automations/_generated/get_triggers_by_entity.py +24 -0
- wandb/automations/_generated/input_types.py +104 -0
- wandb/automations/_generated/integrations_by_entity.py +22 -0
- wandb/automations/_generated/operations.py +710 -0
- wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
- wandb/automations/_generated/update_filter_trigger.py +21 -0
- wandb/automations/_utils.py +123 -0
- wandb/automations/_validators.py +73 -0
- wandb/automations/actions.py +205 -0
- wandb/automations/automations.py +109 -0
- wandb/automations/events.py +235 -0
- wandb/automations/integrations.py +26 -0
- wandb/automations/scopes.py +76 -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/integration/keras/keras.py +2 -1
- wandb/integration/langchain/wandb_tracer.py +2 -1
- wandb/integration/metaflow/metaflow.py +19 -17
- wandb/integration/sacred/__init__.py +1 -1
- wandb/jupyter.py +155 -133
- 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 +10 -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 +248 -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_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/fragments.py +186 -0
- wandb/sdk/artifacts/_generated/input_types.py +16 -0
- wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
- wandb/sdk/artifacts/_generated/operations.py +510 -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_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_graphql_fragments.py +56 -81
- wandb/sdk/artifacts/_validators.py +1 -0
- wandb/sdk/artifacts/artifact.py +110 -49
- wandb/sdk/artifacts/artifact_manifest_entry.py +2 -1
- wandb/sdk/artifacts/artifact_saver.py +16 -2
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +23 -2
- wandb/sdk/data_types/audio.py +1 -3
- wandb/sdk/data_types/base_types/media.py +13 -7
- 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 +56 -37
- wandb/sdk/data_types/molecule.py +1 -5
- wandb/sdk/data_types/object_3d.py +2 -1
- wandb/sdk/data_types/saved_model.py +7 -9
- 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 +15 -30
- wandb/sdk/interface/interface.py +2 -0
- wandb/{apis/public → sdk/internal}/_generated/__init__.py +0 -6
- wandb/{apis/public → sdk/internal}/_generated/server_features_query.py +3 -3
- wandb/sdk/internal/internal_api.py +138 -47
- wandb/sdk/internal/profiler.py +6 -5
- wandb/sdk/internal/run.py +13 -6
- wandb/sdk/internal/sender.py +2 -0
- wandb/sdk/internal/sender_config.py +8 -11
- wandb/sdk/internal/settings_static.py +24 -2
- wandb/sdk/lib/apikey.py +40 -20
- 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/lib/run_moment.py +4 -6
- wandb/sdk/lib/wb_logging.py +161 -0
- wandb/sdk/service/server_sock.py +19 -14
- wandb/sdk/service/service.py +9 -7
- wandb/sdk/service/streams.py +5 -0
- wandb/sdk/verify/verify.py +6 -3
- wandb/sdk/wandb_config.py +44 -43
- wandb/sdk/wandb_init.py +323 -141
- wandb/sdk/wandb_login.py +13 -4
- wandb/sdk/wandb_metadata.py +107 -91
- wandb/sdk/wandb_run.py +529 -325
- wandb/sdk/wandb_settings.py +422 -202
- wandb/sdk/wandb_setup.py +52 -1
- wandb/util.py +29 -29
- {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/METADATA +7 -7
- {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/RECORD +151 -94
- wandb/_globals.py +0 -19
- wandb/apis/public/_generated/base.py +0 -128
- wandb/apis/public/_generated/typing_compat.py +0 -14
- /wandb/{apis/public → sdk/internal}/_generated/enums.py +0 -0
- /wandb/{apis/public → sdk/internal}/_generated/input_types.py +0 -0
- /wandb/{apis/public → sdk/internal}/_generated/operations.py +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/WHEEL +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,235 @@
|
|
1
|
+
"""Events that trigger W&B Automations."""
|
2
|
+
|
3
|
+
# ruff: noqa: UP007 # Avoid using `X | Y` for union fields, as this can cause issues with pydantic < 2.6
|
4
|
+
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
|
8
|
+
|
9
|
+
from pydantic import Field
|
10
|
+
from typing_extensions import Self, TypeAlias, get_args
|
11
|
+
|
12
|
+
from wandb._pydantic import (
|
13
|
+
GQLBase,
|
14
|
+
SerializedToJson,
|
15
|
+
field_validator,
|
16
|
+
model_validator,
|
17
|
+
pydantic_isinstance,
|
18
|
+
)
|
19
|
+
|
20
|
+
from ._filters import And, MongoLikeFilter, Or
|
21
|
+
from ._filters.expressions import FilterableField
|
22
|
+
from ._filters.run_metrics import (
|
23
|
+
Agg,
|
24
|
+
MetricChangeFilter,
|
25
|
+
MetricOperand,
|
26
|
+
MetricThresholdFilter,
|
27
|
+
)
|
28
|
+
from ._generated import EventTriggeringConditionType, FilterEventFields
|
29
|
+
from ._validators import simplify_op
|
30
|
+
from .actions import InputAction, InputActionTypes
|
31
|
+
from .scopes import ArtifactCollectionScope, InputScope, ProjectScope
|
32
|
+
|
33
|
+
if TYPE_CHECKING:
|
34
|
+
from .automations import NewAutomation
|
35
|
+
|
36
|
+
|
37
|
+
# NOTE: Re-defined publicly with a more readable name for easier access
|
38
|
+
EventType = EventTriggeringConditionType
|
39
|
+
"""The type of event that triggers an automation."""
|
40
|
+
|
41
|
+
Agg = Agg
|
42
|
+
|
43
|
+
|
44
|
+
# ------------------------------------------------------------------------------
|
45
|
+
# Saved types: for parsing response data from saved automations
|
46
|
+
|
47
|
+
|
48
|
+
# Note: In GQL responses containing saved automation data, the filter is wrapped in an extra `filter` key.
|
49
|
+
class SavedEventFilter(GQLBase):
|
50
|
+
filter: SerializedToJson[MongoLikeFilter] = Field(default_factory=And)
|
51
|
+
|
52
|
+
|
53
|
+
class _InnerRunMetricFilter(GQLBase): # from `RunMetricFilter`
|
54
|
+
threshold_filter: Optional[MetricThresholdFilter] = None
|
55
|
+
change_filter: Optional[MetricChangeFilter] = None
|
56
|
+
|
57
|
+
@model_validator(mode="before")
|
58
|
+
@classmethod
|
59
|
+
def _wrap_metric_filter(cls, v: Any) -> Any:
|
60
|
+
if pydantic_isinstance(v, MetricThresholdFilter):
|
61
|
+
return cls(threshold_filter=v)
|
62
|
+
if pydantic_isinstance(v, MetricChangeFilter):
|
63
|
+
return cls(change_filter=v)
|
64
|
+
return v
|
65
|
+
|
66
|
+
@model_validator(mode="after")
|
67
|
+
def _ensure_exactly_one_set(self) -> Self:
|
68
|
+
set_field_names = [name for name, val in self if (val is not None)]
|
69
|
+
if not set_field_names:
|
70
|
+
raise ValueError("Must specify a run metric filter")
|
71
|
+
if len(set_field_names) > 1:
|
72
|
+
names = ", ".join(map(repr, set_field_names))
|
73
|
+
raise ValueError(f"Must specify a single run metric filter, got: {names}")
|
74
|
+
return self
|
75
|
+
|
76
|
+
|
77
|
+
class RunMetricFilter(GQLBase): # from `RunMetricEvent`
|
78
|
+
run_filter: SerializedToJson[MongoLikeFilter] = Field(default_factory=And)
|
79
|
+
run_metric_filter: _InnerRunMetricFilter
|
80
|
+
|
81
|
+
#: Legacy field to define triggers on run metrics from absolute thresholds. Use `run_metric_filter` instead.
|
82
|
+
metric_filter: Optional[SerializedToJson[MetricThresholdFilter]] = Field(
|
83
|
+
default=None,
|
84
|
+
deprecated="The `metric_filter` field is deprecated: use `run_metric_filter` instead.",
|
85
|
+
)
|
86
|
+
|
87
|
+
@model_validator(mode="before")
|
88
|
+
@classmethod
|
89
|
+
def _wrap_metric_filter(cls, v: Any) -> Any:
|
90
|
+
if pydantic_isinstance(v, (MetricThresholdFilter, MetricChangeFilter)):
|
91
|
+
# If we're only given an (unwrapped) metric filter, automatically wrap it
|
92
|
+
# in the appropriate nested structure, and use the default run filter.
|
93
|
+
|
94
|
+
# Delegate to the inner validator to further wrap the filter as appropriate.
|
95
|
+
return cls(run_metric_filter=_InnerRunMetricFilter.model_validate(v))
|
96
|
+
return v
|
97
|
+
|
98
|
+
@field_validator("run_filter", mode="after")
|
99
|
+
@classmethod
|
100
|
+
def _wrap_run_filter(cls, v: MongoLikeFilter) -> Any:
|
101
|
+
v_new = simplify_op(v)
|
102
|
+
return (
|
103
|
+
And.model_validate(v_new)
|
104
|
+
if pydantic_isinstance(v_new, And)
|
105
|
+
else And(and_=[v_new])
|
106
|
+
)
|
107
|
+
|
108
|
+
|
109
|
+
# type alias defined for naming consistency/clarity
|
110
|
+
SavedRunMetricFilter: TypeAlias = RunMetricFilter
|
111
|
+
|
112
|
+
|
113
|
+
class SavedEvent(FilterEventFields): # from `FilterEventTriggeringCondition`
|
114
|
+
"""A more introspection-friendly representation of a triggering event from a saved automation."""
|
115
|
+
|
116
|
+
# We override the type of the `filter` field since the original GraphQL
|
117
|
+
# schema (and generated class) defines it as a JSONString (str), but we
|
118
|
+
# have more specific expectations for the structure of the JSON data.
|
119
|
+
filter: SerializedToJson[Union[SavedEventFilter, SavedRunMetricFilter]]
|
120
|
+
|
121
|
+
|
122
|
+
# ------------------------------------------------------------------------------
|
123
|
+
# Input types: for creating or updating automations
|
124
|
+
|
125
|
+
|
126
|
+
# Note: The GQL input for "eventFilter" does NOT wrap the filter in an extra `filter` key, unlike the
|
127
|
+
# eventFilter returned in responses for saved automations.
|
128
|
+
class _BaseEventInput(GQLBase):
|
129
|
+
event_type: EventType
|
130
|
+
scope: InputScope
|
131
|
+
filter: SerializedToJson[Any]
|
132
|
+
|
133
|
+
def add_action(self, action: InputAction) -> NewAutomation:
|
134
|
+
"""Define an executed action to be triggered by this event."""
|
135
|
+
from .automations import NewAutomation
|
136
|
+
|
137
|
+
if isinstance(action, InputActionTypes):
|
138
|
+
return NewAutomation(scope=self.scope, event=self, action=action)
|
139
|
+
|
140
|
+
raise TypeError(f"Expected a valid action, got: {type(action).__qualname__!r}")
|
141
|
+
|
142
|
+
def __rshift__(self, other: InputAction) -> NewAutomation:
|
143
|
+
"""Supports `event >> action` as syntactic sugar to combine an event and action."""
|
144
|
+
return self.add_action(other)
|
145
|
+
|
146
|
+
|
147
|
+
class _BaseMutationEventInput(_BaseEventInput):
|
148
|
+
event_type: EventType
|
149
|
+
scope: InputScope
|
150
|
+
filter: SerializedToJson[MongoLikeFilter] = Field(default_factory=And)
|
151
|
+
|
152
|
+
@field_validator("filter", mode="after")
|
153
|
+
@classmethod
|
154
|
+
def _wrap_filter(cls, v: Any) -> Any:
|
155
|
+
"""Ensure the given filter is wrapped like: `{"$or": [{"$and": [<original_filter>]}]}`.
|
156
|
+
|
157
|
+
This is awkward but necessary, because the frontend expects this format.
|
158
|
+
"""
|
159
|
+
v_new = simplify_op(v)
|
160
|
+
v_new = (
|
161
|
+
And.model_validate(v_new)
|
162
|
+
if pydantic_isinstance(v_new, And)
|
163
|
+
else And(and_=[v_new])
|
164
|
+
)
|
165
|
+
v_new = Or(or_=[v_new])
|
166
|
+
return v_new
|
167
|
+
|
168
|
+
|
169
|
+
class OnLinkArtifact(_BaseMutationEventInput):
|
170
|
+
"""A new artifact is linked to a collection."""
|
171
|
+
|
172
|
+
event_type: Literal[EventType.LINK_MODEL] = EventType.LINK_MODEL
|
173
|
+
scope: InputScope
|
174
|
+
|
175
|
+
|
176
|
+
class OnAddArtifactAlias(_BaseMutationEventInput):
|
177
|
+
"""A new alias is assigned to an artifact."""
|
178
|
+
|
179
|
+
event_type: Literal[EventType.ADD_ARTIFACT_ALIAS] = EventType.ADD_ARTIFACT_ALIAS
|
180
|
+
scope: InputScope
|
181
|
+
|
182
|
+
|
183
|
+
class OnCreateArtifact(_BaseMutationEventInput):
|
184
|
+
"""A new artifact is created."""
|
185
|
+
|
186
|
+
event_type: Literal[EventType.CREATE_ARTIFACT] = EventType.CREATE_ARTIFACT
|
187
|
+
scope: ArtifactCollectionScope
|
188
|
+
|
189
|
+
|
190
|
+
class OnRunMetric(_BaseEventInput):
|
191
|
+
"""A run metric satisfies a user-defined absolute threshold."""
|
192
|
+
|
193
|
+
event_type: Literal[EventType.RUN_METRIC] = EventType.RUN_METRIC
|
194
|
+
scope: ProjectScope
|
195
|
+
filter: SerializedToJson[RunMetricFilter]
|
196
|
+
|
197
|
+
|
198
|
+
# for type annotations
|
199
|
+
InputEvent = Union[
|
200
|
+
OnLinkArtifact,
|
201
|
+
OnAddArtifactAlias,
|
202
|
+
OnCreateArtifact,
|
203
|
+
OnRunMetric,
|
204
|
+
]
|
205
|
+
# for runtime type checks
|
206
|
+
InputEventTypes: tuple[type, ...] = get_args(InputEvent)
|
207
|
+
|
208
|
+
|
209
|
+
# ----------------------------------------------------------------------------
|
210
|
+
|
211
|
+
|
212
|
+
class RunEvent:
|
213
|
+
name = FilterableField("display_name")
|
214
|
+
# `Run.name` is actually filtered on `Run.display_name` in the backend.
|
215
|
+
# We can't reasonably expect users to know this a priori, so
|
216
|
+
# automatically fix it here.
|
217
|
+
|
218
|
+
@staticmethod
|
219
|
+
def metric(name: str) -> MetricOperand:
|
220
|
+
"""Define a metric filter condition."""
|
221
|
+
return MetricOperand(name=name)
|
222
|
+
|
223
|
+
|
224
|
+
class ArtifactEvent:
|
225
|
+
alias = FilterableField()
|
226
|
+
|
227
|
+
|
228
|
+
MetricThresholdFilter.model_rebuild()
|
229
|
+
RunMetricFilter.model_rebuild()
|
230
|
+
SavedEventFilter.model_rebuild()
|
231
|
+
|
232
|
+
OnLinkArtifact.model_rebuild()
|
233
|
+
OnAddArtifactAlias.model_rebuild()
|
234
|
+
OnCreateArtifact.model_rebuild()
|
235
|
+
OnRunMetric.model_rebuild()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from typing import Union
|
2
|
+
|
3
|
+
from pydantic import Field
|
4
|
+
|
5
|
+
from wandb._pydantic import GQLBase
|
6
|
+
from wandb.automations._generated import (
|
7
|
+
GenericWebhookIntegrationFields,
|
8
|
+
SlackIntegrationFields,
|
9
|
+
)
|
10
|
+
|
11
|
+
|
12
|
+
class SlackIntegration(SlackIntegrationFields):
|
13
|
+
pass
|
14
|
+
|
15
|
+
|
16
|
+
class WebhookIntegration(GenericWebhookIntegrationFields):
|
17
|
+
pass
|
18
|
+
|
19
|
+
|
20
|
+
Integration = Union[SlackIntegration, WebhookIntegration]
|
21
|
+
|
22
|
+
|
23
|
+
# For parsing integration instances from paginated responses
|
24
|
+
class _IntegrationEdge(GQLBase):
|
25
|
+
cursor: str
|
26
|
+
node: Integration = Field(discriminator="typename__")
|
@@ -0,0 +1,76 @@
|
|
1
|
+
"""Scopes in which a W&B Automation can be triggered."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import Literal, Union
|
6
|
+
|
7
|
+
from pydantic import BeforeValidator, Field
|
8
|
+
from typing_extensions import Annotated, TypeAlias, get_args
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase
|
11
|
+
from wandb.automations._generated import (
|
12
|
+
ArtifactPortfolioScopeFields,
|
13
|
+
ArtifactSequenceScopeFields,
|
14
|
+
ProjectScopeFields,
|
15
|
+
)
|
16
|
+
|
17
|
+
from ._generated import TriggerScopeType
|
18
|
+
from ._validators import validate_scope
|
19
|
+
|
20
|
+
# NOTE: Re-defined publicly with a more readable name for easier access
|
21
|
+
ScopeType = TriggerScopeType
|
22
|
+
"""The type of scope that triggers an automation."""
|
23
|
+
|
24
|
+
|
25
|
+
class _BaseScope(GQLBase):
|
26
|
+
scope_type: ScopeType
|
27
|
+
|
28
|
+
|
29
|
+
class _ArtifactSequenceScope(_BaseScope, ArtifactSequenceScopeFields):
|
30
|
+
"""The ID and name of a "sequence"-type ArtifactCollection scope of an automation."""
|
31
|
+
|
32
|
+
scope_type: Literal[ScopeType.ARTIFACT_COLLECTION] = ScopeType.ARTIFACT_COLLECTION
|
33
|
+
|
34
|
+
|
35
|
+
class _ArtifactPortfolioScope(_BaseScope, ArtifactPortfolioScopeFields):
|
36
|
+
"""The ID and name of a "portfolio"-type ArtifactCollection scope of an automation."""
|
37
|
+
|
38
|
+
scope_type: Literal[ScopeType.ARTIFACT_COLLECTION] = ScopeType.ARTIFACT_COLLECTION
|
39
|
+
|
40
|
+
|
41
|
+
# for type annotations
|
42
|
+
ArtifactCollectionScope = Annotated[
|
43
|
+
Union[_ArtifactSequenceScope, _ArtifactPortfolioScope],
|
44
|
+
BeforeValidator(validate_scope),
|
45
|
+
Field(discriminator="typename__"),
|
46
|
+
]
|
47
|
+
"""The ID and name of the ArtifactCollection scope of an automation."""
|
48
|
+
|
49
|
+
# for runtime type checks
|
50
|
+
ArtifactCollectionScopeTypes: tuple[type, ...] = (
|
51
|
+
_ArtifactSequenceScope,
|
52
|
+
_ArtifactPortfolioScope,
|
53
|
+
)
|
54
|
+
|
55
|
+
|
56
|
+
class ProjectScope(_BaseScope, ProjectScopeFields):
|
57
|
+
"""The ID and name of the Project scope of an automation."""
|
58
|
+
|
59
|
+
scope_type: Literal[ScopeType.PROJECT] = ScopeType.PROJECT
|
60
|
+
|
61
|
+
|
62
|
+
# for type annotations
|
63
|
+
AutomationScope: TypeAlias = Annotated[
|
64
|
+
Union[_ArtifactSequenceScope, _ArtifactPortfolioScope, ProjectScope],
|
65
|
+
BeforeValidator(validate_scope),
|
66
|
+
Field(discriminator="typename__"),
|
67
|
+
]
|
68
|
+
# for runtime type checks
|
69
|
+
AutomationScopeTypes: tuple[type, ...] = get_args(AutomationScope)
|
70
|
+
|
71
|
+
# Aliases for naming clarity/consistency
|
72
|
+
SavedScope: TypeAlias = AutomationScope
|
73
|
+
InputScope: TypeAlias = AutomationScope
|
74
|
+
|
75
|
+
SavedScopeTypes: tuple[type, ...] = get_args(SavedScope)
|
76
|
+
InputScopeTypes: tuple[type, ...] = get_args(InputScope)
|
wandb/beta/workflows.py
CHANGED
@@ -5,6 +5,7 @@ from typing import Any, Dict, List, Optional, Union
|
|
5
5
|
import wandb
|
6
6
|
import wandb.data_types as data_types
|
7
7
|
from wandb.data_types import _SavedModel
|
8
|
+
from wandb.sdk import wandb_setup
|
8
9
|
from wandb.sdk.artifacts.artifact import Artifact
|
9
10
|
from wandb.sdk.artifacts.artifact_manifest_entry import ArtifactManifestEntry
|
10
11
|
|
@@ -85,12 +86,13 @@ def _log_artifact_version(
|
|
85
86
|
Artifact
|
86
87
|
|
87
88
|
"""
|
88
|
-
|
89
|
+
run = wandb_setup._setup(start_service=False).most_recent_active_run
|
90
|
+
if not run:
|
89
91
|
run = wandb.init(
|
90
|
-
project=project,
|
92
|
+
project=project,
|
93
|
+
job_type=job_type,
|
94
|
+
settings=wandb.Settings(silent=True),
|
91
95
|
)
|
92
|
-
else:
|
93
|
-
run = wandb.run
|
94
96
|
|
95
97
|
if not scope_project:
|
96
98
|
name = f"{name}-{run.id}"
|
@@ -124,7 +126,7 @@ def log_model(
|
|
124
126
|
|
125
127
|
Supported frameworks include PyTorch, Keras, Tensorflow, Scikit-learn, etc. Under
|
126
128
|
the hood, we create a model artifact, bind it to the run that produced this model,
|
127
|
-
associate it with the latest metrics logged with `
|
129
|
+
associate it with the latest metrics logged with `run.log(...)` and more.
|
128
130
|
|
129
131
|
Args:
|
130
132
|
model_obj: any model object created with the following ML frameworks: PyTorch,
|
@@ -215,8 +217,7 @@ def use_model(aliased_path: str, unsafe: bool = False) -> "_SavedModel":
|
|
215
217
|
)
|
216
218
|
|
217
219
|
# Returns a _SavedModel instance
|
218
|
-
if
|
219
|
-
run = wandb.run
|
220
|
+
if run := wandb_setup._setup(start_service=False).most_recent_active_run:
|
220
221
|
artifact = run.use_artifact(aliased_path)
|
221
222
|
sm = artifact.get("index")
|
222
223
|
|
@@ -261,9 +262,7 @@ def link_model(
|
|
261
262
|
"""
|
262
263
|
aliases = wandb.util._resolve_aliases(aliases)
|
263
264
|
|
264
|
-
if
|
265
|
-
run = wandb.run
|
266
|
-
|
265
|
+
if run := wandb_setup._setup(start_service=False).most_recent_active_run:
|
267
266
|
# _artifact_source, if it exists, points to a Public Artifact.
|
268
267
|
# Its existence means that _SavedModel was deserialized from a logged artifact, most likely from `use_model`.
|
269
268
|
if model._artifact_source:
|
wandb/bin/gpu_stats
CHANGED
Binary file
|
wandb/bin/wandb-core
CHANGED
Binary file
|
wandb/cli/cli.py
CHANGED
@@ -83,14 +83,13 @@ def cli_unsupported(argument):
|
|
83
83
|
|
84
84
|
class ClickWandbException(ClickException):
|
85
85
|
def format_message(self):
|
86
|
-
# log_file = util.get_log_file_path()
|
87
|
-
log_file = ""
|
88
86
|
orig_type = f"{self.orig_type.__module__}.{self.orig_type.__name__}"
|
89
87
|
if issubclass(self.orig_type, Error):
|
90
88
|
return click.style(str(self.message), fg="red")
|
91
89
|
else:
|
92
90
|
return (
|
93
|
-
f"An Exception was raised, see {
|
91
|
+
f"An Exception was raised, see {_wandb_log_path} for full"
|
92
|
+
" traceback.\n"
|
94
93
|
f"{orig_type}: {self.message}"
|
95
94
|
)
|
96
95
|
|
@@ -257,6 +256,7 @@ def login(key, host, cloud, relogin, anonymously, verify, no_offline=False):
|
|
257
256
|
key=key,
|
258
257
|
relogin=relogin,
|
259
258
|
verify=verify,
|
259
|
+
referrer="models",
|
260
260
|
)
|
261
261
|
|
262
262
|
|
wandb/integration/keras/keras.py
CHANGED
@@ -12,8 +12,9 @@ import tensorflow as tf
|
|
12
12
|
import tensorflow.keras.backend as K # noqa: N812
|
13
13
|
|
14
14
|
import wandb
|
15
|
+
from wandb.proto.wandb_deprecated import Deprecated
|
15
16
|
from wandb.sdk.integration_utils.data_logging import ValidationDataLogger
|
16
|
-
from wandb.sdk.lib.deprecate import
|
17
|
+
from wandb.sdk.lib.deprecate import deprecate
|
17
18
|
from wandb.util import add_import_hook
|
18
19
|
|
19
20
|
|
@@ -18,6 +18,7 @@ will be raised when importing this module.
|
|
18
18
|
from packaging import version
|
19
19
|
|
20
20
|
import wandb.util
|
21
|
+
from wandb.proto.wandb_deprecated import Deprecated
|
21
22
|
from wandb.sdk.lib import deprecate
|
22
23
|
|
23
24
|
langchain = wandb.util.get_module(
|
@@ -40,7 +41,7 @@ class WandbTracer(WandbTracer):
|
|
40
41
|
def __init__(self, *args, **kwargs):
|
41
42
|
super().__init__(*args, **kwargs)
|
42
43
|
deprecate.deprecate(
|
43
|
-
field_name=
|
44
|
+
field_name=Deprecated.langchain_tracer,
|
44
45
|
warning_message="This feature is deprecated and has been moved to `langchain`. Enable tracing by setting "
|
45
46
|
"LANGCHAIN_WANDB_TRACING=true in your environment. See the documentation at "
|
46
47
|
"https://python.langchain.com/docs/ecosystem/integrations/agent_with_wandb_tracing for guidance. "
|
@@ -13,6 +13,7 @@ import inspect
|
|
13
13
|
import pickle
|
14
14
|
from functools import wraps
|
15
15
|
from pathlib import Path
|
16
|
+
from typing import Union
|
16
17
|
|
17
18
|
import wandb
|
18
19
|
from wandb.sdk.lib import telemetry as wb_telemetry
|
@@ -25,17 +26,18 @@ except ImportError as e:
|
|
25
26
|
) from e
|
26
27
|
|
27
28
|
try:
|
28
|
-
from
|
29
|
+
from plum import dispatch
|
29
30
|
except ImportError as e:
|
30
31
|
raise Exception(
|
31
|
-
"Error: `
|
32
|
+
"Error: `plum-dispatch` not installed >> "
|
33
|
+
"This integration requires plum-dispatch! To fix, please `pip install -Uqq plum-dispatch`"
|
32
34
|
) from e
|
33
35
|
|
34
36
|
|
35
37
|
try:
|
36
38
|
import pandas as pd
|
37
39
|
|
38
|
-
@
|
40
|
+
@dispatch # noqa: F811
|
39
41
|
def _wandb_use(
|
40
42
|
name: str,
|
41
43
|
data: pd.DataFrame,
|
@@ -52,7 +54,7 @@ try:
|
|
52
54
|
run.use_artifact(f"{name}:latest")
|
53
55
|
wandb.termlog(f"Using artifact: {name} ({type(data)})")
|
54
56
|
|
55
|
-
@
|
57
|
+
@dispatch # noqa: F811
|
56
58
|
def wandb_track(
|
57
59
|
name: str,
|
58
60
|
data: pd.DataFrame,
|
@@ -81,7 +83,7 @@ try:
|
|
81
83
|
import torch
|
82
84
|
import torch.nn as nn
|
83
85
|
|
84
|
-
@
|
86
|
+
@dispatch # noqa: F811
|
85
87
|
def _wandb_use(
|
86
88
|
name: str,
|
87
89
|
data: nn.Module,
|
@@ -98,7 +100,7 @@ try:
|
|
98
100
|
run.use_artifact(f"{name}:latest")
|
99
101
|
wandb.termlog(f"Using artifact: {name} ({type(data)})")
|
100
102
|
|
101
|
-
@
|
103
|
+
@dispatch # noqa: F811
|
102
104
|
def wandb_track(
|
103
105
|
name: str,
|
104
106
|
data: nn.Module,
|
@@ -126,7 +128,7 @@ except ImportError:
|
|
126
128
|
try:
|
127
129
|
from sklearn.base import BaseEstimator
|
128
130
|
|
129
|
-
@
|
131
|
+
@dispatch # noqa: F811
|
130
132
|
def _wandb_use(
|
131
133
|
name: str,
|
132
134
|
data: BaseEstimator,
|
@@ -143,7 +145,7 @@ try:
|
|
143
145
|
run.use_artifact(f"{name}:latest")
|
144
146
|
wandb.termlog(f"Using artifact: {name} ({type(data)})")
|
145
147
|
|
146
|
-
@
|
148
|
+
@dispatch # noqa: F811
|
147
149
|
def wandb_track(
|
148
150
|
name: str,
|
149
151
|
data: BaseEstimator,
|
@@ -192,10 +194,10 @@ class ArtifactProxy:
|
|
192
194
|
return getattr(self.flow, key)
|
193
195
|
|
194
196
|
|
195
|
-
@
|
197
|
+
@dispatch # noqa: F811
|
196
198
|
def wandb_track(
|
197
199
|
name: str,
|
198
|
-
data:
|
200
|
+
data: Union[dict, list, set, str, int, float, bool],
|
199
201
|
run=None,
|
200
202
|
testing=False,
|
201
203
|
*args,
|
@@ -207,7 +209,7 @@ def wandb_track(
|
|
207
209
|
run.log({name: data})
|
208
210
|
|
209
211
|
|
210
|
-
@
|
212
|
+
@dispatch # noqa: F811
|
211
213
|
def wandb_track(
|
212
214
|
name: str, data: Path, datasets=False, run=None, testing=False, *args, **kwargs
|
213
215
|
):
|
@@ -225,7 +227,7 @@ def wandb_track(
|
|
225
227
|
|
226
228
|
|
227
229
|
# this is the base case
|
228
|
-
@
|
230
|
+
@dispatch # noqa: F811
|
229
231
|
def wandb_track(
|
230
232
|
name: str, data, others=False, run=None, testing=False, *args, **kwargs
|
231
233
|
):
|
@@ -240,7 +242,7 @@ def wandb_track(
|
|
240
242
|
wandb.termlog(f"Logging artifact: {name} ({type(data)})")
|
241
243
|
|
242
244
|
|
243
|
-
@
|
245
|
+
@dispatch # noqa: F811
|
244
246
|
def wandb_use(name: str, data, *args, **kwargs):
|
245
247
|
try:
|
246
248
|
return _wandb_use(name, data, *args, **kwargs)
|
@@ -252,14 +254,14 @@ def wandb_use(name: str, data, *args, **kwargs):
|
|
252
254
|
)
|
253
255
|
|
254
256
|
|
255
|
-
@
|
257
|
+
@dispatch # noqa: F811
|
256
258
|
def wandb_use(
|
257
|
-
name: str, data:
|
259
|
+
name: str, data: Union[dict, list, set, str, int, float, bool], *args, **kwargs
|
258
260
|
): # type: ignore
|
259
261
|
pass # do nothing for these types
|
260
262
|
|
261
263
|
|
262
|
-
@
|
264
|
+
@dispatch # noqa: F811
|
263
265
|
def _wandb_use(
|
264
266
|
name: str, data: Path, datasets=False, run=None, testing=False, *args, **kwargs
|
265
267
|
): # type: ignore
|
@@ -271,7 +273,7 @@ def _wandb_use(
|
|
271
273
|
wandb.termlog(f"Using artifact: {name} ({type(data)})")
|
272
274
|
|
273
275
|
|
274
|
-
@
|
276
|
+
@dispatch # noqa: F811
|
275
277
|
def _wandb_use(name: str, data, others=False, run=None, testing=False, *args, **kwargs): # type: ignore
|
276
278
|
if testing:
|
277
279
|
return "others" if others else None
|
@@ -23,7 +23,7 @@ class WandbObserver(RunObserver):
|
|
23
23
|
job_type — the type of job you are logging, e.g. eval, worker, ps (default: training)
|
24
24
|
save_code — save the main python or notebook file to wandb to enable diffing (default: editable from your settings page)
|
25
25
|
group — a string by which to group other runs; see Grouping
|
26
|
-
reinit —
|
26
|
+
reinit — Shorthand for the reinit setting that defines what to do when `wandb.init()` is called while a run is active. See the setting's documentation.
|
27
27
|
id — A unique ID for this run primarily used for Resuming. It must be globally unique, and if you delete a run you can't reuse the ID. Use the name field for a descriptive, useful name for the run. The ID cannot contain special characters.
|
28
28
|
resume — if set to True, the run auto resumes; can also be a unique string for manual resuming; see Resuming (default: False)
|
29
29
|
anonymous — can be "allow", "never", or "must". This enables or explicitly disables anonymous logging. (default: never)
|