wandb 0.21.1__py3-none-win32.whl → 0.21.3__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 -1
- wandb/apis/public/api.py +1 -2
- wandb/apis/public/artifacts.py +3 -5
- wandb/apis/public/registries/_utils.py +14 -16
- wandb/apis/public/registries/registries_search.py +176 -289
- wandb/apis/public/reports.py +13 -10
- wandb/automations/_generated/delete_automation.py +1 -3
- wandb/automations/_generated/enums.py +13 -11
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +47 -2
- wandb/integration/metaflow/data_pandas.py +2 -2
- wandb/integration/metaflow/data_pytorch.py +75 -0
- wandb/integration/metaflow/data_sklearn.py +76 -0
- wandb/integration/metaflow/metaflow.py +16 -87
- wandb/integration/weave/__init__.py +6 -0
- wandb/integration/weave/interface.py +49 -0
- wandb/integration/weave/weave.py +63 -0
- wandb/proto/v3/wandb_internal_pb2.py +3 -2
- wandb/proto/v4/wandb_internal_pb2.py +2 -2
- wandb/proto/v5/wandb_internal_pb2.py +2 -2
- wandb/proto/v6/wandb_internal_pb2.py +2 -2
- wandb/sdk/artifacts/_factories.py +17 -0
- wandb/sdk/artifacts/_generated/__init__.py +221 -13
- wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
- wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
- wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
- wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
- wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
- wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
- wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
- wandb/sdk/artifacts/_generated/enums.py +5 -0
- wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
- wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
- wandb/sdk/artifacts/_generated/fragments.py +279 -41
- wandb/sdk/artifacts/_generated/link_artifact.py +6 -0
- wandb/sdk/artifacts/_generated/operations.py +654 -51
- wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
- wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
- wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
- wandb/sdk/artifacts/_graphql_fragments.py +3 -86
- wandb/sdk/artifacts/_validators.py +6 -4
- wandb/sdk/artifacts/artifact.py +410 -547
- wandb/sdk/artifacts/artifact_file_cache.py +11 -7
- wandb/sdk/artifacts/artifact_manifest.py +10 -9
- wandb/sdk/artifacts/artifact_manifest_entry.py +15 -18
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +5 -3
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -1
- wandb/sdk/data_types/video.py +2 -2
- wandb/sdk/interface/interface_queue.py +1 -4
- wandb/sdk/interface/interface_shared.py +26 -37
- wandb/sdk/interface/interface_sock.py +24 -14
- wandb/sdk/internal/settings_static.py +2 -3
- wandb/sdk/launch/create_job.py +12 -1
- wandb/sdk/launch/inputs/internal.py +25 -24
- wandb/sdk/launch/inputs/schema.py +31 -1
- wandb/sdk/launch/runner/kubernetes_runner.py +24 -29
- wandb/sdk/lib/asyncio_compat.py +16 -16
- wandb/sdk/lib/asyncio_manager.py +252 -0
- wandb/sdk/lib/hashutil.py +13 -4
- wandb/sdk/lib/paths.py +23 -21
- wandb/sdk/lib/printer.py +2 -2
- wandb/sdk/lib/printer_asyncio.py +3 -1
- wandb/sdk/lib/retry.py +185 -78
- wandb/sdk/lib/service/service_client.py +106 -0
- wandb/sdk/lib/service/service_connection.py +20 -26
- wandb/sdk/lib/service/service_token.py +30 -13
- wandb/sdk/mailbox/mailbox.py +13 -5
- wandb/sdk/mailbox/mailbox_handle.py +22 -13
- wandb/sdk/mailbox/response_handle.py +42 -106
- wandb/sdk/mailbox/wait_with_progress.py +7 -42
- wandb/sdk/wandb_init.py +11 -25
- wandb/sdk/wandb_login.py +1 -1
- wandb/sdk/wandb_run.py +92 -56
- wandb/sdk/wandb_settings.py +45 -32
- wandb/sdk/wandb_setup.py +176 -96
- wandb/util.py +1 -1
- {wandb-0.21.1.dist-info → wandb-0.21.3.dist-info}/METADATA +2 -2
- {wandb-0.21.1.dist-info → wandb-0.21.3.dist-info}/RECORD +88 -72
- wandb/sdk/interface/interface_relay.py +0 -38
- wandb/sdk/interface/router.py +0 -89
- wandb/sdk/interface/router_queue.py +0 -43
- wandb/sdk/interface/router_relay.py +0 -50
- wandb/sdk/interface/router_sock.py +0 -32
- wandb/sdk/lib/sock_client.py +0 -232
- {wandb-0.21.1.dist-info → wandb-0.21.3.dist-info}/WHEEL +0 -0
- {wandb-0.21.1.dist-info → wandb-0.21.3.dist-info}/entry_points.txt +0 -0
- {wandb-0.21.1.dist-info → wandb-0.21.3.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/mailbox/mailbox.py
CHANGED
@@ -7,6 +7,7 @@ import threading
|
|
7
7
|
|
8
8
|
from wandb.proto import wandb_internal_pb2 as pb
|
9
9
|
from wandb.proto import wandb_server_pb2 as spb
|
10
|
+
from wandb.sdk.lib import asyncio_manager
|
10
11
|
|
11
12
|
from .mailbox_handle import MailboxHandle
|
12
13
|
from .response_handle import MailboxResponseHandle
|
@@ -27,7 +28,8 @@ class Mailbox:
|
|
27
28
|
service process becomes unreachable.
|
28
29
|
"""
|
29
30
|
|
30
|
-
def __init__(self) -> None:
|
31
|
+
def __init__(self, asyncer: asyncio_manager.AsyncioManager) -> None:
|
32
|
+
self._asyncer = asyncer
|
31
33
|
self._handles: dict[str, MailboxResponseHandle] = {}
|
32
34
|
self._handles_lock = threading.Lock()
|
33
35
|
self._closed = False
|
@@ -51,11 +53,17 @@ class Mailbox:
|
|
51
53
|
cannot be created.
|
52
54
|
"""
|
53
55
|
if isinstance(request, spb.ServerRequest):
|
54
|
-
if address := request.request_id
|
56
|
+
if (address := request.request_id) or (
|
57
|
+
address := request.record_publish.control.mailbox_slot
|
58
|
+
):
|
55
59
|
raise ValueError(f"Request already has an address ({address})")
|
56
60
|
|
57
61
|
address = self._new_address()
|
58
62
|
request.request_id = address
|
63
|
+
if request.HasField("record_publish"):
|
64
|
+
request.record_publish.control.mailbox_slot = address
|
65
|
+
if request.HasField("record_communicate"):
|
66
|
+
request.record_communicate.control.mailbox_slot = address
|
59
67
|
else:
|
60
68
|
if address := request.control.mailbox_slot:
|
61
69
|
raise ValueError(f"Request already has an address ({address})")
|
@@ -67,7 +75,7 @@ class Mailbox:
|
|
67
75
|
if self._closed:
|
68
76
|
raise MailboxClosedError()
|
69
77
|
|
70
|
-
handle = MailboxResponseHandle(address)
|
78
|
+
handle = MailboxResponseHandle(address, asyncer=self._asyncer)
|
71
79
|
self._handles[address] = handle
|
72
80
|
|
73
81
|
return handle
|
@@ -92,7 +100,7 @@ class Mailbox:
|
|
92
100
|
|
93
101
|
return address
|
94
102
|
|
95
|
-
def deliver(self, response: spb.ServerResponse) -> None:
|
103
|
+
async def deliver(self, response: spb.ServerResponse) -> None:
|
96
104
|
"""Deliver a response from the service.
|
97
105
|
|
98
106
|
If the response address is invalid, this does nothing.
|
@@ -116,7 +124,7 @@ class Mailbox:
|
|
116
124
|
# It is not an error if there is no handle for the address:
|
117
125
|
# handles can be abandoned if the result is no longer needed.
|
118
126
|
if handle:
|
119
|
-
handle.deliver(response)
|
127
|
+
await handle.deliver(response)
|
120
128
|
|
121
129
|
def close(self) -> None:
|
122
130
|
"""Indicate no further responses will be delivered.
|
@@ -5,6 +5,8 @@ from typing import TYPE_CHECKING, Callable, Generic
|
|
5
5
|
|
6
6
|
from typing_extensions import TypeVar, override
|
7
7
|
|
8
|
+
from wandb.sdk.lib import asyncio_manager
|
9
|
+
|
8
10
|
# Necessary to break an import loop.
|
9
11
|
if TYPE_CHECKING:
|
10
12
|
from wandb.sdk.interface import interface
|
@@ -19,7 +21,18 @@ class HandleAbandonedError(Exception):
|
|
19
21
|
|
20
22
|
|
21
23
|
class MailboxHandle(abc.ABC, Generic[_T]):
|
22
|
-
"""A
|
24
|
+
"""A handle for waiting on a response to a request."""
|
25
|
+
|
26
|
+
def __init__(self, asyncer: asyncio_manager.AsyncioManager) -> None:
|
27
|
+
self._asyncer = asyncer
|
28
|
+
|
29
|
+
@property
|
30
|
+
def asyncer(self) -> asyncio_manager.AsyncioManager:
|
31
|
+
"""The asyncio thread to which the handle belongs.
|
32
|
+
|
33
|
+
The handle's async methods must be run using this object.
|
34
|
+
"""
|
35
|
+
return self._asyncer
|
23
36
|
|
24
37
|
def map(self, fn: Callable[[_T], _S]) -> MailboxHandle[_S]:
|
25
38
|
"""Returns a transformed handle.
|
@@ -35,7 +48,11 @@ class MailboxHandle(abc.ABC, Generic[_T]):
|
|
35
48
|
|
36
49
|
@abc.abstractmethod
|
37
50
|
def abandon(self) -> None:
|
38
|
-
"""Abandon the handle, indicating it will not receive a response.
|
51
|
+
"""Abandon the handle, indicating it will not receive a response.
|
52
|
+
|
53
|
+
This may not happen immediately: it is possible for an existing
|
54
|
+
call to `wait_async` to complete successfully after this method returns.
|
55
|
+
"""
|
39
56
|
|
40
57
|
@abc.abstractmethod
|
41
58
|
def cancel(self, iface: interface.InterfaceBase) -> None:
|
@@ -48,14 +65,12 @@ class MailboxHandle(abc.ABC, Generic[_T]):
|
|
48
65
|
iface: The interface on which to publish the cancel request.
|
49
66
|
"""
|
50
67
|
|
51
|
-
@abc.abstractmethod
|
52
|
-
def check(self) -> _T | None:
|
53
|
-
"""Returns the response if it's ready."""
|
54
|
-
|
55
68
|
@abc.abstractmethod
|
56
69
|
def wait_or(self, *, timeout: float | None) -> _T:
|
57
70
|
"""Wait for a response or a timeout.
|
58
71
|
|
72
|
+
It is an error to call this from an async function.
|
73
|
+
|
59
74
|
Args:
|
60
75
|
timeout: A finite number of seconds or None to never time out.
|
61
76
|
If less than or equal to zero, times out immediately unless
|
@@ -95,6 +110,7 @@ class _MailboxMappedHandle(Generic[_S], MailboxHandle[_S]):
|
|
95
110
|
handle: MailboxHandle[_T],
|
96
111
|
fn: Callable[[_T], _S],
|
97
112
|
) -> None:
|
113
|
+
super().__init__(handle.asyncer)
|
98
114
|
self._handle = handle
|
99
115
|
self._fn = fn
|
100
116
|
|
@@ -106,13 +122,6 @@ class _MailboxMappedHandle(Generic[_S], MailboxHandle[_S]):
|
|
106
122
|
def cancel(self, iface: interface.InterfaceBase) -> None:
|
107
123
|
self._handle.cancel(iface)
|
108
124
|
|
109
|
-
@override
|
110
|
-
def check(self) -> _S | None:
|
111
|
-
if response := self._handle.check():
|
112
|
-
return self._fn(response)
|
113
|
-
else:
|
114
|
-
return None
|
115
|
-
|
116
125
|
@override
|
117
126
|
def wait_or(self, *, timeout: float | None) -> _S:
|
118
127
|
return self._fn(self._handle.wait_or(timeout=timeout))
|
@@ -2,12 +2,12 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import asyncio
|
4
4
|
import math
|
5
|
-
import threading
|
6
5
|
from typing import TYPE_CHECKING
|
7
6
|
|
8
7
|
from typing_extensions import override
|
9
8
|
|
10
9
|
from wandb.proto import wandb_server_pb2 as spb
|
10
|
+
from wandb.sdk.lib import asyncio_manager
|
11
11
|
|
12
12
|
from .mailbox_handle import HandleAbandonedError, MailboxHandle
|
13
13
|
|
@@ -19,33 +19,36 @@ if TYPE_CHECKING:
|
|
19
19
|
class MailboxResponseHandle(MailboxHandle[spb.ServerResponse]):
|
20
20
|
"""A general handle for any ServerResponse."""
|
21
21
|
|
22
|
-
def __init__(
|
22
|
+
def __init__(
|
23
|
+
self,
|
24
|
+
address: str,
|
25
|
+
*,
|
26
|
+
asyncer: asyncio_manager.AsyncioManager,
|
27
|
+
) -> None:
|
28
|
+
super().__init__(asyncer)
|
29
|
+
|
23
30
|
self._address = address
|
24
|
-
self._lock = threading.Lock()
|
25
|
-
self._event = threading.Event()
|
26
31
|
|
27
32
|
self._abandoned = False
|
28
33
|
self._response: spb.ServerResponse | None = None
|
29
34
|
|
30
|
-
|
35
|
+
# Initialized on first use in the asyncio thread.
|
36
|
+
self._done_event: asyncio.Event | None = None
|
31
37
|
|
32
|
-
def deliver(self, response: spb.ServerResponse) -> None:
|
33
|
-
|
38
|
+
async def deliver(self, response: spb.ServerResponse) -> None:
|
39
|
+
if self._abandoned:
|
40
|
+
return
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if self._abandoned:
|
40
|
-
return
|
42
|
+
if self._response:
|
43
|
+
raise ValueError(
|
44
|
+
f"A response has already been delivered to {self._address}."
|
45
|
+
)
|
41
46
|
|
42
|
-
|
43
|
-
raise ValueError(
|
44
|
-
f"A response has already been delivered to {self._address}."
|
45
|
-
)
|
47
|
+
self._response = response
|
46
48
|
|
47
|
-
|
48
|
-
self.
|
49
|
+
if not self._done_event:
|
50
|
+
self._done_event = asyncio.Event()
|
51
|
+
self._done_event.set()
|
49
52
|
|
50
53
|
@override
|
51
54
|
def cancel(self, iface: interface.InterfaceBase) -> None:
|
@@ -54,110 +57,43 @@ class MailboxResponseHandle(MailboxHandle[spb.ServerResponse]):
|
|
54
57
|
|
55
58
|
@override
|
56
59
|
def abandon(self) -> None:
|
57
|
-
|
60
|
+
async def impl() -> None:
|
58
61
|
self._abandoned = True
|
59
|
-
self._signal_done()
|
60
|
-
|
61
|
-
def _signal_done(self) -> None:
|
62
|
-
"""Indicate that the handle either got a response or became abandoned.
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
self._event.set()
|
63
|
+
if not self._done_event:
|
64
|
+
self._done_event = asyncio.Event()
|
65
|
+
self._done_event.set()
|
68
66
|
|
69
|
-
|
70
|
-
for asyncio_event in self._asyncio_events.values():
|
71
|
-
asyncio_event.set_threadsafe()
|
72
|
-
self._asyncio_events.clear()
|
73
|
-
|
74
|
-
@override
|
75
|
-
def check(self) -> spb.ServerResponse | None:
|
76
|
-
with self._lock:
|
77
|
-
return self._response
|
67
|
+
self.asyncer.run_soon(impl)
|
78
68
|
|
79
69
|
@override
|
80
70
|
def wait_or(self, *, timeout: float | None) -> spb.ServerResponse:
|
81
|
-
|
82
|
-
raise ValueError("Timeout must be finite or None.")
|
83
|
-
|
84
|
-
if not self._event.wait(timeout=timeout):
|
85
|
-
raise TimeoutError(
|
86
|
-
f"Timed out waiting for response on {self._address}",
|
87
|
-
)
|
88
|
-
|
89
|
-
with self._lock:
|
90
|
-
if self._response:
|
91
|
-
return self._response
|
92
|
-
|
93
|
-
assert self._abandoned
|
94
|
-
raise HandleAbandonedError()
|
71
|
+
return self.asyncer.run(lambda: self.wait_async(timeout=timeout))
|
95
72
|
|
96
73
|
@override
|
97
74
|
async def wait_async(self, *, timeout: float | None) -> spb.ServerResponse:
|
98
75
|
if timeout is not None and not math.isfinite(timeout):
|
99
76
|
raise ValueError("Timeout must be finite or None.")
|
100
77
|
|
101
|
-
|
102
|
-
|
78
|
+
if not self._done_event:
|
79
|
+
self._done_event = asyncio.Event()
|
103
80
|
|
104
81
|
try:
|
105
|
-
await asyncio.wait_for(
|
82
|
+
await asyncio.wait_for(self._done_event.wait(), timeout=timeout)
|
106
83
|
|
107
84
|
except (asyncio.TimeoutError, TimeoutError) as e:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
elif self._abandoned:
|
112
|
-
raise HandleAbandonedError()
|
113
|
-
else:
|
114
|
-
raise TimeoutError(
|
115
|
-
f"Timed out waiting for response on {self._address}"
|
116
|
-
) from e
|
117
|
-
|
118
|
-
else:
|
119
|
-
with self._lock:
|
120
|
-
if self._response:
|
121
|
-
return self._response
|
122
|
-
|
123
|
-
assert self._abandoned
|
85
|
+
if self._response:
|
86
|
+
return self._response
|
87
|
+
elif self._abandoned:
|
124
88
|
raise HandleAbandonedError()
|
125
|
-
|
126
|
-
finally:
|
127
|
-
self._forget_asyncio_event(evt)
|
128
|
-
|
129
|
-
def _add_asyncio_event(
|
130
|
-
self,
|
131
|
-
loop: asyncio.AbstractEventLoop,
|
132
|
-
event: asyncio.Event,
|
133
|
-
) -> None:
|
134
|
-
"""Add an event to signal when a response is received.
|
135
|
-
|
136
|
-
If a response already exists, this notifies the event loop immediately.
|
137
|
-
"""
|
138
|
-
asyncio_event = _AsyncioEvent(loop, event)
|
139
|
-
|
140
|
-
with self._lock:
|
141
|
-
if self._response or self._abandoned:
|
142
|
-
asyncio_event.set_threadsafe()
|
143
89
|
else:
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
"""Cancel signalling an event when a response is received."""
|
148
|
-
with self._lock:
|
149
|
-
self._asyncio_events.pop(event, None)
|
90
|
+
raise TimeoutError(
|
91
|
+
f"Timed out waiting for response on {self._address}"
|
92
|
+
) from e
|
150
93
|
|
94
|
+
else:
|
95
|
+
if self._response:
|
96
|
+
return self._response
|
151
97
|
|
152
|
-
|
153
|
-
|
154
|
-
self,
|
155
|
-
loop: asyncio.AbstractEventLoop,
|
156
|
-
event: asyncio.Event,
|
157
|
-
):
|
158
|
-
self._loop = loop
|
159
|
-
self._event = event
|
160
|
-
|
161
|
-
def set_threadsafe(self) -> None:
|
162
|
-
"""Set the asyncio event in its own loop."""
|
163
|
-
self._loop.call_soon_threadsafe(self._event.set)
|
98
|
+
assert self._abandoned
|
99
|
+
raise HandleAbandonedError()
|
@@ -14,7 +14,6 @@ def wait_with_progress(
|
|
14
14
|
handle: MailboxHandle[_T],
|
15
15
|
*,
|
16
16
|
timeout: float | None,
|
17
|
-
progress_after: float,
|
18
17
|
display_progress: Callable[[], Coroutine[Any, Any, None]],
|
19
18
|
) -> _T:
|
20
19
|
"""Wait for a handle, possibly displaying progress to the user.
|
@@ -24,7 +23,6 @@ def wait_with_progress(
|
|
24
23
|
return wait_all_with_progress(
|
25
24
|
[handle],
|
26
25
|
timeout=timeout,
|
27
|
-
progress_after=progress_after,
|
28
26
|
display_progress=display_progress,
|
29
27
|
)[0]
|
30
28
|
|
@@ -33,7 +31,6 @@ def wait_all_with_progress(
|
|
33
31
|
handle_list: list[MailboxHandle[_T]],
|
34
32
|
*,
|
35
33
|
timeout: float | None,
|
36
|
-
progress_after: float,
|
37
34
|
display_progress: Callable[[], Coroutine[Any, Any, None]],
|
38
35
|
) -> list[_T]:
|
39
36
|
"""Wait for multiple handles, possibly displaying progress to the user.
|
@@ -42,18 +39,14 @@ def wait_all_with_progress(
|
|
42
39
|
handle_list: The handles to wait for.
|
43
40
|
timeout: A number of seconds after which to raise a TimeoutError,
|
44
41
|
or None if this should never timeout.
|
45
|
-
progress_after: A number of seconds after which to start the
|
46
|
-
display_progress callback. Starting the callback creates a thread
|
47
|
-
and starts an asyncio loop, so we want to avoid doing it if
|
48
|
-
the handle is resolved quickly.
|
49
42
|
display_progress: An asyncio function that displays progress to
|
50
|
-
the user. This function
|
51
|
-
if the timeout is exceeded.
|
43
|
+
the user. This function runs using the handles' AsyncioManager.
|
52
44
|
|
53
45
|
Returns:
|
54
46
|
A list where the Nth item is the Nth handle's result.
|
55
47
|
|
56
48
|
Raises:
|
49
|
+
ValueError: If the handles live in different asyncio threads.
|
57
50
|
TimeoutError: If the overall timeout expires.
|
58
51
|
HandleAbandonedError: If any handle becomes abandoned.
|
59
52
|
Exception: Any exception from the display function is propagated.
|
@@ -61,16 +54,13 @@ def wait_all_with_progress(
|
|
61
54
|
if not handle_list:
|
62
55
|
return []
|
63
56
|
|
64
|
-
|
65
|
-
|
57
|
+
asyncer = handle_list[0].asyncer
|
58
|
+
for handle in handle_list:
|
59
|
+
if handle.asyncer is not asyncer:
|
60
|
+
raise ValueError("Handles have different AsyncioManagers.")
|
66
61
|
|
67
62
|
start_time = time.monotonic()
|
68
63
|
|
69
|
-
try:
|
70
|
-
return _wait_handles(handle_list, timeout=progress_after)
|
71
|
-
except TimeoutError:
|
72
|
-
pass
|
73
|
-
|
74
64
|
async def progress_loop_with_timeout() -> list[_T]:
|
75
65
|
with asyncio_compat.cancel_on_exit(display_progress()):
|
76
66
|
if timeout is not None:
|
@@ -84,32 +74,7 @@ def wait_all_with_progress(
|
|
84
74
|
timeout=remaining_timeout,
|
85
75
|
)
|
86
76
|
|
87
|
-
return
|
88
|
-
|
89
|
-
|
90
|
-
def _wait_handles(
|
91
|
-
handle_list: list[MailboxHandle[_T]],
|
92
|
-
*,
|
93
|
-
timeout: float,
|
94
|
-
) -> list[_T]:
|
95
|
-
"""Wait for multiple mailbox handles.
|
96
|
-
|
97
|
-
Returns:
|
98
|
-
Each handle's result, in the same order as the given handles.
|
99
|
-
|
100
|
-
Raises:
|
101
|
-
TimeoutError: If the overall timeout expires.
|
102
|
-
HandleAbandonedError: If any handle becomes abandoned.
|
103
|
-
"""
|
104
|
-
results: list[_T] = []
|
105
|
-
|
106
|
-
start_time = time.monotonic()
|
107
|
-
for handle in handle_list:
|
108
|
-
elapsed_time = time.monotonic() - start_time
|
109
|
-
remaining_timeout = timeout - elapsed_time
|
110
|
-
results.append(handle.wait_or(timeout=remaining_timeout))
|
111
|
-
|
112
|
-
return results
|
77
|
+
return asyncer.run(progress_loop_with_timeout)
|
113
78
|
|
114
79
|
|
115
80
|
async def _wait_handles_async(
|
wandb/sdk/wandb_init.py
CHANGED
@@ -11,7 +11,6 @@ For more on using `wandb.init()`, including code snippets, check out our
|
|
11
11
|
from __future__ import annotations
|
12
12
|
|
13
13
|
import contextlib
|
14
|
-
import copy
|
15
14
|
import dataclasses
|
16
15
|
import json
|
17
16
|
import logging
|
@@ -31,7 +30,7 @@ from wandb import env, trigger
|
|
31
30
|
from wandb.errors import CommError, Error, UsageError
|
32
31
|
from wandb.errors.links import url_registry
|
33
32
|
from wandb.errors.util import ProtobufErrorHandler
|
34
|
-
from wandb.integration import sagemaker
|
33
|
+
from wandb.integration import sagemaker, weave
|
35
34
|
from wandb.proto.wandb_deprecated import Deprecated
|
36
35
|
from wandb.sdk.lib import ipython as wb_ipython
|
37
36
|
from wandb.sdk.lib import progress, runid, wb_logging
|
@@ -202,23 +201,7 @@ class _WandbInit:
|
|
202
201
|
Returns:
|
203
202
|
A callback to print any generated warnings.
|
204
203
|
"""
|
205
|
-
|
206
|
-
# check if environment variables have changed
|
207
|
-
singleton_env = {
|
208
|
-
k: v
|
209
|
-
for k, v in wandb_setup.singleton()._environ.items()
|
210
|
-
if k.startswith("WANDB_") and k not in exclude_env_vars
|
211
|
-
}
|
212
|
-
os_env = {
|
213
|
-
k: v
|
214
|
-
for k, v in os.environ.items()
|
215
|
-
if k.startswith("WANDB_") and k not in exclude_env_vars
|
216
|
-
}
|
217
|
-
|
218
|
-
if (
|
219
|
-
set(singleton_env.keys()) == set(os_env.keys()) #
|
220
|
-
and set(singleton_env.values()) == set(os_env.values())
|
221
|
-
):
|
204
|
+
if not self._wl.did_environment_change():
|
222
205
|
return _noop_printer_callback()
|
223
206
|
|
224
207
|
def print_warning(run_printer: printer.Printer) -> None:
|
@@ -475,9 +458,9 @@ class _WandbInit:
|
|
475
458
|
)
|
476
459
|
self._telemetry.feature.sagemaker = True
|
477
460
|
|
478
|
-
if self._wl.
|
461
|
+
if self._wl.config:
|
479
462
|
self._split_artifacts_from_config(
|
480
|
-
self._wl.
|
463
|
+
self._wl.config,
|
481
464
|
config_target=result.base_no_artifacts,
|
482
465
|
artifacts=result.artifacts,
|
483
466
|
)
|
@@ -996,7 +979,6 @@ class _WandbInit:
|
|
996
979
|
result = wait_with_progress(
|
997
980
|
run_init_handle,
|
998
981
|
timeout=timeout,
|
999
|
-
progress_after=1,
|
1000
982
|
display_progress=display_init_message,
|
1001
983
|
)
|
1002
984
|
|
@@ -1112,8 +1094,7 @@ def _attach(
|
|
1112
1094
|
except Exception as e:
|
1113
1095
|
raise UsageError(f"Unable to attach to run {attach_id}") from e
|
1114
1096
|
|
1115
|
-
settings
|
1116
|
-
|
1097
|
+
settings = _wl.settings.model_copy()
|
1117
1098
|
settings.update_from_dict(
|
1118
1099
|
{
|
1119
1100
|
"run_id": attach_id,
|
@@ -1578,7 +1559,12 @@ def init( # noqa: C901
|
|
1578
1559
|
if run_settings.x_server_side_derived_summary:
|
1579
1560
|
init_telemetry.feature.server_side_derived_summary = True
|
1580
1561
|
|
1581
|
-
|
1562
|
+
run = wi.init(run_settings, run_config, run_printer)
|
1563
|
+
|
1564
|
+
# Set up automatic Weave integration if Weave is installed
|
1565
|
+
weave.setup(run_settings.entity, run_settings.project)
|
1566
|
+
|
1567
|
+
return run
|
1582
1568
|
|
1583
1569
|
except KeyboardInterrupt as e:
|
1584
1570
|
if wl:
|
wandb/sdk/wandb_login.py
CHANGED
@@ -202,7 +202,7 @@ class _WandbLogin:
|
|
202
202
|
# Whenever the key changes, make sure to pull in user settings
|
203
203
|
# from server.
|
204
204
|
if not self._wandb_setup.settings._offline:
|
205
|
-
self._wandb_setup.
|
205
|
+
self._wandb_setup.update_user_settings()
|
206
206
|
|
207
207
|
def _prompt_api_key(
|
208
208
|
self, referrer: Optional[str] = None
|