wandb 0.19.8__py3-none-any.whl → 0.19.10__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.
Files changed (153) hide show
  1. wandb/__init__.py +5 -1
  2. wandb/__init__.pyi +15 -8
  3. wandb/_pydantic/__init__.py +30 -0
  4. wandb/_pydantic/base.py +148 -0
  5. wandb/_pydantic/utils.py +66 -0
  6. wandb/_pydantic/v1_compat.py +284 -0
  7. wandb/apis/paginator.py +82 -38
  8. wandb/apis/public/__init__.py +2 -2
  9. wandb/apis/public/api.py +111 -53
  10. wandb/apis/public/artifacts.py +387 -639
  11. wandb/apis/public/automations.py +69 -0
  12. wandb/apis/public/files.py +2 -2
  13. wandb/apis/public/integrations.py +168 -0
  14. wandb/apis/public/projects.py +32 -2
  15. wandb/apis/public/reports.py +2 -2
  16. wandb/apis/public/runs.py +19 -11
  17. wandb/apis/public/utils.py +107 -1
  18. wandb/automations/__init__.py +81 -0
  19. wandb/automations/_filters/__init__.py +40 -0
  20. wandb/automations/_filters/expressions.py +179 -0
  21. wandb/automations/_filters/operators.py +267 -0
  22. wandb/automations/_filters/run_metrics.py +183 -0
  23. wandb/automations/_generated/__init__.py +184 -0
  24. wandb/automations/_generated/create_filter_trigger.py +21 -0
  25. wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
  26. wandb/automations/_generated/delete_trigger.py +19 -0
  27. wandb/automations/_generated/enums.py +33 -0
  28. wandb/automations/_generated/fragments.py +343 -0
  29. wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
  30. wandb/automations/_generated/get_triggers.py +24 -0
  31. wandb/automations/_generated/get_triggers_by_entity.py +24 -0
  32. wandb/automations/_generated/input_types.py +104 -0
  33. wandb/automations/_generated/integrations_by_entity.py +22 -0
  34. wandb/automations/_generated/operations.py +710 -0
  35. wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
  36. wandb/automations/_generated/update_filter_trigger.py +21 -0
  37. wandb/automations/_utils.py +123 -0
  38. wandb/automations/_validators.py +73 -0
  39. wandb/automations/actions.py +205 -0
  40. wandb/automations/automations.py +109 -0
  41. wandb/automations/events.py +235 -0
  42. wandb/automations/integrations.py +26 -0
  43. wandb/automations/scopes.py +76 -0
  44. wandb/beta/workflows.py +9 -10
  45. wandb/bin/gpu_stats +0 -0
  46. wandb/cli/cli.py +3 -3
  47. wandb/integration/keras/keras.py +2 -1
  48. wandb/integration/langchain/wandb_tracer.py +2 -1
  49. wandb/integration/metaflow/metaflow.py +19 -17
  50. wandb/integration/sacred/__init__.py +1 -1
  51. wandb/jupyter.py +155 -133
  52. wandb/old/summary.py +0 -2
  53. wandb/proto/v3/wandb_internal_pb2.py +297 -292
  54. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  55. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  56. wandb/proto/v4/wandb_internal_pb2.py +292 -292
  57. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  58. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  59. wandb/proto/v5/wandb_internal_pb2.py +292 -292
  60. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  61. wandb/proto/v5/wandb_telemetry_pb2.py +10 -10
  62. wandb/proto/v6/wandb_base_pb2.py +41 -0
  63. wandb/proto/v6/wandb_internal_pb2.py +393 -0
  64. wandb/proto/v6/wandb_server_pb2.py +78 -0
  65. wandb/proto/v6/wandb_settings_pb2.py +58 -0
  66. wandb/proto/v6/wandb_telemetry_pb2.py +52 -0
  67. wandb/proto/wandb_base_pb2.py +2 -0
  68. wandb/proto/wandb_deprecated.py +10 -0
  69. wandb/proto/wandb_internal_pb2.py +3 -1
  70. wandb/proto/wandb_server_pb2.py +2 -0
  71. wandb/proto/wandb_settings_pb2.py +2 -0
  72. wandb/proto/wandb_telemetry_pb2.py +2 -0
  73. wandb/sdk/artifacts/_generated/__init__.py +248 -0
  74. wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +43 -0
  75. wandb/sdk/artifacts/_generated/artifact_version_files.py +36 -0
  76. wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +36 -0
  77. wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +25 -0
  78. wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +35 -0
  79. wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +35 -0
  80. wandb/sdk/artifacts/_generated/enums.py +17 -0
  81. wandb/sdk/artifacts/_generated/fragments.py +186 -0
  82. wandb/sdk/artifacts/_generated/input_types.py +16 -0
  83. wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
  84. wandb/sdk/artifacts/_generated/operations.py +510 -0
  85. wandb/sdk/artifacts/_generated/project_artifact_collection.py +101 -0
  86. wandb/sdk/artifacts/_generated/project_artifact_collections.py +33 -0
  87. wandb/sdk/artifacts/_generated/project_artifact_type.py +24 -0
  88. wandb/sdk/artifacts/_generated/project_artifact_types.py +24 -0
  89. wandb/sdk/artifacts/_generated/project_artifacts.py +42 -0
  90. wandb/sdk/artifacts/_generated/run_input_artifacts.py +51 -0
  91. wandb/sdk/artifacts/_generated/run_output_artifacts.py +51 -0
  92. wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +35 -0
  93. wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
  94. wandb/sdk/artifacts/_graphql_fragments.py +56 -81
  95. wandb/sdk/artifacts/_validators.py +1 -0
  96. wandb/sdk/artifacts/artifact.py +110 -49
  97. wandb/sdk/artifacts/artifact_manifest_entry.py +2 -1
  98. wandb/sdk/artifacts/artifact_saver.py +16 -2
  99. wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
  100. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +23 -2
  101. wandb/sdk/data_types/audio.py +1 -3
  102. wandb/sdk/data_types/base_types/media.py +13 -7
  103. wandb/sdk/data_types/base_types/wb_value.py +34 -11
  104. wandb/sdk/data_types/html.py +36 -9
  105. wandb/sdk/data_types/image.py +56 -37
  106. wandb/sdk/data_types/molecule.py +1 -5
  107. wandb/sdk/data_types/object_3d.py +2 -1
  108. wandb/sdk/data_types/saved_model.py +7 -9
  109. wandb/sdk/data_types/table.py +5 -0
  110. wandb/sdk/data_types/trace_tree.py +2 -0
  111. wandb/sdk/data_types/utils.py +1 -1
  112. wandb/sdk/data_types/video.py +15 -30
  113. wandb/sdk/interface/interface.py +2 -0
  114. wandb/{apis/public → sdk/internal}/_generated/__init__.py +0 -6
  115. wandb/{apis/public → sdk/internal}/_generated/server_features_query.py +3 -3
  116. wandb/sdk/internal/internal_api.py +138 -47
  117. wandb/sdk/internal/profiler.py +6 -5
  118. wandb/sdk/internal/run.py +13 -6
  119. wandb/sdk/internal/sender.py +2 -0
  120. wandb/sdk/internal/sender_config.py +8 -11
  121. wandb/sdk/internal/settings_static.py +24 -2
  122. wandb/sdk/lib/apikey.py +40 -20
  123. wandb/sdk/lib/asyncio_compat.py +1 -1
  124. wandb/sdk/lib/deprecate.py +13 -22
  125. wandb/sdk/lib/disabled.py +2 -1
  126. wandb/sdk/lib/printer.py +37 -8
  127. wandb/sdk/lib/printer_asyncio.py +46 -0
  128. wandb/sdk/lib/redirect.py +10 -5
  129. wandb/sdk/lib/run_moment.py +4 -6
  130. wandb/sdk/lib/wb_logging.py +161 -0
  131. wandb/sdk/service/server_sock.py +19 -14
  132. wandb/sdk/service/service.py +9 -7
  133. wandb/sdk/service/streams.py +5 -0
  134. wandb/sdk/verify/verify.py +6 -3
  135. wandb/sdk/wandb_config.py +44 -43
  136. wandb/sdk/wandb_init.py +323 -141
  137. wandb/sdk/wandb_login.py +13 -4
  138. wandb/sdk/wandb_metadata.py +107 -91
  139. wandb/sdk/wandb_run.py +529 -325
  140. wandb/sdk/wandb_settings.py +422 -202
  141. wandb/sdk/wandb_setup.py +52 -1
  142. wandb/util.py +29 -29
  143. {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/METADATA +7 -7
  144. {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/RECORD +150 -93
  145. wandb/_globals.py +0 -19
  146. wandb/apis/public/_generated/base.py +0 -128
  147. wandb/apis/public/_generated/typing_compat.py +0 -14
  148. /wandb/{apis/public → sdk/internal}/_generated/enums.py +0 -0
  149. /wandb/{apis/public → sdk/internal}/_generated/input_types.py +0 -0
  150. /wandb/{apis/public → sdk/internal}/_generated/operations.py +0 -0
  151. {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/WHEEL +0 -0
  152. {wandb-0.19.8.dist-info → wandb-0.19.10.dist-info}/entry_points.txt +0 -0
  153. {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
- if wandb.run is None:
89
+ run = wandb_setup._setup(start_service=False).most_recent_active_run
90
+ if not run:
89
91
  run = wandb.init(
90
- project=project, job_type=job_type, settings=wandb.Settings(silent="true")
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 `wandb.log(...)` and more.
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 wandb.run:
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 wandb.run:
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/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 {log_file} for full traceback.\n"
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
 
@@ -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 Deprecated, deprecate
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=deprecate.Deprecated.langchain_tracer,
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 fastcore.all import typedispatch
29
+ from plum import dispatch
29
30
  except ImportError as e:
30
31
  raise Exception(
31
- "Error: `fastcore` not installed >> This integration requires fastcore! To fix, please `pip install -Uqq fastcore`"
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
197
+ @dispatch # noqa: F811
196
198
  def wandb_track(
197
199
  name: str,
198
- data: (dict, list, set, str, int, float, bool),
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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
- @typedispatch
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
- @typedispatch # noqa: F811
257
+ @dispatch # noqa: F811
256
258
  def wandb_use(
257
- name: str, data: (dict, list, set, str, int, float, bool), *args, **kwargs
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
- @typedispatch # noqa: F811
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
- @typedispatch # noqa: F811
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 — whether to allow multiple calls to wandb.init in the same process (default: False)
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)