wandb 0.19.1rc1__py3-none-macosx_11_0_arm64.whl → 0.19.2__py3-none-macosx_11_0_arm64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. wandb/__init__.py +1 -7
  2. wandb/__init__.pyi +3 -5
  3. wandb/agents/pyagent.py +1 -1
  4. wandb/apis/importers/wandb.py +1 -1
  5. wandb/apis/public/files.py +1 -1
  6. wandb/apis/public/jobs.py +1 -1
  7. wandb/apis/public/runs.py +2 -7
  8. wandb/apis/reports/v1/__init__.py +1 -1
  9. wandb/apis/reports/v2/__init__.py +1 -1
  10. wandb/apis/workspaces/__init__.py +1 -1
  11. wandb/bin/gpu_stats +0 -0
  12. wandb/bin/wandb-core +0 -0
  13. wandb/cli/beta.py +7 -4
  14. wandb/cli/cli.py +5 -7
  15. wandb/docker/__init__.py +4 -4
  16. wandb/integration/fastai/__init__.py +4 -6
  17. wandb/integration/keras/keras.py +5 -3
  18. wandb/integration/metaflow/metaflow.py +7 -7
  19. wandb/integration/prodigy/prodigy.py +3 -11
  20. wandb/integration/sagemaker/__init__.py +5 -3
  21. wandb/integration/sagemaker/config.py +17 -8
  22. wandb/integration/sagemaker/files.py +0 -1
  23. wandb/integration/sagemaker/resources.py +47 -18
  24. wandb/integration/torch/wandb_torch.py +1 -1
  25. wandb/proto/v3/wandb_internal_pb2.py +273 -235
  26. wandb/proto/v4/wandb_internal_pb2.py +222 -214
  27. wandb/proto/v5/wandb_internal_pb2.py +222 -214
  28. wandb/sdk/artifacts/artifact.py +3 -9
  29. wandb/sdk/backend/backend.py +1 -1
  30. wandb/sdk/data_types/base_types/wb_value.py +1 -1
  31. wandb/sdk/data_types/graph.py +2 -2
  32. wandb/sdk/data_types/saved_model.py +1 -1
  33. wandb/sdk/data_types/video.py +1 -1
  34. wandb/sdk/interface/interface.py +25 -25
  35. wandb/sdk/interface/interface_shared.py +21 -5
  36. wandb/sdk/internal/handler.py +19 -1
  37. wandb/sdk/internal/internal.py +1 -1
  38. wandb/sdk/internal/internal_api.py +4 -5
  39. wandb/sdk/internal/sample.py +2 -2
  40. wandb/sdk/internal/sender.py +1 -2
  41. wandb/sdk/internal/settings_static.py +3 -1
  42. wandb/sdk/internal/system/assets/disk.py +4 -4
  43. wandb/sdk/internal/system/assets/gpu.py +1 -1
  44. wandb/sdk/internal/system/assets/memory.py +1 -1
  45. wandb/sdk/internal/system/system_info.py +1 -1
  46. wandb/sdk/internal/system/system_monitor.py +3 -1
  47. wandb/sdk/internal/tb_watcher.py +1 -1
  48. wandb/sdk/launch/_project_spec.py +3 -3
  49. wandb/sdk/launch/builder/abstract.py +1 -1
  50. wandb/sdk/lib/apikey.py +2 -3
  51. wandb/sdk/lib/fsm.py +1 -1
  52. wandb/sdk/lib/gitlib.py +1 -1
  53. wandb/sdk/lib/gql_request.py +1 -1
  54. wandb/sdk/lib/interrupt.py +37 -0
  55. wandb/sdk/lib/lazyloader.py +1 -1
  56. wandb/sdk/lib/progress.py +7 -1
  57. wandb/sdk/lib/service_connection.py +1 -1
  58. wandb/sdk/lib/telemetry.py +1 -1
  59. wandb/sdk/service/_startup_debug.py +1 -1
  60. wandb/sdk/service/server_sock.py +3 -2
  61. wandb/sdk/service/service.py +1 -1
  62. wandb/sdk/service/streams.py +19 -17
  63. wandb/sdk/verify/verify.py +13 -13
  64. wandb/sdk/wandb_init.py +95 -104
  65. wandb/sdk/wandb_login.py +1 -1
  66. wandb/sdk/wandb_metadata.py +547 -0
  67. wandb/sdk/wandb_run.py +127 -35
  68. wandb/sdk/wandb_settings.py +6 -37
  69. wandb/sdk/wandb_setup.py +83 -82
  70. wandb/sdk/wandb_sweep.py +2 -2
  71. wandb/sdk/wandb_sync.py +15 -18
  72. wandb/sync/sync.py +10 -10
  73. wandb/util.py +11 -3
  74. wandb/wandb_agent.py +11 -16
  75. wandb/wandb_controller.py +7 -7
  76. {wandb-0.19.1rc1.dist-info → wandb-0.19.2.dist-info}/METADATA +3 -2
  77. {wandb-0.19.1rc1.dist-info → wandb-0.19.2.dist-info}/RECORD +80 -78
  78. {wandb-0.19.1rc1.dist-info → wandb-0.19.2.dist-info}/WHEEL +0 -0
  79. {wandb-0.19.1rc1.dist-info → wandb-0.19.2.dist-info}/entry_points.txt +0 -0
  80. {wandb-0.19.1rc1.dist-info → wandb-0.19.2.dist-info}/licenses/LICENSE +0 -0
