wandb 0.19.4rc1__py3-none-win32.whl → 0.19.5__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 +1 -1
- wandb/__init__.pyi +1 -8
- wandb/_iterutils.py +46 -0
- wandb/apis/internal.py +4 -0
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +9 -2
- wandb/sdk/artifacts/artifact.py +87 -1
- wandb/sdk/backend/backend.py +7 -11
- wandb/sdk/data_types/base_types/wb_value.py +10 -10
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +2 -2
- wandb/sdk/data_types/helper_types/image_mask.py +2 -2
- wandb/sdk/data_types/image.py +0 -3
- wandb/sdk/data_types/utils.py +2 -6
- wandb/sdk/interface/interface.py +26 -12
- wandb/sdk/interface/interface_sock.py +7 -11
- wandb/sdk/internal/internal_api.py +9 -1
- wandb/sdk/internal/system/assets/cpu.py +1 -1
- wandb/sdk/lib/apikey.py +4 -17
- wandb/sdk/lib/mailbox.py +0 -10
- wandb/sdk/lib/server.py +20 -0
- wandb/sdk/lib/service_connection.py +2 -2
- wandb/sdk/wandb_init.py +60 -45
- wandb/sdk/wandb_login.py +86 -110
- wandb/sdk/wandb_metadata.py +57 -31
- wandb/sdk/wandb_run.py +32 -45
- wandb/sdk/wandb_settings.py +26 -10
- wandb/sdk/wandb_setup.py +10 -22
- {wandb-0.19.4rc1.dist-info → wandb-0.19.5.dist-info}/METADATA +1 -1
- {wandb-0.19.4rc1.dist-info → wandb-0.19.5.dist-info}/RECORD +33 -32
- {wandb-0.19.4rc1.dist-info → wandb-0.19.5.dist-info}/WHEEL +0 -0
- {wandb-0.19.4rc1.dist-info → wandb-0.19.5.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.4rc1.dist-info → wandb-0.19.5.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/lib/mailbox.py
CHANGED
@@ -341,16 +341,6 @@ class Mailbox:
|
|
341
341
|
def enable_keepalive(self) -> None:
|
342
342
|
self._keepalive = True
|
343
343
|
|
344
|
-
def wait(
|
345
|
-
self,
|
346
|
-
handle: MailboxHandle,
|
347
|
-
*,
|
348
|
-
timeout: float,
|
349
|
-
on_progress: Optional[Callable[[MailboxProgress], None]] = None,
|
350
|
-
cancel: bool = False,
|
351
|
-
) -> Optional[pb.Result]:
|
352
|
-
return handle.wait(timeout=timeout, on_progress=on_progress, cancel=cancel)
|
353
|
-
|
354
344
|
def _time(self) -> float:
|
355
345
|
return time.monotonic()
|
356
346
|
|
wandb/sdk/lib/server.py
CHANGED
@@ -25,6 +25,7 @@ class Server:
|
|
25
25
|
def query_with_timeout(self, timeout: int | float = 5) -> None:
|
26
26
|
if self._settings.x_disable_viewer:
|
27
27
|
return
|
28
|
+
|
28
29
|
async_viewer = util.async_call(self._api.viewer_server_info, timeout=timeout)
|
29
30
|
try:
|
30
31
|
viewer_tuple, viewer_thread = async_viewer()
|
@@ -36,3 +37,22 @@ class Server:
|
|
36
37
|
# TODO(jhr): should we kill the thread?
|
37
38
|
self._viewer, self._serverinfo = viewer_tuple
|
38
39
|
self._flags = json.loads(self._viewer.get("flags", "{}"))
|
40
|
+
|
41
|
+
@property
|
42
|
+
def viewer(self) -> dict[str, Any]:
|
43
|
+
"""Returns information about the currently authenticated user.
|
44
|
+
|
45
|
+
If the API key is valid, the following is returned:
|
46
|
+
- id
|
47
|
+
- entity
|
48
|
+
- username
|
49
|
+
- flags
|
50
|
+
- teams
|
51
|
+
|
52
|
+
If the API key is not valid or the server is not reachable,
|
53
|
+
an empty dict is returned.
|
54
|
+
"""
|
55
|
+
if not self._viewer and not self._settings._offline:
|
56
|
+
self.query_with_timeout()
|
57
|
+
|
58
|
+
return self._viewer
|
@@ -124,9 +124,9 @@ class ServiceConnection:
|
|
124
124
|
self._torn_down = False
|
125
125
|
self._cleanup = cleanup
|
126
126
|
|
127
|
-
def make_interface(self, mailbox: Mailbox) -> InterfaceBase:
|
127
|
+
def make_interface(self, mailbox: Mailbox, stream_id: str) -> InterfaceBase:
|
128
128
|
"""Returns an interface for communicating with the service."""
|
129
|
-
return InterfaceSock(self._client, mailbox)
|
129
|
+
return InterfaceSock(self._client, mailbox, stream_id=stream_id)
|
130
130
|
|
131
131
|
def send_record(self, record: pb.Record) -> None:
|
132
132
|
"""Sends data to the service."""
|
wandb/sdk/wandb_init.py
CHANGED
@@ -20,7 +20,7 @@ import platform
|
|
20
20
|
import sys
|
21
21
|
import tempfile
|
22
22
|
import time
|
23
|
-
from typing import
|
23
|
+
from typing import Any, Literal, Sequence
|
24
24
|
|
25
25
|
if sys.version_info >= (3, 11):
|
26
26
|
from typing import Self
|
@@ -40,16 +40,13 @@ from wandb.util import _is_artifact_representation
|
|
40
40
|
|
41
41
|
from . import wandb_login, wandb_setup
|
42
42
|
from .backend.backend import Backend
|
43
|
-
from .lib import SummaryDisabled, filesystem, module, printer, telemetry
|
43
|
+
from .lib import SummaryDisabled, filesystem, module, paths, printer, telemetry
|
44
44
|
from .lib.deprecate import Deprecated, deprecate
|
45
45
|
from .lib.mailbox import Mailbox, MailboxProgress
|
46
46
|
from .wandb_helper import parse_config
|
47
47
|
from .wandb_run import Run, TeardownHook, TeardownStage
|
48
48
|
from .wandb_settings import Settings
|
49
49
|
|
50
|
-
if TYPE_CHECKING:
|
51
|
-
from wandb.proto import wandb_internal_pb2 as pb
|
52
|
-
|
53
50
|
|
54
51
|
def _huggingface_version() -> str | None:
|
55
52
|
if "transformers" in sys.modules:
|
@@ -180,7 +177,6 @@ class _WandbInit:
|
|
180
177
|
force=run_settings.force,
|
181
178
|
_disable_warning=True,
|
182
179
|
_silent=run_settings.quiet or run_settings.silent,
|
183
|
-
_entity=run_settings.entity,
|
184
180
|
)
|
185
181
|
|
186
182
|
def warn_env_vars_change_after_setup(self) -> None:
|
@@ -454,6 +450,23 @@ class _WandbInit:
|
|
454
450
|
artifacts=result.artifacts,
|
455
451
|
)
|
456
452
|
|
453
|
+
wandb_internal = result.base_no_artifacts.setdefault("_wandb", dict())
|
454
|
+
|
455
|
+
if settings.save_code and settings.program_relpath:
|
456
|
+
wandb_internal["code_path"] = paths.LogicalPath(
|
457
|
+
os.path.join("code", settings.program_relpath)
|
458
|
+
)
|
459
|
+
if settings.fork_from is not None:
|
460
|
+
wandb_internal["branch_point"] = {
|
461
|
+
"run_id": settings.fork_from.run,
|
462
|
+
"step": settings.fork_from.value,
|
463
|
+
}
|
464
|
+
if settings.resume_from is not None:
|
465
|
+
wandb_internal["branch_point"] = {
|
466
|
+
"run_id": settings.resume_from.run,
|
467
|
+
"step": settings.resume_from.value,
|
468
|
+
}
|
469
|
+
|
457
470
|
return result
|
458
471
|
|
459
472
|
def teardown(self) -> None:
|
@@ -891,7 +904,6 @@ class _WandbInit:
|
|
891
904
|
run._set_backend(backend)
|
892
905
|
run._set_teardown_hooks(self._teardown_hooks)
|
893
906
|
|
894
|
-
backend._hack_set_run(run)
|
895
907
|
assert backend.interface
|
896
908
|
mailbox.enable_keepalive()
|
897
909
|
backend.interface.publish_header()
|
@@ -902,8 +914,6 @@ class _WandbInit:
|
|
902
914
|
if not (settings.disable_git or settings.x_disable_machine_info):
|
903
915
|
run._populate_git_info()
|
904
916
|
|
905
|
-
run_result: pb.RunUpdateResult | None = None
|
906
|
-
|
907
917
|
if settings._offline and settings.resume:
|
908
918
|
wandb.termwarn(
|
909
919
|
"`resume` will be ignored since W&B syncing is set to `offline`. "
|
@@ -923,47 +933,53 @@ class _WandbInit:
|
|
923
933
|
on_progress=self._on_progress_init,
|
924
934
|
cancel=True,
|
925
935
|
)
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
936
|
+
|
937
|
+
# Raise an error if deliver_run failed.
|
938
|
+
#
|
939
|
+
# This is wrapped in a try-except to perform additional cleanup logic
|
940
|
+
# when x_disable_service is True.
|
941
|
+
#
|
942
|
+
# TODO: Remove try-except once x_disable_service is removed.
|
943
|
+
try:
|
944
|
+
if not result or not result.run_result:
|
945
|
+
run_init_handle._cancel()
|
946
|
+
|
947
|
+
# This may either be an issue with the W&B server (a CommError)
|
948
|
+
# or a bug in the SDK (an Error). We cannot distinguish between
|
949
|
+
# the two causes here.
|
950
|
+
raise CommError(
|
951
|
+
f"Run initialization has timed out after {timeout} sec."
|
952
|
+
" Please try increasing the timeout with the `init_timeout`"
|
953
|
+
" setting: `wandb.init(settings=wandb.Settings(init_timeout=120))`."
|
954
|
+
)
|
955
|
+
|
956
|
+
if error := ProtobufErrorHandler.to_exception(result.run_result.error):
|
957
|
+
raise error
|
958
|
+
|
959
|
+
if not result.run_result.HasField("run"):
|
960
|
+
raise Error("Assertion failed: run_result is missing the run field")
|
961
|
+
|
962
|
+
except Exception:
|
946
963
|
if not service:
|
947
|
-
#
|
948
|
-
# we don't need to do console cleanup at this point
|
964
|
+
# Kill the background thread or process.
|
949
965
|
backend.cleanup()
|
950
|
-
self.teardown()
|
951
|
-
raise error
|
952
|
-
|
953
|
-
assert run_result is not None # for mypy
|
954
966
|
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
967
|
+
# Do some Jupyter and logger cleanup.
|
968
|
+
#
|
969
|
+
# NOTE: This shouldn't be necessary. The logger is global,
|
970
|
+
# so on any error outside of this try-catch, we fail to
|
971
|
+
# clean it up, causing the next run to write some of its
|
972
|
+
# initial logs to this run's log file. The Jupyter
|
973
|
+
# monkeypatching should probably happen at the library level
|
974
|
+
# (in wandb.setup()) rather than per-run.
|
975
|
+
self.teardown()
|
976
|
+
raise
|
961
977
|
|
962
|
-
if run_result.run.resumed:
|
978
|
+
if result.run_result.run.resumed:
|
963
979
|
self._logger.info("run resumed")
|
964
980
|
with telemetry.context(run=run) as tel:
|
965
|
-
tel.feature.resumed = run_result.run.resumed
|
966
|
-
run._set_run_obj(run_result.run)
|
981
|
+
tel.feature.resumed = result.run_result.run.resumed
|
982
|
+
run._set_run_obj(result.run_result.run)
|
967
983
|
|
968
984
|
self._logger.info("starting run threads in backend")
|
969
985
|
# initiate run (stats and metadata probing)
|
@@ -1069,7 +1085,6 @@ def _attach(
|
|
1069
1085
|
run._init(settings=settings)
|
1070
1086
|
run._set_library(_wl)
|
1071
1087
|
run._set_backend(backend)
|
1072
|
-
backend._hack_set_run(run)
|
1073
1088
|
assert backend.interface
|
1074
1089
|
|
1075
1090
|
mailbox.enable_keepalive()
|
wandb/sdk/wandb_login.py
CHANGED
@@ -8,6 +8,7 @@ import os
|
|
8
8
|
from typing import Literal, Optional, Tuple
|
9
9
|
|
10
10
|
import click
|
11
|
+
from requests.exceptions import ConnectionError
|
11
12
|
|
12
13
|
import wandb
|
13
14
|
from wandb.errors import AuthenticationError, UsageError
|
@@ -16,7 +17,6 @@ from wandb.old.settings import Settings as OldSettings
|
|
16
17
|
from ..apis import InternalApi
|
17
18
|
from .internal.internal_api import Api
|
18
19
|
from .lib import apikey
|
19
|
-
from .wandb_settings import Settings
|
20
20
|
|
21
21
|
|
22
22
|
def _handle_host_wandb_setting(host: Optional[str], cloud: bool = False) -> None:
|
@@ -73,30 +73,16 @@ def login(
|
|
73
73
|
UsageError - if api_key cannot be configured and no tty
|
74
74
|
"""
|
75
75
|
_handle_host_wandb_setting(host)
|
76
|
-
|
77
|
-
return True
|
78
|
-
|
79
|
-
configured = _login(
|
76
|
+
return _login(
|
80
77
|
anonymous=anonymous,
|
81
78
|
key=key,
|
82
79
|
relogin=relogin,
|
83
80
|
host=host,
|
84
81
|
force=force,
|
85
82
|
timeout=timeout,
|
83
|
+
verify=verify,
|
86
84
|
)
|
87
85
|
|
88
|
-
if verify:
|
89
|
-
from . import wandb_setup
|
90
|
-
|
91
|
-
singleton = wandb_setup.singleton()
|
92
|
-
assert singleton is not None
|
93
|
-
viewer = singleton._server._viewer
|
94
|
-
if not viewer:
|
95
|
-
raise AuthenticationError(
|
96
|
-
"API key verification failed. Make sure your API key is valid."
|
97
|
-
)
|
98
|
-
return True if configured else False
|
99
|
-
|
100
86
|
|
101
87
|
class ApiKeyStatus(enum.Enum):
|
102
88
|
VALID = 1
|
@@ -106,26 +92,15 @@ class ApiKeyStatus(enum.Enum):
|
|
106
92
|
|
107
93
|
|
108
94
|
class _WandbLogin:
|
109
|
-
def __init__(
|
110
|
-
self._settings: Optional[Settings] = None
|
111
|
-
self._backend = None
|
112
|
-
self._silent: Optional[bool] = None
|
113
|
-
self._entity: Optional[str] = None
|
114
|
-
self._wl = None
|
115
|
-
self._key = None
|
116
|
-
self._relogin = None
|
117
|
-
|
118
|
-
def setup(
|
95
|
+
def __init__(
|
119
96
|
self,
|
120
|
-
|
121
|
-
|
97
|
+
anonymous: Optional[Literal["must", "allow", "never"]] = None,
|
98
|
+
force: Optional[bool] = None,
|
99
|
+
host: Optional[str] = None,
|
122
100
|
key: Optional[str] = None,
|
123
101
|
relogin: Optional[bool] = None,
|
124
|
-
host: Optional[str] = None,
|
125
|
-
force: Optional[bool] = None,
|
126
102
|
timeout: Optional[int] = None,
|
127
|
-
)
|
128
|
-
"""Updates login-related settings on the global setup object."""
|
103
|
+
):
|
129
104
|
self._relogin = relogin
|
130
105
|
|
131
106
|
login_settings = {
|
@@ -135,61 +110,47 @@ class _WandbLogin:
|
|
135
110
|
"force": force,
|
136
111
|
"login_timeout": timeout,
|
137
112
|
}
|
113
|
+
self.is_anonymous = anonymous == "must"
|
138
114
|
|
139
|
-
|
140
|
-
self.
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
)
|
145
|
-
|
115
|
+
self._wandb_setup = wandb.setup()
|
116
|
+
self._wandb_setup.settings.update_from_dict(login_settings)
|
117
|
+
self._settings = self._wandb_setup.settings
|
118
|
+
|
119
|
+
def _update_global_anonymous_setting(self) -> None:
|
120
|
+
api = InternalApi()
|
121
|
+
if self.is_anonymous:
|
122
|
+
api.set_setting("anonymous", "must", globally=True, persist=True)
|
123
|
+
else:
|
124
|
+
api.clear_setting("anonymous", globally=True, persist=True)
|
146
125
|
|
147
126
|
def is_apikey_configured(self) -> bool:
|
148
127
|
"""Returns whether an API key is set or can be inferred."""
|
149
128
|
return apikey.api_key(settings=self._settings) is not None
|
150
129
|
|
151
|
-
def should_use_identity_token(self):
|
152
|
-
return self._settings.identity_token_file is not None
|
153
|
-
|
154
|
-
def set_backend(self, backend):
|
155
|
-
self._backend = backend
|
156
|
-
|
157
|
-
def set_silent(self, silent: bool) -> None:
|
158
|
-
self._silent = silent
|
159
|
-
|
160
|
-
def set_entity(self, entity: str) -> None:
|
161
|
-
self._entity = entity
|
162
|
-
|
163
|
-
def login(self) -> bool:
|
164
|
-
"""Returns whether the user is logged in (i.e. an API key exists).
|
165
|
-
|
166
|
-
If the user is logged in, this also prints an informational message.
|
167
|
-
"""
|
168
|
-
apikey_configured = self.is_apikey_configured()
|
169
|
-
if self._settings.relogin or self._relogin:
|
170
|
-
apikey_configured = False
|
171
|
-
if not apikey_configured:
|
172
|
-
return False
|
173
|
-
|
174
|
-
if not self._silent:
|
175
|
-
self._print_logged_in_message()
|
176
|
-
|
177
|
-
return apikey_configured
|
178
|
-
|
179
130
|
def _print_logged_in_message(self) -> None:
|
180
131
|
"""Prints a message telling the user they are logged in."""
|
181
|
-
username = self.
|
132
|
+
username = self._wandb_setup._get_username()
|
182
133
|
|
183
134
|
if username:
|
135
|
+
host_str = (
|
136
|
+
f" to {click.style(self._settings.base_url, fg='green')}"
|
137
|
+
if self._settings.base_url
|
138
|
+
else ""
|
139
|
+
)
|
140
|
+
|
184
141
|
# check to see if we got an entity from the setup call or from the user
|
185
|
-
entity = self.
|
142
|
+
entity = self._settings.entity or self._wandb_setup._get_entity()
|
186
143
|
|
187
144
|
entity_str = ""
|
188
145
|
# check if entity exist, valid (is part of a certain team) and different from the username
|
189
|
-
if
|
146
|
+
if (
|
147
|
+
entity
|
148
|
+
and entity in self._wandb_setup._get_teams()
|
149
|
+
and entity != username
|
150
|
+
):
|
190
151
|
entity_str = f" ({click.style(entity, fg='yellow')})"
|
191
152
|
|
192
|
-
login_state_str = f"Currently logged in as: {click.style(username, fg='yellow')}{entity_str}"
|
153
|
+
login_state_str = f"Currently logged in as: {click.style(username, fg='yellow')}{entity_str}{host_str}"
|
193
154
|
else:
|
194
155
|
login_state_str = "W&B API key is configured"
|
195
156
|
|
@@ -210,9 +171,8 @@ class _WandbLogin:
|
|
210
171
|
"WANDB_API_KEY environment variable, or running "
|
211
172
|
"`wandb login` from the command line."
|
212
173
|
)
|
213
|
-
|
214
|
-
|
215
|
-
self._key = key
|
174
|
+
if key:
|
175
|
+
apikey.write_key(self._settings, key)
|
216
176
|
|
217
177
|
def update_session(
|
218
178
|
self,
|
@@ -230,11 +190,11 @@ class _WandbLogin:
|
|
230
190
|
login_settings = dict(mode="disabled")
|
231
191
|
elif key:
|
232
192
|
login_settings = dict(api_key=key)
|
233
|
-
self.
|
193
|
+
self._wandb_setup.settings.update_from_dict(login_settings)
|
234
194
|
# Whenever the key changes, make sure to pull in user settings
|
235
195
|
# from server.
|
236
|
-
if not self.
|
237
|
-
self.
|
196
|
+
if not self._wandb_setup.settings._offline:
|
197
|
+
self._wandb_setup._update_user_settings()
|
238
198
|
|
239
199
|
def _prompt_api_key(self) -> Tuple[Optional[str], ApiKeyStatus]:
|
240
200
|
api = Api(self._settings)
|
@@ -259,7 +219,7 @@ class _WandbLogin:
|
|
259
219
|
return None, ApiKeyStatus.OFFLINE
|
260
220
|
return key, ApiKeyStatus.VALID
|
261
221
|
|
262
|
-
def prompt_api_key(self) ->
|
222
|
+
def prompt_api_key(self) -> Tuple[Optional[str], ApiKeyStatus]:
|
263
223
|
"""Updates the global API key by prompting the user."""
|
264
224
|
key, status = self._prompt_api_key()
|
265
225
|
if status == ApiKeyStatus.NOTTY:
|
@@ -270,8 +230,24 @@ class _WandbLogin:
|
|
270
230
|
)
|
271
231
|
raise UsageError("api_key not configured (no-tty). call " + directive)
|
272
232
|
|
273
|
-
|
274
|
-
|
233
|
+
return key, status
|
234
|
+
|
235
|
+
def _verify_login(self, key: str) -> None:
|
236
|
+
api = InternalApi(api_key=key)
|
237
|
+
|
238
|
+
try:
|
239
|
+
is_api_key_valid = api.validate_api_key()
|
240
|
+
|
241
|
+
if not is_api_key_valid:
|
242
|
+
raise AuthenticationError(
|
243
|
+
"API key verification failed. Make sure your API key is valid."
|
244
|
+
)
|
245
|
+
except ConnectionError:
|
246
|
+
raise AuthenticationError(
|
247
|
+
"Unable to connect to server to verify API token."
|
248
|
+
)
|
249
|
+
except Exception:
|
250
|
+
raise AuthenticationError("An error occurred while verifying the API key.")
|
275
251
|
|
276
252
|
|
277
253
|
def _login(
|
@@ -282,38 +258,29 @@ def _login(
|
|
282
258
|
host: Optional[str] = None,
|
283
259
|
force: Optional[bool] = None,
|
284
260
|
timeout: Optional[int] = None,
|
285
|
-
|
261
|
+
verify: bool = False,
|
286
262
|
_silent: Optional[bool] = None,
|
287
263
|
_disable_warning: Optional[bool] = None,
|
288
|
-
|
289
|
-
):
|
264
|
+
) -> bool:
|
290
265
|
if wandb.run is not None:
|
291
266
|
if not _disable_warning:
|
292
267
|
wandb.termwarn("Calling wandb.login() after wandb.init() has no effect.")
|
293
268
|
return True
|
294
269
|
|
295
|
-
wlogin = _WandbLogin(
|
296
|
-
|
297
|
-
if _backend:
|
298
|
-
wlogin.set_backend(_backend)
|
299
|
-
|
300
|
-
if _silent:
|
301
|
-
wlogin.set_silent(_silent)
|
302
|
-
|
303
|
-
if _entity:
|
304
|
-
wlogin.set_entity(_entity)
|
305
|
-
|
306
|
-
# configure login object
|
307
|
-
wlogin.setup(
|
270
|
+
wlogin = _WandbLogin(
|
308
271
|
anonymous=anonymous,
|
272
|
+
force=force,
|
273
|
+
host=host,
|
309
274
|
key=key,
|
310
275
|
relogin=relogin,
|
311
|
-
host=host,
|
312
|
-
force=force,
|
313
276
|
timeout=timeout,
|
314
277
|
)
|
315
278
|
|
316
|
-
if wlogin._settings.
|
279
|
+
if wlogin._settings._noop:
|
280
|
+
return True
|
281
|
+
|
282
|
+
if wlogin._settings._offline and not wlogin._settings.x_cli_only_mode:
|
283
|
+
wandb.termwarn("Unable to verify login in offline mode.")
|
317
284
|
return False
|
318
285
|
elif wandb.util._is_kaggle() and not wandb.util._has_internet():
|
319
286
|
wandb.termerror(
|
@@ -321,19 +288,28 @@ def _login(
|
|
321
288
|
)
|
322
289
|
return False
|
323
290
|
|
324
|
-
if wlogin.
|
291
|
+
if wlogin._settings.identity_token_file:
|
325
292
|
return True
|
326
293
|
|
327
|
-
|
328
|
-
|
294
|
+
key_is_pre_configured = False
|
295
|
+
key_status = None
|
296
|
+
if key is None:
|
297
|
+
# Check if key is already set in the settings, or configured in the users .netrc file.
|
298
|
+
key = apikey.api_key(settings=wlogin._settings)
|
299
|
+
if key and not relogin:
|
300
|
+
key_is_pre_configured = True
|
301
|
+
else:
|
302
|
+
key, key_status = wlogin.prompt_api_key()
|
303
|
+
|
304
|
+
if verify:
|
305
|
+
wlogin._verify_login(key)
|
329
306
|
|
330
|
-
if
|
307
|
+
if not key_is_pre_configured:
|
331
308
|
wlogin.configure_api_key(key)
|
309
|
+
wlogin.update_session(key, status=key_status)
|
310
|
+
wlogin._update_global_anonymous_setting()
|
332
311
|
|
333
|
-
if
|
334
|
-
|
335
|
-
|
336
|
-
if not key:
|
337
|
-
wlogin.prompt_api_key()
|
312
|
+
if key and not _silent:
|
313
|
+
wlogin._print_logged_in_message()
|
338
314
|
|
339
|
-
return
|
315
|
+
return key is not None
|
wandb/sdk/wandb_metadata.py
CHANGED
@@ -234,37 +234,63 @@ class Metadata(BaseModel, validate_assignment=True):
|
|
234
234
|
NOTE: Definitions must be kept in sync with wandb_internal.proto::MetadataRequest.
|
235
235
|
|
236
236
|
Attributes:
|
237
|
-
os
|
238
|
-
python
|
239
|
-
heartbeat_at
|
240
|
-
started_at
|
241
|
-
docker
|
242
|
-
cuda
|
243
|
-
args
|
244
|
-
state
|
245
|
-
program
|
246
|
-
code_path
|
247
|
-
git
|
248
|
-
email
|
249
|
-
root
|
250
|
-
host
|
251
|
-
username
|
252
|
-
executable
|
253
|
-
code_path_local
|
254
|
-
colab
|
255
|
-
cpu_count
|
256
|
-
cpu_count_logical
|
257
|
-
gpu_type
|
258
|
-
disk
|
259
|
-
memory
|
260
|
-
cpu
|
261
|
-
apple
|
262
|
-
gpu_nvidia
|
263
|
-
gpu_amd
|
264
|
-
slurm
|
265
|
-
cuda_version
|
266
|
-
trainium
|
267
|
-
tpu
|
237
|
+
os: Operating system.
|
238
|
+
python: Python version.
|
239
|
+
heartbeat_at: Timestamp of last heartbeat.
|
240
|
+
started_at: Timestamp of run start.
|
241
|
+
docker: Docker image.
|
242
|
+
cuda: CUDA version.
|
243
|
+
args: Command-line arguments.
|
244
|
+
state: Run state.
|
245
|
+
program: Program name.
|
246
|
+
code_path: Path to code.
|
247
|
+
git: Git repository information.
|
248
|
+
email: Email address.
|
249
|
+
root: Root directory.
|
250
|
+
host: Host name.
|
251
|
+
username: Username.
|
252
|
+
executable: Python executable path.
|
253
|
+
code_path_local: Local code path.
|
254
|
+
colab: Colab URL.
|
255
|
+
cpu_count: CPU count.
|
256
|
+
cpu_count_logical: Logical CPU count.
|
257
|
+
gpu_type: GPU type.
|
258
|
+
disk: Disk information.
|
259
|
+
memory: Memory information.
|
260
|
+
cpu: CPU information.
|
261
|
+
apple: Apple silicon information.
|
262
|
+
gpu_nvidia: NVIDIA GPU information.
|
263
|
+
gpu_amd: AMD GPU information.
|
264
|
+
slurm: Slurm environment information.
|
265
|
+
cuda_version: CUDA version.
|
266
|
+
trainium: Trainium information.
|
267
|
+
tpu: TPU information.
|
268
|
+
|
269
|
+
Examples:
|
270
|
+
Update Run metadata:
|
271
|
+
|
272
|
+
```python
|
273
|
+
with wandb.init(settings=settings) as run:
|
274
|
+
run._metadata.gpu_nvidia = [
|
275
|
+
{
|
276
|
+
"name": "Tesla T4",
|
277
|
+
"memory_total": "16106127360",
|
278
|
+
"cuda_cores": 2560,
|
279
|
+
"architecture": "Turing",
|
280
|
+
},
|
281
|
+
...,
|
282
|
+
]
|
283
|
+
|
284
|
+
run._metadata.gpu_type = "Tesla T4"
|
285
|
+
run._metadata.gpu_count = 42
|
286
|
+
|
287
|
+
run._metadata.tpu = {
|
288
|
+
"name": "v6e",
|
289
|
+
"hbm_gib": 32,
|
290
|
+
"devices_per_chip": 1,
|
291
|
+
"count": 1337,
|
292
|
+
}
|
293
|
+
```
|
268
294
|
"""
|
269
295
|
|
270
296
|
# TODO: Pydantic configuration.
|