wandb 0.19.2__py3-none-any.whl → 0.19.3__py3-none-any.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 CHANGED
@@ -10,7 +10,7 @@ For reference documentation, see https://docs.wandb.com/ref/python.
10
10
  """
11
11
  from __future__ import annotations
12
12
 
13
- __version__ = "0.19.2"
13
+ __version__ = "0.19.3"
14
14
 
15
15
 
16
16
  from wandb.errors import Error
wandb/__init__.pyi CHANGED
@@ -103,7 +103,7 @@ if TYPE_CHECKING:
103
103
  import wandb
104
104
  from wandb.plot import CustomChart
105
105
 
106
- __version__: str = "0.19.2"
106
+ __version__: str = "0.19.3"
107
107
 
108
108
  run: Run | None
109
109
  config: wandb_config.Config
@@ -651,7 +651,12 @@ def log(
651
651
  run = wandb.init()
652
652
  examples = []
653
653
  for i in range(3):
654
- pixels = np.random.randint(low=0, high=256, size=(100, 100, 3), dtype=np.uint8)
654
+ pixels = np.random.randint(
655
+ low=0,
656
+ high=256,
657
+ size=(100, 100, 3),
658
+ dtype=np.uint8,
659
+ )
655
660
  pil_image = PILImage.fromarray(pixels, mode="RGB")
656
661
  image = wandb.Image(pil_image, caption=f"random field {i}")
657
662
  examples.append(image)
@@ -666,7 +671,12 @@ def log(
666
671
 
667
672
  run = wandb.init()
668
673
  # axes are (time, channel, height, width)
669
- frames = np.random.randint(low=0, high=256, size=(10, 3, 100, 100), dtype=np.uint8)
674
+ frames = np.random.randint(
675
+ low=0,
676
+ high=256,
677
+ size=(10, 3, 100, 100),
678
+ dtype=np.uint8,
679
+ )
670
680
  run.log({"video": wandb.Video(frames, fps=4)})
671
681
  ```
672
682
 
@@ -328,15 +328,13 @@ def wandb_log(
328
328
  if not isinstance(settings, wandb.sdk.wandb_settings.Settings):
329
329
  settings = wandb.Settings()
330
330
 
331
- settings.update(
332
- run_group=coalesce(
333
- settings.run_group, f"{current.flow_name}/{current.run_id}"
334
- ),
335
- source=wandb.sdk.wandb_settings.Source.INIT,
336
- )
337
- settings.update(
338
- run_job_type=coalesce(settings.run_job_type, current.step_name),
339
- source=wandb.sdk.wandb_settings.Source.INIT,
331
+ settings.update_from_dict(
332
+ {
333
+ "run_group": coalesce(
334
+ settings.run_group, f"{current.flow_name}/{current.run_id}"
335
+ ),
336
+ "run_job_type": coalesce(settings.run_job_type, current.step_name),
337
+ }
340
338
  )
341
339
 
342
340
  with wandb.init(settings=settings) as run:
wandb/sdk/wandb_init.py CHANGED
@@ -14,6 +14,7 @@ import copy
14
14
  import json
15
15
  import logging
16
16
  import os
17
+ import pathlib
17
18
  import platform
18
19
  import sys
19
20
  import tempfile
@@ -48,14 +49,6 @@ from .wandb_settings import Settings
48
49
  if TYPE_CHECKING:
49
50
  from wandb.proto import wandb_internal_pb2 as pb
50
51
 
51
- logger: wandb_setup.Logger | None = None # logger configured during wandb.init()
52
-
53
-
54
- def _set_logger(log_object: wandb_setup.Logger | None) -> None:
55
- """Configure module logger."""
56
- global logger
57
- logger = log_object
58
-
59
52
 
60
53
  def _huggingface_version() -> str | None:
61
54
  if "transformers" in sys.modules:
@@ -115,9 +108,10 @@ def _handle_launch_config(settings: Settings) -> dict[str, Any]:
115
108
  class _WandbInit:
116
109
  _init_telemetry_obj: telemetry.TelemetryRecord
117
110
 
118
- def __init__(self) -> None:
111
+ def __init__(self, wl: wandb_setup._WandbSetup) -> None:
112
+ self._wl = wl
113
+
119
114
  self.kwargs = None
120
- self.settings: Settings | None = None
121
115
  self.sweep_config: dict[str, Any] = {}
122
116
  self.launch_config: dict[str, Any] = {}
123
117
  self.config: dict[str, Any] = {}
@@ -125,7 +119,6 @@ class _WandbInit:
125
119
  self.backend: Backend | None = None
126
120
 
127
121
  self._teardown_hooks: list[TeardownHook] = []
128
- self._wl = wandb.setup()
129
122
  self.notebook: wandb.jupyter.Notebook | None = None # type: ignore
130
123
  self.printer = printer.new_printer()
131
124
 
@@ -133,6 +126,40 @@ class _WandbInit:
133
126
 
134
127
  self.deprecated_features_used: dict[str, str] = dict()
135
128
 
129
+ @property
130
+ def _logger(self) -> wandb_setup.Logger:
131
+ return self._wl._get_logger()
132
+
133
+ def maybe_login(self, init_settings: Settings) -> None:
134
+ """Log in if we are not creating an offline or disabled run.
135
+
136
+ This may change the W&B singleton settings.
137
+
138
+ Args:
139
+ init_settings: Settings passed to `wandb.init()` or set via
140
+ keyword arguments.
141
+ """
142
+ # Allow settings passed to init() to override inferred values.
143
+ #
144
+ # Calling login() may change settings on the singleton,
145
+ # so these may not be the final run settings.
146
+ run_settings = self._wl.settings.model_copy()
147
+ run_settings.update_from_settings(init_settings)
148
+
149
+ # NOTE: _noop or _offline can become true after _login().
150
+ # _noop happens if _login hits a timeout.
151
+ # _offline can be selected by the user at the login prompt.
152
+ if run_settings._noop or run_settings._offline:
153
+ return
154
+
155
+ wandb_login._login(
156
+ anonymous=run_settings.anonymous,
157
+ force=run_settings.force,
158
+ _disable_warning=True,
159
+ _silent=run_settings.quiet or run_settings.silent,
160
+ _entity=run_settings.entity,
161
+ )
162
+
136
163
  def warn_env_vars_change_after_setup(self) -> None:
137
164
  """Warn if environment variables change after wandb singleton is initialized.
