wandb 0.21.0__py3-none-win32.whl → 0.21.2__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.
Files changed (153) hide show
  1. wandb/__init__.py +16 -14
  2. wandb/__init__.pyi +427 -450
  3. wandb/agents/pyagent.py +41 -12
  4. wandb/analytics/sentry.py +7 -2
  5. wandb/apis/importers/mlflow.py +1 -1
  6. wandb/apis/public/__init__.py +1 -1
  7. wandb/apis/public/api.py +525 -360
  8. wandb/apis/public/artifacts.py +207 -13
  9. wandb/apis/public/automations.py +19 -3
  10. wandb/apis/public/files.py +172 -33
  11. wandb/apis/public/history.py +67 -15
  12. wandb/apis/public/integrations.py +25 -2
  13. wandb/apis/public/jobs.py +90 -2
  14. wandb/apis/public/projects.py +130 -79
  15. wandb/apis/public/query_generator.py +11 -1
  16. wandb/apis/public/registries/_utils.py +14 -16
  17. wandb/apis/public/registries/registries_search.py +183 -304
  18. wandb/apis/public/reports.py +96 -15
  19. wandb/apis/public/runs.py +299 -105
  20. wandb/apis/public/sweeps.py +222 -22
  21. wandb/apis/public/teams.py +41 -4
  22. wandb/apis/public/users.py +45 -4
  23. wandb/automations/_generated/delete_automation.py +1 -3
  24. wandb/automations/_generated/enums.py +13 -11
  25. wandb/beta/workflows.py +66 -30
  26. wandb/bin/gpu_stats.exe +0 -0
  27. wandb/bin/wandb-core +0 -0
  28. wandb/cli/cli.py +127 -3
  29. wandb/env.py +8 -0
  30. wandb/errors/errors.py +4 -1
  31. wandb/integration/lightning/fabric/logger.py +3 -4
  32. wandb/integration/metaflow/__init__.py +6 -0
  33. wandb/integration/metaflow/data_pandas.py +74 -0
  34. wandb/integration/metaflow/data_pytorch.py +75 -0
  35. wandb/integration/metaflow/data_sklearn.py +76 -0
  36. wandb/integration/metaflow/errors.py +13 -0
  37. wandb/integration/metaflow/metaflow.py +167 -223
  38. wandb/integration/openai/fine_tuning.py +1 -2
  39. wandb/integration/weave/__init__.py +6 -0
  40. wandb/integration/weave/interface.py +49 -0
  41. wandb/integration/weave/weave.py +63 -0
  42. wandb/jupyter.py +5 -5
  43. wandb/plot/custom_chart.py +30 -7
  44. wandb/proto/v3/wandb_internal_pb2.py +281 -280
  45. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  46. wandb/proto/v4/wandb_internal_pb2.py +280 -280
  47. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  48. wandb/proto/v5/wandb_internal_pb2.py +280 -280
  49. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  50. wandb/proto/v6/wandb_internal_pb2.py +280 -280
  51. wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
  52. wandb/proto/wandb_deprecated.py +6 -0
  53. wandb/sdk/artifacts/_factories.py +17 -0
  54. wandb/sdk/artifacts/_generated/__init__.py +221 -13
  55. wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
  56. wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
  57. wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
  58. wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
  59. wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
  60. wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
  61. wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
  62. wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
  63. wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
  64. wandb/sdk/artifacts/_generated/enums.py +5 -0
  65. wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
  66. wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
  67. wandb/sdk/artifacts/_generated/fragments.py +279 -41
  68. wandb/sdk/artifacts/_generated/link_artifact.py +6 -0
  69. wandb/sdk/artifacts/_generated/operations.py +654 -51
  70. wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
  71. wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
  72. wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
  73. wandb/sdk/artifacts/_graphql_fragments.py +3 -86
  74. wandb/sdk/artifacts/_internal_artifact.py +19 -8
  75. wandb/sdk/artifacts/_validators.py +14 -4
  76. wandb/sdk/artifacts/artifact.py +512 -618
  77. wandb/sdk/artifacts/artifact_file_cache.py +10 -6
  78. wandb/sdk/artifacts/artifact_manifest.py +10 -9
  79. wandb/sdk/artifacts/artifact_manifest_entry.py +9 -10
  80. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +5 -3
  81. wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -1
  82. wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
  83. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -1
  84. wandb/sdk/data_types/audio.py +38 -10
  85. wandb/sdk/data_types/base_types/media.py +6 -56
  86. wandb/sdk/data_types/graph.py +48 -14
  87. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
  88. wandb/sdk/data_types/helper_types/image_mask.py +1 -3
  89. wandb/sdk/data_types/histogram.py +34 -21
  90. wandb/sdk/data_types/html.py +35 -12
  91. wandb/sdk/data_types/image.py +104 -68
  92. wandb/sdk/data_types/molecule.py +32 -19
  93. wandb/sdk/data_types/object_3d.py +36 -17
  94. wandb/sdk/data_types/plotly.py +18 -5
  95. wandb/sdk/data_types/saved_model.py +4 -6
  96. wandb/sdk/data_types/table.py +59 -30
  97. wandb/sdk/data_types/video.py +53 -26
  98. wandb/sdk/integration_utils/auto_logging.py +2 -2
  99. wandb/sdk/interface/interface_queue.py +1 -4
  100. wandb/sdk/interface/interface_shared.py +26 -37
  101. wandb/sdk/interface/interface_sock.py +24 -14
  102. wandb/sdk/internal/internal_api.py +6 -0
  103. wandb/sdk/internal/job_builder.py +6 -0
  104. wandb/sdk/internal/settings_static.py +2 -3
  105. wandb/sdk/launch/agent/agent.py +8 -1
  106. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
  107. wandb/sdk/launch/create_job.py +15 -2
  108. wandb/sdk/launch/inputs/internal.py +3 -4
  109. wandb/sdk/launch/inputs/schema.py +1 -0
  110. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  111. wandb/sdk/launch/runner/kubernetes_runner.py +323 -1
  112. wandb/sdk/launch/sweeps/scheduler.py +2 -3
  113. wandb/sdk/lib/asyncio_compat.py +19 -16
  114. wandb/sdk/lib/asyncio_manager.py +252 -0
  115. wandb/sdk/lib/deprecate.py +1 -7
  116. wandb/sdk/lib/disabled.py +1 -1
  117. wandb/sdk/lib/hashutil.py +27 -5
  118. wandb/sdk/lib/module.py +7 -13
  119. wandb/sdk/lib/printer.py +2 -2
  120. wandb/sdk/lib/printer_asyncio.py +3 -1
  121. wandb/sdk/lib/progress.py +0 -19
  122. wandb/sdk/lib/retry.py +185 -78
  123. wandb/sdk/lib/service/service_client.py +106 -0
  124. wandb/sdk/lib/service/service_connection.py +20 -26
  125. wandb/sdk/lib/service/service_token.py +30 -13
  126. wandb/sdk/mailbox/mailbox.py +13 -5
  127. wandb/sdk/mailbox/mailbox_handle.py +22 -13
  128. wandb/sdk/mailbox/response_handle.py +42 -106
  129. wandb/sdk/mailbox/wait_with_progress.py +7 -42
  130. wandb/sdk/wandb_init.py +77 -116
  131. wandb/sdk/wandb_login.py +19 -15
  132. wandb/sdk/wandb_metric.py +2 -0
  133. wandb/sdk/wandb_run.py +497 -469
  134. wandb/sdk/wandb_settings.py +145 -4
  135. wandb/sdk/wandb_setup.py +204 -124
  136. wandb/sdk/wandb_sweep.py +14 -13
  137. wandb/sdk/wandb_watch.py +4 -6
  138. wandb/sync/sync.py +10 -0
  139. wandb/util.py +58 -1
  140. wandb/wandb_run.py +1 -2
  141. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/METADATA +1 -1
  142. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/RECORD +145 -129
  143. wandb/sdk/interface/interface_relay.py +0 -38
  144. wandb/sdk/interface/router.py +0 -89
  145. wandb/sdk/interface/router_queue.py +0 -43
  146. wandb/sdk/interface/router_relay.py +0 -50
  147. wandb/sdk/interface/router_sock.py +0 -32
  148. wandb/sdk/lib/sock_client.py +0 -236
  149. wandb/vendor/pynvml/__init__.py +0 -0
  150. wandb/vendor/pynvml/pynvml.py +0 -4779
  151. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/WHEEL +0 -0
  152. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/entry_points.txt +0 -0
  153. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,252 @@
