wandb 0.19.8__py3-none-win_amd64.whl → 0.19.9__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 +5 -1
- wandb/__init__.pyi +12 -8
- wandb/_pydantic/__init__.py +23 -0
- wandb/_pydantic/base.py +113 -0
- wandb/_pydantic/v1_compat.py +262 -0
- wandb/apis/paginator.py +82 -38
- wandb/apis/public/api.py +10 -64
- wandb/apis/public/artifacts.py +73 -17
- wandb/apis/public/files.py +2 -2
- wandb/apis/public/projects.py +3 -2
- wandb/apis/public/reports.py +2 -2
- wandb/apis/public/runs.py +19 -11
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/integration/metaflow/metaflow.py +19 -17
- wandb/integration/sacred/__init__.py +1 -1
- wandb/jupyter.py +18 -15
- wandb/proto/v3/wandb_internal_pb2.py +7 -3
- 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 +3 -3
- 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 +3 -3
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
- wandb/proto/wandb_deprecated.py +2 -0
- wandb/sdk/artifacts/_graphql_fragments.py +18 -20
- wandb/sdk/artifacts/_validators.py +1 -0
- wandb/sdk/artifacts/artifact.py +70 -36
- wandb/sdk/artifacts/artifact_saver.py +16 -2
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +23 -2
- wandb/sdk/data_types/audio.py +1 -3
- wandb/sdk/data_types/base_types/media.py +11 -4
- wandb/sdk/data_types/image.py +44 -25
- wandb/sdk/data_types/molecule.py +1 -5
- wandb/sdk/data_types/object_3d.py +2 -1
- wandb/sdk/data_types/saved_model.py +7 -9
- wandb/sdk/data_types/video.py +1 -4
- wandb/{apis/public → sdk/internal}/_generated/__init__.py +0 -6
- wandb/sdk/internal/_generated/base.py +226 -0
- wandb/{apis/public → sdk/internal}/_generated/server_features_query.py +3 -3
- wandb/{apis/public → sdk/internal}/_generated/typing_compat.py +1 -1
- wandb/sdk/internal/internal_api.py +138 -47
- wandb/sdk/internal/sender.py +2 -0
- wandb/sdk/internal/sender_config.py +8 -11
- wandb/sdk/internal/settings_static.py +24 -2
- wandb/sdk/lib/apikey.py +15 -16
- wandb/sdk/lib/run_moment.py +4 -6
- wandb/sdk/lib/wb_logging.py +161 -0
- wandb/sdk/wandb_config.py +44 -43
- wandb/sdk/wandb_init.py +141 -79
- wandb/sdk/wandb_metadata.py +107 -91
- wandb/sdk/wandb_run.py +152 -44
- wandb/sdk/wandb_settings.py +403 -201
- wandb/sdk/wandb_setup.py +3 -1
- {wandb-0.19.8.dist-info → wandb-0.19.9.dist-info}/METADATA +3 -3
- {wandb-0.19.8.dist-info → wandb-0.19.9.dist-info}/RECORD +64 -60
- wandb/apis/public/_generated/base.py +0 -128
- /wandb/{apis/public → sdk/internal}/_generated/enums.py +0 -0
- /wandb/{apis/public → sdk/internal}/_generated/input_types.py +0 -0
- /wandb/{apis/public → sdk/internal}/_generated/operations.py +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.9.dist-info}/WHEEL +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.9.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.8.dist-info → wandb-0.19.9.dist-info}/licenses/LICENSE +0 -0
@@ -21,11 +21,33 @@ class SettingsStatic(Settings):
|
|
21
21
|
def _proto_to_dict(self, proto: wandb_settings_pb2.Settings) -> dict:
|
22
22
|
data = {}
|
23
23
|
|
24
|
+
exclude_fields = {
|
25
|
+
"model_config",
|
26
|
+
"model_fields",
|
27
|
+
"model_fields_set",
|
28
|
+
"__fields__",
|
29
|
+
"__model_fields_set",
|
30
|
+
"__pydantic_self__",
|
31
|
+
"__pydantic_initialised__",
|
32
|
+
}
|
33
|
+
|
34
|
+
fields = (
|
35
|
+
Settings.model_fields
|
36
|
+
if hasattr(Settings, "model_fields")
|
37
|
+
else Settings.__fields__
|
38
|
+
) # type: ignore [attr-defined]
|
39
|
+
|
40
|
+
fields = {k: v for k, v in fields.items() if k not in exclude_fields} # type: ignore [union-attr]
|
41
|
+
|
24
42
|
forks_specified: list[str] = []
|
25
|
-
for key in
|
43
|
+
for key in fields:
|
44
|
+
# Skip Python-only keys that do not exist on the proto.
|
45
|
+
if key in ("reinit",):
|
46
|
+
continue
|
47
|
+
|
26
48
|
value: Any = None
|
27
49
|
|
28
|
-
field_info =
|
50
|
+
field_info = fields[key]
|
29
51
|
annotation = str(field_info.annotation)
|
30
52
|
|
31
53
|
if key == "_stats_open_metrics_filters":
|
wandb/sdk/lib/apikey.py
CHANGED
@@ -11,7 +11,7 @@ import textwrap
|
|
11
11
|
from functools import partial
|
12
12
|
|
13
13
|
# import Literal
|
14
|
-
from typing import TYPE_CHECKING, Callable,
|
14
|
+
from typing import TYPE_CHECKING, Callable, Literal
|
15
15
|
from urllib.parse import urlparse
|
16
16
|
|
17
17
|
import click
|
@@ -23,6 +23,9 @@ from wandb.errors import term
|
|
23
23
|
from wandb.errors.links import url_registry
|
24
24
|
from wandb.util import _is_databricks, isatty, prompt_choices
|
25
25
|
|
26
|
+
if TYPE_CHECKING:
|
27
|
+
from wandb.sdk.wandb_settings import Settings
|
28
|
+
|
26
29
|
LOGIN_CHOICE_ANON = "Private W&B dashboard, no account required"
|
27
30
|
LOGIN_CHOICE_NEW = "Create a W&B account"
|
28
31
|
LOGIN_CHOICE_EXISTS = "Use an existing W&B account"
|
@@ -50,18 +53,14 @@ class WriteNetrcError(Exception):
|
|
50
53
|
Mode = Literal["allow", "must", "never", "false", "true"]
|
51
54
|
|
52
55
|
|
53
|
-
if TYPE_CHECKING:
|
54
|
-
from wandb.sdk.wandb_settings import Settings
|
55
|
-
|
56
|
-
|
57
56
|
getpass = partial(click.prompt, hide_input=True, err=True)
|
58
57
|
|
59
58
|
|
60
|
-
def _fixup_anon_mode(default:
|
59
|
+
def _fixup_anon_mode(default: Mode | None) -> Mode | None:
|
61
60
|
# Convert weird anonymode values from legacy settings files
|
62
61
|
# into one of our expected values.
|
63
62
|
anon_mode = default or "never"
|
64
|
-
mapping:
|
63
|
+
mapping: dict[Mode, Mode] = {"true": "allow", "false": "never"}
|
65
64
|
return mapping.get(anon_mode, anon_mode)
|
66
65
|
|
67
66
|
|
@@ -85,14 +84,14 @@ def get_netrc_file_path() -> str:
|
|
85
84
|
|
86
85
|
|
87
86
|
def prompt_api_key( # noqa: C901
|
88
|
-
settings:
|
89
|
-
api:
|
90
|
-
input_callback:
|
91
|
-
browser_callback:
|
87
|
+
settings: Settings,
|
88
|
+
api: InternalApi | None = None,
|
89
|
+
input_callback: Callable | None = None,
|
90
|
+
browser_callback: Callable | None = None,
|
92
91
|
no_offline: bool = False,
|
93
92
|
no_create: bool = False,
|
94
93
|
local: bool = False,
|
95
|
-
) ->
|
94
|
+
) -> str | bool | None:
|
96
95
|
"""Prompt for api key.
|
97
96
|
|
98
97
|
Returns:
|
@@ -276,9 +275,9 @@ def write_netrc(host: str, entity: str, key: str):
|
|
276
275
|
|
277
276
|
|
278
277
|
def write_key(
|
279
|
-
settings:
|
280
|
-
key:
|
281
|
-
api:
|
278
|
+
settings: Settings,
|
279
|
+
key: str | None,
|
280
|
+
api: InternalApi | None = None,
|
282
281
|
) -> None:
|
283
282
|
if not key:
|
284
283
|
raise ValueError("No API key specified.")
|
@@ -298,7 +297,7 @@ def write_key(
|
|
298
297
|
write_netrc(settings.base_url, "user", key)
|
299
298
|
|
300
299
|
|
301
|
-
def api_key(settings:
|
300
|
+
def api_key(settings: Settings | None = None) -> str | None:
|
302
301
|
if settings is None:
|
303
302
|
settings = wandb.setup().settings
|
304
303
|
if settings.api_key:
|
wandb/sdk/lib/run_moment.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import
|
4
|
+
from typing import Union
|
5
5
|
from urllib import parse
|
6
6
|
|
7
|
-
_STEP = Literal["_step"]
|
8
|
-
|
9
7
|
|
10
8
|
@dataclass
|
11
9
|
class RunMoment:
|
@@ -19,10 +17,10 @@ class RunMoment:
|
|
19
17
|
run: str
|
20
18
|
"""run ID"""
|
21
19
|
|
22
|
-
value: int
|
20
|
+
value: Union[int, float]
|
23
21
|
"""Value of the metric."""
|
24
22
|
|
25
|
-
metric:
|
23
|
+
metric: str = "_step"
|
26
24
|
"""Metric to use to determine the moment in the run.
|
27
25
|
|
28
26
|
Currently, only the metric '_step' is supported.
|
@@ -81,4 +79,4 @@ class RunMoment:
|
|
81
79
|
except ValueError as e:
|
82
80
|
raise parse_err from e
|
83
81
|
|
84
|
-
return cls(run=run, metric=
|
82
|
+
return cls(run=run, metric=metric, value=num_value)
|
@@ -0,0 +1,161 @@
|
|
1
|
+
"""Logging configuration for the "wandb" logger.
|
2
|
+
|
3
|
+
Most log statements in wandb are made in the context of a run and should be
|
4
|
+
redirected to that run's log file (usually named 'debug.log'). This module
|
5
|
+
provides a context manager to temporarily set the current run ID and registers
|
6
|
+
a global handler for the 'wandb' logger that sends log statements to the right
|
7
|
+
place.
|
8
|
+
|
9
|
+
All functions in this module are threadsafe.
|
10
|
+
|
11
|
+
NOTE: The pytest caplog fixture will fail to capture logs from the wandb logger
|
12
|
+
because they are not propagated to the root logger.
|
13
|
+
"""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import contextlib
|
18
|
+
import contextvars
|
19
|
+
import logging
|
20
|
+
import pathlib
|
21
|
+
from typing import Iterator
|
22
|
+
|
23
|
+
|
24
|
+
class _NotRunSpecific:
|
25
|
+
"""Sentinel for `not_run_specific()`."""
|
26
|
+
|
27
|
+
|
28
|
+
_NOT_RUN_SPECIFIC = _NotRunSpecific()
|
29
|
+
|
30
|
+
|
31
|
+
_run_id: contextvars.ContextVar[str | _NotRunSpecific | None] = contextvars.ContextVar(
|
32
|
+
"_run_id",
|
33
|
+
default=None,
|
34
|
+
)
|
35
|
+
|
36
|
+
_logger = logging.getLogger("wandb")
|
37
|
+
|
38
|
+
|
39
|
+
def configure_wandb_logger() -> None:
|
40
|
+
"""Configures the global 'wandb' logger.
|
41
|
+
|
42
|
+
The wandb logger is not intended to be customized by users. Instead, it is
|
43
|
+
used as a mechanism to redirect log messages into wandb run-specific log
|
44
|
+
files.
|
45
|
+
|
46
|
+
This function is idempotent: calling it multiple times has the same effect.
|
47
|
+
"""
|
48
|
+
# Send all DEBUG and above messages to registered handlers.
|
49
|
+
#
|
50
|
+
# Per-run handlers can set different levels.
|
51
|
+
_logger.setLevel(logging.DEBUG)
|
52
|
+
|
53
|
+
# Do not propagate wandb logs to the root logger, which the user may have
|
54
|
+
# configured to point elsewhere. All wandb log messages should go to a run's
|
55
|
+
# log file.
|
56
|
+
_logger.propagate = False
|
57
|
+
|
58
|
+
# If no handlers are configured for the 'wandb' logger, don't activate the
|
59
|
+
# "lastResort" handler which sends messages to stderr with a level of
|
60
|
+
# WARNING by default.
|
61
|
+
#
|
62
|
+
# This occurs in wandb code that runs outside the context of a Run and
|
63
|
+
# not as part of the CLI.
|
64
|
+
#
|
65
|
+
# Most such code uses the `termlog` / `termwarn` / `termerror` methods
|
66
|
+
# to communicate with the user. When that code executes while a run is
|
67
|
+
# active, its logger messages go to that run's log file.
|
68
|
+
if not _logger.handlers:
|
69
|
+
_logger.addHandler(logging.NullHandler())
|
70
|
+
|
71
|
+
|
72
|
+
@contextlib.contextmanager
|
73
|
+
def log_to_run(run_id: str | None) -> Iterator[None]:
|
74
|
+
"""Direct all wandb log messages to the given run.
|
75
|
+
|
76
|
+
Args:
|
77
|
+
id: The current run ID, or None if actions in the context manager are
|
78
|
+
not associated to a specific run. In the latter case, log messages
|
79
|
+
will go to all runs.
|
80
|
+
|
81
|
+
Usage:
|
82
|
+
|
83
|
+
with wb_logging.run_id(...):
|
84
|
+
... # Log messages here go to the specified run's logger.
|
85
|
+
"""
|
86
|
+
token = _run_id.set(run_id)
|
87
|
+
try:
|
88
|
+
yield
|
89
|
+
finally:
|
90
|
+
_run_id.reset(token)
|
91
|
+
|
92
|
+
|
93
|
+
@contextlib.contextmanager
|
94
|
+
def log_to_all_runs() -> Iterator[None]:
|
95
|
+
"""Direct wandb log messages to all runs.
|
96
|
+
|
97
|
+
Unlike `log_to_run(None)`, this indicates an intentional choice.
|
98
|
+
This is often convenient to use as a decorator:
|
99
|
+
|
100
|
+
@wb_logging.log_to_all_runs()
|
101
|
+
def my_func():
|
102
|
+
... # Log messages here go to the specified run's logger.
|
103
|
+
"""
|
104
|
+
token = _run_id.set(_NOT_RUN_SPECIFIC)
|
105
|
+
try:
|
106
|
+
yield
|
107
|
+
finally:
|
108
|
+
_run_id.reset(token)
|
109
|
+
|
110
|
+
|
111
|
+
def add_file_handler(run_id: str, filepath: pathlib.Path) -> logging.Handler:
|
112
|
+
"""Direct log messages for a run to a file.
|
113
|
+
|
114
|
+
Args:
|
115
|
+
run_id: The run for which to create a log file.
|
116
|
+
filepath: The file to write log messages to.
|
117
|
+
|
118
|
+
Returns:
|
119
|
+
The added handler which can then be configured further or removed
|
120
|
+
from the 'wandb' logger directly.
|
121
|
+
|
122
|
+
The default logging level is INFO.
|
123
|
+
"""
|
124
|
+
handler = logging.FileHandler(filepath)
|
125
|
+
handler.setLevel(logging.INFO)
|
126
|
+
handler.addFilter(_RunIDFilter(run_id))
|
127
|
+
handler.setFormatter(
|
128
|
+
logging.Formatter(
|
129
|
+
"%(asctime)s %(levelname)-7s %(threadName)-10s:%(process)d"
|
130
|
+
" [%(filename)s:%(funcName)s():%(lineno)s]%(run_id_tag)s"
|
131
|
+
" %(message)s"
|
132
|
+
)
|
133
|
+
)
|
134
|
+
|
135
|
+
_logger.addHandler(handler)
|
136
|
+
return handler
|
137
|
+
|
138
|
+
|
139
|
+
class _RunIDFilter(logging.Filter):
|
140
|
+
"""Filters out messages logged for a different run."""
|
141
|
+
|
142
|
+
def __init__(self, run_id: str) -> None:
|
143
|
+
"""Create a _RunIDFilter.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
run_id: Allows messages when the run ID is this or None.
|
147
|
+
"""
|
148
|
+
self._run_id = run_id
|
149
|
+
|
150
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
151
|
+
run_id = _run_id.get()
|
152
|
+
|
153
|
+
if run_id is None:
|
154
|
+
record.run_id_tag = " [no run ID]"
|
155
|
+
return True
|
156
|
+
elif isinstance(run_id, _NotRunSpecific):
|
157
|
+
record.run_id_tag = " [all runs]"
|
158
|
+
return True
|
159
|
+
else:
|
160
|
+
record.run_id_tag = ""
|
161
|
+
return run_id == self._run_id
|
wandb/sdk/wandb_config.py
CHANGED
@@ -22,65 +22,63 @@ logger = logging.getLogger("wandb")
|
|
22
22
|
class Config:
|
23
23
|
"""Config object.
|
24
24
|
|
25
|
-
Config objects are intended to hold all of the hyperparameters associated
|
26
|
-
a wandb run and are saved with the run object when `wandb.init` is
|
25
|
+
Config objects are intended to hold all of the hyperparameters associated
|
26
|
+
with a wandb run and are saved with the run object when `wandb.init` is
|
27
|
+
called.
|
27
28
|
|
28
|
-
We recommend setting
|
29
|
-
|
29
|
+
We recommend setting the config once when initializing your run by passing
|
30
|
+
the `config` parameter to `init`:
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
```
|
33
|
+
wandb.init(config=my_config_dict)
|
34
|
+
```
|
35
|
+
|
36
|
+
You can create a file called `config-defaults.yaml`, and it will
|
37
|
+
automatically be loaded as each run's config. You can also pass the name
|
38
|
+
of the file as the `config` parameter to `init`:
|
39
|
+
|
40
|
+
```
|
41
|
+
wandb.init(config="my_config.yaml")
|
42
|
+
```
|
33
43
|
|
34
|
-
You can also load a config YAML file with your custom name and pass the filename
|
35
|
-
into `wandb.init(config="special_config.yaml")`.
|
36
44
|
See https://docs.wandb.com/guides/track/config#file-based-configs.
|
37
45
|
|
38
46
|
Examples:
|
39
47
|
Basic usage
|
40
48
|
```
|
41
|
-
wandb.config
|
42
|
-
|
43
|
-
|
44
|
-
# train
|
45
|
-
```
|
46
|
-
|
47
|
-
Using wandb.init to set config
|
48
|
-
```
|
49
|
-
wandb.init(config={"epochs": 4, "batch_size": 32})
|
50
|
-
for x in range(wandb.config.epochs):
|
51
|
-
# train
|
49
|
+
with wandb.init(config={"epochs": 4}) as run:
|
50
|
+
for x in range(run.config.epochs):
|
51
|
+
# train
|
52
52
|
```
|
53
53
|
|
54
|
-
Nested
|
54
|
+
Nested values
|
55
55
|
```
|
56
|
-
wandb.config
|
57
|
-
|
58
|
-
|
59
|
-
# train
|
56
|
+
with wandb.init(config={"train": {"epochs": 4}}) as run:
|
57
|
+
for x in range(run.config["train"]["epochs"]):
|
58
|
+
# train
|
60
59
|
```
|
61
60
|
|
62
61
|
Using absl flags
|
63
62
|
```
|
64
63
|
flags.DEFINE_string("model", None, "model to run") # name, default, help
|
65
|
-
wandb.
|
64
|
+
with wandb.init() as run:
|
65
|
+
run.config.update(flags.FLAGS) # adds all absl flags to config
|
66
66
|
```
|
67
67
|
|
68
68
|
Argparse flags
|
69
69
|
```python
|
70
|
-
wandb.init()
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
args = parser.parse_args()
|
83
|
-
wandb.config.update(args)
|
70
|
+
with wandb.init(config={"epochs": 4}) as run:
|
71
|
+
parser = argparse.ArgumentParser()
|
72
|
+
parser.add_argument(
|
73
|
+
"-b",
|
74
|
+
"--batch-size",
|
75
|
+
type=int,
|
76
|
+
default=8,
|
77
|
+
metavar="N",
|
78
|
+
help="input batch size for training (default: 8)",
|
79
|
+
)
|
80
|
+
args = parser.parse_args()
|
81
|
+
run.config.update(args)
|
84
82
|
```
|
85
83
|
|
86
84
|
Using TensorFlow flags (deprecated in tensorflow v2)
|
@@ -88,7 +86,9 @@ class Config:
|
|
88
86
|
flags = tf.app.flags
|
89
87
|
flags.DEFINE_string("data_dir", "/tmp/data")
|
90
88
|
flags.DEFINE_integer("batch_size", 128, "Batch size.")
|
91
|
-
|
89
|
+
|
90
|
+
with wandb.init() as run:
|
91
|
+
run.config.update(flags.FLAGS)
|
92
92
|
```
|
93
93
|
"""
|
94
94
|
|
@@ -298,7 +298,8 @@ class Config:
|
|
298
298
|
# best if we don't allow nested artifacts until we can lock nested keys in the config
|
299
299
|
if isinstance(v, dict) and check_dict_contains_nested_artifact(v, nested):
|
300
300
|
raise ValueError(
|
301
|
-
"Instances of wandb.Artifact can only be top level keys in
|
301
|
+
"Instances of wandb.Artifact can only be top level keys in"
|
302
|
+
" a run's config"
|
302
303
|
)
|
303
304
|
|
304
305
|
|
@@ -307,10 +308,10 @@ class ConfigStatic:
|
|
307
308
|
object.__setattr__(self, "__dict__", dict(config))
|
308
309
|
|
309
310
|
def __setattr__(self, name, value):
|
310
|
-
raise AttributeError("Error:
|
311
|
+
raise AttributeError("Error: run.config_static is a readonly object")
|
311
312
|
|
312
313
|
def __setitem__(self, key, val):
|
313
|
-
raise AttributeError("Error:
|
314
|
+
raise AttributeError("Error: run.config_static is a readonly object")
|
314
315
|
|
315
316
|
def keys(self):
|
316
317
|
return self.__dict__.keys()
|