138
165
 
@@ -202,24 +229,15 @@ class _WandbInit:
202
229
  warn("run_id", init_settings.run_id)
203
230
  init_settings.run_id = None
204
231
 
205
- def setup( # noqa: C901
206
- self,
207
- init_settings: Settings,
208
- config: dict | str | None = None,
209
- config_exclude_keys: list[str] | None = None,
210
- config_include_keys: list[str] | None = None,
211
- allow_val_change: bool | None = None,
212
- monitor_gym: bool | None = None,
213
- ) -> None:
214
- """Complete setup for `wandb.init()`.
232
+ def compute_run_settings(self, init_settings: Settings) -> Settings:
233
+ """Returns the run's settings.
215
234
 
216
- This includes parsing all arguments, applying them with settings and enabling logging.
235
+ Args:
236
+ init_settings: Settings passed to `wandb.init()` or set via
237
+ keyword arguments.
217
238
  """
218
239
  self.warn_env_vars_change_after_setup()
219
240
 
220
- _set_logger(self._wl._get_logger())
221
- assert logger
222
-
223
241
  self.clear_run_path_if_sweep_or_launch(init_settings)
224
242
 
225
243
  # Inherit global settings.
@@ -231,10 +249,121 @@ class _WandbInit:
231
249
  # Infer the run ID from SageMaker.
232
250
  if not settings.sagemaker_disable and sagemaker.is_using_sagemaker():
233
251
  if sagemaker.set_run_id(settings):
234
- logger.info("set run ID and group based on SageMaker")
252
+ self._logger.info("set run ID and group based on SageMaker")
235
253
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
236
254
  tel.feature.sagemaker = True
237
255
 
256
+ # get status of code saving before applying user settings
257
+ save_code_pre_user_settings = settings.save_code
258
+ if not settings._offline and not settings._noop:
259
+ user_settings = self._wl._load_user_settings()
260
+ if user_settings is not None:
261
+ settings.update_from_dict(user_settings)
262
+
263
+ # ensure that user settings don't set saving to true
264
+ # if user explicitly set these to false in UI
265
+ if save_code_pre_user_settings is False:
266
+ settings.save_code = False
267
+
268
+ # TODO: remove this once we refactor the client. This is a temporary
269
+ # fix to make sure that we use the same project name for wandb-core.
270
+ # The reason this is not going through the settings object is to
271
+ # avoid failure cases in other parts of the code that will be
272
+ # removed with the switch to wandb-core.
273
+ if settings.project is None:
274
+ settings.project = wandb.util.auto_project_name(settings.program)
275
+
276
+ settings.x_start_time = time.time()
277
+
278
+ return settings
279
+
280
+ def _load_autoresume_run_id(self, resume_file: pathlib.Path) -> str | None:
281
+ """Returns the run_id stored in the auto-resume file, if any.
282
+
283
+ Returns None if the file does not exist or is not in a valid format.
284
+
285
+ Args:
286
+ resume_file: The file path to use for resume='auto' mode.
287
+ """
288
+ if not resume_file.exists():
289
+ return None
290
+
291
+ with resume_file.open() as f:
292
+ try:
293
+ return json.load(f)["run_id"]
294
+
295
+ except json.JSONDecodeError as e:
296
+ self._logger.exception(
297
+ f"could not decode {resume_file}, ignoring",
298
+ exc_info=e,
299
+ )
300
+ return None
301
+
302
+ except KeyError:
303
+ self._logger.error(
304
+ f"resume file at {resume_file} did not store a run_id"
305
+ )
306
+ return None
307
+
308
+ def _save_autoresume_run_id(
309
+ self,
310
+ *,
311
+ resume_file: pathlib.Path,
312
+ run_id: str,
313
+ ) -> None:
314
+ """Write the run ID to the auto-resume file."""
315
+ resume_file.parent.mkdir(exist_ok=True)
316
+ with resume_file.open("w") as f:
317
+ json.dump({"run_id": run_id}, f)
318
+
319
+ def set_run_id(self, settings: Settings) -> None:
320
+ """Set the run ID and possibly save it to the auto-resume file.
321
+
322
+ After this, `settings.run_id` is guaranteed to be set.
323
+
324
+ Args:
325
+ settings: The run's settings derived from the environment
326
+ and explicit values passed to `wandb.init()`.
327
+ """
328
+ if settings.resume == "auto" and settings.resume_fname:
329
+ resume_path = pathlib.Path(settings.resume_fname)
330
+ else:
331
+ resume_path = None
332
+
333
+ if resume_path:
334
+ previous_id = self._load_autoresume_run_id(resume_path)
335
+
336
+ if not previous_id:
337
+ pass
338
+ elif settings.run_id is None:
339
+ self._logger.info(f"loaded run ID from {resume_path}")
340
+ settings.run_id = previous_id
341
+ elif settings.run_id != previous_id:
342
+ wandb.termwarn(
343
+ f"Ignoring ID {previous_id} loaded due to resume='auto'"
344
+ f" because the run ID is set to {settings.run_id}.",
345
+ )
346
+
347
+ # If no run ID was inferred, explicitly set, or loaded from an
348
+ # auto-resume file, then we generate a new ID.
349
+ if settings.run_id is None:
350
+ settings.run_id = runid.generate_id()
351
+
352
+ if resume_path:
353
+ self._save_autoresume_run_id(
354
+ resume_file=resume_path,
355
+ run_id=settings.run_id,
356
+ )
357
+
358
+ def setup(
359
+ self,
360
+ settings: Settings,
361
+ config: dict | str | None = None,
362
+ config_exclude_keys: list[str] | None = None,
363
+ config_include_keys: list[str] | None = None,
364
+ monitor_gym: bool | None = None,
365
+ ) -> None:
366
+ """Compute the run's config and some telemetry."""
238
367
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
239
368
  if config is not None:
240
369
  tel.feature.set_init_config = True
@@ -295,55 +424,6 @@ class _WandbInit:
295
424
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
296
425
  tel.feature.tensorboard_sync = True
297
426
 
298
- if not settings._offline and not settings._noop:
299
- wandb_login._login(
300
- anonymous=settings.anonymous,
301
- force=settings.force,
302
- _disable_warning=True,
303
- _silent=settings.quiet or settings.silent,
304
- _entity=settings.entity,
305
- )
306
-
307
- # apply updated global state after login was handled
308
- login_settings = {
309
- k: v
310
- for k, v in {
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,
316
- }.items()
317
- if v is not None
318
- }
319
- if login_settings:
320
- settings.update_from_dict(login_settings)
321
-
322
- # handle custom resume logic
323
- settings.handle_resume_logic()
324
-
325
- # get status of code saving before applying user settings
326
- save_code_pre_user_settings = settings.save_code
327
- if not settings._offline and not settings._noop:
328
- user_settings = self._wl._load_user_settings()
329
- if user_settings is not None:
330
- settings.update_from_dict(user_settings)
331
-
332
- # ensure that user settings don't set saving to true
333
- # if user explicitly set these to false in UI
334
- if save_code_pre_user_settings is False:
335
- settings.save_code = False
336
-
337
- # TODO: remove this once we refactor the client. This is a temporary
338
- # fix to make sure that we use the same project name for wandb-core.
339
- # The reason this is not going through the settings object is to
340
- # avoid failure cases in other parts of the code that will be
341
- # removed with the switch to wandb-core.
342
- if settings.project is None:
343
- settings.project = wandb.util.auto_project_name(settings.program)
344
-
345
- settings.x_start_time = time.time()
346
-
347
427
  if not settings._noop:
348
428
  self._log_setup(settings)
349
429
 
@@ -353,13 +433,10 @@ class _WandbInit:
353
433
  if launch_config:
354
434
  self._split_artifacts_from_config(launch_config, self.launch_config)
355
435
 
356
- self.settings = settings
357
-
358
436
  def teardown(self) -> None:
359
437
  # TODO: currently this is only called on failed wandb.init attempts
360
438
  # normally this happens on the run object
361
- assert logger
362
- logger.info("tearing down wandb.init")
439
+ self._logger.info("tearing down wandb.init")
363
440
  for hook in self._teardown_hooks:
364
441
  hook.call()
365
442
 
@@ -372,11 +449,12 @@ class _WandbInit:
372
449
  else:
373
450
  config_target.setdefault(k, v)
374
451
 
375
- def _enable_logging(self, log_fname: str) -> None:
376
- """Enable logging to the global debug log.
452
+ def _create_logger(self, log_fname: str) -> logging.Logger:
453
+ """Returns a logger configured to write to a file.
377
454
 
378
- This adds a run_id to the log, in case of multiple processes on the same machine.
379
- Currently, there is no way to disable logging after it's enabled.
455
+ This adds a run_id to the log, in case of multiple processes on the same
456
+ machine. Currently, there is no way to disable logging after it's
457
+ enabled.
380
458
  """
381
459
  handler = logging.FileHandler(log_fname)
382
460
  handler.setLevel(logging.INFO)
@@ -387,7 +465,8 @@ class _WandbInit:
387
465
  )
388
466
 
389
467
  handler.setFormatter(formatter)
390
- assert isinstance(logger, logging.Logger)
468
+
469
+ logger = logging.getLogger("wandb")
391
470
  logger.propagate = False
392
471
  logger.addHandler(handler)
393
472
  # TODO: make me configurable
@@ -399,6 +478,8 @@ class _WandbInit:
399
478
  )
400
479
  )
401
480
 
481
+ return logger
482
+
402
483
  def _safe_symlink(
403
484
  self, base: str, target: str, name: str, delete: bool = False
404
485
  ) -> None:
@@ -429,14 +510,14 @@ class _WandbInit:
429
510
  if self.notebook.save_ipynb(): # type: ignore
430
511
  assert self.run is not None
431
512
  res = self.run.log_code(root=None)
432
- logger.info("saved code: %s", res) # type: ignore
513
+ self._logger.info("saved code: %s", res) # type: ignore
433
514
  if self.backend.interface is not None:
434
- logger.info("pausing backend") # type: ignore
515
+ self._logger.info("pausing backend") # type: ignore
435
516
  self.backend.interface.publish_pause()
436
517
 
437
518
  def _resume_backend(self, *args: Any, **kwargs: Any) -> None: # noqa
438
519
  if self.backend is not None and self.backend.interface is not None:
439
- logger.info("resuming backend") # type: ignore
520
+ self._logger.info("resuming backend") # type: ignore
440
521
  self.backend.interface.publish_resume()
441
522
 
442
523
  def _jupyter_teardown(self) -> None:
@@ -447,8 +528,8 @@ class _WandbInit:
447
528
  if self.notebook.save_ipynb():
448
529
  assert self.run is not None
449
530
  res = self.run.log_code(root=None)
450
- logger.info("saved code and history: %s", res) # type: ignore
451
- logger.info("cleaning up jupyter logic") # type: ignore
531
+ self._logger.info("saved code and history: %s", res) # type: ignore
532
+ self._logger.info("cleaning up jupyter logic") # type: ignore
452
533
  # because of how we bind our methods we manually find them to unregister
453
534
  for hook in ipython.events.callbacks["pre_run_cell"]:
454
535
  if "_resume_backend" in hook.__name__:
@@ -466,7 +547,7 @@ class _WandbInit:
466
547
 
467
548
  # Monkey patch ipython publish to capture displayed outputs
468
549
  if not hasattr(ipython.display_pub, "_orig_publish"):
469
- logger.info("configuring jupyter hooks %s", self) # type: ignore
550
+ self._logger.info("configuring jupyter hooks %s", self) # type: ignore
470
551
  ipython.display_pub._orig_publish = ipython.display_pub.publish
471
552
  # Registering resume and pause hooks
472
553
 
@@ -513,15 +594,9 @@ class _WandbInit:
513
594
  delete=True,
514
595
  )
515
596
 
516
- _set_logger(logging.getLogger("wandb"))
517
- self._enable_logging(settings.log_user)
518
-
519
- assert self._wl
520
- assert logger
521
-
522
- self._wl._early_logger_flush(logger)
523
- logger.info(f"Logging user logs to {settings.log_user}")
524
- logger.info(f"Logging internal logs to {settings.log_internal}")
597
+ self._wl._early_logger_flush(self._create_logger(settings.log_user))
598
+ self._logger.info(f"Logging user logs to {settings.log_user}")
599
+ self._logger.info(f"Logging internal logs to {settings.log_internal}")
525
600
 
526
601
  def _make_run_disabled(self) -> Run:
527
602
  """Returns a Run-like object where all methods are no-ops.
@@ -635,24 +710,20 @@ class _WandbInit:
635
710
  percent_done = handle.percent_done
636
711
  self.printer.progress_update(line, percent_done=percent_done)
637
712
 
638
- def init(self) -> Run: # noqa: C901
639
- if logger is None:
640
- raise RuntimeError("Logger not initialized")
641
- logger.info("calling init triggers")
713
+ def init(self, settings: Settings) -> Run: # noqa: C901
714
+ self._logger.info("calling init triggers")
642
715
  trigger.call("on_init")
643
716
 
644
- assert self.settings is not None
645
717
  assert self._wl is not None
646
718
 
647
- logger.info(
719
+ self._logger.info(
648
720
  f"wandb.init called with sweep_config: {self.sweep_config}\nconfig: {self.config}"
649
721
  )
650
722
 
651
- if self.settings._noop:
723
+ if settings._noop:
652
724
  return self._make_run_disabled()
653
725
  if (
654
- self.settings.reinit
655
- or (self.settings._jupyter and self.settings.reinit is not False)
726
+ settings.reinit or (settings._jupyter and settings.reinit is not False)
656
727
  ) and len(self._wl._global_run_stack) > 0:
657
728
  if len(self._wl._global_run_stack) > 1:
658
729
  wandb.termwarn(
@@ -663,39 +734,39 @@ class _WandbInit:
663
734
  )
664
735
 
665
736
  latest_run = self._wl._global_run_stack[-1]
666
- logger.info(f"found existing run on stack: {latest_run.id}")
737
+ self._logger.info(f"found existing run on stack: {latest_run.id}")
667
738
  latest_run.finish()
668
739
  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")
740
+ self._logger.info("wandb.init() called when a run is still active")
670
741
  with telemetry.context() as tel:
671
742
  tel.feature.init_return_run = True
672
743
  return wandb.run
673
744
 
674
- logger.info("starting backend")
745
+ self._logger.info("starting backend")
675
746
 
676
- if not self.settings.x_disable_service:
747
+ if not settings.x_disable_service:
677
748
  service = self._wl.ensure_service()
678
- logger.info("sending inform_init request")
749
+ self._logger.info("sending inform_init request")
679
750
  service.inform_init(
680
- settings=self.settings.to_proto(),
681
- run_id=self.settings.run_id, # type: ignore
751
+ settings=settings.to_proto(),
752
+ run_id=settings.run_id, # type: ignore
682
753
  )
683
754
  else:
684
755
  service = None
685
756
 
686
757
  mailbox = Mailbox()
687
758
  backend = Backend(
688
- settings=self.settings,
759
+ settings=settings,
689
760
  service=service,
690
761
  mailbox=mailbox,
691
762
  )
692
763
  backend.ensure_launched()
693
- logger.info("backend started and connected")
764
+ self._logger.info("backend started and connected")
694
765
 
695
766
  # resuming needs access to the server, check server_status()?
696
767
  run = Run(
697
768
  config=self.config,
698
- settings=self.settings,
769
+ settings=settings,
699
770
  sweep_config=self.sweep_config,
700
771
  launch_config=self.launch_config,
701
772
  )
@@ -708,18 +779,18 @@ class _WandbInit:
708
779
  hf_version = _huggingface_version()
709
780
  if hf_version:
710
781
  tel.huggingface_version = hf_version
711
- if self.settings._jupyter:
782
+ if settings._jupyter:
712
783
  tel.env.jupyter = True
713
- if self.settings._ipython:
784
+ if settings._ipython:
714
785
  tel.env.ipython = True
715
- if self.settings._colab:
786
+ if settings._colab:
716
787
  tel.env.colab = True
717
- if self.settings._kaggle:
788
+ if settings._kaggle:
718
789
  tel.env.kaggle = True
719
- if self.settings._windows:
790
+ if settings._windows:
720
791
  tel.env.windows = True
721
792
 
722
- if self.settings.launch:
793
+ if settings.launch:
723
794
  tel.feature.launch = True
724
795
 
725
796
  for module_name in telemetry.list_telemetry_imports(only_imported=True):
@@ -727,8 +798,8 @@ class _WandbInit:
727
798
 
728
799
  # probe the active start method
729
800
  active_start_method: str | None = None
730
- if self.settings.start_method == "thread":
731
- active_start_method = self.settings.start_method
801
+ if settings.start_method == "thread":
802
+ active_start_method = settings.start_method
732
803
  else:
733
804
  active_start_method = getattr(
734
805
  backend._multiprocessing, "get_start_method", lambda: None
@@ -746,7 +817,7 @@ class _WandbInit:
746
817
  if os.environ.get("PEX"):
747
818
  tel.env.pex = True
748
819
 
749
- if self.settings._aws_lambda:
820
+ if settings._aws_lambda:
750
821
  tel.env.aws_lambda = True
751
822
 
752
823
  if os.environ.get(wandb.env._DISABLE_SERVICE):
@@ -754,13 +825,13 @@ class _WandbInit:
754
825
 
755
826
  if service:
756
827
  tel.feature.service = True
757
- if self.settings.x_flow_control_disabled:
828
+ if settings.x_flow_control_disabled:
758
829
  tel.feature.flow_control_disabled = True
759
- if self.settings.x_flow_control_custom:
830
+ if settings.x_flow_control_custom:
760
831
  tel.feature.flow_control_custom = True
761
- if not self.settings.x_require_legacy_service:
832
+ if not settings.x_require_legacy_service:
762
833
  tel.feature.core = True
763
- if self.settings._shared:
834
+ if settings._shared:
764
835
  wandb.termwarn(
765
836
  "The `_shared` feature is experimental and may change. "
766
837
  "Please contact support@wandb.com for guidance and to report any issues."
@@ -769,7 +840,7 @@ class _WandbInit:
769
840
 
770
841
  tel.env.maybe_mp = _maybe_mp_process(backend)
771
842
 
772
- if not self.settings.label_disable:
843
+ if not settings.label_disable:
773
844
  if self.notebook:
774
845
  run._label_probe_notebook(self.notebook)
775
846
  else:
@@ -783,7 +854,7 @@ class _WandbInit:
783
854
  run=run,
784
855
  )
785
856
 
786
- logger.info("updated telemetry")
857
+ self._logger.info("updated telemetry")
787
858
 
788
859
  run._set_library(self._wl)
789
860
  run._set_backend(backend)
@@ -797,25 +868,27 @@ class _WandbInit:
797
868
  # Using GitRepo() blocks & can be slow, depending on user's current git setup.
798
869
  # We don't want to block run initialization/start request, so populate run's git
799
870
  # info beforehand.
800
- if not (self.settings.disable_git or self.settings.x_disable_machine_info):
871
+ if not (settings.disable_git or settings.x_disable_machine_info):
801
872
  run._populate_git_info()
802
873
 
803
874
  run_result: pb.RunUpdateResult | None = None
804
875
 
805
- if self.settings._offline:
876
+ if settings._offline:
806
877
  with telemetry.context(run=run) as tel:
807
878
  tel.feature.offline = True
808
879
 
809
- if self.settings.resume:
880
+ if settings.resume:
810
881
  wandb.termwarn(
811
882
  "`resume` will be ignored since W&B syncing is set to `offline`. "
812
883
  f"Starting a new run with run id {run.id}."
813
884
  )
814
885
  error: wandb.Error | None = None
815
886
 
816
- timeout = self.settings.init_timeout
887
+ timeout = settings.init_timeout
817
888
 
818
- logger.info(f"communicating run to backend with {timeout} second timeout")
889
+ self._logger.info(
890
+ f"communicating run to backend with {timeout} second timeout",
891
+ )
819
892
 
820
893
  run_init_handle = backend.interface.deliver_run(run)
821
894
  result = run_init_handle.wait(
@@ -842,7 +915,7 @@ class _WandbInit:
842
915
  error = ProtobufErrorHandler.to_exception(run_result.error)
843
916
 
844
917
  if error is not None:
845
- logger.error(f"encountered error: {error}")
918
+ self._logger.error(f"encountered error: {error}")
846
919
  if not service:
847
920
  # Shutdown the backend and get rid of the logger
848
921
  # we don't need to do console cleanup at this point
@@ -860,19 +933,19 @@ class _WandbInit:
860
933
  )
861
934
 
862
935
  if run_result.run.resumed:
863
- logger.info("run resumed")
936
+ self._logger.info("run resumed")
864
937
  with telemetry.context(run=run) as tel:
865
938
  tel.feature.resumed = run_result.run.resumed
866
939
  run._set_run_obj(run_result.run)
867
940
 
868
- logger.info("starting run threads in backend")
941
+ self._logger.info("starting run threads in backend")
869
942
  # initiate run (stats and metadata probing)
870
943
 
871
944
  if service:
872
- assert self.settings.run_id
945
+ assert settings.run_id
873
946
  service.inform_start(
874
- settings=self.settings.to_proto(),
875
- run_id=self.settings.run_id,
947
+ settings=settings.to_proto(),
948
+ run_id=settings.run_id,
876
949
  )
877
950
 
878
951
  assert backend.interface
@@ -889,11 +962,11 @@ class _WandbInit:
889
962
 
890
963
  run._handle_launch_artifact_overrides()
891
964
  if (
892
- self.settings.launch
893
- and self.settings.launch_config_path
894
- and os.path.exists(self.settings.launch_config_path)
965
+ settings.launch
966
+ and settings.launch_config_path
967
+ and os.path.exists(settings.launch_config_path)
895
968
  ):
896
- run.save(self.settings.launch_config_path)
969
+ run.save(settings.launch_config_path)
897
970
  # put artifacts in run config here
898
971
  # since doing so earlier will cause an error
899
972
  # as the run is not upserted
@@ -907,7 +980,7 @@ class _WandbInit:
907
980
 
908
981
  self.backend = backend
909
982
  run._on_start()
910
- logger.info("run started, returning control to user process")
983
+ self._logger.info("run started, returning control to user process")
911
984
  return run
912
985
 
913
986
 
@@ -938,10 +1011,7 @@ def _attach(
938
1011
  wandb._assert_is_user_process() # type: ignore
939
1012
 
940
1013
  _wl = wandb.setup()
941
-
942
- _set_logger(_wl._get_logger())
943
- if logger is None:
944
- raise UsageError("logger is not initialized")
1014
+ logger = _wl._get_logger()
945
1015
 
946
1016
  service = _wl.ensure_service()
947
1017
 
@@ -1276,27 +1346,36 @@ def init( # noqa: C901
1276
1346
  if resume_from is not None:
1277
1347
  init_settings.resume_from = resume_from # type: ignore
1278
1348
 
1349
+ wl: wandb_setup._WandbSetup | None = None
1350
+
1279
1351
  try:
1280
- wi = _WandbInit()
1352
+ wl = wandb.setup()
1353
+
1354
+ wi = _WandbInit(wl)
1355
+
1356
+ wi.maybe_login(init_settings)
1357
+ run_settings = wi.compute_run_settings(init_settings)
1358
+ wi.set_run_id(run_settings)
1359
+
1281
1360
  wi.setup(
1282
- init_settings=init_settings,
1361
+ settings=run_settings,
1283
1362
  config=config,
1284
1363
  config_exclude_keys=config_exclude_keys,
1285
1364
  config_include_keys=config_include_keys,
1286
- allow_val_change=allow_val_change,
1287
1365
  monitor_gym=monitor_gym,
1288
1366
  )
1289
- return wi.init()
1367
+
1368
+ return wi.init(run_settings)
1290
1369
 
1291
1370
  except KeyboardInterrupt as e:
1292
- if logger is not None:
1293
- logger.warning("interrupted", exc_info=e)
1371
+ if wl:
1372
+ wl._get_logger().warning("interrupted", exc_info=e)
1294
1373
 
1295
1374
  raise
1296
1375
 
1297
1376
  except Exception as e:
1298
- if logger is not None:
1299
- logger.exception("error in wandb.init()", exc_info=e)
1377
+ if wl:
1378
+ wl._get_logger().exception("error in wandb.init()", exc_info=e)
1300
1379
 
1301
1380
  # Need to build delay into this sentry capture because our exit hooks
1302
1381
  # mess with sentry's ability to send out errors before the program ends.
wandb/sdk/wandb_run.py CHANGED
@@ -29,7 +29,6 @@ import wandb.util
29
29
  from wandb import trigger
30
30
  from wandb._globals import _datatypes_set_callback
31
31
  from wandb.apis import internal, public
32
- from wandb.apis.internal import Api
33
32
  from wandb.apis.public import Api as PublicApi
34
33
  from wandb.errors import CommError, UnsupportedError, UsageError
35
34
  from wandb.errors.links import url_registry
@@ -1814,7 +1813,10 @@ class Run:
1814
1813
  examples = []
1815
1814
  for i in range(3):
1816
1815
  pixels = np.random.randint(
1817
- low=0, high=256, size=(100, 100, 3), dtype=np.uint8
1816
+ low=0,
1817
+ high=256,
1818
+ size=(100, 100, 3),
1819
+ dtype=np.uint8,
1818
1820
  )
1819
1821
  pil_image = PILImage.fromarray(pixels, mode="RGB")
1820
1822
  image = wandb.Image(pil_image, caption=f"random field {i}")
@@ -1831,7 +1833,10 @@ class Run:
1831
1833
  run = wandb.init()
1832
1834
  # axes are (time, channel, height, width)
1833
1835
  frames = np.random.randint(
1834
- low=0, high=256, size=(10, 3, 100, 100), dtype=np.uint8
1836
+ low=0,
1837
+ high=256,
1838
+ size=(10, 3, 100, 100),
1839
+ dtype=np.uint8,
1835
1840
  )
1836
1841
  run.log({"video": wandb.Video(frames, fps=4)})
1837
1842
  ```
@@ -3266,8 +3271,7 @@ class Run:
3266
3271
  is_user_created: bool = False,
3267
3272
  use_after_commit: bool = False,
3268
3273
  ) -> Artifact:
3269
- api = internal.Api()
3270
- if api.settings().get("anonymous") in ["allow", "must"]:
3274
+ if self._settings.anonymous in ["allow", "must"]:
3271
3275
  wandb.termwarn(
3272
3276
  "Artifacts logged anonymously cannot be claimed and expire after 7 days."
3273
3277
  )
@@ -3864,8 +3868,7 @@ class Run:
3864
3868
  f'{printer.emoji("rocket")} View run at {printer.link(run_url)}',
3865
3869
  )
3866
3870
 
3867
- # TODO(settings) use `wandb_settings` (if self.settings.anonymous in ["allow", "must"]:)
3868
- if run_name and Api().api.settings().get("anonymous") in ["allow", "must"]:
3871
+ if run_name and settings.anonymous in ["allow", "must"]:
3869
3872
  printer.display(
3870
3873
  (
3871
3874
  "Do NOT share these links with anyone."
@@ -34,14 +34,12 @@ from pydantic_core import SchemaValidator, core_schema
34
34
 
35
35
  import wandb
36
36
  from wandb import env, termwarn, util
37
- from wandb.apis.internal import Api
38
37
  from wandb.errors import UsageError
39
38
  from wandb.proto import wandb_settings_pb2
40
39
 
41
- from .lib import apikey, credentials, filesystem, ipython
40
+ from .lib import apikey, credentials, ipython
42
41
  from .lib.gitlib import GitRepo
43
42
  from .lib.run_moment import RunMoment
44
- from .lib.runid import generate_id
45
43
 
46
44
 
47
45
  def _path_convert(*args: str) -> str:
@@ -1154,29 +1152,6 @@ class Settings(BaseModel, validate_assignment=True):
1154
1152
 
1155
1153
  return settings_proto
1156
1154
 
1157
- def handle_resume_logic(self):
1158
- """Handle logic for resuming runs."""
1159
- # handle auto resume logic
1160
- if self.resume == "auto":
1161
- if os.path.exists(self.resume_fname):
1162
- with open(self.resume_fname) as f:
1163
- resume_run_id = json.load(f)["run_id"]
1164
- if self.run_id is None:
1165
- self.run_id = resume_run_id
1166
- elif self.run_id != resume_run_id:
1167
- wandb.termwarn(
1168
- "Tried to auto resume run with "
1169
- f"id {resume_run_id} but id {self.run_id} is set.",
1170
- )
1171
- if self.run_id is None:
1172
- self.run_id = generate_id()
1173
-
1174
- # persist run_id in case of failure
1175
- if self.resume == "auto" and self.resume_fname is not None:
1176
- filesystem.mkdir_exists_ok(self.wandb_dir)
1177
- with open(self.resume_fname, "w") as f:
1178
- f.write(json.dumps({"run_id": self.run_id}))
1179
-
1180
1155
  @staticmethod
1181
1156
  def validate_url(url: str) -> None:
1182
1157
  """Validate a URL string."""
@@ -1262,7 +1237,7 @@ class Settings(BaseModel, validate_assignment=True):
1262
1237
  def _get_url_query_string(self) -> str:
1263
1238
  """Construct the query string for project, run, and sweep URLs."""
1264
1239
  # TODO: remove dependency on Api()
1265
- if Api().settings().get("anonymous") not in ["allow", "must"]:
1240
+ if self.anonymous not in ["allow", "must"]:
1266
1241
  return ""
1267
1242
 
1268
1243
  api_key = apikey.api_key(settings=self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wandb
3
- Version: 0.19.2
3
+ Version: 0.19.3
4
4
  Summary: A CLI and library for interacting with the Weights & Biases API.
5
5
  Project-URL: Source, https://github.com/wandb/wandb
6
6
  Project-URL: Bug Reports, https://github.com/wandb/wandb/issues
@@ -1,6 +1,6 @@
1
1
  package_readme.md,sha256=U9047nyMDICgctm1HLm4HfXwFnFKsEn2m77hsYPUZ1I,4298
2
- wandb/__init__.py,sha256=iDFm6Xdx3kjLvr0RB6XXjuZU-HQk3tXRsKJ8_qeSipM,6988
3
- wandb/__init__.pyi,sha256=vZwj1Cmk9HSNo0zj5h084WSFg63X-EabSmgGhm48HIs,46886
2
+ wandb/__init__.py,sha256=5f1_Sih9Sxjo5YN6UOofmcFjW0XnL5FxgWk-saYyMhw,6988
3
+ wandb/__init__.pyi,sha256=__KjZYDXGiHshy_OUrsV7chJrIiOon8DuzRjM6ubHnc,47024
4
4
  wandb/__main__.py,sha256=gripuDgB7J8wMMeJt4CIBRjn1BMSFr5zvsrt585Pnj4,64
5
5
  wandb/_globals.py,sha256=CccwOAls5bxJArYHg12b08ZeKR8Qu9u57GtYWjBH0o0,702
6
6
  wandb/data_types.py,sha256=tjxcQ8padGuGxST192PyEDX_nhU__izHcAK-kaSyevI,2276
@@ -104,7 +104,7 @@ wandb/integration/lightning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
104
104
  wandb/integration/lightning/fabric/__init__.py,sha256=RFhr2VkC0D8b6bAXUMZzcVzqDQaoOozfP_HOogAWi9o,94
105
105
  wandb/integration/lightning/fabric/logger.py,sha256=ev8xFbCohaRp4MvrBn1x_5ypuvLe2FJdUWY7Jjw0ylk,27251
106
106
  wandb/integration/metaflow/__init__.py,sha256=nYn3ubiX9Ay6PFxr7r7F8Ia_2dLImb63rpYDmuDlkkQ,109
107
- wandb/integration/metaflow/metaflow.py,sha256=faj0W4clDGBX9cuoU1fqVeCM7qePwGp5N3A6mdfLYsc,11901
107
+ wandb/integration/metaflow/metaflow.py,sha256=qlzrdkTmT_KTg6sUE3PV8PStuZyFGYEdQzNNNil05jI,11804
108
108
  wandb/integration/openai/__init__.py,sha256=T6x9lIFfw2NzOSi46wi3otY_-DSwyMgnIjMIOIod7iU,66
109
109
  wandb/integration/openai/fine_tuning.py,sha256=w9_F3bLTG72KdNkD2rAPRdrq6rc58EtltFxwedyI690,18555
110
110
  wandb/integration/openai/openai.py,sha256=zGD1kj6yjDP1IfAAYRcltuXD5Bf569CSnMHMf4rDm54,496
@@ -203,14 +203,14 @@ wandb/sdk/__init__.py,sha256=N-GTAC0AzbZF2J8RzB33DTmYk9u-jubllCwvhWrPgsE,813
203
203
  wandb/sdk/wandb_alerts.py,sha256=SwBPBiXRxknMTMGbsVoMMWqWK65UWMcKAdTWZtdwAeo,193
204
204
  wandb/sdk/wandb_config.py,sha256=b7kxQVnIh5HCBZXb2pOGZ4c02xCVlW4IQiAu3N-8Opg,10856
205
205
  wandb/sdk/wandb_helper.py,sha256=IbJ7opO8UkfwCDekSjRYIrGBblUxnTPBfp1EdesfF4U,1824
206
- wandb/sdk/wandb_init.py,sha256=yQ8BthOAFOQaJKLFZhPc2KQxIgbA_60Hcfs60CpG7zA,53887
206
+ wandb/sdk/wandb_init.py,sha256=z19KqQWjmOcnswowWoq4VAHGalTmjLKwz1R-Rm1i-Bo,56484
207
207
  wandb/sdk/wandb_login.py,sha256=DP7nDUGx2UmqGRBrvTmcpvzRBVeRD0qEENtmu4sjDAQ,10966
208
208
  wandb/sdk/wandb_metadata.py,sha256=nT6TUF4Yh-ka3VQGyKd3y9MTEHJUgRVT4ICyfJkbHFo,20111
209
209
  wandb/sdk/wandb_metric.py,sha256=a3GiQXr6H18m81uobYjlJaC8CL8iANzI42qxkxfZsDs,3268
210
210
  wandb/sdk/wandb_require.py,sha256=Y0ib8h27__t7hXos1F2srfsQzVfzH4BB6wq8E1aRbRA,2950
211
211
  wandb/sdk/wandb_require_helpers.py,sha256=ZmKv5aXXHDTTU6nYHMLKW4_pt9X-PlaMtbRJl77kHX8,1331
212
- wandb/sdk/wandb_run.py,sha256=_hH8Pe-lEZE_FiPHYmOrQxdGfs4V2PuFOu0SD5jczlg,155746
213
- wandb/sdk/wandb_settings.py,sha256=jvD7tTJ9J-aQvsmIz8UdVPS2Qd_zpSW3aDP-82mT_Hk,48386
212
+ wandb/sdk/wandb_run.py,sha256=eI6WIi2pmkBkP5aMgscMU9C94PjGVknEYQvVPlC-YDM,155668
213
+ wandb/sdk/wandb_settings.py,sha256=gXZydMDYH8OLcAoK78mA4naRqBA2aKlsIGKn3i4OC0s,47290
214
214
  wandb/sdk/wandb_setup.py,sha256=7j3UBiqm8x7f4JsFPX5jR19wNRSRvf77TIyncd0HpJg,13014
215
215
  wandb/sdk/wandb_summary.py,sha256=yQdOVIPrZaZanhBQ7yuSfPLX0x6dxwkN_KAn4SgjSZU,4536
216
216
  wandb/sdk/wandb_sweep.py,sha256=Sg_JqxVzmjUBvii41azpdr-c6RPwHOBnSha8k7jrRhk,4028
@@ -816,8 +816,8 @@ wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/importlib2.py,sha256=cJIaJ2EQso
816
816
  wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/platform.py,sha256=UORYTNVcUSE2NpFcq9UVLIS-tsS0TS_Qw8akhKxn2eY,1506
817
817
  wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/unicode_paths.py,sha256=UWX8DB97ygkEeSxWQUYCHR4MahNilux7vl5TCTQtPPk,2190
818
818
  wandb/vendor/watchdog_0_9_0/wandb_watchdog/utils/win32stat.py,sha256=ZOevOTbSo8NRiIxkuBVGaG4yigWnPoO0goxAi-jsBkM,3828
819
- wandb-0.19.2.dist-info/METADATA,sha256=IpB8Qg0TddJcHZwNDfVMZPAOLEDw10Lx1KyDY944YDM,10282
820
- wandb-0.19.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
821
- wandb-0.19.2.dist-info/entry_points.txt,sha256=v4FCOZ9gW7Pc6KLsmgQqpCiKTrA1wh2XHmNf-NUP1-I,67
822
- wandb-0.19.2.dist-info/licenses/LICENSE,sha256=izOKRJpGOx1PrJiGOKR0HsNdlB5JdH2d0Z4P7a7ssTc,1081
823
- wandb-0.19.2.dist-info/RECORD,,
819
+ wandb-0.19.3.dist-info/METADATA,sha256=AGD2Iwy-cUjmtannnNpN4Nh9wQAjRZw7WgFow2-DvwI,10282
820
+ wandb-0.19.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
821
+ wandb-0.19.3.dist-info/entry_points.txt,sha256=v4FCOZ9gW7Pc6KLsmgQqpCiKTrA1wh2XHmNf-NUP1-I,67
822
+ wandb-0.19.3.dist-info/licenses/LICENSE,sha256=izOKRJpGOx1PrJiGOKR0HsNdlB5JdH2d0Z4P7a7ssTc,1081
823
+ wandb-0.19.3.dist-info/RECORD,,
File without changes