1
+ """Implements an asyncio thread suitable for internal wandb use."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import concurrent.futures
7
+ import contextlib
8
+ import logging
9
+ import threading
10
+ from typing import Any, Callable, Coroutine, TypeVar
11
+
12
+ from . import asyncio_compat
13
+
14
+ _T = TypeVar("_T")
15
+
16
+ _logger = logging.getLogger(__name__)
17
+
18
+
19
+ class RunCancelledError(Exception):
20
+ """A function passed to AsyncioManager.run() was cancelled."""
21
+
22
+
23
+ class AlreadyJoinedError(Exception):
24
+ """AsyncioManager.run() used after join()."""
25
+
26
+
27
+ class AsyncioManager:
28
+ """Manages a thread running an asyncio loop.
29
+
30
+ The thread must be started using start() and should be joined using
31
+ join(). The thread is a daemon thread, so if join() is not invoked,
32
+ the asyncio work could end abruptly when all non-daemon threads exit.
33
+
34
+ The run() method allows invoking an async function in the asyncio thread
35
+ and waiting until it completes. The run_soon() method allows running
36
+ an async function without waiting for it.
37
+
38
+ Note that although tempting, it is **not** possible to write a safe
39
+ run_in_loop() method that chooses whether to use run() or execute a function
40
+ directly based on whether it's called from the asyncio thread: Suppose a
41
+ function bad() holds a threading.Lock while using run_in_loop() and an
42
+ asyncio task calling bad() is scheduled. If bad() is then invoked in a
43
+ different thread that reaches run_in_loop(), the aforementioned asyncio task
44
+ will deadlock. It is unreasonable to require that run_in_loop() never be
45
+ called while holding a lock (which would apply to the callers of its
46
+ callers, and so on), so it cannot safely exist.
47
+ """
48
+
49
+ def __init__(self) -> None:
50
+ self._runner = asyncio_compat.CancellableRunner()
51
+ self._thread = threading.Thread(
52
+ target=self._main,
53
+ name="wandb-AsyncioManager-main",
54
+ daemon=True,
55
+ )
56
+ self._lock = threading.Lock()
57
+
58
+ self._ready_event = threading.Event()
59
+ """Whether asyncio primitives have been initialized."""
60
+
61
+ self._joined = False
62
+ """Whether join() has been called. Guarded by _lock."""
63
+
64
+ self._loop: asyncio.AbstractEventLoop
65
+ """A handle for interacting with the asyncio event loop."""
66
+
67
+ self._done_event: asyncio.Event
68
+ """Indicates to the asyncio loop that join() was called."""
69
+
70
+ self._remaining_tasks = 0
71
+ """The number of tasks remaining. Guarded by _lock."""
72
+
73
+ self._task_finished_cond: asyncio.Condition
74
+ """Signalled when _remaining_tasks is decremented."""
75
+
76
+ def start(self) -> None:
77
+ """Start the asyncio thread."""
78
+ self._thread.start()
79
+
80
+ def join(self) -> None:
81
+ """Stop accepting new asyncio tasks and wait for the remaining ones."""
82
+ try:
83
+ with self._lock:
84
+ # If join() was already called, block until the thread completes
85
+ # and then return.
86
+ if self._joined:
87
+ self._thread.join()
88
+ return
89
+
90
+ self._joined = True
91
+
92
+ # Wait until _loop and _done_event are initialized.
93
+ self._ready_event.wait()
94
+
95
+ # Set the done event. The main function will exit once all
96
+ # tasks complete.
97
+ self._loop.call_soon_threadsafe(self._done_event.set)
98
+
99
+ self._thread.join()
100
+
101
+ finally:
102
+ # Any of the above may get interrupted by Ctrl+C, in which case we
103
+ # should cancel all tasks, since join() can only be called once.
104
+ # This only matters if the KeyboardInterrupt is suppressed.
105
+ self._runner.cancel()
106
+
107
+ def run(self, fn: Callable[[], Coroutine[Any, Any, _T]]) -> _T:
108
+ """Run an async function to completion.
109
+
110
+ The function is called in the asyncio thread. Blocks until start()
111
+ is called. This raises an error if called inside an async function,
112
+ and as a consequence, the caller may also not be called inside an
113
+ async function.
114
+
115
+ Args:
116
+ fn: The function to run.
117
+
118
+ Returns:
119
+ The return value of fn.
120
+
121
+ Raises:
122
+ Exception: Any exception raised by fn.
123
+ RunCancelledError: If fn is cancelled, particularly when join()
124
+ is interrupted by Ctrl+C or if it otherwise cancels itself.
125
+ AlreadyJoinedError: If join() was already called.
126
+ ValueError: If called inside an async function.
127
+ """
128
+ self._ready_event.wait()
129
+
130
+ if threading.current_thread().ident == self._thread.ident:
131
+ raise ValueError("Cannot use run() inside async loop.")
132
+
133
+ future = self._schedule(fn, daemon=False)
134
+
135
+ try:
136
+ return future.result()
137
+
138
+ except concurrent.futures.CancelledError:
139
+ raise RunCancelledError from None
140
+
141
+ except KeyboardInterrupt:
142
+ # If we're interrupted here, we only cancel this task rather than
143
+ # cancelling all tasks like in join(). This only matters if the
144
+ # interrupt is then suppressed (or delayed) in which case we
145
+ # should let other tasks progress.
146
+ future.cancel()
147
+ raise
148
+
149
+ def run_soon(
150
+ self,
151
+ fn: Callable[[], Coroutine[Any, Any, None]],
152
+ *,
153
+ daemon: bool = False,
154
+ name: str | None = None,
155
+ ) -> None:
156
+ """Run an async function without waiting for it to complete.
157
+
158
+ The function is called in the asyncio thread. Note that since that's
159
+ a daemon thread, it will not get joined when the main thread exits,
160
+ so fn can stop abruptly.
161
+
162
+ Unlike run(), it is OK to call this inside an async function.
163
+
164
+ Blocks until start() is called.
165
+
166
+ Args:
167
+ fn: The function to run.
168
+ daemon: If true, join() will cancel fn after all non-daemon
169
+ tasks complete. By default, join() blocks until fn
170
+ completes.
171
+ name: An optional name to give to long-running tasks which can
172
+ appear in error traces and be useful to debugging.
173
+
174
+ Raises:
175
+ AlreadyJoinedError: If join() was already called.
176
+ """
177
+
178
+ # Wrap exceptions so that they're not printed to console.
179
+ async def fn_wrap_exceptions() -> None:
180
+ try:
181
+ await fn()
182
+ except Exception:
183
+ _logger.exception("Uncaught exception in run_soon callback.")
184
+
185
+ _ = self._schedule(fn_wrap_exceptions, daemon=daemon, name=name)
186
+
187
+ def _schedule(
188
+ self,
189
+ fn: Callable[[], Coroutine[Any, Any, _T]],
190
+ daemon: bool,
191
+ name: str | None = None,
192
+ ) -> concurrent.futures.Future[_T]:
193
+ # Wait for _loop to be initialized.
194
+ self._ready_event.wait()
195
+
196
+ with self._lock:
197
+ if self._joined:
198
+ raise AlreadyJoinedError
199
+
200
+ if not daemon:
201
+ self._remaining_tasks += 1
202
+
203
+ return asyncio.run_coroutine_threadsafe(
204
+ self._wrap(fn, daemon=daemon, name=name),
205
+ self._loop,
206
+ )
207
+
208
+ async def _wrap(
209
+ self,
210
+ fn: Callable[[], Coroutine[Any, Any, _T]],
211
+ daemon: bool,
212
+ name: str | None,
213
+ ) -> _T:
214
+ """Run fn to completion and possibly decrement _remaining tasks."""
215
+ try:
216
+ if name and (task := asyncio.current_task()):
217
+ task.set_name(name)
218
+
219
+ return await fn()
220
+ finally:
221
+ if not daemon:
222
+ async with self._task_finished_cond:
223
+ with self._lock:
224
+ self._remaining_tasks -= 1
225
+ self._task_finished_cond.notify_all()
226
+
227
+ def _main(self) -> None:
228
+ """Run the asyncio loop until join() is called and all tasks finish."""
229
+ # A cancellation error is expected if join() is interrupted.
230
+ #
231
+ # Were it not suppressed, its stacktrace would get printed.
232
+ with contextlib.suppress(asyncio_compat.RunnerCancelledError):
233
+ self._runner.run(self._main_async)
234
+
235
+ async def _main_async(self) -> None:
236
+ """Wait until join() is called and all tasks finish."""
237
+ self._loop = asyncio.get_running_loop()
238
+ self._done_event = asyncio.Event()
239
+ self._task_finished_cond = asyncio.Condition()
240
+
241
+ self._ready_event.set()
242
+
243
+ # Wait until done.
244
+ await self._done_event.wait()
245
+
246
+ # Wait for all tasks to complete.
247
+ #
248
+ # Once we exit, asyncio will cancel any leftover tasks.
249
+ async with self._task_finished_cond:
250
+ await self._task_finished_cond.wait_for(
251
+ lambda: self._remaining_tasks <= 0,
252
+ )
@@ -1,20 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING
4
-
5
3
  import wandb
6
4
  from wandb.proto.wandb_deprecated import DEPRECATED_FEATURES
7
5
  from wandb.sdk.lib import telemetry
8
6
 
9
- # Necessary to break import cycle.
10
- if TYPE_CHECKING:
11
- from wandb import wandb_run
12
-
13
7
 
14
8
  def deprecate(
15
9
  field_name: DEPRECATED_FEATURES,
16
10
  warning_message: str,
17
- run: wandb_run.Run | None = None,
11
+ run: wandb.Run | None = None,
18
12
  ) -> None:
19
13
  """Warn the user that a feature has been deprecated.
