wandb 0.21.0__py3-none-win_amd64.whl → 0.21.2__py3-none-win_amd64.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 +16 -14
  2. wandb/__init__.pyi +427 -450
  3. wandb/agents/pyagent.py +41 -12
  4. wandb/analytics/sentry.py +7 -2
  5. wandb/apis/importers/mlflow.py +1 -1
  6. wandb/apis/public/__init__.py +1 -1
  7. wandb/apis/public/api.py +525 -360
  8. wandb/apis/public/artifacts.py +207 -13
  9. wandb/apis/public/automations.py +19 -3
  10. wandb/apis/public/files.py +172 -33
  11. wandb/apis/public/history.py +67 -15
  12. wandb/apis/public/integrations.py +25 -2
  13. wandb/apis/public/jobs.py +90 -2
  14. wandb/apis/public/projects.py +130 -79
  15. wandb/apis/public/query_generator.py +11 -1
  16. wandb/apis/public/registries/_utils.py +14 -16
  17. wandb/apis/public/registries/registries_search.py +183 -304
  18. wandb/apis/public/reports.py +96 -15
  19. wandb/apis/public/runs.py +299 -105
  20. wandb/apis/public/sweeps.py +222 -22
  21. wandb/apis/public/teams.py +41 -4
  22. wandb/apis/public/users.py +45 -4
  23. wandb/automations/_generated/delete_automation.py +1 -3
  24. wandb/automations/_generated/enums.py +13 -11
  25. wandb/beta/workflows.py +66 -30
  26. wandb/bin/gpu_stats.exe +0 -0
  27. wandb/bin/wandb-core +0 -0
  28. wandb/cli/cli.py +127 -3
  29. wandb/env.py +8 -0
  30. wandb/errors/errors.py +4 -1
  31. wandb/integration/lightning/fabric/logger.py +3 -4
  32. wandb/integration/metaflow/__init__.py +6 -0
  33. wandb/integration/metaflow/data_pandas.py +74 -0
  34. wandb/integration/metaflow/data_pytorch.py +75 -0
  35. wandb/integration/metaflow/data_sklearn.py +76 -0
  36. wandb/integration/metaflow/errors.py +13 -0
  37. wandb/integration/metaflow/metaflow.py +167 -223
  38. wandb/integration/openai/fine_tuning.py +1 -2
  39. wandb/integration/weave/__init__.py +6 -0
  40. wandb/integration/weave/interface.py +49 -0
  41. wandb/integration/weave/weave.py +63 -0
  42. wandb/jupyter.py +5 -5
  43. wandb/plot/custom_chart.py +30 -7
  44. wandb/proto/v3/wandb_internal_pb2.py +281 -280
  45. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  46. wandb/proto/v4/wandb_internal_pb2.py +280 -280
  47. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  48. wandb/proto/v5/wandb_internal_pb2.py +280 -280
  49. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  50. wandb/proto/v6/wandb_internal_pb2.py +280 -280
  51. wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
  52. wandb/proto/wandb_deprecated.py +6 -0
  53. wandb/sdk/artifacts/_factories.py +17 -0
  54. wandb/sdk/artifacts/_generated/__init__.py +221 -13
  55. wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
  56. wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
  57. wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
  58. wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
  59. wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
  60. wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
  61. wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
  62. wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
  63. wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
  64. wandb/sdk/artifacts/_generated/enums.py +5 -0
  65. wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
  66. wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
  67. wandb/sdk/artifacts/_generated/fragments.py +279 -41
  68. wandb/sdk/artifacts/_generated/link_artifact.py +6 -0
  69. wandb/sdk/artifacts/_generated/operations.py +654 -51
  70. wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
  71. wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
  72. wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
  73. wandb/sdk/artifacts/_graphql_fragments.py +3 -86
  74. wandb/sdk/artifacts/_internal_artifact.py +19 -8
  75. wandb/sdk/artifacts/_validators.py +14 -4
  76. wandb/sdk/artifacts/artifact.py +512 -618
  77. wandb/sdk/artifacts/artifact_file_cache.py +10 -6
  78. wandb/sdk/artifacts/artifact_manifest.py +10 -9
  79. wandb/sdk/artifacts/artifact_manifest_entry.py +9 -10
  80. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +5 -3
  81. wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -1
  82. wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
  83. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -1
  84. wandb/sdk/data_types/audio.py +38 -10
  85. wandb/sdk/data_types/base_types/media.py +6 -56
  86. wandb/sdk/data_types/graph.py +48 -14
  87. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
  88. wandb/sdk/data_types/helper_types/image_mask.py +1 -3
  89. wandb/sdk/data_types/histogram.py +34 -21
  90. wandb/sdk/data_types/html.py +35 -12
  91. wandb/sdk/data_types/image.py +104 -68
  92. wandb/sdk/data_types/molecule.py +32 -19
  93. wandb/sdk/data_types/object_3d.py +36 -17
  94. wandb/sdk/data_types/plotly.py +18 -5
  95. wandb/sdk/data_types/saved_model.py +4 -6
  96. wandb/sdk/data_types/table.py +59 -30
  97. wandb/sdk/data_types/video.py +53 -26
  98. wandb/sdk/integration_utils/auto_logging.py +2 -2
  99. wandb/sdk/interface/interface_queue.py +1 -4
  100. wandb/sdk/interface/interface_shared.py +26 -37
  101. wandb/sdk/interface/interface_sock.py +24 -14
  102. wandb/sdk/internal/internal_api.py +6 -0
  103. wandb/sdk/internal/job_builder.py +6 -0
  104. wandb/sdk/internal/settings_static.py +2 -3
  105. wandb/sdk/launch/agent/agent.py +8 -1
  106. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
  107. wandb/sdk/launch/create_job.py +15 -2
  108. wandb/sdk/launch/inputs/internal.py +3 -4
  109. wandb/sdk/launch/inputs/schema.py +1 -0
  110. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  111. wandb/sdk/launch/runner/kubernetes_runner.py +323 -1
  112. wandb/sdk/launch/sweeps/scheduler.py +2 -3
  113. wandb/sdk/lib/asyncio_compat.py +19 -16
  114. wandb/sdk/lib/asyncio_manager.py +252 -0
  115. wandb/sdk/lib/deprecate.py +1 -7
  116. wandb/sdk/lib/disabled.py +1 -1
  117. wandb/sdk/lib/hashutil.py +27 -5
  118. wandb/sdk/lib/module.py +7 -13
  119. wandb/sdk/lib/printer.py +2 -2
  120. wandb/sdk/lib/printer_asyncio.py +3 -1
  121. wandb/sdk/lib/progress.py +0 -19
  122. wandb/sdk/lib/retry.py +185 -78
  123. wandb/sdk/lib/service/service_client.py +106 -0
  124. wandb/sdk/lib/service/service_connection.py +20 -26
  125. wandb/sdk/lib/service/service_token.py +30 -13
  126. wandb/sdk/mailbox/mailbox.py +13 -5
  127. wandb/sdk/mailbox/mailbox_handle.py +22 -13
  128. wandb/sdk/mailbox/response_handle.py +42 -106
  129. wandb/sdk/mailbox/wait_with_progress.py +7 -42
  130. wandb/sdk/wandb_init.py +77 -116
  131. wandb/sdk/wandb_login.py +19 -15
  132. wandb/sdk/wandb_metric.py +2 -0
  133. wandb/sdk/wandb_run.py +497 -469
  134. wandb/sdk/wandb_settings.py +145 -4
  135. wandb/sdk/wandb_setup.py +204 -124
  136. wandb/sdk/wandb_sweep.py +14 -13
  137. wandb/sdk/wandb_watch.py +4 -6
  138. wandb/sync/sync.py +10 -0
  139. wandb/util.py +58 -1
  140. wandb/wandb_run.py +1 -2
  141. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/METADATA +1 -1
  142. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/RECORD +145 -129
  143. wandb/sdk/interface/interface_relay.py +0 -38
  144. wandb/sdk/interface/router.py +0 -89
  145. wandb/sdk/interface/router_queue.py +0 -43
  146. wandb/sdk/interface/router_relay.py +0 -50
  147. wandb/sdk/interface/router_sock.py +0 -32
  148. wandb/sdk/lib/sock_client.py +0 -236
  149. wandb/vendor/pynvml/__init__.py +0 -0
  150. wandb/vendor/pynvml/pynvml.py +0 -4779
  151. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/WHEEL +0 -0
  152. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/entry_points.txt +0 -0
  153. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,13 @@
