wandb 0.20.2rc20250616__py3-none-win_amd64.whl → 0.21.1__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.
- wandb/__init__.py +16 -14
- wandb/__init__.pyi +450 -472
- wandb/agents/pyagent.py +41 -12
- wandb/analytics/sentry.py +7 -2
- wandb/apis/importers/mlflow.py +1 -1
- wandb/apis/internal.py +3 -0
- wandb/apis/paginator.py +17 -4
- wandb/apis/public/__init__.py +1 -1
- wandb/apis/public/api.py +606 -359
- wandb/apis/public/artifacts.py +214 -16
- wandb/apis/public/automations.py +19 -3
- wandb/apis/public/files.py +177 -38
- wandb/apis/public/history.py +67 -15
- wandb/apis/public/integrations.py +25 -2
- wandb/apis/public/jobs.py +90 -2
- wandb/apis/public/projects.py +161 -69
- wandb/apis/public/query_generator.py +11 -1
- wandb/apis/public/registries/registries_search.py +7 -15
- wandb/apis/public/reports.py +147 -13
- wandb/apis/public/runs.py +315 -128
- wandb/apis/public/sweeps.py +222 -22
- wandb/apis/public/teams.py +41 -4
- wandb/apis/public/users.py +45 -4
- wandb/automations/__init__.py +10 -10
- wandb/automations/_filters/run_metrics.py +0 -2
- wandb/automations/_utils.py +0 -2
- wandb/automations/actions.py +0 -2
- wandb/automations/automations.py +0 -2
- wandb/automations/events.py +0 -2
- wandb/beta/workflows.py +66 -30
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +80 -1
- wandb/env.py +8 -0
- wandb/errors/errors.py +4 -1
- wandb/integration/catboost/catboost.py +6 -2
- wandb/integration/kfp/kfp_patch.py +3 -1
- wandb/integration/lightning/fabric/logger.py +3 -4
- wandb/integration/metaflow/__init__.py +6 -0
- wandb/integration/metaflow/data_pandas.py +74 -0
- wandb/integration/metaflow/errors.py +13 -0
- wandb/integration/metaflow/metaflow.py +205 -190
- wandb/integration/openai/fine_tuning.py +1 -2
- wandb/integration/sb3/sb3.py +3 -3
- wandb/integration/ultralytics/callback.py +6 -2
- wandb/jupyter.py +5 -5
- wandb/plot/__init__.py +2 -0
- wandb/plot/bar.py +30 -29
- wandb/plot/confusion_matrix.py +75 -71
- wandb/plot/custom_chart.py +30 -7
- wandb/plot/histogram.py +26 -25
- wandb/plot/line.py +33 -32
- wandb/plot/line_series.py +100 -103
- wandb/plot/pr_curve.py +33 -32
- wandb/plot/roc_curve.py +38 -38
- wandb/plot/scatter.py +27 -27
- wandb/proto/v3/wandb_internal_pb2.py +366 -385
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v4/wandb_internal_pb2.py +352 -356
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v5/wandb_internal_pb2.py +352 -356
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v6/wandb_internal_pb2.py +352 -356
- wandb/proto/v6/wandb_settings_pb2.py +2 -2
- wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
- wandb/proto/wandb_deprecated.py +6 -0
- wandb/sdk/artifacts/_generated/__init__.py +12 -1
- wandb/sdk/artifacts/_generated/input_types.py +20 -2
- wandb/sdk/artifacts/_generated/link_artifact.py +21 -0
- wandb/sdk/artifacts/_generated/operations.py +9 -0
- wandb/sdk/artifacts/_internal_artifact.py +19 -8
- wandb/sdk/artifacts/_validators.py +48 -2
- wandb/sdk/artifacts/artifact.py +269 -96
- wandb/sdk/data_types/audio.py +38 -10
- wandb/sdk/data_types/base_types/media.py +15 -63
- wandb/sdk/data_types/base_types/wb_value.py +6 -6
- wandb/sdk/data_types/graph.py +48 -14
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
- wandb/sdk/data_types/helper_types/image_mask.py +1 -3
- wandb/sdk/data_types/histogram.py +34 -21
- wandb/sdk/data_types/html.py +35 -12
- wandb/sdk/data_types/image.py +104 -68
- wandb/sdk/data_types/molecule.py +32 -19
- wandb/sdk/data_types/object_3d.py +36 -17
- wandb/sdk/data_types/plotly.py +18 -5
- wandb/sdk/data_types/saved_model.py +7 -9
- wandb/sdk/data_types/table.py +99 -70
- wandb/sdk/data_types/trace_tree.py +12 -12
- wandb/sdk/data_types/video.py +53 -26
- wandb/sdk/integration_utils/auto_logging.py +2 -2
- wandb/sdk/interface/interface.py +8 -19
- wandb/sdk/interface/interface_shared.py +7 -16
- wandb/sdk/internal/datastore.py +18 -18
- wandb/sdk/internal/handler.py +3 -5
- wandb/sdk/internal/internal_api.py +60 -0
- wandb/sdk/internal/job_builder.py +6 -0
- wandb/sdk/internal/sender.py +23 -3
- wandb/sdk/internal/sender_config.py +9 -0
- wandb/sdk/launch/_project_spec.py +3 -3
- wandb/sdk/launch/agent/agent.py +11 -4
- wandb/sdk/launch/agent/job_status_tracker.py +3 -1
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
- wandb/sdk/launch/create_job.py +3 -1
- wandb/sdk/launch/inputs/internal.py +3 -4
- wandb/sdk/launch/inputs/schema.py +1 -0
- wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +328 -1
- wandb/sdk/launch/sweeps/scheduler.py +2 -3
- wandb/sdk/launch/utils.py +3 -3
- wandb/sdk/lib/asyncio_compat.py +3 -0
- wandb/sdk/lib/console_capture.py +66 -19
- wandb/sdk/lib/deprecate.py +1 -7
- wandb/sdk/lib/disabled.py +1 -1
- wandb/sdk/lib/hashutil.py +14 -1
- wandb/sdk/lib/module.py +7 -13
- wandb/sdk/lib/progress.py +0 -19
- wandb/sdk/lib/sock_client.py +0 -4
- wandb/sdk/wandb_init.py +67 -93
- wandb/sdk/wandb_login.py +18 -14
- wandb/sdk/wandb_metric.py +2 -0
- wandb/sdk/wandb_require.py +0 -1
- wandb/sdk/wandb_run.py +429 -527
- wandb/sdk/wandb_settings.py +364 -74
- wandb/sdk/wandb_setup.py +28 -28
- wandb/sdk/wandb_sweep.py +14 -13
- wandb/sdk/wandb_watch.py +4 -6
- wandb/sync/sync.py +10 -0
- wandb/util.py +57 -0
- wandb/wandb_run.py +1 -2
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/METADATA +1 -1
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/RECORD +137 -137
- wandb/sdk/wandb_metadata.py +0 -623
- wandb/vendor/pynvml/__init__.py +0 -0
- wandb/vendor/pynvml/pynvml.py +0 -4779
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/WHEEL +0 -0
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/data_types/audio.py
CHANGED
@@ -15,15 +15,7 @@ if TYPE_CHECKING:
|
|
15
15
|
|
16
16
|
|
17
17
|
class Audio(BatchableMedia):
|
18
|
-
"""
|
19
|
-
|
20
|
-
Args:
|
21
|
-
data_or_path: (string or numpy array) A path to an audio file
|
22
|
-
or a numpy array of audio data.
|
23
|
-
sample_rate: (int) Sample rate, required when passing in raw
|
24
|
-
numpy array of audio data.
|
25
|
-
caption: (string) Caption to display with audio.
|
26
|
-
"""
|
18
|
+
"""W&B class for audio clips."""
|
27
19
|
|
28
20
|
_log_type = "audio-file"
|
29
21
|
|
@@ -38,7 +30,13 @@ class Audio(BatchableMedia):
|
|
38
30
|
sample_rate: Optional[int] = None,
|
39
31
|
caption: Optional[str] = None,
|
40
32
|
):
|
41
|
-
"""Accept a path to an audio file or a numpy array of audio data.
|
33
|
+
"""Accept a path to an audio file or a numpy array of audio data.
|
34
|
+
|
35
|
+
Args:
|
36
|
+
data_or_path: A path to an audio file or a NumPy array of audio data.
|
37
|
+
sample_rate: Sample rate, required when passing in raw NumPy array of audio data.
|
38
|
+
caption: Caption to display with audio.
|
39
|
+
"""
|
42
40
|
super().__init__(caption=caption)
|
43
41
|
self._duration = None
|
44
42
|
self._sample_rate = sample_rate
|
@@ -72,10 +70,18 @@ class Audio(BatchableMedia):
|
|
72
70
|
|
73
71
|
@classmethod
|
74
72
|
def get_media_subdir(cls):
|
73
|
+
"""Get media subdirectory.
|
74
|
+
|
75
|
+
<!-- lazydoc-ignore-classmethod: internal -->
|
76
|
+
"""
|
75
77
|
return os.path.join("media", "audio")
|
76
78
|
|
77
79
|
@classmethod
|
78
80
|
def from_json(cls, json_obj, source_artifact):
|
81
|
+
"""Deserialize JSON object into it's class representation.
|
82
|
+
|
83
|
+
<!-- lazydoc-ignore-classmethod: internal -->
|
84
|
+
"""
|
79
85
|
return cls(
|
80
86
|
source_artifact.get_entry(json_obj["path"]).download(),
|
81
87
|
caption=json_obj["caption"],
|
@@ -84,6 +90,10 @@ class Audio(BatchableMedia):
|
|
84
90
|
def bind_to_run(
|
85
91
|
self, run, key, step, id_=None, ignore_copy_err: Optional[bool] = None
|
86
92
|
):
|
93
|
+
"""Bind this object to a run.
|
94
|
+
|
95
|
+
<!-- lazydoc-ignore: internal -->
|
96
|
+
"""
|
87
97
|
if self.path_is_reference(self._path):
|
88
98
|
raise ValueError(
|
89
99
|
"Audio media created by a reference to external storage cannot currently be added to a run"
|
@@ -92,6 +102,10 @@ class Audio(BatchableMedia):
|
|
92
102
|
return super().bind_to_run(run, key, step, id_, ignore_copy_err)
|
93
103
|
|
94
104
|
def to_json(self, run):
|
105
|
+
"""Returns the JSON representation expected by the backend.
|
106
|
+
|
107
|
+
<!-- lazydoc-ignore: internal -->
|
108
|
+
"""
|
95
109
|
json_dict = super().to_json(run)
|
96
110
|
json_dict.update(
|
97
111
|
{
|
@@ -102,6 +116,10 @@ class Audio(BatchableMedia):
|
|
102
116
|
|
103
117
|
@classmethod
|
104
118
|
def seq_to_json(cls, seq, run, key, step):
|
119
|
+
"""Convert a sequence of Audio objects to a JSON representation.
|
120
|
+
|
121
|
+
<!-- lazydoc-ignore-classmethod: internal -->
|
122
|
+
"""
|
105
123
|
audio_list = list(seq)
|
106
124
|
|
107
125
|
util.get_module(
|
@@ -129,14 +147,20 @@ class Audio(BatchableMedia):
|
|
129
147
|
|
130
148
|
@classmethod
|
131
149
|
def durations(cls, audio_list):
|
150
|
+
"""Calculate the duration of the audio files."""
|
132
151
|
return [a._duration for a in audio_list]
|
133
152
|
|
134
153
|
@classmethod
|
135
154
|
def sample_rates(cls, audio_list):
|
155
|
+
"""Get sample rates of the audio files."""
|
136
156
|
return [a._sample_rate for a in audio_list]
|
137
157
|
|
138
158
|
@classmethod
|
139
159
|
def captions(cls, audio_list):
|
160
|
+
"""Get the captions of the audio files.
|
161
|
+
|
162
|
+
<!-- lazydoc-ignore-classmethod: internal -->
|
163
|
+
"""
|
140
164
|
captions = [a._caption for a in audio_list]
|
141
165
|
if all(c is None for c in captions):
|
142
166
|
return False
|
@@ -144,6 +168,10 @@ class Audio(BatchableMedia):
|
|
144
168
|
return ["" if c is None else c for c in captions]
|
145
169
|
|
146
170
|
def resolve_ref(self):
|
171
|
+
"""Resolve the reference to the actual file path.
|
172
|
+
|
173
|
+
<!-- lazydoc-ignore: internal -->
|
174
|
+
"""
|
147
175
|
if self.path_is_reference(self._path):
|
148
176
|
# this object was already created using a ref:
|
149
177
|
return self._path
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import hashlib
|
2
2
|
import os
|
3
3
|
import pathlib
|
4
|
-
import platform
|
5
4
|
import re
|
6
5
|
import shutil
|
7
6
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Type, Union, cast
|
@@ -18,39 +17,12 @@ if TYPE_CHECKING: # pragma: no cover
|
|
18
17
|
|
19
18
|
from wandb.sdk.artifacts.artifact import Artifact
|
20
19
|
|
21
|
-
from ...wandb_run import Run as LocalRun
|
22
|
-
|
23
|
-
|
24
|
-
SYS_PLATFORM = platform.system()
|
25
|
-
|
26
|
-
|
27
|
-
def check_windows_valid_filename(path: Union[int, str]) -> bool:
|
28
|
-
r"""Verify that the given path does not contain any invalid characters for a Windows filename.
|
29
|
-
|
30
|
-
Windows filenames cannot contain the following characters:
|
31
|
-
< > : " \ / | ? *
|
32
|
-
|
33
|
-
For more details, refer to the official documentation:
|
34
|
-
https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
|
35
|
-
|
36
|
-
Args:
|
37
|
-
path: The file path to check, which can be either an integer or a string.
|
38
|
-
|
39
|
-
Returns:
|
40
|
-
bool: True if the path does not contain any invalid characters, False otherwise.
|
41
|
-
"""
|
42
|
-
return not bool(re.search(r'[<>:"\\?*]', path)) # type: ignore
|
43
|
-
|
44
20
|
|
45
21
|
def _wb_filename(
|
46
22
|
key: Union[str, int], step: Union[str, int], id: Union[str, int], extension: str
|
47
23
|
) -> str:
|
48
24
|
r"""Generates a safe filename/path for storing media files, using the provided key, step, and id.
|
49
25
|
|
50
|
-
The filename is made safe by:
|
51
|
-
1. Removing any leading slashes to prevent writing to absolute paths
|
52
|
-
2. Replacing '.' and '..' with underscores to prevent directory traversal attacks
|
53
|
-
|
54
26
|
If the key contains slashes (e.g. 'images/cats/fluffy.jpg'), subdirectories will be created:
|
55
27
|
media/
|
56
28
|
images/
|
@@ -70,28 +42,7 @@ def _wb_filename(
|
|
70
42
|
ValueError: If running on Windows and the key contains invalid filename characters
|
71
43
|
(\\, :, *, ?, ", <, >, |)
|
72
44
|
"""
|
73
|
-
|
74
|
-
raise ValueError(
|
75
|
-
f'Media {key} is invalid. Please remove invalid filename characters (\\, :, *, ?, ", <, >, |)'
|
76
|
-
)
|
77
|
-
|
78
|
-
# On Windows, convert forward slashes to backslashes.
|
79
|
-
# This ensures that the key is a valid filename on Windows.
|
80
|
-
if SYS_PLATFORM == "Windows":
|
81
|
-
key = str(key).replace("/", os.sep)
|
82
|
-
|
83
|
-
# Avoid writing to absolute paths by striping any leading slashes.
|
84
|
-
# The key has already been validated for windows operating systems in util.check_windows_valid_filename
|
85
|
-
# This ensures the key does not contain invalid characters for windows, such as '\' or ':'.
|
86
|
-
# So we can check only for '/' in the key.
|
87
|
-
key = str(key).lstrip(os.sep)
|
88
|
-
|
89
|
-
# Avoid directory traversal by replacing dots with underscores.
|
90
|
-
keys = key.split(os.sep)
|
91
|
-
keys = [k.replace(".", "_") if k in (os.curdir, os.pardir) else k for k in keys]
|
92
|
-
|
93
|
-
# Recombine the key into a relative path.
|
94
|
-
key = os.sep.join(keys)
|
45
|
+
key = util.make_file_path_upload_safe(str(key))
|
95
46
|
|
96
47
|
return f"{str(key)}_{str(step)}_{str(id)}{extension}"
|
97
48
|
|
@@ -104,7 +55,7 @@ class Media(WBValue):
|
|
104
55
|
"""
|
105
56
|
|
106
57
|
_path: Optional[str]
|
107
|
-
_run: Optional["
|
58
|
+
_run: Optional["wandb.Run"]
|
108
59
|
_caption: Optional[str]
|
109
60
|
_is_tmp: Optional[bool]
|
110
61
|
_extension: Optional[str]
|
@@ -127,9 +78,9 @@ class Media(WBValue):
|
|
127
78
|
self._path = path
|
128
79
|
self._is_tmp = is_tmp
|
129
80
|
self._extension = extension
|
130
|
-
assert extension is None or path.endswith(
|
131
|
-
extension
|
132
|
-
)
|
81
|
+
assert extension is None or path.endswith(extension), (
|
82
|
+
f'Media file extension "{extension}" must occur at the end of path "{path}".'
|
83
|
+
)
|
133
84
|
|
134
85
|
with open(self._path, "rb") as f:
|
135
86
|
self._sha256 = hashlib.sha256(f.read()).hexdigest()
|
@@ -156,7 +107,7 @@ class Media(WBValue):
|
|
156
107
|
|
157
108
|
def bind_to_run(
|
158
109
|
self,
|
159
|
-
run: "
|
110
|
+
run: "wandb.Run",
|
160
111
|
key: Union[int, str],
|
161
112
|
step: Union[int, str],
|
162
113
|
id_: Optional[Union[int, str]] = None,
|
@@ -205,7 +156,7 @@ class Media(WBValue):
|
|
205
156
|
self._path = new_path
|
206
157
|
run._publish_file(media_path)
|
207
158
|
|
208
|
-
def to_json(self, run: Union["
|
159
|
+
def to_json(self, run: Union["wandb.Run", "Artifact"]) -> dict:
|
209
160
|
"""Serialize the object into a JSON blob.
|
210
161
|
|
211
162
|
Uses run or artifact to store additional data. If `run_or_artifact` is a
|
@@ -223,14 +174,13 @@ class Media(WBValue):
|
|
223
174
|
# into Media itself we should get rid of them
|
224
175
|
from wandb import Image
|
225
176
|
from wandb.data_types import Audio
|
226
|
-
from wandb.sdk.wandb_run import Run
|
227
177
|
|
228
178
|
json_obj: Dict[str, Any] = {}
|
229
179
|
|
230
180
|
if self._caption is not None:
|
231
181
|
json_obj["caption"] = self._caption
|
232
182
|
|
233
|
-
if isinstance(run, Run):
|
183
|
+
if isinstance(run, wandb.Run):
|
234
184
|
json_obj.update(
|
235
185
|
{
|
236
186
|
"_type": "file", # TODO(adrian): This isn't (yet) a real media type we support on the frontend.
|
@@ -247,11 +197,13 @@ class Media(WBValue):
|
|
247
197
|
json_obj["_latest_artifact_path"] = artifact_entry_latest_url
|
248
198
|
|
249
199
|
if artifact_entry_url is None or self.is_bound():
|
250
|
-
assert self.is_bound(),
|
200
|
+
assert self.is_bound(), (
|
201
|
+
f"Value of type {type(self).__name__} must be bound to a run with bind_to_run() before being serialized to JSON."
|
202
|
+
)
|
251
203
|
|
252
|
-
assert (
|
253
|
-
|
254
|
-
)
|
204
|
+
assert self._run is run, (
|
205
|
+
"We don't support referring to media files across runs."
|
206
|
+
)
|
255
207
|
|
256
208
|
# The following two assertions are guaranteed to pass
|
257
209
|
# by definition is_bound, but are needed for
|
@@ -355,7 +307,7 @@ class BatchableMedia(Media):
|
|
355
307
|
def seq_to_json(
|
356
308
|
cls: Type["BatchableMedia"],
|
357
309
|
seq: Sequence["BatchableMedia"],
|
358
|
-
run: "
|
310
|
+
run: "wandb.Run",
|
359
311
|
key: str,
|
360
312
|
step: Union[int, str],
|
361
313
|
) -> dict:
|
@@ -218,17 +218,17 @@ class WBValue:
|
|
218
218
|
def _set_artifact_source(
|
219
219
|
self, artifact: "Artifact", name: Optional[str] = None
|
220
220
|
) -> None:
|
221
|
-
assert (
|
222
|
-
self._artifact_source
|
223
|
-
)
|
221
|
+
assert self._artifact_source is None, (
|
222
|
+
f"Cannot update artifact_source. Existing source: {self._artifact_source.artifact}/{self._artifact_source.name}"
|
223
|
+
)
|
224
224
|
self._artifact_source = _WBValueArtifactSource(artifact, name)
|
225
225
|
|
226
226
|
def _set_artifact_target(
|
227
227
|
self, artifact: "Artifact", name: Optional[str] = None
|
228
228
|
) -> None:
|
229
|
-
assert (
|
230
|
-
self._artifact_target
|
231
|
-
)
|
229
|
+
assert self._artifact_target is None, (
|
230
|
+
f"Cannot update artifact_target. Existing target: {self._artifact_target.artifact}/{self._artifact_target.name}"
|
231
|
+
)
|
232
232
|
self._artifact_target = _WBValueArtifactTarget(artifact, name)
|
233
233
|
|
234
234
|
def _get_artifact_entry_ref_url(self) -> Optional[str]:
|
wandb/sdk/data_types/graph.py
CHANGED
@@ -243,25 +243,29 @@ class Node(WBValue):
|
|
243
243
|
|
244
244
|
|
245
245
|
class Graph(Media):
|
246
|
-
"""
|
246
|
+
"""W&B class for graphs.
|
247
247
|
|
248
|
-
This class is typically used for saving and displaying neural net models.
|
249
|
-
represents the graph as an array of nodes and edges.
|
248
|
+
This class is typically used for saving and displaying neural net models.
|
249
|
+
It represents the graph as an array of nodes and edges. The nodes can have
|
250
250
|
labels that can be visualized by wandb.
|
251
251
|
|
252
|
-
Examples:
|
253
|
-
Import a keras model:
|
254
|
-
```
|
255
|
-
Graph.from_keras(keras_model)
|
256
|
-
```
|
257
|
-
|
258
252
|
Attributes:
|
259
253
|
format (string): Format to help wandb display the graph nicely.
|
260
|
-
nodes ([wandb.Node]): List of wandb.Nodes
|
254
|
+
nodes ([wandb.Node]): List of `wandb.Nodes`.
|
261
255
|
nodes_by_id (dict): dict of ids -> nodes
|
262
|
-
edges ([(wandb.Node, wandb.Node)]): List of pairs of nodes interpreted
|
263
|
-
|
264
|
-
|
256
|
+
edges ([(wandb.Node, wandb.Node)]): List of pairs of nodes interpreted
|
257
|
+
as edges.
|
258
|
+
loaded (boolean): Flag to tell whether the graph is completely loaded.
|
259
|
+
root (wandb.Node): Root node of the graph.
|
260
|
+
|
261
|
+
Examples:
|
262
|
+
Import a keras model.
|
263
|
+
|
264
|
+
```python
|
265
|
+
import wandb
|
266
|
+
|
267
|
+
wandb.Graph.from_keras(keras_model)
|
268
|
+
```
|
265
269
|
"""
|
266
270
|
|
267
271
|
_log_type = "graph-file"
|
@@ -287,6 +291,10 @@ class Graph(Media):
|
|
287
291
|
}
|
288
292
|
|
289
293
|
def bind_to_run(self, *args, **kwargs):
|
294
|
+
"""Bind this object to a run.
|
295
|
+
|
296
|
+
<!-- lazydoc-ignore: internal -->
|
297
|
+
"""
|
290
298
|
data = self._to_graph_json()
|
291
299
|
tmp_path = os.path.join(MEDIA_TMP.name, runid.generate_id() + ".graph.json")
|
292
300
|
data = _numpy_arrays_to_lists(data)
|
@@ -299,9 +307,17 @@ class Graph(Media):
|
|
299
307
|
|
300
308
|
@classmethod
|
301
309
|
def get_media_subdir(cls):
|
310
|
+
"""Get media subdirectory.
|
311
|
+
|
312
|
+
"<!-- lazydoc-ignore-classmethod: internal -->
|
313
|
+
"""
|
302
314
|
return os.path.join("media", "graph")
|
303
315
|
|
304
316
|
def to_json(self, run):
|
317
|
+
"""Returns the JSON representation expected by the backend.
|
318
|
+
|
319
|
+
<!-- lazydoc-ignore: internal -->
|
320
|
+
"""
|
305
321
|
json_dict = super().to_json(run)
|
306
322
|
json_dict["_type"] = self._log_type
|
307
323
|
return json_dict
|
@@ -310,12 +326,20 @@ class Graph(Media):
|
|
310
326
|
return self.nodes_by_id[nid]
|
311
327
|
|
312
328
|
def pprint(self):
|
329
|
+
"""Pretty print the graph.
|
330
|
+
|
331
|
+
<!-- lazydoc-ignore: internal -->
|
332
|
+
"""
|
313
333
|
for edge in self.edges:
|
314
334
|
pprint.pprint(edge.attributes) # noqa: T203
|
315
335
|
for node in self.nodes:
|
316
336
|
pprint.pprint(node.attributes) # noqa: T203
|
317
337
|
|
318
338
|
def add_node(self, node=None, **node_kwargs):
|
339
|
+
"""Add a node to the graph.
|
340
|
+
|
341
|
+
<!-- lazydoc-ignore: internal -->
|
342
|
+
"""
|
319
343
|
if node is None:
|
320
344
|
node = Node(**node_kwargs)
|
321
345
|
elif node_kwargs:
|
@@ -328,6 +352,10 @@ class Graph(Media):
|
|
328
352
|
return node
|
329
353
|
|
330
354
|
def add_edge(self, from_node, to_node):
|
355
|
+
"""Add an edge to the graph.
|
356
|
+
|
357
|
+
<!-- lazydoc-ignore: internal -->
|
358
|
+
"""
|
331
359
|
edge = Edge(from_node, to_node)
|
332
360
|
self.edges.append(edge)
|
333
361
|
|
@@ -335,7 +363,13 @@ class Graph(Media):
|
|
335
363
|
|
336
364
|
@classmethod
|
337
365
|
def from_keras(cls, model):
|
338
|
-
|
366
|
+
"""Create a graph from a Keras model.
|
367
|
+
|
368
|
+
This method is not supported for Keras 3.0.0 and above.
|
369
|
+
Requires a refactor.
|
370
|
+
|
371
|
+
"<!-- lazydoc-ignore-classmethod: internal -->
|
372
|
+
"""
|
339
373
|
graph = cls()
|
340
374
|
# Shamelessly copied (then modified) from keras/keras/utils/layer_utils.py
|
341
375
|
sequential_like = cls._is_sequential(model)
|
@@ -310,9 +310,7 @@ class BoundingBoxes2D(JSONMetadata):
|
|
310
310
|
return True
|
311
311
|
|
312
312
|
def to_json(self, run_or_artifact: Union["LocalRun", "Artifact"]) -> dict:
|
313
|
-
|
314
|
-
|
315
|
-
if isinstance(run_or_artifact, Run):
|
313
|
+
if isinstance(run_or_artifact, wandb.Run):
|
316
314
|
return super().to_json(run_or_artifact)
|
317
315
|
elif isinstance(run_or_artifact, wandb.Artifact):
|
318
316
|
# TODO (tim): I would like to log out a proper dictionary representing this object, but don't
|
@@ -209,11 +209,9 @@ class ImageMask(Media):
|
|
209
209
|
)
|
210
210
|
|
211
211
|
def to_json(self, run_or_artifact: Union["LocalRun", "Artifact"]) -> dict:
|
212
|
-
from wandb.sdk.wandb_run import Run
|
213
|
-
|
214
212
|
json_dict = super().to_json(run_or_artifact)
|
215
213
|
|
216
|
-
if isinstance(run_or_artifact, Run):
|
214
|
+
if isinstance(run_or_artifact, wandb.Run):
|
217
215
|
json_dict["_type"] = self.type_name()
|
218
216
|
return json_dict
|
219
217
|
elif isinstance(run_or_artifact, wandb.Artifact):
|
@@ -16,32 +16,14 @@ if TYPE_CHECKING: # pragma: no cover
|
|
16
16
|
|
17
17
|
|
18
18
|
class Histogram(WBValue):
|
19
|
-
"""
|
19
|
+
"""W&B class for histograms.
|
20
20
|
|
21
21
|
This object works just like numpy's histogram function
|
22
22
|
https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html
|
23
23
|
|
24
|
-
Examples:
|
25
|
-
Generate histogram from a sequence
|
26
|
-
```python
|
27
|
-
wandb.Histogram([1, 2, 3])
|
28
|
-
```
|
29
|
-
|
30
|
-
Efficiently initialize from np.histogram.
|
31
|
-
```python
|
32
|
-
hist = np.histogram(data)
|
33
|
-
wandb.Histogram(np_histogram=hist)
|
34
|
-
```
|
35
|
-
|
36
|
-
Args:
|
37
|
-
sequence: (array_like) input data for histogram
|
38
|
-
np_histogram: (numpy histogram) alternative input of a precomputed histogram
|
39
|
-
num_bins: (int) Number of bins for the histogram. The default number of bins
|
40
|
-
is 64. The maximum number of bins is 512
|
41
|
-
|
42
24
|
Attributes:
|
43
|
-
bins
|
44
|
-
histogram
|
25
|
+
bins ([float]): Edges of bins
|
26
|
+
histogram ([int]): Number of elements falling in each bin.
|
45
27
|
"""
|
46
28
|
|
47
29
|
MAX_LENGTH: int = 512
|
@@ -53,6 +35,33 @@ class Histogram(WBValue):
|
|
53
35
|
np_histogram: Optional["NumpyHistogram"] = None,
|
54
36
|
num_bins: int = 64,
|
55
37
|
) -> None:
|
38
|
+
"""Initialize a Histogram object.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
sequence: Input data for histogram.
|
42
|
+
np_histogram: Alternative input of a precomputed histogram.
|
43
|
+
num_bins: Number of bins for the histogram. The default number of bins
|
44
|
+
is 64. The maximum number of bins is 512.
|
45
|
+
|
46
|
+
Examples:
|
47
|
+
Generate histogram from a sequence.
|
48
|
+
|
49
|
+
```python
|
50
|
+
import wandb
|
51
|
+
|
52
|
+
wandb.Histogram([1, 2, 3])
|
53
|
+
```
|
54
|
+
|
55
|
+
Efficiently initialize from np.histogram.
|
56
|
+
|
57
|
+
```python
|
58
|
+
import numpy as np
|
59
|
+
import wandb
|
60
|
+
|
61
|
+
hist = np.histogram(data)
|
62
|
+
wandb.Histogram(np_histogram=hist)
|
63
|
+
```
|
64
|
+
"""
|
56
65
|
if np_histogram:
|
57
66
|
if len(np_histogram) == 2:
|
58
67
|
self.histogram = (
|
@@ -83,6 +92,10 @@ class Histogram(WBValue):
|
|
83
92
|
raise ValueError("len(bins) must be len(histogram) + 1")
|
84
93
|
|
85
94
|
def to_json(self, run: Optional[Union["LocalRun", "Artifact"]] = None) -> dict:
|
95
|
+
"""Returns the JSON representation expected by the backend.
|
96
|
+
|
97
|
+
<!-- lazydoc-ignore: internal -->
|
98
|
+
"""
|
86
99
|
return {"_type": self._log_type, "values": self.histogram, "bins": self.bins}
|
87
100
|
|
88
101
|
def __sizeof__(self) -> int:
|
wandb/sdk/data_types/html.py
CHANGED
@@ -17,7 +17,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
17
17
|
|
18
18
|
|
19
19
|
class Html(BatchableMedia):
|
20
|
-
"""
|
20
|
+
"""W&B class for logging HTML content to W&B."""
|
21
21
|
|
22
22
|
_log_type = "html-file"
|
23
23
|
|
@@ -29,27 +29,30 @@ class Html(BatchableMedia):
|
|
29
29
|
) -> None:
|
30
30
|
"""Creates a W&B HTML object.
|
31
31
|
|
32
|
+
Args:
|
33
|
+
data:
|
34
|
+
A string that is a path to a file with the extension ".html",
|
35
|
+
or a string or IO object containing literal HTML.
|
36
|
+
inject: Add a stylesheet to the HTML object. If set
|
37
|
+
to False the HTML will pass through unchanged.
|
38
|
+
data_is_not_path: If set to False, the data will be
|
39
|
+
treated as a path to a file.
|
40
|
+
|
41
|
+
Examples:
|
32
42
|
It can be initialized by providing a path to a file:
|
33
|
-
|
43
|
+
|
44
|
+
```python
|
34
45
|
with wandb.init() as run:
|
35
46
|
run.log({"html": wandb.Html("./index.html")})
|
36
47
|
```
|
37
48
|
|
38
49
|
Alternatively, it can be initialized by providing literal HTML,
|
39
50
|
in either a string or IO object:
|
40
|
-
|
51
|
+
|
52
|
+
```python
|
41
53
|
with wandb.init() as run:
|
42
54
|
run.log({"html": wandb.Html("<h1>Hello, world!</h1>")})
|
43
55
|
```
|
44
|
-
|
45
|
-
Args:
|
46
|
-
data:
|
47
|
-
A string that is a path to a file with the extension ".html",
|
48
|
-
or a string or IO object containing literal HTML.
|
49
|
-
inject: Add a stylesheet to the HTML object. If set
|
50
|
-
to False the HTML will pass through unchanged.
|
51
|
-
data_is_not_path: If set to False, the data will be
|
52
|
-
treated as a path to a file.
|
53
56
|
"""
|
54
57
|
super().__init__()
|
55
58
|
data_is_path = (
|
@@ -84,6 +87,10 @@ class Html(BatchableMedia):
|
|
84
87
|
self._set_file(data_path, is_tmp=False)
|
85
88
|
|
86
89
|
def inject_head(self) -> None:
|
90
|
+
"""Inject a <head> tag into the HTML.
|
91
|
+
|
92
|
+
<!-- lazydoc-ignore: internal -->
|
93
|
+
"""
|
87
94
|
join = ""
|
88
95
|
if "<head>" in self.html:
|
89
96
|
parts = self.html.split("<head>", 1)
|
@@ -102,9 +109,17 @@ class Html(BatchableMedia):
|
|
102
109
|
|
103
110
|
@classmethod
|
104
111
|
def get_media_subdir(cls: Type["Html"]) -> str:
|
112
|
+
"""Get media subdirectory.
|
113
|
+
|
114
|
+
"<!-- lazydoc-ignore-classmethod: internal -->
|
115
|
+
"""
|
105
116
|
return os.path.join("media", "html")
|
106
117
|
|
107
118
|
def to_json(self, run_or_artifact: Union["LocalRun", "Artifact"]) -> dict:
|
119
|
+
"""Returns the JSON representation expected by the backend.
|
120
|
+
|
121
|
+
<!-- lazydoc-ignore: internal -->
|
122
|
+
"""
|
108
123
|
json_dict = super().to_json(run_or_artifact)
|
109
124
|
json_dict["_type"] = self._log_type
|
110
125
|
return json_dict
|
@@ -113,6 +128,10 @@ class Html(BatchableMedia):
|
|
113
128
|
def from_json(
|
114
129
|
cls: Type["Html"], json_obj: dict, source_artifact: "Artifact"
|
115
130
|
) -> "Html":
|
131
|
+
"""Deserialize a JSON object into it's class representation.
|
132
|
+
|
133
|
+
"<!-- lazydoc-ignore-classmethod: internal -->
|
134
|
+
"""
|
116
135
|
return cls(source_artifact.get_entry(json_obj["path"]).download(), inject=False)
|
117
136
|
|
118
137
|
@classmethod
|
@@ -123,6 +142,10 @@ class Html(BatchableMedia):
|
|
123
142
|
key: str,
|
124
143
|
step: Union[int, str],
|
125
144
|
) -> dict:
|
145
|
+
"""Convert a sequence of HTML objects to a JSON representation.
|
146
|
+
|
147
|
+
"<!-- lazydoc-ignore-classmethod: internal -->
|
148
|
+
"""
|
126
149
|
base_path = os.path.join(run.dir, cls.get_media_subdir())
|
127
150
|
filesystem.mkdir_exists_ok(base_path)
|
128
151
|
|