20
14
 
wandb/sdk/lib/disabled.py CHANGED
@@ -26,5 +26,5 @@ class RunDisabled:
26
26
  deprecate.deprecate(
27
27
  field_name=Deprecated.run_disabled,
28
28
  warning_message="RunDisabled is deprecated and is a no-op. "
29
- '`wandb.init(mode="disabled")` now returns and instance of `wandb.sdk.wandb_run.Run`.',
29
+ '`wandb.init(mode="disabled")` now returns an instance of `wandb.Run`.',
30
30
  )
wandb/sdk/lib/hashutil.py CHANGED
@@ -2,18 +2,31 @@ from __future__ import annotations
2
2
 
3
3
  import base64
4
4
  import hashlib
5
+ import logging
5
6
  import mmap
6
7
  import sys
7
- from typing import TYPE_CHECKING, NewType
8
+ import time
9
+ from typing import TYPE_CHECKING
10
+
11
+ from typing_extensions import TypeAlias
8
12
 
9
13
  from wandb.sdk.lib.paths import StrPath
10
14
 
11
15
  if TYPE_CHECKING:
12
16
  import _hashlib # type: ignore[import-not-found]
13
17
 
14
- ETag = NewType("ETag", str)
15
- HexMD5 = NewType("HexMD5", str)
16
- B64MD5 = NewType("B64MD5", str)
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ # In the future, consider relying on pydantic to validate these types via e.g.
22
+ # - Base64Str: https://docs.pydantic.dev/latest/api/types/#pydantic.types.Base64Str
23
+ # - a custom EncodedStr + Encoder impl: https://docs.pydantic.dev/latest/api/types/#pydantic.types.EncodedStr
24
+ #
25
+ # Note that so long as we continue to support Pydantic v1, the options above will require a compatible shim/backport
26
+ # implementation, since those types are not in Pydantic v1.
27
+ ETag: TypeAlias = str
28
+ HexMD5: TypeAlias = str
29
+ B64MD5: TypeAlias = str
17
30
 
18
31
 
19
32
  def _md5(data: bytes = b"") -> _hashlib.HASH:
@@ -44,7 +57,16 @@ def hex_to_b64_id(encoded_string: str | bytes) -> B64MD5:
44
57
 
45
58
 
46
59
  def md5_file_b64(*paths: StrPath) -> B64MD5:
47
- return _b64_from_hasher(_md5_file_hasher(*paths))
60
+ start_time = time.monotonic()
61
+ digest = _b64_from_hasher(_md5_file_hasher(*paths))
62
+ hash_time_seconds = time.monotonic() - start_time
63
+ if hash_time_seconds > 1.0:
64
+ logger.debug(
65
+ "Computed MD5 hash for file. paths=%s, hashTimeMs=%d",
66
+ paths,
67
+ int(hash_time_seconds * 1000),
68
+ )
69
+ return digest
48
70
 
49
71
 
50
72
  def md5_file_hex(*paths: StrPath) -> HexMD5:
wandb/sdk/lib/module.py CHANGED
@@ -57,22 +57,16 @@ def unset_globals():
57
57
  wandb.run = None
58
58
  wandb.config = preinit.PreInitObject("wandb.config")
59
59
  wandb.summary = preinit.PreInitObject("wandb.summary")
60
- wandb.log = preinit.PreInitCallable("wandb.log", wandb.wandb_sdk.wandb_run.Run.log)
61
- wandb.watch = preinit.PreInitCallable(
62
- "wandb.watch", wandb.wandb_sdk.wandb_run.Run.watch
63
- )
64
- wandb.unwatch = preinit.PreInitCallable(
65
- "wandb.unwatch", wandb.wandb_sdk.wandb_run.Run.unwatch
66
- )
67
- wandb.save = preinit.PreInitCallable(
68
- "wandb.save", wandb.wandb_sdk.wandb_run.Run.save
69
- )
60
+ wandb.log = preinit.PreInitCallable("wandb.log", wandb.Run.log)
61
+ wandb.watch = preinit.PreInitCallable("wandb.watch", wandb.Run.watch)
62
+ wandb.unwatch = preinit.PreInitCallable("wandb.unwatch", wandb.Run.unwatch)
63
+ wandb.save = preinit.PreInitCallable("wandb.save", wandb.Run.save)
70
64
  wandb.use_artifact = preinit.PreInitCallable(
71
- "wandb.use_artifact", wandb.wandb_sdk.wandb_run.Run.use_artifact
65
+ "wandb.use_artifact", wandb.Run.use_artifact
72
66
  )
73
67
  wandb.log_artifact = preinit.PreInitCallable(
74
- "wandb.log_artifact", wandb.wandb_sdk.wandb_run.Run.log_artifact
68
+ "wandb.log_artifact", wandb.Run.log_artifact
75
69
  )
76
70
  wandb.define_metric = preinit.PreInitCallable(
77
- "wandb.define_metric", wandb.wandb_sdk.wandb_run.Run.define_metric
71
+ "wandb.define_metric", wandb.Run.define_metric
78
72
  )
wandb/sdk/lib/printer.py CHANGED
@@ -102,8 +102,8 @@ def new_printer(settings: wandb.Settings | None = None) -> Printer:
102
102
  has been called, then global settings are used. Otherwise,
103
103
  settings (such as silent mode) are ignored.
104
104
  """
105
- if not settings and (singleton := wandb_setup.singleton_if_setup()):
106
- settings = singleton.settings
105
+ if not settings and (s := wandb_setup.singleton().settings_if_loaded):
106
+ settings = s
107
107
 
108
108
  if ipython.in_jupyter():
109
109
  return _PrinterJupyter(settings=settings)
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  from typing import Callable, TypeVar
3
3
 
4
+ from wandb.sdk import wandb_setup
4
5
  from wandb.sdk.lib import asyncio_compat, printer
5
6
 
6
7
  _T = TypeVar("_T")
@@ -43,4 +44,5 @@ def run_async_with_spinner(
43
44
  func_running.set()
44
45
  return res
45
46
 
46
- return asyncio_compat.run(_loop_run_with_spinner)
47
+ asyncer = wandb_setup.singleton().asyncer
48
+ return asyncer.run(_loop_run_with_spinner)
wandb/sdk/lib/progress.py CHANGED
@@ -14,25 +14,6 @@ from wandb.sdk.lib import asyncio_compat
14
14
  from . import printer as p
15
15
 
16
16
 
17
- def print_sync_dedupe_stats(
18
- printer: p.Printer,
19
- final_result: pb.PollExitResponse,
20
- ) -> None:
21
- """Print how much W&B sync reduced the amount of uploaded data.
22
-
23
- Args:
24
- final_result: The final PollExit result.
25
- """
26
- deduped_bytes = final_result.pusher_stats.deduped_bytes
27
- total_bytes = final_result.pusher_stats.total_bytes
28
-
29
- if total_bytes <= 0 or deduped_bytes <= 0:
30
- return
31
-
32
- frac = deduped_bytes / total_bytes
33
- printer.display(f"W&B sync reduced upload amount by {frac:.1%}")
34
-
35
-
36
17
  async def loop_printing_operation_stats(
37
18
  progress: ProgressPrinter,
38
19
  interface: interface.InterfaceBase,