@@ -4,6 +4,7 @@ import threading
4
4
  import time
5
5
  from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
6
6
 
7
+ import wandb
7
8
  from wandb.proto import wandb_server_pb2 as spb
8
9
  from wandb.sdk.internal.settings_static import SettingsStatic
9
10
 
@@ -225,7 +226,7 @@ class DebugThread(threading.Thread):
225
226
  while True:
226
227
  time.sleep(30)
227
228
  for thread in threading.enumerate():
228
- print(f"DEBUG: {thread.name}")
229
+ wandb.termwarn(f"DEBUG: {thread.name}")
229
230
 
230
231
 
231
232
  class SocketServer:
@@ -266,7 +267,7 @@ class SocketServer:
266
267
  # socket.shutdown() is a more heavy handed approach to interrupting socket.accept()
267
268
  # in the future we might want to consider a more graceful shutdown which would involve setting
268
269
  # a threading Event and then initiating one last connection just to close down the thread
269
- # The advantage of the heavy handed approach is that it doesnt depend on the threads functioning
270
+ # The advantage of the heavy handed approach is that it does not depend on the threads functioning
270
271
  # properly, that is, if something has gone wrong, we probably want to use this hammer to shut things down
271
272
  self._sock.shutdown(socket.SHUT_RDWR)
272
273
  except OSError:
@@ -160,7 +160,7 @@ class _Service:
160
160
  service_args.append("--no-observability")
161
161
 
162
162
  if core_debug(default="False"):
163
- service_args.append("--debug")
163
+ service_args.extend(["--log-level", "-4"])
164
164
 
165
165
  exec_cmd_list = []
