wandb 0.18.2__py3-none-win32.whl → 0.18.4__py3-none-win32.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 -7
- wandb/__init__.pyi +96 -63
- wandb/analytics/sentry.py +91 -88
- wandb/apis/public/api.py +18 -4
- wandb/apis/public/runs.py +53 -2
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/beta.py +178 -0
- wandb/cli/cli.py +5 -171
- wandb/data_types.py +3 -0
- wandb/env.py +74 -73
- wandb/errors/term.py +300 -43
- wandb/proto/v3/wandb_internal_pb2.py +271 -221
- wandb/proto/v3/wandb_server_pb2.py +57 -37
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_internal_pb2.py +226 -216
- wandb/proto/v4/wandb_server_pb2.py +41 -37
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_internal_pb2.py +226 -216
- wandb/proto/v5/wandb_server_pb2.py +41 -37
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/sdk/__init__.py +3 -3
- wandb/sdk/artifacts/_validators.py +41 -8
- wandb/sdk/artifacts/artifact.py +35 -4
- wandb/sdk/artifacts/artifact_file_cache.py +1 -2
- wandb/sdk/data_types/_dtypes.py +7 -3
- wandb/sdk/data_types/video.py +15 -6
- wandb/sdk/interface/interface.py +2 -0
- wandb/sdk/internal/internal_api.py +122 -5
- wandb/sdk/internal/sender.py +16 -3
- wandb/sdk/launch/inputs/internal.py +1 -1
- wandb/sdk/lib/module.py +12 -0
- wandb/sdk/lib/printer.py +291 -105
- wandb/sdk/lib/progress.py +274 -0
- wandb/sdk/service/streams.py +21 -11
- wandb/sdk/wandb_init.py +59 -54
- wandb/sdk/wandb_run.py +413 -480
- wandb/sdk/wandb_settings.py +2 -0
- wandb/sdk/wandb_watch.py +17 -11
- wandb/util.py +6 -2
- {wandb-0.18.2.dist-info → wandb-0.18.4.dist-info}/METADATA +5 -4
- {wandb-0.18.2.dist-info → wandb-0.18.4.dist-info}/RECORD +45 -42
- {wandb-0.18.2.dist-info → wandb-0.18.4.dist-info}/WHEEL +0 -0
- {wandb-0.18.2.dist-info → wandb-0.18.4.dist-info}/entry_points.txt +0 -0
- {wandb-0.18.2.dist-info → wandb-0.18.4.dist-info}/licenses/LICENSE +0 -0
wandb/apis/public/runs.py
CHANGED
@@ -753,11 +753,62 @@ class Run(Attrs):
|
|
753
753
|
)
|
754
754
|
|
755
755
|
@normalize_exceptions
|
756
|
-
def logged_artifacts(self, per_page=100):
|
756
|
+
def logged_artifacts(self, per_page: int = 100) -> public.RunArtifacts:
|
757
|
+
"""Fetches all artifacts logged by this run.
|
758
|
+
|
759
|
+
Retrieves all output artifacts that were logged during the run. Returns a
|
760
|
+
paginated result that can be iterated over or collected into a single list.
|
761
|
+
|
762
|
+
Args:
|
763
|
+
per_page: Number of artifacts to fetch per API request.
|
764
|
+
|
765
|
+
Returns:
|
766
|
+
An iterable collection of all Artifact objects logged as outputs during this run.
|
767
|
+
|
768
|
+
Example:
|
769
|
+
>>> import wandb
|
770
|
+
>>> import tempfile
|
771
|
+
>>> with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as tmp:
|
772
|
+
... tmp.write("This is a test artifact")
|
773
|
+
... tmp_path = tmp.name
|
774
|
+
>>> run = wandb.init(project="artifact-example")
|
775
|
+
>>> artifact = wandb.Artifact("test_artifact", type="dataset")
|
776
|
+
>>> artifact.add_file(tmp_path)
|
777
|
+
>>> run.log_artifact(artifact)
|
778
|
+
>>> run.finish()
|
779
|
+
>>> api = wandb.Api()
|
780
|
+
>>> finished_run = api.run(f"{run.entity}/{run.project}/{run.id}")
|
781
|
+
>>> for logged_artifact in finished_run.logged_artifacts():
|
782
|
+
... print(logged_artifact.name)
|
783
|
+
test_artifact
|
784
|
+
"""
|
757
785
|
return public.RunArtifacts(self.client, self, mode="logged", per_page=per_page)
|
758
786
|
|
759
787
|
@normalize_exceptions
|
760
|
-
def used_artifacts(self, per_page=100):
|
788
|
+
def used_artifacts(self, per_page: int = 100) -> public.RunArtifacts:
|
789
|
+
"""Fetches artifacts explicitly used by this run.
|
790
|
+
|
791
|
+
Retrieves only the input artifacts that were explicitly declared as used
|
792
|
+
during the run, typically via `run.use_artifact()`. Returns a paginated
|
793
|
+
result that can be iterated over or collected into a single list.
|
794
|
+
|
795
|
+
Args:
|
796
|
+
per_page: Number of artifacts to fetch per API request.
|
797
|
+
|
798
|
+
Returns:
|
799
|
+
An iterable collection of Artifact objects explicitly used as inputs in this run.
|
800
|
+
|
801
|
+
Example:
|
802
|
+
>>> import wandb
|
803
|
+
>>> run = wandb.init(project="artifact-example")
|
804
|
+
>>> run.use_artifact("test_artifact:latest")
|
805
|
+
>>> run.finish()
|
806
|
+
>>> api = wandb.Api()
|
807
|
+
>>> finished_run = api.run(f"{run.entity}/{run.project}/{run.id}")
|
808
|
+
>>> for used_artifact in finished_run.used_artifacts():
|
809
|
+
... print(used_artifact.name)
|
810
|
+
test_artifact
|
811
|
+
"""
|
761
812
|
return public.RunArtifacts(self.client, self, mode="used", per_page=per_page)
|
762
813
|
|
763
814
|
@normalize_exceptions
|
wandb/bin/gpu_stats.exe
ADDED
Binary file
|
wandb/bin/wandb-core
CHANGED
Binary file
|
wandb/cli/beta.py
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
"""Beta versions of wandb CLI commands.
|
2
|
+
|
3
|
+
These commands are experimental and may change or be removed in future versions.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
import pathlib
|
9
|
+
import sys
|
10
|
+
|
11
|
+
import click
|
12
|
+
|
13
|
+
import wandb
|
14
|
+
from wandb.errors import UsageError, WandbCoreNotAvailableError
|
15
|
+
from wandb.util import get_core_path
|
16
|
+
|
17
|
+
|
18
|
+
@click.group()
|
19
|
+
def beta():
|
20
|
+
"""Beta versions of wandb CLI commands. Requires wandb-core."""
|
21
|
+
# this is the future that requires wandb-core!
|
22
|
+
import wandb.env
|
23
|
+
|
24
|
+
wandb._sentry.configure_scope(process_context="wandb_beta")
|
25
|
+
|
26
|
+
if wandb.env.is_require_legacy_service():
|
27
|
+
raise UsageError(
|
28
|
+
"wandb beta commands can only be used with wandb-core. "
|
29
|
+
f"Please make sure that `{wandb.env._REQUIRE_LEGACY_SERVICE}` is not set."
|
30
|
+
)
|
31
|
+
|
32
|
+
try:
|
33
|
+
get_core_path()
|
34
|
+
except WandbCoreNotAvailableError as e:
|
35
|
+
wandb._sentry.exception(f"using `wandb beta`. failed with {e}")
|
36
|
+
click.secho(
|
37
|
+
(e),
|
38
|
+
fg="red",
|
39
|
+
err=True,
|
40
|
+
)
|
41
|
+
|
42
|
+
|
43
|
+
@beta.command(
|
44
|
+
name="sync",
|
45
|
+
context_settings={"default_map": {}},
|
46
|
+
help="Upload a training run to W&B",
|
47
|
+
)
|
48
|
+
@click.pass_context
|
49
|
+
@click.argument("wandb_dir", nargs=1, type=click.Path(exists=True))
|
50
|
+
@click.option("--id", "run_id", help="The run you want to upload to.")
|
51
|
+
@click.option("--project", "-p", help="The project you want to upload to.")
|
52
|
+
@click.option("--entity", "-e", help="The entity to scope to.")
|
53
|
+
@click.option("--skip-console", is_flag=True, default=False, help="Skip console logs")
|
54
|
+
@click.option("--append", is_flag=True, default=False, help="Append run")
|
55
|
+
@click.option(
|
56
|
+
"--include",
|
57
|
+
"-i",
|
58
|
+
help="Glob to include. Can be used multiple times.",
|
59
|
+
multiple=True,
|
60
|
+
)
|
61
|
+
@click.option(
|
62
|
+
"--exclude",
|
63
|
+
"-e",
|
64
|
+
help="Glob to exclude. Can be used multiple times.",
|
65
|
+
multiple=True,
|
66
|
+
)
|
67
|
+
@click.option(
|
68
|
+
"--mark-synced/--no-mark-synced",
|
69
|
+
is_flag=True,
|
70
|
+
default=True,
|
71
|
+
help="Mark runs as synced",
|
72
|
+
)
|
73
|
+
@click.option(
|
74
|
+
"--skip-synced/--no-skip-synced",
|
75
|
+
is_flag=True,
|
76
|
+
default=True,
|
77
|
+
help="Skip synced runs",
|
78
|
+
)
|
79
|
+
@click.option(
|
80
|
+
"--dry-run", is_flag=True, help="Perform a dry run without uploading anything."
|
81
|
+
)
|
82
|
+
def sync_beta( # noqa: C901
|
83
|
+
ctx,
|
84
|
+
wandb_dir=None,
|
85
|
+
run_id: str | None = None,
|
86
|
+
project: str | None = None,
|
87
|
+
entity: str | None = None,
|
88
|
+
skip_console: bool = False,
|
89
|
+
append: bool = False,
|
90
|
+
include: str | None = None,
|
91
|
+
exclude: str | None = None,
|
92
|
+
skip_synced: bool = True,
|
93
|
+
mark_synced: bool = True,
|
94
|
+
dry_run: bool = False,
|
95
|
+
) -> None:
|
96
|
+
import concurrent.futures
|
97
|
+
from multiprocessing import cpu_count
|
98
|
+
|
99
|
+
paths = set()
|
100
|
+
|
101
|
+
# TODO: test file discovery logic
|
102
|
+
# include and exclude globs are evaluated relative to the provided base_path
|
103
|
+
if include:
|
104
|
+
for pattern in include:
|
105
|
+
matching_dirs = list(pathlib.Path(wandb_dir).glob(pattern))
|
106
|
+
for d in matching_dirs:
|
107
|
+
if not d.is_dir():
|
108
|
+
continue
|
109
|
+
wandb_files = [p for p in d.glob("*.wandb") if p.is_file()]
|
110
|
+
if len(wandb_files) > 1:
|
111
|
+
print(f"Multiple wandb files found in directory {d}, skipping")
|
112
|
+
elif len(wandb_files) == 1:
|
113
|
+
paths.add(d)
|
114
|
+
else:
|
115
|
+
paths.update({p.parent for p in pathlib.Path(wandb_dir).glob("**/*.wandb")})
|
116
|
+
|
117
|
+
for pattern in exclude:
|
118
|
+
matching_dirs = list(pathlib.Path(wandb_dir).glob(pattern))
|
119
|
+
for d in matching_dirs:
|
120
|
+
if not d.is_dir():
|
121
|
+
continue
|
122
|
+
if d in paths:
|
123
|
+
paths.remove(d)
|
124
|
+
|
125
|
+
# remove paths that are already synced, if requested
|
126
|
+
if skip_synced:
|
127
|
+
synced_paths = set()
|
128
|
+
for path in paths:
|
129
|
+
wandb_synced_files = [p for p in path.glob("*.wandb.synced") if p.is_file()]
|
130
|
+
if len(wandb_synced_files) > 1:
|
131
|
+
print(
|
132
|
+
f"Multiple wandb.synced files found in directory {path}, skipping"
|
133
|
+
)
|
134
|
+
elif len(wandb_synced_files) == 1:
|
135
|
+
synced_paths.add(path)
|
136
|
+
paths -= synced_paths
|
137
|
+
|
138
|
+
if run_id and len(paths) > 1:
|
139
|
+
# TODO: handle this more gracefully
|
140
|
+
click.echo("id can only be set for a single run.", err=True)
|
141
|
+
sys.exit(1)
|
142
|
+
|
143
|
+
if not paths:
|
144
|
+
click.echo("No runs to sync.")
|
145
|
+
return
|
146
|
+
|
147
|
+
click.echo("Found runs:")
|
148
|
+
for path in paths:
|
149
|
+
click.echo(f" {path}")
|
150
|
+
|
151
|
+
if dry_run:
|
152
|
+
return
|
153
|
+
|
154
|
+
wandb.sdk.wandb_setup.setup()
|
155
|
+
|
156
|
+
# TODO: make it thread-safe in the Rust code
|
157
|
+
with concurrent.futures.ProcessPoolExecutor(
|
158
|
+
max_workers=min(len(paths), cpu_count())
|
159
|
+
) as executor:
|
160
|
+
futures = []
|
161
|
+
for path in paths:
|
162
|
+
# we already know there is only one wandb file in the directory
|
163
|
+
wandb_file = [p for p in path.glob("*.wandb") if p.is_file()][0]
|
164
|
+
future = executor.submit(
|
165
|
+
wandb._sync,
|
166
|
+
wandb_file,
|
167
|
+
run_id=run_id,
|
168
|
+
project=project,
|
169
|
+
entity=entity,
|
170
|
+
skip_console=skip_console,
|
171
|
+
append=append,
|
172
|
+
mark_synced=mark_synced,
|
173
|
+
)
|
174
|
+
futures.append(future)
|
175
|
+
|
176
|
+
# Wait for tasks to complete
|
177
|
+
for _ in concurrent.futures.as_completed(futures):
|
178
|
+
pass
|
wandb/cli/cli.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
1
|
import asyncio
|
4
2
|
import configparser
|
5
3
|
import datetime
|
@@ -7,7 +5,6 @@ import getpass
|
|
7
5
|
import json
|
8
6
|
import logging
|
9
7
|
import os
|
10
|
-
import pathlib
|
11
8
|
import shlex
|
12
9
|
import shutil
|
13
10
|
import subprocess
|
@@ -28,14 +25,11 @@ from dockerpycreds.utils import find_executable
|
|
28
25
|
|
29
26
|
import wandb
|
30
27
|
import wandb.env
|
31
|
-
|
32
|
-
# from wandb.old.core import wandb_dir
|
33
28
|
import wandb.errors
|
34
29
|
import wandb.sdk.verify.verify as wandb_verify
|
35
30
|
from wandb import Config, Error, env, util, wandb_agent, wandb_sdk
|
36
31
|
from wandb.apis import InternalApi, PublicApi
|
37
32
|
from wandb.apis.public import RunQueue
|
38
|
-
from wandb.errors import UsageError, WandbCoreNotAvailableError
|
39
33
|
from wandb.integration.magic import magic_install
|
40
34
|
from wandb.sdk.artifacts.artifact_file_cache import get_artifact_file_cache
|
41
35
|
from wandb.sdk.launch import utils as launch_utils
|
@@ -46,7 +40,8 @@ from wandb.sdk.launch.sweeps.scheduler import Scheduler
|
|
46
40
|
from wandb.sdk.lib import filesystem
|
47
41
|
from wandb.sdk.lib.wburls import wburls
|
48
42
|
from wandb.sync import SyncManager, get_run_from_path, get_runs
|
49
|
-
|
43
|
+
|
44
|
+
from .beta import beta
|
50
45
|
|
51
46
|
# Send cli logs to wandb/debug-cli.<username>.log by default and fallback to a temp dir.
|
52
47
|
_wandb_dir = wandb.old.core.wandb_dir(env.get_dir())
|
@@ -432,170 +427,6 @@ def init(ctx, project, entity, reset, mode):
|
|
432
427
|
)
|
433
428
|
|
434
429
|
|
435
|
-
@cli.group()
|
436
|
-
def beta():
|
437
|
-
"""Beta versions of wandb CLI commands. Requires wandb-core."""
|
438
|
-
# this is the future that requires wandb-core!
|
439
|
-
import wandb.env
|
440
|
-
|
441
|
-
wandb._sentry.configure_scope(process_context="wandb_beta")
|
442
|
-
|
443
|
-
if wandb.env.is_require_legacy_service():
|
444
|
-
raise UsageError(
|
445
|
-
"wandb beta commands can only be used with wandb-core. "
|
446
|
-
f"Please make sure that `{wandb.env._REQUIRE_LEGACY_SERVICE}` is not set."
|
447
|
-
)
|
448
|
-
|
449
|
-
try:
|
450
|
-
get_core_path()
|
451
|
-
except WandbCoreNotAvailableError as e:
|
452
|
-
wandb._sentry.exception(f"using `wandb beta`. failed with {e}")
|
453
|
-
click.secho(
|
454
|
-
(e),
|
455
|
-
fg="red",
|
456
|
-
err=True,
|
457
|
-
)
|
458
|
-
|
459
|
-
|
460
|
-
@beta.command(
|
461
|
-
name="sync",
|
462
|
-
context_settings=CONTEXT,
|
463
|
-
help="Upload a training run to W&B",
|
464
|
-
)
|
465
|
-
@click.pass_context
|
466
|
-
@click.argument("wandb_dir", nargs=1, type=click.Path(exists=True))
|
467
|
-
@click.option("--id", "run_id", help="The run you want to upload to.")
|
468
|
-
@click.option("--project", "-p", help="The project you want to upload to.")
|
469
|
-
@click.option("--entity", "-e", help="The entity to scope to.")
|
470
|
-
@click.option("--skip-console", is_flag=True, default=False, help="Skip console logs")
|
471
|
-
@click.option("--append", is_flag=True, default=False, help="Append run")
|
472
|
-
@click.option(
|
473
|
-
"--include",
|
474
|
-
"-i",
|
475
|
-
help="Glob to include. Can be used multiple times.",
|
476
|
-
multiple=True,
|
477
|
-
)
|
478
|
-
@click.option(
|
479
|
-
"--exclude",
|
480
|
-
"-e",
|
481
|
-
help="Glob to exclude. Can be used multiple times.",
|
482
|
-
multiple=True,
|
483
|
-
)
|
484
|
-
@click.option(
|
485
|
-
"--mark-synced/--no-mark-synced",
|
486
|
-
is_flag=True,
|
487
|
-
default=True,
|
488
|
-
help="Mark runs as synced",
|
489
|
-
)
|
490
|
-
@click.option(
|
491
|
-
"--skip-synced/--no-skip-synced",
|
492
|
-
is_flag=True,
|
493
|
-
default=True,
|
494
|
-
help="Skip synced runs",
|
495
|
-
)
|
496
|
-
@click.option(
|
497
|
-
"--dry-run", is_flag=True, help="Perform a dry run without uploading anything."
|
498
|
-
)
|
499
|
-
@display_error
|
500
|
-
def sync_beta(
|
501
|
-
ctx,
|
502
|
-
wandb_dir=None,
|
503
|
-
run_id: Optional[str] = None,
|
504
|
-
project: Optional[str] = None,
|
505
|
-
entity: Optional[str] = None,
|
506
|
-
skip_console: bool = False,
|
507
|
-
append: bool = False,
|
508
|
-
include: Optional[str] = None,
|
509
|
-
exclude: Optional[str] = None,
|
510
|
-
skip_synced: bool = True,
|
511
|
-
mark_synced: bool = True,
|
512
|
-
dry_run: bool = False,
|
513
|
-
):
|
514
|
-
import concurrent.futures
|
515
|
-
from multiprocessing import cpu_count
|
516
|
-
|
517
|
-
paths = set()
|
518
|
-
|
519
|
-
# TODO: test file discovery logic
|
520
|
-
# include and exclude globs are evaluated relative to the provided base_path
|
521
|
-
if include:
|
522
|
-
for pattern in include:
|
523
|
-
matching_dirs = list(pathlib.Path(wandb_dir).glob(pattern))
|
524
|
-
for d in matching_dirs:
|
525
|
-
if not d.is_dir():
|
526
|
-
continue
|
527
|
-
wandb_files = [p for p in d.glob("*.wandb") if p.is_file()]
|
528
|
-
if len(wandb_files) > 1:
|
529
|
-
print(f"Multiple wandb files found in directory {d}, skipping")
|
530
|
-
elif len(wandb_files) == 1:
|
531
|
-
paths.add(d)
|
532
|
-
else:
|
533
|
-
paths.update({p.parent for p in pathlib.Path(wandb_dir).glob("**/*.wandb")})
|
534
|
-
|
535
|
-
for pattern in exclude:
|
536
|
-
matching_dirs = list(pathlib.Path(wandb_dir).glob(pattern))
|
537
|
-
for d in matching_dirs:
|
538
|
-
if not d.is_dir():
|
539
|
-
continue
|
540
|
-
if d in paths:
|
541
|
-
paths.remove(d)
|
542
|
-
|
543
|
-
# remove paths that are already synced, if requested
|
544
|
-
if skip_synced:
|
545
|
-
synced_paths = set()
|
546
|
-
for path in paths:
|
547
|
-
wandb_synced_files = [p for p in path.glob("*.wandb.synced") if p.is_file()]
|
548
|
-
if len(wandb_synced_files) > 1:
|
549
|
-
print(
|
550
|
-
f"Multiple wandb.synced files found in directory {path}, skipping"
|
551
|
-
)
|
552
|
-
elif len(wandb_synced_files) == 1:
|
553
|
-
synced_paths.add(path)
|
554
|
-
paths -= synced_paths
|
555
|
-
|
556
|
-
if run_id and len(paths) > 1:
|
557
|
-
# TODO: handle this more gracefully
|
558
|
-
click.echo("id can only be set for a single run.", err=True)
|
559
|
-
sys.exit(1)
|
560
|
-
|
561
|
-
if not paths:
|
562
|
-
click.echo("No runs to sync.")
|
563
|
-
return
|
564
|
-
|
565
|
-
click.echo("Found runs:")
|
566
|
-
for path in paths:
|
567
|
-
click.echo(f" {path}")
|
568
|
-
|
569
|
-
if dry_run:
|
570
|
-
return
|
571
|
-
|
572
|
-
wandb.sdk.wandb_setup.setup()
|
573
|
-
|
574
|
-
# TODO: make it thread-safe in the Rust code
|
575
|
-
with concurrent.futures.ProcessPoolExecutor(
|
576
|
-
max_workers=min(len(paths), cpu_count())
|
577
|
-
) as executor:
|
578
|
-
futures = []
|
579
|
-
for path in paths:
|
580
|
-
# we already know there is only one wandb file in the directory
|
581
|
-
wandb_file = [p for p in path.glob("*.wandb") if p.is_file()][0]
|
582
|
-
future = executor.submit(
|
583
|
-
wandb._sync,
|
584
|
-
wandb_file,
|
585
|
-
run_id=run_id,
|
586
|
-
project=project,
|
587
|
-
entity=entity,
|
588
|
-
skip_console=skip_console,
|
589
|
-
append=append,
|
590
|
-
mark_synced=mark_synced,
|
591
|
-
)
|
592
|
-
futures.append(future)
|
593
|
-
|
594
|
-
# Wait for tasks to complete
|
595
|
-
for _ in concurrent.futures.as_completed(futures):
|
596
|
-
pass
|
597
|
-
|
598
|
-
|
599
430
|
@cli.command(
|
600
431
|
context_settings=CONTEXT, help="Upload an offline training directory to W&B"
|
601
432
|
)
|
@@ -3002,3 +2833,6 @@ def verify(host):
|
|
3002
2833
|
and url_success
|
3003
2834
|
):
|
3004
2835
|
sys.exit(1)
|
2836
|
+
|
2837
|
+
|
2838
|
+
cli.add_command(beta)
|
wandb/data_types.py
CHANGED
@@ -14,6 +14,7 @@ and upload them to the W&B server.
|
|
14
14
|
"""
|
15
15
|
|
16
16
|
from .sdk.data_types.audio import Audio
|
17
|
+
from .sdk.data_types.base_types.media import BatchableMedia, Media
|
17
18
|
from .sdk.data_types.base_types.wb_value import WBValue
|
18
19
|
from .sdk.data_types.bokeh import Bokeh
|
19
20
|
from .sdk.data_types.graph import Graph, Node
|
@@ -56,6 +57,8 @@ __all__ = [
|
|
56
57
|
"WBTraceTree",
|
57
58
|
"_SavedModel",
|
58
59
|
"WBValue",
|
60
|
+
"Media",
|
61
|
+
"BatchableMedia",
|
59
62
|
# Typed Legacy Exports (I'd like to remove these)
|
60
63
|
"ImageMask",
|
61
64
|
"BoundingBoxes2D",
|