1
+ import wandb
2
+
3
+
4
+ class MissingDependencyError(Exception):
5
+ """An optional dependency is missing."""
6
+
7
+ def __init__(self, *args: object, warning: str) -> None:
8
+ super().__init__(*args)
9
+ self._wb_warning = warning
10
+
11
+ def warn(self) -> None:
12
+ """Print a warning for the problem."""
13
+ wandb.termwarn(self._wb_warning)
@@ -1,174 +1,40 @@
1
- """W&B Integration for Metaflow.
2
-
3
- This integration lets users apply decorators to Metaflow flows and steps to automatically log parameters and artifacts to W&B by type dispatch.
4
-
5
- - Decorating a step will enable or disable logging for certain types within that step
6
- - Decorating the flow is equivalent to decorating all steps with a default
7
- - Decorating a step after decorating the flow will overwrite the flow decoration
8
-
9
- Examples can be found at wandb/wandb/functional_tests/metaflow
10
- """
11
-
12
1
  import inspect
13
2
  import pickle
14
3
  from functools import wraps
15
4
  from pathlib import Path
16
- from typing import Union
5
+ from typing import Optional, Union
17
6
 
18
7
  import wandb
19
8
  from wandb.sdk.lib import telemetry as wb_telemetry
20
9
 
21
- try:
22
- from metaflow import current
23
- except ImportError as e:
24
- raise Exception(
25
- "Error: `metaflow` not installed >> This integration requires metaflow! To fix, please `pip install -Uqq metaflow`"
26
- ) from e
10
+ from . import errors
27
11
 