166
166
  termlog(
@@ -6,13 +6,15 @@ StreamAction: Lightweight record for stream ops for thread safety
6
6
  StreamMux: Container for dictionary of stream threads per runid
7
7
  """
8
8
 
9
+ from __future__ import annotations
10
+
9
11
  import functools
10
12
  import multiprocessing
11
13
  import queue
12
14
  import threading
13
15
  import time
14
16
  from threading import Event
15
- from typing import Any, Callable, Dict, List, Optional
17
+ from typing import Any, Callable
16
18
 
17
19
  import psutil
18
20
 
@@ -38,7 +40,7 @@ from ..interface.interface_relay import InterfaceRelay
38
40
  class StreamThread(threading.Thread):
39
41
  """Class to running internal process as a thread."""
40
42
 
41
- def __init__(self, target: Callable, kwargs: Dict[str, Any]) -> None:
43
+ def __init__(self, target: Callable, kwargs: dict[str, Any]) -> None:
42
44
  threading.Thread.__init__(self)
43
45
  self.name = "StreamThr"
44
46
  self._target = target
@@ -51,9 +53,9 @@ class StreamThread(threading.Thread):
51
53
 
52
54
 
53
55
  class StreamRecord:
54
- _record_q: "queue.Queue[pb.Record]"
55
- _result_q: "queue.Queue[pb.Result]"
56
- _relay_q: "queue.Queue[pb.Result]"
56
+ _record_q: queue.Queue[pb.Record]
57
+ _result_q: queue.Queue[pb.Result]
58
+ _relay_q: queue.Queue[pb.Result]
57
59
  _iface: InterfaceRelay
58
60
  _thread: StreamThread
59
61
  _settings: SettingsStatic
@@ -111,7 +113,7 @@ class StreamAction:
111
113
  _processed: Event
112
114
  _data: Any
113
115
 
114
- def __init__(self, action: str, stream_id: str, data: Optional[Any] = None):
116
+ def __init__(self, action: str, stream_id: str, data: Any | None = None):
115
117
  self._action = action
116
118
  self._stream_id = stream_id
117
119
  self._data = data
@@ -133,12 +135,12 @@ class StreamAction:
133
135
 
134
136
  class StreamMux:
135
137
  _streams_lock: threading.Lock
136
- _streams: Dict[str, StreamRecord]
137
- _port: Optional[int]
138
- _pid: Optional[int]
139
- _action_q: "queue.Queue[StreamAction]"
138
+ _streams: dict[str, StreamRecord]
139
+ _port: int | None
140
+ _pid: int | None
141
+ _action_q: queue.Queue[StreamAction]
140
142
  _stopped: Event
141
- _pid_checked_ts: Optional[float]
143
+ _pid_checked_ts: float | None
142
144
  _mailbox: Mailbox
143
145
 
144
146
  def __init__(self) -> None:
@@ -152,7 +154,7 @@ class StreamMux:
152
154
  self._mailbox = Mailbox()
153
155
  self._mailbox.enable_keepalive()
154
156
 
155
- def _get_stopped_event(self) -> "Event":
157
+ def _get_stopped_event(self) -> Event:
156
158
  # TODO: clean this up, there should be a better way to abstract this
157
159
  return self._stopped
158
160
 
@@ -192,7 +194,7 @@ class StreamMux:
192
194
  self._action_q.put(action)
193
195
  action.wait_handled()
194
196
 
195
- def stream_names(self) -> List[str]:
197
+ def stream_names(self) -> list[str]:
196
198
  with self._streams_lock:
197
199
  names = list(self._streams.keys())
198
200
  return names
@@ -273,7 +275,7 @@ class StreamMux:
273
275
  if self._check_orphaned():
274
276
  self._stopped.set()
275
277
 
276
- poll_exit_responses: List[pb.PollExitResponse] = []
278
+ poll_exit_responses: list[pb.PollExitResponse] = []
277
279
  for probe_handle in probe_handles:
278
280
  result = probe_handle.get_probe_result()
279
281
  if result:
@@ -281,7 +283,7 @@ class StreamMux:
281
283
 
282
284
  progress_printer.update(poll_exit_responses)
283
285
 
284
- def _finish_all(self, streams: Dict[str, StreamRecord], exit_code: int) -> None:
286
+ def _finish_all(self, streams: dict[str, StreamRecord], exit_code: int) -> None:
285
287
  if not streams:
286
288
  return
287
289
 
@@ -292,8 +294,8 @@ class StreamMux:
292
294
  exit_handles = []
293
295
 
294
296
  # only finish started streams, non started streams failed early
295
- started_streams: Dict[str, StreamRecord] = {}
296
- not_started_streams: Dict[str, StreamRecord] = {}
297
+ started_streams: dict[str, StreamRecord] = {}
298
+ not_started_streams: dict[str, StreamRecord] = {}
297
299
  for stream_id, stream in streams.items():
298
300
  d = started_streams if stream._started else not_started_streams
299
301
  d[stream_id] = stream
@@ -37,17 +37,17 @@ def print_results(
37
37
  else:
38
38
  color = "red"
39
39
  if isinstance(failed_test_or_tests, str):
40
- print(RED_X)
41
- print(click.style(failed_test_or_tests, fg=color, bold=True))
40
+ print(RED_X) # noqa: T201
41
+ print(click.style(failed_test_or_tests, fg=color, bold=True)) # noqa: T201
42
42
  elif isinstance(failed_test_or_tests, list) and len(failed_test_or_tests) > 0:
43
- print(RED_X)
44
- print(
43
+ print(RED_X) # noqa: T201
44
+ print( # noqa: T201
45
45
  "\n".join(
46
46
  [click.style(f, fg=color, bold=True) for f in failed_test_or_tests]
47
47
  )
48
48
  )
49
49
  else:
50
- print(CHECKMARK)
50
+ print(CHECKMARK) # noqa: T201
51
51
 
52
52
 
53
53
  def check_host(host: str) -> bool:
@@ -58,7 +58,7 @@ def check_host(host: str) -> bool:
58
58
 
59
59
 
60
60
  def check_logged_in(api: Api, host: str) -> bool:
61
- print("Checking if logged in".ljust(72, "."), end="")
61
+ print("Checking if logged in".ljust(72, "."), end="") # noqa: T201
62
62
  login_doc_url = "https://docs.wandb.ai/ref/cli/wandb-login"
63
63
  fail_string = None
64
64
  if api.api_key is None:
@@ -83,7 +83,7 @@ def check_logged_in(api: Api, host: str) -> bool:
83
83
 
84
84
  def check_secure_requests(url: str, test_url_string: str, failure_output: str) -> None:
85
85
  # check if request is over https
86
- print(test_url_string.ljust(72, "."), end="")
86
+ print(test_url_string.ljust(72, "."), end="") # noqa: T201
87
87
  fail_string = None
88
88
  if not url.startswith("https"):
89
89
  fail_string = failure_output
@@ -91,7 +91,7 @@ def check_secure_requests(url: str, test_url_string: str, failure_output: str) -
91
91
 
92
92
 
93
93
  def check_cors_configuration(url: str, origin: str) -> None:
94
- print("Checking CORs configuration of the bucket".ljust(72, "."), end="")
94
+ print("Checking CORs configuration of the bucket".ljust(72, "."), end="") # noqa: T201
95
95
  fail_string = None
96
96
  res_get = requests.options(
97
97
  url, headers={"Origin": origin, "Access-Control-Request-Method": "GET"}
@@ -107,7 +107,7 @@ def check_cors_configuration(url: str, origin: str) -> None:
107
107
 
108
108
 
109
109
  def check_run(api: Api) -> bool:
110
- print(
110
+ print( # noqa: T201
111
111
  "Checking logged metrics, saving and downloading a file".ljust(72, "."), end=""
112
112
  )
113
113
  failed_test_strings = []
@@ -308,7 +308,7 @@ def log_use_download_artifact(
308
308
 
309
309
 
310
310
  def check_artifacts() -> bool:
311
- print("Checking artifact save and download workflows".ljust(72, "."), end="")
311
+ print("Checking artifact save and download workflows".ljust(72, "."), end="") # noqa: T201
312
312
  failed_test_strings: List[str] = []
313
313
 
314
314
  # test checksum
@@ -365,7 +365,7 @@ def check_artifacts() -> bool:
365
365
 
366
366
  def check_graphql_put(api: Api, host: str) -> Tuple[bool, Optional[str]]:
367
367
  # check graphql endpoint using an upload
368
- print("Checking signed URL upload".ljust(72, "."), end="")
368
+ print("Checking signed URL upload".ljust(72, "."), end="") # noqa: T201
369
369
  failed_test_strings = []
370
370
  gql_fp = "gql_test_file.txt"
371
371
  f = open(gql_fp, "w")
@@ -410,7 +410,7 @@ def check_graphql_put(api: Api, host: str) -> Tuple[bool, Optional[str]]:
410
410
 
411
411
 
412
412
  def check_large_post() -> bool:
413
- print(
413
+ print( # noqa: T201
414
414
  "Checking ability to send large payloads through proxy".ljust(72, "."), end=""
415
415
  )
416
416
  descy = "a" * int(10**7)
@@ -461,7 +461,7 @@ def check_large_post() -> bool:
461
461
 
462
462
 
463
463
  def check_wandb_version(api: Api) -> None:
464
- print("Checking wandb package version is up to date".ljust(72, "."), end="")
464
+ print("Checking wandb package version is up to date".ljust(72, "."), end="") # noqa: T201
465
465
  _, server_info = api.viewer_server_info()
466
466
  fail_string = None
467
467
  warning = False
wandb/sdk/wandb_init.py CHANGED
@@ -48,10 +48,10 @@ from .wandb_settings import Settings
48
48
  if TYPE_CHECKING:
49
49
  from wandb.proto import wandb_internal_pb2 as pb
50
50
 
51
- logger: logging.Logger | None = None # logger configured during wandb.init()
51
+ logger: wandb_setup.Logger | None = None # logger configured during wandb.init()
52
52
 
53
53
 
54
- def _set_logger(log_object: logging.Logger) -> None:
54
+ def _set_logger(log_object: wandb_setup.Logger | None) -> None:
55
55
  """Configure module logger."""
56
56
  global logger
57
57
  logger = log_object
@@ -125,7 +125,7 @@ class _WandbInit:
125
125
  self.backend: Backend | None = None
126
126
 
127
127
  self._teardown_hooks: list[TeardownHook] = []
128
- self._wl: wandb_setup._WandbSetup | None = None
128
+ self._wl = wandb.setup()
129
129
  self.notebook: wandb.jupyter.Notebook | None = None # type: ignore
130
130
  self.printer = printer.new_printer()
131
131
 
@@ -139,7 +139,7 @@ class _WandbInit:
139
139
  Any settings from environment variables set after the singleton is initialized
140
140
  (via login/setup/etc.) will be ignored.
141
141
  """
142
- singleton = wandb_setup._WandbSetup._instance
142
+ singleton = wandb_setup.singleton()
143
143
  if singleton is None:
144
144
  return
145
145
 
@@ -167,6 +167,41 @@ class _WandbInit:
167
167
  )
168
168
  self.printer.display(line, level="warn")
169
169
 
170
+ def clear_run_path_if_sweep_or_launch(
171
+ self,
172
+ init_settings: Settings,
173
+ ) -> None:
174
+ """Clear project/entity/run_id keys if in a Sweep or a Launch context.
175
+
176
+ Args:
177
+ init_settings: Settings specified in the call to `wandb.init()`.
178
+ """
179
+ when_doing_thing = ""
180
+
181
+ if self._wl.settings.sweep_id:
182
+ when_doing_thing = "when running a sweep"
183
+ elif self._wl.settings.launch:
184
+ when_doing_thing = "when running from a wandb launch context"
185
+
186
+ if not when_doing_thing:
187
+ return
188
+
189
+ def warn(key: str, value: str) -> None:
190
+ self.printer.display(
191
+ f"Ignoring {key} {value!r} {when_doing_thing}.",
192
+ level="warn",
193
+ )
194
+
195
+ if init_settings.project is not None:
196
+ warn("project", init_settings.project)
197
+ init_settings.project = None
198
+ if init_settings.entity is not None:
199
+ warn("entity", init_settings.entity)
200
+ init_settings.entity = None
201
+ if init_settings.run_id is not None:
202
+ warn("run_id", init_settings.run_id)
203
+ init_settings.run_id = None
204
+
170
205
  def setup( # noqa: C901
171
206
  self,
172
207
  init_settings: Settings,
@@ -182,50 +217,23 @@ class _WandbInit:
182
217
  """
183
218
  self.warn_env_vars_change_after_setup()
184
219
 
185
- # mode="disabled" is a special case where we don't want to start wandb-core
186
- setup_settings_dict: dict[str, Any] = {}
187
- if init_settings.mode == "disabled":
188
- setup_settings_dict["mode"] = init_settings.mode
189
- # TODO: x_disable_service is deprecated, remove this once officially deprecated
190
- if init_settings.x_disable_service:
191
- setup_settings_dict["x_disable_service"] = init_settings.x_disable_service
192
- setup_settings = (
193
- wandb.Settings(**setup_settings_dict) if setup_settings_dict else None
194
- )
195
-
196
- self._wl = wandb_setup.setup(settings=setup_settings)
197
-
198
- assert self._wl is not None
199
220
  _set_logger(self._wl._get_logger())
221
+ assert logger
200
222
 
201
- # Start with settings from wandb library singleton
202
- settings = self._wl.settings.copy()
223
+ self.clear_run_path_if_sweep_or_launch(init_settings)
203
224
 
204
- # handle custom sweep- and launch-related logic for init settings
205
- if settings.sweep_id:
206
- init_settings.sweep_id = settings.sweep_id
207
- init_settings.handle_sweep_logic()
208
- if settings.launch:
209
- init_settings.launch = settings.launch
210
- init_settings.handle_launch_logic()
225
+ # Inherit global settings.
226
+ settings = self._wl.settings.model_copy()
211
227
 
212
- # Apply settings from wandb.init() call
228
+ # Apply settings from wandb.init() call.
213
229
  settings.update_from_settings(init_settings)
214
230
 
215
- sagemaker_config: dict = (
216
- dict() if settings.sagemaker_disable else sagemaker.parse_sm_config()
217
- )
218
- if sagemaker_config:
219
- sagemaker_api_key = sagemaker_config.get("wandb_api_key", None)
220
- sagemaker_run, sagemaker_env = sagemaker.parse_sm_resources()
221
- if sagemaker_env:
222
- if sagemaker_api_key:
223
- sagemaker_env["WANDB_API_KEY"] = sagemaker_api_key
224
- settings.update_from_env_vars(sagemaker_env)
225
- wandb.setup(settings=settings)
226
- settings.update_from_dict(sagemaker_run)
227
- with telemetry.context(obj=self._init_telemetry_obj) as tel:
228
- tel.feature.sagemaker = True
231
+ # Infer the run ID from SageMaker.
232
+ if not settings.sagemaker_disable and sagemaker.is_using_sagemaker():
233
+ if sagemaker.set_run_id(settings):
234
+ logger.info("set run ID and group based on SageMaker")
235
+ with telemetry.context(obj=self._init_telemetry_obj) as tel:
236
+ tel.feature.sagemaker = True
229
237
 
230
238
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
231
239
  if config is not None:
@@ -252,23 +260,25 @@ class _WandbInit:
252
260
  exclude=config_exclude_keys,
253
261
  )
254
262
 
255
- # merge config with sweep or sagemaker (or config file)
256
- self.sweep_config = dict()
257
- sweep_config = self._wl._sweep_config or dict()
263
+ # Construct the run's config.
258
264
  self.config = dict()
259
265
  self.init_artifact_config: dict[str, Any] = dict()
260
- for config_data in (
261
- sagemaker_config,
262
- self._wl._config,
263
- config,
264
- ):
265
- if not config_data:
266
- continue
267
- # split out artifacts, since when inserted into
268
- # config they will trigger use_artifact
269
- # but the run is not yet upserted
270
- self._split_artifacts_from_config(config_data, self.config) # type: ignore
271
266
 
267
+ if not settings.sagemaker_disable and sagemaker.is_using_sagemaker():
268
+ sagemaker_config = sagemaker.parse_sm_config()
269
+ self._split_artifacts_from_config(sagemaker_config, self.config)
270
+
271
+ with telemetry.context(obj=self._init_telemetry_obj) as tel:
272
+ tel.feature.sagemaker = True
273
+
274
+ if self._wl._config:
275
+ self._split_artifacts_from_config(self._wl._config, self.config)
276
+
277
+ if config and isinstance(config, dict):
278
+ self._split_artifacts_from_config(config, self.config)
279
+
280
+ self.sweep_config = dict()
281
+ sweep_config = self._wl._sweep_config or dict()
272
282
  if sweep_config:
273
283
  self._split_artifacts_from_config(sweep_config, self.sweep_config)
274
284
 
@@ -295,16 +305,14 @@ class _WandbInit:
295
305
  )
296
306
 
297
307
  # apply updated global state after login was handled
298
- wl = wandb.setup()
299
- assert wl is not None
300
308
  login_settings = {
301
309
  k: v
302
310
  for k, v in {
303
- "anonymous": wl.settings.anonymous,
304
- "api_key": wl.settings.api_key,
305
- "base_url": wl.settings.base_url,
306
- "force": wl.settings.force,
307
- "login_timeout": wl.settings.login_timeout,
311
+ "anonymous": self._wl.settings.anonymous,
312
+ "api_key": self._wl.settings.api_key,
313
+ "base_url": self._wl.settings.base_url,
314
+ "force": self._wl.settings.force,
315
+ "login_timeout": self._wl.settings.login_timeout,
308
316
  }.items()
309
317
  if v is not None
310
318
  }
@@ -328,7 +336,7 @@ class _WandbInit:
328
336
 
329
337
  # TODO: remove this once we refactor the client. This is a temporary
330
338
  # fix to make sure that we use the same project name for wandb-core.
331
- # The reason this is not going throught the settings object is to
339
+ # The reason this is not going through the settings object is to
332
340
  # avoid failure cases in other parts of the code that will be
333
341
  # removed with the switch to wandb-core.
334
342
  if settings.project is None:
@@ -364,7 +372,7 @@ class _WandbInit:
364
372
  else:
365
373
  config_target.setdefault(k, v)
366
374
 
367
- def _enable_logging(self, log_fname: str, run_id: str | None = None) -> None:
375
+ def _enable_logging(self, log_fname: str) -> None:
368
376
  """Enable logging to the global debug log.
369
377
 
370
378
  This adds a run_id to the log, in case of multiple processes on the same machine.
@@ -373,26 +381,13 @@ class _WandbInit:
373
381
  handler = logging.FileHandler(log_fname)
374
382
  handler.setLevel(logging.INFO)
375
383
 
376
- class WBFilter(logging.Filter):
377
- def filter(self, record: logging.LogRecord) -> bool:
378
- record.run_id = run_id
379
- return True
380
-
381
- if run_id:
382
- formatter = logging.Formatter(
383
- "%(asctime)s %(levelname)-7s %(threadName)-10s:%(process)d "
384
- "[%(run_id)s:%(filename)s:%(funcName)s():%(lineno)s] %(message)s"
385
- )
386
- else:
387
- formatter = logging.Formatter(
388
- "%(asctime)s %(levelname)-7s %(threadName)-10s:%(process)d "
389
- "[%(filename)s:%(funcName)s():%(lineno)s] %(message)s"
390
- )
384
+ formatter = logging.Formatter(
385
+ "%(asctime)s %(levelname)-7s %(threadName)-10s:%(process)d "
386
+ "[%(filename)s:%(funcName)s():%(lineno)s] %(message)s"
387
+ )
391
388
 
392
389
  handler.setFormatter(formatter)
393
- if run_id:
394
- handler.addFilter(WBFilter())
395
- assert logger is not None
390
+ assert isinstance(logger, logging.Logger)
396
391
  logger.propagate = False
397
392
  logger.addHandler(handler)
398
393
  # TODO: make me configurable
@@ -407,7 +402,7 @@ class _WandbInit:
407
402
  def _safe_symlink(
408
403
  self, base: str, target: str, name: str, delete: bool = False
409
404
  ) -> None:
410
- # TODO(jhr): do this with relpaths, but i cant figure it out on no sleep
405
+ # TODO(jhr): do this with relpaths, but i can't figure it out on no sleep
411
406
  if not hasattr(os, "symlink"):
412
407
  return
413
408
 
@@ -552,11 +547,13 @@ class _WandbInit:
552
547
  entity="dummy",
553
548
  )