28
12
  try:
29
- from plum import dispatch
13
+ from metaflow import current
30
14
  except ImportError as e:
31
15
  raise Exception(
32
- "Error: `plum-dispatch` not installed >> "
33
- "This integration requires plum-dispatch! To fix, please `pip install -Uqq plum-dispatch`"
16
+ "Error: `metaflow` not installed >> This integration requires metaflow!"
17
+ " To fix, please `pip install -Uqq metaflow`"
34
18
  ) from e
35
19
 
36
20
 
37
21
  try:
38
- import pandas as pd
39
-
40
- @dispatch
41
- def _wandb_use(
42
- name: str,
43
- data: pd.DataFrame,
44
- datasets=False,
45
- run=None,
46
- testing=False,
47
- *args,
48
- **kwargs,
49
- ): # type: ignore
50
- if testing:
51
- return "datasets" if datasets else None
52
-
53
- if datasets:
54
- run.use_artifact(f"{name}:latest")
55
- wandb.termlog(f"Using artifact: {name} ({type(data)})")
56
-
57
- @dispatch
58
- def wandb_track(
59
- name: str,
60
- data: pd.DataFrame,
61
- datasets=False,
62
- run=None,
63
- testing=False,
64
- *args,
65
- **kwargs,
66
- ):
67
- if testing:
68
- return "pd.DataFrame" if datasets else None
69
-
70
- if datasets:
71
- artifact = wandb.Artifact(name, type="dataset")
72
- with artifact.new_file(f"{name}.parquet", "wb") as f:
73
- data.to_parquet(f, engine="pyarrow")
74
- run.log_artifact(artifact)
75
- wandb.termlog(f"Logging artifact: {name} ({type(data)})")
76
-
77
- except ImportError:
78
- wandb.termwarn(
79
- "`pandas` not installed >> @wandb_log(datasets=True) may not auto log your dataset!"
80
- )
22
+ from . import data_pandas
23
+ except errors.MissingDependencyError as e:
24
+ e.warn()
25
+ data_pandas = None
81
26
 
82
27
  try:
83
- import torch
84
- import torch.nn as nn
85
-
86
- @dispatch
87
- def _wandb_use(
88
- name: str,
89
- data: nn.Module,
90
- models=False,
91
- run=None,
92
- testing=False,
93
- *args,
94
- **kwargs,
95
- ): # type: ignore
96
- if testing:
97
- return "models" if models else None
98
-
99
- if models:
100
- run.use_artifact(f"{name}:latest")
101
- wandb.termlog(f"Using artifact: {name} ({type(data)})")
102
-
103
- @dispatch
104
- def wandb_track(
105
- name: str,
106
- data: nn.Module,
107
- models=False,
108
- run=None,
109
- testing=False,
110
- *args,
111
- **kwargs,
112
- ):
113
- if testing:
114
- return "nn.Module" if models else None
115
-
116
- if models:
117
- artifact = wandb.Artifact(name, type="model")
118
- with artifact.new_file(f"{name}.pkl", "wb") as f:
119
- torch.save(data, f)
120
- run.log_artifact(artifact)
121
- wandb.termlog(f"Logging artifact: {name} ({type(data)})")
122
-
123
- except ImportError:
124
- wandb.termwarn(
125
- "`pytorch` not installed >> @wandb_log(models=True) may not auto log your model!"
126
- )
28
+ from . import data_pytorch
29
+ except errors.MissingDependencyError as e:
30
+ e.warn()
31
+ data_pytorch = None
127
32
 
128
33
  try:
129
- from sklearn.base import BaseEstimator
130
-
131
- @dispatch
132
- def _wandb_use(
133
- name: str,
134
- data: BaseEstimator,
135
- models=False,
136
- run=None,
137
- testing=False,
138
- *args,
139
- **kwargs,
140
- ): # type: ignore
141
- if testing:
142
- return "models" if models else None
143
-
144
- if models:
145
- run.use_artifact(f"{name}:latest")
146
- wandb.termlog(f"Using artifact: {name} ({type(data)})")
147
-
148
- @dispatch
149
- def wandb_track(
150
- name: str,
151
- data: BaseEstimator,
152
- models=False,
153
- run=None,
154
- testing=False,
155
- *args,
156
- **kwargs,
157
- ):
158
- if testing:
159
- return "BaseEstimator" if models else None
160
-
161
- if models:
162
- artifact = wandb.Artifact(name, type="model")
163
- with artifact.new_file(f"{name}.pkl", "wb") as f:
164
- pickle.dump(data, f)
165
- run.log_artifact(artifact)
166
- wandb.termlog(f"Logging artifact: {name} ({type(data)})")
167
-
168
- except ImportError:
169
- wandb.termwarn(
170
- "`sklearn` not installed >> @wandb_log(models=True) may not auto log your model!"
171
- )
34
+ from . import data_sklearn
35
+ except errors.MissingDependencyError as e:
36
+ e.warn()
37
+ data_sklearn = None
172
38
 
173
39
 
174
40
  class ArtifactProxy:
@@ -194,93 +60,166 @@ class ArtifactProxy:
194
60
  return getattr(self.flow, key)
195
61
 
196
62
 
197
- @dispatch
198
- def wandb_track(
63
+ def _track_scalar(
199
64
  name: str,
200
65
  data: Union[dict, list, set, str, int, float, bool],
201
- run=None,
202
- testing=False,
203
- *args,
204
- **kwargs,
205
- ): # type: ignore
66
+ run,
67
+ testing: bool = False,
68
+ ) -> Optional[str]:
206
69
  if testing:
207
70
  return "scalar"
208
71
 
209
72
  run.log({name: data})
73
+ return None
210
74
 
211
75
 
212
- @dispatch
213
- def wandb_track(
214
- name: str, data: Path, datasets=False, run=None, testing=False, *args, **kwargs
215
- ):
76
+ def _track_path(
77
+ name: str,
78
+ data: Path,
79
+ run,
80
+ testing: bool = False,
81
+ ) -> Optional[str]:
216
82
  if testing:
217
- return "Path" if datasets else None
83
+ return "Path"
218
84
 
219
- if datasets:
220
- artifact = wandb.Artifact(name, type="dataset")
221
- if data.is_dir():
222
- artifact.add_dir(data)
223
- elif data.is_file():
224
- artifact.add_file(data)
225
- run.log_artifact(artifact)
226
- wandb.termlog(f"Logging artifact: {name} ({type(data)})")
85
+ artifact = wandb.Artifact(name, type="dataset")
86
+ if data.is_dir():
87
+ artifact.add_dir(data)
88
+ elif data.is_file():
89
+ artifact.add_file(data)
90
+ run.log_artifact(artifact)
91
+ wandb.termlog(f"Logging artifact: {name} ({type(data)})")
92
+ return None
227
93
 
228
94
 
229
- # this is the base case
230
- @dispatch
231
- def wandb_track(
232
- name: str, data, others=False, run=None, testing=False, *args, **kwargs
233
- ):
95
+ def _track_generic(
96
+ name: str,
97
+ data,
98
+ run,
99
+ testing: bool = False,
100
+ ) -> Optional[str]:
234
101
  if testing:
235
- return "generic" if others else None
102
+ return "generic"
103
+
104
+ artifact = wandb.Artifact(name, type="other")
105
+ with artifact.new_file(f"{name}.pkl", "wb") as f:
106
+ pickle.dump(data, f)
107
+ run.log_artifact(artifact)
108
+ wandb.termlog(f"Logging artifact: {name} ({type(data)})")
109
+ return None
110
+
236
111
 
112
+ def wandb_track(
113
+ name: str,
114
+ data,
115
+ datasets: bool = False,
116
+ models: bool = False,
117
+ others: bool = False,
118
+ run: Optional[wandb.Run] = None,
119
+ testing: bool = False,
120
+ ) -> Optional[str]:
121
+ """Track data as wandb artifacts based on type and flags."""
122
+ # Check for pandas DataFrame
123
+ if data_pandas and data_pandas.is_dataframe(data) and datasets:
124
+ return data_pandas.track_dataframe(name, data, run, testing)
125
+
126
+ # Check for PyTorch Module
127
+ if data_pytorch and data_pytorch.is_nn_module(data) and models:
128
+ return data_pytorch.track_nn_module(name, data, run, testing)
129
+
130
+ # Check for scikit-learn BaseEstimator
131
+ if data_sklearn and data_sklearn.is_estimator(data) and models:
132
+ return data_sklearn.track_estimator(name, data, run, testing)
133
+
134
+ # Check for Path objects
135
+ if isinstance(data, Path) and datasets:
136
+ return _track_path(name, data, run, testing)
137
+
138
+ # Check for scalar types
139
+ if isinstance(data, (dict, list, set, str, int, float, bool)):
140
+ return _track_scalar(name, data, run, testing)
141
+
142
+ # Generic fallback
237
143
  if others:
238
- artifact = wandb.Artifact(name, type="other")
239
- with artifact.new_file(f"{name}.pkl", "wb") as f:
240
- pickle.dump(data, f)
241
- run.log_artifact(artifact)
242
- wandb.termlog(f"Logging artifact: {name} ({type(data)})")
144
+ return _track_generic(name, data, run, testing)
145
+
146
+ # No action taken
147
+ return None
243
148
 
244
149
 
245
- @dispatch
246
- def wandb_use(name: str, data, *args, **kwargs):
150
+ def wandb_use(
151
+ name: str,
152
+ data,
153
+ datasets: bool = False,
154
+ models: bool = False,
155
+ others: bool = False,
156
+ run=None,
157
+ testing: bool = False,
158
+ ) -> Optional[str]:
159
+ """Use wandb artifacts based on data type and flags."""
160
+ # Skip scalar types - nothing to use
161
+ if isinstance(data, (dict, list, set, str, int, float, bool)):
162
+ return None
163
+
247
164
  try:
248
- return _wandb_use(name, data, *args, **kwargs)
165
+ # Check for pandas DataFrame
166
+ if data_pandas and data_pandas.is_dataframe(data) and datasets:
167
+ return data_pandas.use_dataframe(name, run, testing)
168
+
169
+ # Check for PyTorch Module
170
+ elif data_pytorch and data_pytorch.is_nn_module(data) and models:
171
+ return data_pytorch.use_nn_module(name, run, testing)
172
+
173
+ # Check for scikit-learn BaseEstimator
174
+ elif data_sklearn and data_sklearn.is_estimator(data) and models:
175
+ return data_sklearn.use_estimator(name, run, testing)
176
+
177
+ # Check for Path objects
178
+ elif isinstance(data, Path) and datasets:
179
+ return _use_path(name, data, run, testing)
180
+
181
+ # Generic fallback
182
+ elif others:
183
+ return _use_generic(name, data, run, testing)
184
+
185
+ else:
186
+ return None
187
+
249
188
  except wandb.CommError:
250
189
  wandb.termwarn(
251
190
  f"This artifact ({name}, {type(data)}) does not exist in the wandb datastore!"
252
- f"If you created an instance inline (e.g. sklearn.ensemble.RandomForestClassifier), then you can safely ignore this"
253
- f"Otherwise you may want to check your internet connection!"
191
+ " If you created an instance inline (e.g. sklearn.ensemble.RandomForestClassifier),"
192
+ " then you can safely ignore this. Otherwise you may want to check your internet connection!"
254
193
  )
194
+ return None
255
195
 
256
196
 
257
- @dispatch
258
- def wandb_use(
259
- name: str, data: Union[dict, list, set, str, int, float, bool], *args, **kwargs
260
- ): # type: ignore
261
- pass # do nothing for these types
262
-
263
-
264
- @dispatch
265
- def _wandb_use(
266
- name: str, data: Path, datasets=False, run=None, testing=False, *args, **kwargs
267
- ): # type: ignore
197
+ def _use_path(
198
+ name: str,
199
+ data: Path,
200
+ run,
201
+ testing: bool = False,
202
+ ) -> Optional[str]:
268
203
  if testing:
269
- return "datasets" if datasets else None
204
+ return "datasets"
270
205
 
271
- if datasets:
272
- run.use_artifact(f"{name}:latest")
273
- wandb.termlog(f"Using artifact: {name} ({type(data)})")
206
+ run.use_artifact(f"{name}:latest")
207
+ wandb.termlog(f"Using artifact: {name} ({type(data)})")
208
+ return None
274
209
 
275
210
 
276
- @dispatch
277
- def _wandb_use(name: str, data, others=False, run=None, testing=False, *args, **kwargs): # type: ignore
211
+ def _use_generic(
212
+ name: str,
213
+ data,
214
+ run,
215
+ testing: bool = False,
216
+ ) -> Optional[str]:
278
217
  if testing:
279
- return "others" if others else None
218
+ return "others"
280
219
 
281
- if others:
282
- run.use_artifact(f"{name}:latest")
283
- wandb.termlog(f"Using artifact: {name} ({type(data)})")
220
+ run.use_artifact(f"{name}:latest")
221
+ wandb.termlog(f"Using artifact: {name} ({type(data)})")
222
+ return None
284
223
 
285
224
 
286
225
  def coalesce(*arg):
@@ -289,25 +228,30 @@ def coalesce(*arg):
289
228
 
290
229
  def wandb_log(
291
230
  func=None,
292
- # /, # py38 only
293
- datasets=False,
294
- models=False,
295
- others=False,
296
- settings=None,
231
+ /,
232
+ datasets: bool = False,
233
+ models: bool = False,
234
+ others: bool = False,
235
+ settings: Optional[wandb.Settings] = None,
297
236
  ):
298
- """Automatically log parameters and artifacts to W&B by type dispatch.
237
+ """Automatically log parameters and artifacts to W&B.
238
+
239
+ This decorator can be applied to a flow, step, or both:
299
240
 
300
- This decorator can be applied to a flow, step, or both.
301
- - Decorating a step will enable or disable logging for certain types within that step
302
- - Decorating the flow is equivalent to decorating all steps with a default
303
- - Decorating a step after decorating the flow will overwrite the flow decoration
241
+ - Decorating a step enables or disables logging within that step
242
+ - Decorating a flow is equivalent to decorating all steps
243
+ - Decorating a step after decorating its flow overwrites the flow decoration
304
244
 
305
245
  Args:
306
- func: (`Callable`). The method or class being decorated (if decorating a step or flow respectively).
307
- datasets: (`bool`). If `True`, log datasets. Datasets can be a `pd.DataFrame` or `pathlib.Path`. The default value is `False`, so datasets are not logged.
308
- models: (`bool`). If `True`, log models. Models can be a `nn.Module` or `sklearn.base.BaseEstimator`. The default value is `False`, so models are not logged.
309
- others: (`bool`). If `True`, log anything pickle-able. The default value is `False`, so files are not logged.
310
- settings: (`wandb.sdk.wandb_settings.Settings`). Custom settings passed to `wandb.init`. The default value is `None`, and is the same as passing `wandb.Settings()`. If `settings.run_group` is `None`, it will be set to `{flow_name}/{run_id}. If `settings.run_job_type` is `None`, it will be set to `{run_job_type}/{step_name}`
246
+ func: The step method or flow class to decorate.
247
+ datasets: Whether to log `pd.DataFrame` and `pathlib.Path`
248
+ types. Defaults to False.
249
+ models: Whether to log `nn.Module` and `sklearn.base.BaseEstimator`
250
+ types. Defaults to False.
251
+ others: If `True`, log anything pickle-able. Defaults to False.
252
+ settings: Custom settings to pass to `wandb.init`.
253
+ If `run_group` is `None`, it is set to `{flow_name}/{run_id}`.
254
+ If `run_job_type` is `None`, it is set to `{run_job_type}/{step_name}`.
311
255
  """
312
256
 
313
257
  @wraps(func)
@@ -14,7 +14,6 @@ import wandb
14
14
  from wandb import util
15
15
  from wandb.data_types import Table
16
16
  from wandb.sdk.lib import telemetry
17
- from wandb.sdk.wandb_run import Run
18
17
 
19
18
  openai = util.get_module(
20
19
  name="openai",
@@ -54,7 +53,7 @@ class WandbLogger:
54
53
  _wandb_api: Optional[wandb.Api] = None
55
54
  _logged_in: bool = False
56
55
  openai_client: Optional[OpenAI] = None
57
- _run: Optional[Run] = None
56
+ _run: Optional[wandb.Run] = None
58
57
 
59
58
  @classmethod
60
59
  def sync(
@@ -0,0 +1,6 @@
1
+ """Weave integration for W&B."""
2
+
3
+ from .interface import RunPath, active_run_path
4
+ from .weave import setup
5
+
6
+ __all__ = ("active_run_path", "RunPath", "setup")
@@ -0,0 +1,49 @@
1
+ """Internal APIs for integrating with weave.
2
+
3
+ The public functions here are intended to be called by weave and care should
4
+ be taken to maintain backward compatibility.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import dataclasses
10
+
11
+ from wandb.sdk import wandb_setup
12
+
13
+
14
+ @dataclasses.dataclass(frozen=True)
15
+ class RunPath:
16
+ entity: str
17
+ """The entity to which the run is logging. Never empty."""
18
+
19
+ project: str
20
+ """The project to which the run is logging. Never empty."""
21
+
22
+ run_id: str
23
+ """The run's ID. Never empty."""
24
+
25
+
26
+ def active_run_path() -> RunPath | None:
27
+ """Returns the path of an initialized, unfinished run.
28
+
29
+ Returns None if all initialized runs are finished. If there is
30
+ more than one active run, an arbitrary path is returned.
31
+ The run may be finished by the time its path is returned.
32
+
33
+ Thread-safe.
34
+ """
35
+ singleton = wandb_setup.singleton()
36
+
37
+ if (
38
+ (run := singleton.most_recent_active_run)
39
+ and run.entity
40
+ and run.project
41
+ and run.id
42
+ ):
43
+ return RunPath(
44
+ entity=run.entity,
45
+ project=run.project,
46
+ run_id=run.id,
47
+ )
48
+
49
+ return None
@@ -0,0 +1,63 @@
1
+ """Integration module for automatic Weave initialization with W&B.
2
+
3
+ This module provides automatic initialization of Weave when:
4
+ 1. Weave is installed
5
+ 2. A W&B run is active with a project
6
+ 3. Weave is imported (init-on-import)
7
+
8
+ The integration can be disabled by setting the WANDB_DISABLE_WEAVE environment variable.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import os
14
+ import sys
15
+ import threading
16
+
17
+ import wandb
18
+
19
+ _weave_init_lock = threading.Lock()
20
+
21
+ _DISABLE_WEAVE = "WANDB_DISABLE_WEAVE"
22
+ _WEAVE_PACKAGE_NAME = "weave"
23
+
24
+
25
+ def setup(entity: str | None, project: str | None) -> None:
26
+ """Set up automatic Weave initialization for the current W&B run.
27
+
28
+ Args:
29
+ project: The W&B project name to use for Weave initialization.
30
+ """
31
+ # We can't or shouldn't init weave; return
32
+ if os.getenv(_DISABLE_WEAVE):
33
+ return
34
+ if not project:
35
+ return
36
+
37
+ # Use entity/project when available; otherwise fall back to project only
38
+ if entity:
39
+ project_path = f"{entity}/{project}"
40
+ else:
41
+ project_path = project
42
+
43
+ # If weave is not yet imported, we can't init it from here. Instead, we'll
44
+ # rely on the weave library itself to detect a run and init itself.
45
+ if _WEAVE_PACKAGE_NAME not in sys.modules:
46
+ return
47
+
48
+ # If weave has already been imported, initialize immediately
49
+ with _weave_init_lock:
50
+ try:
51
+ # This import should have already happened, so it's effectively a no-op.
52
+ # We just import to keep the symbol for the init that follows
53
+ import weave
54
+ except ImportError:
55
+ # This should never happen; but we don't raise here to avoid
56
+ # breaking the wandb run init flow just in case
57
+ return
58
+
59
+ wandb.termlog("Initializing weave.")
60
+ try:
61
+ weave.init(project_path)
62
+ except Exception as e:
63
+ wandb.termwarn(f"Failed to automatically initialize Weave: {e}")
wandb/jupyter.py CHANGED
@@ -19,13 +19,13 @@ from requests.compat import urljoin
19
19
 
20
20
  import wandb
21
21
  import wandb.util
22
- from wandb.sdk import wandb_run, wandb_setup
22
+ from wandb.sdk import wandb_setup
23
23
  from wandb.sdk.lib import filesystem
24
24
 
25
25
  logger = logging.getLogger(__name__)
26
26
 
27
27
 
28
- def display_if_magic_is_used(run: wandb_run.Run) -> bool:
28
+ def display_if_magic_is_used(run: wandb.Run) -> bool:
29
29
  """Display a run's page if the cell has the %%wandb cell magic.
30
30
 
31
31
  Args:
@@ -53,7 +53,7 @@ class _WandbCellMagicState:
53
53
  self._height = height
54
54
  self._already_displayed = False
55
55
 
56
- def display_if_allowed(self, run: wandb_run.Run) -> None:
56
+ def display_if_allowed(self, run: wandb.Run) -> None:
57
57
  """Display a run's iframe if one is not already displayed.
58
58
 
59
59
  Args:
@@ -93,7 +93,7 @@ def _display_by_wandb_path(path: str, *, height: int) -> None:
93
93
  )
94
94
 
95
95
 
96
- def _display_wandb_run(run: wandb_run.Run, *, height: int) -> None:
96
+ def _display_wandb_run(run: wandb.Run, *, height: int) -> None:
97
97
  """Display a run (usually in an iframe).
98
98
 
99
99
  Args:
@@ -461,7 +461,7 @@ class Notebook:
461
461
 
462
462
  return False
463
463
 
464
- def save_history(self, run: wandb_run.Run):
464
+ def save_history(self, run: wandb.Run):
465
465
  """This saves all cell executions in the current session as a new notebook."""
466
466
  try:
467
467
  from nbformat import v4, validator, write # type: ignore