554
549
  )
555
- # config and summary objects
550
+ # config, summary, and metadata objects
556
551
  drun._config = wandb.sdk.wandb_config.Config()
557
552
  drun._config.update(self.sweep_config)
558
553
  drun._config.update(self.config)
559
554
  drun.summary = SummaryDisabled() # type: ignore
555
+ drun._Run__metadata = wandb.sdk.wandb_metadata.Metadata()
556
+
560
557
  # methods
561
558
  drun.log = lambda data, *_, **__: drun.summary.update(data) # type: ignore
562
559
  drun.finish = lambda *_, **__: module.unset_globals() # type: ignore
@@ -666,26 +663,25 @@ class _WandbInit:
666
663
  )
667
664
 
668
665
  latest_run = self._wl._global_run_stack[-1]
669
- logger.info(f"found existing run on stack: {latest_run._run_id}")
666
+ logger.info(f"found existing run on stack: {latest_run.id}")
670
667
  latest_run.finish()
671
- elif isinstance(wandb.run, Run):
672
- service = self._wl.service
673
- # We shouldn't return a stale global run if we are in a new pid
674
- if not service or os.getpid() == wandb.run._init_pid:
675
- logger.info("wandb.init() called when a run is still active")
676
- with telemetry.context() as tel:
677
- tel.feature.init_return_run = True
678
- return wandb.run
668
+ elif wandb.run is not None and os.getpid() == wandb.run._init_pid:
669
+ logger.info("wandb.init() called when a run is still active")
670
+ with telemetry.context() as tel:
671
+ tel.feature.init_return_run = True
672
+ return wandb.run
679
673
 
680
674
  logger.info("starting backend")
681
675
 
682
- service = self._wl.service
683
- if service:
676
+ if not self.settings.x_disable_service:
677
+ service = self._wl.ensure_service()
684
678
  logger.info("sending inform_init request")
685
679
  service.inform_init(
686
680
  settings=self.settings.to_proto(),
687
681
  run_id=self.settings.run_id, # type: ignore
688
682
  )
683
+ else:
684
+ service = None
689
685
 
690
686
  mailbox = Mailbox()
691
687
  backend = Backend(
@@ -869,8 +865,6 @@ class _WandbInit:
869
865
  tel.feature.resumed = run_result.run.resumed
870
866
  run._set_run_obj(run_result.run)
871
867
 
872
- run._on_init()
873
-
874
868
  logger.info("starting run threads in backend")
875
869
  # initiate run (stats and metadata probing)
876
870
 
@@ -943,16 +937,13 @@ def _attach(
943
937
  )
944
938
  wandb._assert_is_user_process() # type: ignore
945
939
 
946
- _wl = wandb_setup._setup()
947
- assert _wl
940
+ _wl = wandb.setup()
948
941
 
949
942
  _set_logger(_wl._get_logger())
950
943
  if logger is None:
951
944
  raise UsageError("logger is not initialized")
952
945
 
953
- service = _wl.service
954
- if not service:
955
- raise UsageError(f"Unable to attach to run {attach_id} (no service process)")
946
+ service = _wl.ensure_service()
956
947
 
957
948
  try:
958
949
  attach_settings = service.inform_attach(attach_id=attach_id)
@@ -1081,7 +1072,7 @@ def init( # noqa: C901
1081
1072
  entity: The username or team name under which the runs will be logged.
1082
1073
  The entity must already exist, so ensure you’ve created your account
1083
1074
  or team in the UI before starting to log runs. If not specified, the
1084
- run will default your defualt entity. To change the default entity,
1075
+ run will default your default entity. To change the default entity,
1085
1076
  go to [your settings](https://wandb.ai/settings) and update the
1086
1077
  "Default location to create new projects" under "Default team".
1087
1078
  project: The name of the project under which this run will be logged.
wandb/sdk/wandb_login.py CHANGED
@@ -88,7 +88,7 @@ def login(
88
88
  if verify:
89
89
  from . import wandb_setup
90
90
 
91
- singleton = wandb_setup._WandbSetup._instance
91
+ singleton = wandb_setup.singleton()
92
92
  assert singleton is not None
93
93
  viewer = singleton._server._viewer
94
94
  if not viewer: