wandb 0.18.6__py3-none-win_amd64.whl → 0.19.0__py3-none-win_amd64.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 (120) hide show
  1. package_readme.md +8 -0
  2. wandb/__init__.py +5 -7
  3. wandb/__init__.pyi +51 -30
  4. wandb/analytics/sentry.py +4 -10
  5. wandb/apis/importers/internals/internal.py +6 -6
  6. wandb/apis/importers/internals/protocols.py +11 -7
  7. wandb/apis/public/api.py +5 -1
  8. wandb/apis/public/jobs.py +1 -7
  9. wandb/apis/public/reports.py +6 -17
  10. wandb/apis/public/runs.py +12 -10
  11. wandb/bin/gpu_stats.exe +0 -0
  12. wandb/bin/wandb-core +0 -0
  13. wandb/cli/cli.py +9 -45
  14. wandb/env.py +3 -5
  15. wandb/errors/links.py +1 -1
  16. wandb/errors/term.py +1 -6
  17. wandb/filesync/dir_watcher.py +3 -3
  18. wandb/filesync/step_upload.py +2 -5
  19. wandb/integration/fastai/__init__.py +1 -6
  20. wandb/integration/gym/__init__.py +1 -7
  21. wandb/integration/keras/callbacks/metrics_logger.py +1 -8
  22. wandb/integration/keras/callbacks/model_checkpoint.py +1 -8
  23. wandb/integration/keras/keras.py +3 -5
  24. wandb/integration/lightgbm/__init__.py +1 -1
  25. wandb/integration/sb3/sb3.py +1 -7
  26. wandb/integration/sklearn/utils.py +1 -1
  27. wandb/integration/tensorboard/log.py +1 -2
  28. wandb/integration/torch/wandb_torch.py +1 -1
  29. wandb/integration/ultralytics/bbox_utils.py +9 -2
  30. wandb/jupyter.py +4 -4
  31. wandb/proto/v3/wandb_internal_pb2.py +31 -31
  32. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  33. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  34. wandb/proto/v4/wandb_internal_pb2.py +31 -31
  35. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  36. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  37. wandb/proto/v5/wandb_internal_pb2.py +31 -31
  38. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  39. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  40. wandb/proto/wandb_deprecated.py +3 -11
  41. wandb/proto/wandb_generate_deprecated.py +3 -7
  42. wandb/sdk/artifacts/artifact.py +3 -11
  43. wandb/sdk/artifacts/artifact_file_cache.py +2 -5
  44. wandb/sdk/artifacts/artifact_saver.py +2 -6
  45. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +2 -4
  46. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +2 -4
  47. wandb/sdk/artifacts/storage_handlers/s3_handler.py +2 -4
  48. wandb/sdk/backend/backend.py +1 -1
  49. wandb/sdk/data_types/base_types/wb_value.py +20 -10
  50. wandb/sdk/data_types/histogram.py +1 -3
  51. wandb/sdk/data_types/object_3d.py +2 -6
  52. wandb/sdk/data_types/table.py +1 -1
  53. wandb/sdk/data_types/utils.py +1 -2
  54. wandb/sdk/data_types/video.py +15 -4
  55. wandb/sdk/integration_utils/auto_logging.py +1 -8
  56. wandb/sdk/interface/interface.py +12 -5
  57. wandb/sdk/interface/interface_queue.py +0 -6
  58. wandb/sdk/interface/interface_shared.py +9 -0
  59. wandb/sdk/interface/router.py +1 -2
  60. wandb/sdk/interface/router_queue.py +0 -3
  61. wandb/sdk/interface/router_relay.py +0 -2
  62. wandb/sdk/internal/file_stream.py +1 -4
  63. wandb/sdk/internal/flow_control.py +1 -1
  64. wandb/sdk/internal/handler.py +8 -5
  65. wandb/sdk/internal/internal.py +3 -17
  66. wandb/sdk/internal/internal_api.py +3 -10
  67. wandb/sdk/internal/internal_util.py +0 -3
  68. wandb/sdk/internal/job_builder.py +20 -12
  69. wandb/sdk/internal/progress.py +1 -5
  70. wandb/sdk/internal/sender.py +9 -15
  71. wandb/sdk/internal/settings_static.py +4 -10
  72. wandb/sdk/internal/system/assets/cpu.py +2 -2
  73. wandb/sdk/internal/system/assets/disk.py +3 -3
  74. wandb/sdk/internal/system/assets/gpu.py +7 -7
  75. wandb/sdk/internal/system/assets/gpu_amd.py +1 -7
  76. wandb/sdk/internal/system/assets/interfaces.py +11 -13
  77. wandb/sdk/internal/system/assets/ipu.py +1 -1
  78. wandb/sdk/internal/system/assets/memory.py +2 -2
  79. wandb/sdk/internal/system/assets/open_metrics.py +2 -8
  80. wandb/sdk/internal/system/assets/trainium.py +3 -9
  81. wandb/sdk/internal/system/system_info.py +14 -13
  82. wandb/sdk/internal/system/system_monitor.py +5 -12
  83. wandb/sdk/internal/tb_watcher.py +1 -1
  84. wandb/sdk/internal/writer.py +2 -4
  85. wandb/sdk/launch/__init__.py +2 -1
  86. wandb/sdk/launch/agent/run_queue_item_file_saver.py +1 -7
  87. wandb/sdk/launch/create_job.py +2 -3
  88. wandb/sdk/launch/runner/abstract.py +1 -6
  89. wandb/sdk/launch/runner/kubernetes_monitor.py +2 -4
  90. wandb/sdk/lib/apikey.py +2 -6
  91. wandb/sdk/lib/fsm.py +12 -6
  92. wandb/sdk/lib/ipython.py +1 -6
  93. wandb/sdk/lib/module.py +0 -3
  94. wandb/sdk/lib/progress.py +2 -3
  95. wandb/sdk/lib/run_moment.py +1 -7
  96. wandb/sdk/lib/server.py +10 -24
  97. wandb/sdk/lib/sock_client.py +0 -5
  98. wandb/sdk/service/server.py +3 -12
  99. wandb/sdk/service/server_sock.py +0 -2
  100. wandb/sdk/service/service.py +5 -5
  101. wandb/sdk/wandb_init.py +215 -166
  102. wandb/sdk/wandb_login.py +17 -27
  103. wandb/sdk/wandb_run.py +129 -161
  104. wandb/sdk/wandb_settings.py +978 -1760
  105. wandb/sdk/wandb_setup.py +87 -94
  106. wandb/sdk/wandb_watch.py +1 -1
  107. wandb/sync/sync.py +1 -2
  108. wandb/util.py +7 -40
  109. wandb/wandb_controller.py +10 -12
  110. {wandb-0.18.6.dist-info → wandb-0.19.0.dist-info}/METADATA +14 -4
  111. {wandb-0.18.6.dist-info → wandb-0.19.0.dist-info}/RECORD +114 -120
  112. {wandb-0.18.6.dist-info → wandb-0.19.0.dist-info}/WHEEL +1 -1
  113. wandb/integration/magic.py +0 -556
  114. wandb/magic.py +0 -3
  115. wandb/sdk/lib/_settings_toposort_generate.py +0 -159
  116. wandb/sdk/lib/_settings_toposort_generated.py +0 -250
  117. wandb/sdk/lib/reporting.py +0 -99
  118. wandb/sdk/lib/tracelog.py +0 -255
  119. {wandb-0.18.6.dist-info → wandb-0.19.0.dist-info}/entry_points.txt +0 -0
  120. {wandb-0.18.6.dist-info → wandb-0.19.0.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/wandb_init.py CHANGED
@@ -20,6 +20,11 @@ import tempfile
20
20
  import time
21
21
  from typing import TYPE_CHECKING, Any, Sequence
22
22
 
23
+ if sys.version_info >= (3, 11):
24
+ from typing import Self
25
+ else:
26
+ from typing_extensions import Self
27
+
23
28
  import wandb
24
29
  import wandb.env
25
30
  from wandb import trigger
@@ -27,27 +32,18 @@ from wandb.errors import CommError, Error, UsageError
27
32
  from wandb.errors.links import url_registry
28
33
  from wandb.errors.util import ProtobufErrorHandler
29
34
  from wandb.integration import sagemaker
30
- from wandb.integration.magic import magic_install
31
35
  from wandb.sdk.lib import runid
32
36
  from wandb.sdk.lib.paths import StrPath
33
37
  from wandb.util import _is_artifact_representation
34
38
 
35
39
  from . import wandb_login, wandb_setup
36
40
  from .backend.backend import Backend
37
- from .lib import (
38
- SummaryDisabled,
39
- filesystem,
40
- ipython,
41
- module,
42
- printer,
43
- reporting,
44
- telemetry,
45
- )
41
+ from .lib import SummaryDisabled, filesystem, ipython, module, printer, telemetry
46
42
  from .lib.deprecate import Deprecated, deprecate
47
43
  from .lib.mailbox import Mailbox, MailboxProgress
48
44
  from .wandb_helper import parse_config
49
45
  from .wandb_run import Run, TeardownHook, TeardownStage
50
- from .wandb_settings import Settings, Source
46
+ from .wandb_settings import Settings
51
47
 
52
48
  if TYPE_CHECKING:
53
49
  from wandb.proto import wandb_internal_pb2 as pb
@@ -121,7 +117,7 @@ class _WandbInit:
121
117
 
122
118
  def __init__(self) -> None:
123
119
  self.kwargs = None
124
- self.setting: Settings | None = None
120
+ self.settings: Settings | None = None
125
121
  self.sweep_config: dict[str, Any] = {}
126
122
  self.launch_config: dict[str, Any] = {}
127
123
  self.config: dict[str, Any] = {}
@@ -130,7 +126,6 @@ class _WandbInit:
130
126
 
131
127
  self._teardown_hooks: list[TeardownHook] = []
132
128
  self._wl: wandb_setup._WandbSetup | None = None
133
- self._reporter: wandb.sdk.lib.reporting.Reporter | None = None
134
129
  self.notebook: wandb.jupyter.Notebook | None = None # type: ignore
135
130
  self.printer = printer.new_printer()
136
131
 
@@ -138,71 +133,84 @@ class _WandbInit:
138
133
 
139
134
  self.deprecated_features_used: dict[str, str] = dict()
140
135
 
141
- def setup(self, kwargs: Any) -> None: # noqa: C901
142
- """Complete setup for `wandb.init()`.
136
+ def warn_env_vars_change_after_setup(self) -> None:
137
+ """Warn if environment variables change after wandb singleton is initialized.
143
138
 
144
- This includes parsing all arguments, applying them with settings and enabling logging.
139
+ Any settings from environment variables set after the singleton is initialized
140
+ (via login/setup/etc.) will be ignored.
145
141
  """
146
- self.kwargs = kwargs
147
-
148
- # if the user ran, for example, `wandb.login(`) before `wandb.init()`,
149
- # the singleton will already be set up and so if e.g. env vars are set
150
- # in between, they will be ignored, which we need to inform the user about.
151
142
  singleton = wandb_setup._WandbSetup._instance
152
- if singleton is not None:
153
- exclude_env_vars = {"WANDB_SERVICE", "WANDB_KUBEFLOW_URL"}
154
- # check if environment variables have changed
155
- singleton_env = {
156
- k: v
157
- for k, v in singleton._environ.items()
158
- if k.startswith("WANDB_") and k not in exclude_env_vars
159
- }
160
- os_env = {
161
- k: v
162
- for k, v in os.environ.items()
163
- if k.startswith("WANDB_") and k not in exclude_env_vars
164
- }
165
- if set(singleton_env.keys()) != set(os_env.keys()) or set(
166
- singleton_env.values()
167
- ) != set(os_env.values()):
168
- line = (
169
- "Changes to your `wandb` environment variables will be ignored "
170
- "because your `wandb` session has already started. "
171
- "For more information on how to modify your settings with "
172
- "`wandb.init()` arguments, please refer to "
173
- f"{self.printer.link(url_registry.url('wandb-init'), 'the W&B docs')}."
174
- )
175
- self.printer.display(line, level="warn")
176
-
177
- # we add this logic to be backward compatible with the old behavior of disable
178
- # where it would disable the service if the mode was set to disabled
179
- # TODO: use the regular settins object to handle this
180
- mode = kwargs.get("mode")
181
- settings_mode = (kwargs.get("settings") or {}).get("mode") or os.environ.get(
182
- wandb.env.MODE
183
- )
184
- settings__disable_service = (kwargs.get("settings") or {}).get(
185
- "_disable_service"
186
- ) or os.environ.get(wandb.env._DISABLE_SERVICE)
143
+ if singleton is None:
144
+ return
187
145
 
188
- setup_settings = {
189
- "mode": mode or settings_mode,
190
- "_disable_service": settings__disable_service,
146
+ exclude_env_vars = {"WANDB_SERVICE", "WANDB_KUBEFLOW_URL"}
147
+ # check if environment variables have changed
148
+ singleton_env = {
149
+ k: v
150
+ for k, v in singleton._environ.items()
151
+ if k.startswith("WANDB_") and k not in exclude_env_vars
152
+ }
153
+ os_env = {
154
+ k: v
155
+ for k, v in os.environ.items()
156
+ if k.startswith("WANDB_") and k not in exclude_env_vars
191
157
  }
158
+ if set(singleton_env.keys()) != set(os_env.keys()) or set(
159
+ singleton_env.values()
160
+ ) != set(os_env.values()):
161
+ line = (
162
+ "Changes to your `wandb` environment variables will be ignored "
163
+ "because your `wandb` session has already started. "
164
+ "For more information on how to modify your settings with "
165
+ "`wandb.init()` arguments, please refer to "
166
+ f"{self.printer.link(url_registry.url('wandb-init'), 'the W&B docs')}."
167
+ )
168
+ self.printer.display(line, level="warn")
169
+
170
+ def setup( # noqa: C901
171
+ self,
172
+ init_settings: Settings,
173
+ config: dict | str | None = None,
174
+ config_exclude_keys: list[str] | None = None,
175
+ config_include_keys: list[str] | None = None,
176
+ allow_val_change: bool | None = None,
177
+ monitor_gym: bool | None = None,
178
+ ) -> None:
179
+ """Complete setup for `wandb.init()`.
180
+
181
+ This includes parsing all arguments, applying them with settings and enabling logging.
182
+ """
183
+ self.warn_env_vars_change_after_setup()
184
+
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
+ )
192
195
 
193
196
  self._wl = wandb_setup.setup(settings=setup_settings)
194
- # Make sure we have a logger setup (might be an early logger)
197
+
195
198
  assert self._wl is not None
196
199
  _set_logger(self._wl._get_logger())
197
200
 
198
201
  # Start with settings from wandb library singleton
199
- settings: Settings = self._wl.settings.copy()
202
+ settings = self._wl.settings.copy()
200
203
 
201
- settings_param = kwargs.pop("settings", None)
202
- if settings_param is not None and isinstance(settings_param, (Settings, dict)):
203
- settings.update(settings_param, source=Source.INIT)
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()
204
211
 
205
- self._reporter = reporting.setup_reporter(settings=settings)
212
+ # Apply settings from wandb.init() call
213
+ settings.update_from_settings(init_settings)
206
214
 
207
215
  sagemaker_config: dict = (
208
216
  dict() if settings.sagemaker_disable else sagemaker.parse_sm_config()
@@ -213,42 +221,35 @@ class _WandbInit:
213
221
  if sagemaker_env:
214
222
  if sagemaker_api_key:
215
223
  sagemaker_env["WANDB_API_KEY"] = sagemaker_api_key
216
- settings._apply_env_vars(sagemaker_env)
224
+ settings.update_from_env_vars(sagemaker_env)
217
225
  wandb.setup(settings=settings)
218
- settings.update(sagemaker_run, source=Source.SETUP)
226
+ settings.update_from_dict(sagemaker_run)
219
227
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
220
228
  tel.feature.sagemaker = True
221
229
 
222
230
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
223
- if kwargs.get("config"):
231
+ if config is not None:
224
232
  tel.feature.set_init_config = True
225
- if kwargs.get("name"):
233
+ if settings.run_name is not None:
226
234
  tel.feature.set_init_name = True
227
- if kwargs.get("id"):
235
+ if settings.run_id is not None:
228
236
  tel.feature.set_init_id = True
229
- if kwargs.get("tags"):
237
+ if settings.run_tags is not None:
230
238
  tel.feature.set_init_tags = True
231
239
 
232
- # Remove parameters that are not part of settings
233
- init_config = kwargs.pop("config", None) or dict()
234
-
235
- # todo: remove this once officially deprecated
236
- deprecated_kwargs = {
237
- "config_include_keys": (
238
- "Use `config=wandb.helper.parse_config(config_object, include=('key',))` instead."
239
- ),
240
- "config_exclude_keys": (
240
+ # TODO: remove this once officially deprecated
241
+ if config_exclude_keys:
242
+ self.deprecated_features_used["config_exclude_keys"] = (
241
243
  "Use `config=wandb.helper.parse_config(config_object, exclude=('key',))` instead."
242
- ),
243
- }
244
- for deprecated_kwarg, msg in deprecated_kwargs.items():
245
- if kwargs.get(deprecated_kwarg):
246
- self.deprecated_features_used[deprecated_kwarg] = msg
247
-
248
- init_config = parse_config(
249
- init_config,
250
- include=kwargs.pop("config_include_keys", None),
251
- exclude=kwargs.pop("config_exclude_keys", None),
244
+ )
245
+ if config_include_keys:
246
+ self.deprecated_features_used["config_include_keys"] = (
247
+ "Use `config=wandb.helper.parse_config(config_object, include=('key',))` instead."
248
+ )
249
+ config = parse_config(
250
+ config or dict(),
251
+ include=config_include_keys,
252
+ exclude=config_exclude_keys,
252
253
  )
253
254
 
254
255
  # merge config with sweep or sagemaker (or config file)
@@ -259,19 +260,18 @@ class _WandbInit:
259
260
  for config_data in (
260
261
  sagemaker_config,
261
262
  self._wl._config,
262
- init_config,
263
+ config,
263
264
  ):
264
265
  if not config_data:
265
266
  continue
266
267
  # split out artifacts, since when inserted into
267
268
  # config they will trigger use_artifact
268
269
  # but the run is not yet upserted
269
- self._split_artifacts_from_config(config_data, self.config)
270
+ self._split_artifacts_from_config(config_data, self.config) # type: ignore
270
271
 
271
272
  if sweep_config:
272
273
  self._split_artifacts_from_config(sweep_config, self.sweep_config)
273
274
 
274
- monitor_gym = kwargs.pop("monitor_gym", None)
275
275
  if monitor_gym and len(wandb.patched["gym"]) == 0:
276
276
  wandb.gym.monitor() # type: ignore
277
277
 
@@ -279,53 +279,52 @@ class _WandbInit:
279
279
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
280
280
  tel.feature.tensorboard_patch = True
281
281
 
282
- tensorboard = kwargs.pop("tensorboard", None)
283
- sync_tensorboard = kwargs.pop("sync_tensorboard", None)
284
- if tensorboard or sync_tensorboard:
282
+ if settings.sync_tensorboard:
285
283
  if len(wandb.patched["tensorboard"]) == 0:
286
284
  wandb.tensorboard.patch() # type: ignore
287
285
  with telemetry.context(obj=self._init_telemetry_obj) as tel:
288
286
  tel.feature.tensorboard_sync = True
289
287
 
290
- magic = kwargs.get("magic")
291
- if magic not in (None, False):
292
- magic_install(kwargs)
293
-
294
- # handle login related parameters as these are applied to global state
295
- init_settings = {
296
- key: kwargs[key]
297
- for key in ["anonymous", "force", "mode", "resume"]
298
- if kwargs.get(key) is not None
299
- }
300
- if init_settings:
301
- settings.update(init_settings, source=Source.INIT)
302
-
303
288
  if not settings._offline and not settings._noop:
304
289
  wandb_login._login(
305
- anonymous=kwargs.pop("anonymous", None),
306
- force=kwargs.pop("force", None),
290
+ anonymous=settings.anonymous,
291
+ force=settings.force,
307
292
  _disable_warning=True,
308
293
  _silent=settings.quiet or settings.silent,
309
- _entity=kwargs.get("entity") or settings.entity,
294
+ _entity=settings.entity,
310
295
  )
311
296
 
312
297
  # apply updated global state after login was handled
313
298
  wl = wandb.setup()
314
299
  assert wl is not None
315
- settings._apply_settings(wl.settings)
300
+ login_settings = {
301
+ k: v
302
+ 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,
308
+ }.items()
309
+ if v is not None
310
+ }
311
+ if login_settings:
312
+ settings.update_from_dict(login_settings)
313
+
314
+ # handle custom resume logic
315
+ settings.handle_resume_logic()
316
316
 
317
317
  # get status of code saving before applying user settings
318
318
  save_code_pre_user_settings = settings.save_code
319
-
320
- settings._apply_init(kwargs)
321
319
  if not settings._offline and not settings._noop:
322
320
  user_settings = self._wl._load_user_settings()
323
- settings._apply_user(user_settings)
321
+ if user_settings is not None:
322
+ settings.update_from_dict(user_settings)
324
323
 
325
324
  # ensure that user settings don't set saving to true
326
325
  # if user explicitly set these to false in UI
327
326
  if save_code_pre_user_settings is False:
328
- settings.update({"save_code": False}, source=Source.INIT)
327
+ settings.save_code = False
329
328
 
330
329
  # TODO: remove this once we refactor the client. This is a temporary
331
330
  # fix to make sure that we use the same project name for wandb-core.
@@ -333,11 +332,9 @@ class _WandbInit:
333
332
  # avoid failure cases in other parts of the code that will be
334
333
  # removed with the switch to wandb-core.
335
334
  if settings.project is None:
336
- project = wandb.util.auto_project_name(settings.program)
337
- settings.update({"project": project}, source=Source.INIT)
335
+ settings.project = wandb.util.auto_project_name(settings.program)
338
336
 
339
- # TODO(jhr): should this be moved? probably.
340
- settings._set_run_start_time(source=Source.INIT)
337
+ settings.x_start_time = time.time()
341
338
 
342
339
  if not settings._noop:
343
340
  self._log_setup(settings)
@@ -350,8 +347,6 @@ class _WandbInit:
350
347
 
351
348
  self.settings = settings
352
349
 
353
- # self.settings.freeze()
354
-
355
350
  def teardown(self) -> None:
356
351
  # TODO: currently this is only called on failed wandb.init attempts
357
352
  # normally this happens on the run object
@@ -417,7 +412,7 @@ class _WandbInit:
417
412
  return
418
413
 
419
414
  pid = os.getpid()
420
- tmp_name = os.path.join(base, "%s.%d" % (name, pid))
415
+ tmp_name = os.path.join(base, f"{name}.{pid}")
421
416
 
422
417
  if delete:
423
418
  try:
@@ -543,7 +538,9 @@ class _WandbInit:
543
538
  The returned Run object has all expected attributes and methods, but they are
544
539
  no-op versions that don't perform any actual logging or communication.
545
540
  """
546
- drun = Run(settings=Settings(mode="disabled", files_dir=tempfile.gettempdir()))
541
+ drun = Run(
542
+ settings=Settings(mode="disabled", x_files_dir=tempfile.gettempdir())
543
+ )
547
544
  # config and summary objects
548
545
  drun._config = wandb.sdk.wandb_config.Config()
549
546
  drun._config.update(self.sweep_config)
@@ -564,12 +561,10 @@ class _WandbInit:
564
561
  "link_artifact",
565
562
  "link_model",
566
563
  "use_artifact",
567
- "log_artifact",
568
564
  "log_code",
569
565
  "log_model",
570
566
  "use_model",
571
567
  "mark_preempting",
572
- "plot_table",
573
568
  "restore",
574
569
  "status",
575
570
  "watch",
@@ -578,6 +573,32 @@ class _WandbInit:
578
573
  "_finish",
579
574
  ):
580
575
  setattr(drun, symbol, lambda *_, **__: None) # type: ignore
576
+
577
+ class _ChainableNoOp:
578
+ """An object that allows chaining arbitrary attributes and method calls."""
579
+
580
+ def __getattr__(self, _: str) -> Self:
581
+ return self
582
+
583
+ def __call__(self, *_: Any, **__: Any) -> Self:
584
+ return self
585
+
586
+ class _ChainableNoOpField:
587
+ # This is used to chain arbitrary attributes and method calls.
588
+ # For example, `run.log_artifact().state` will work in disabled mode.
589
+ def __init__(self) -> None:
590
+ self._value = None
591
+
592
+ def __set__(self, instance: Any, value: Any) -> None:
593
+ self._value = value
594
+
595
+ def __get__(self, instance: Any, owner: type) -> Any:
596
+ return _ChainableNoOp() if (self._value is None) else self._value
597
+
598
+ def __call__(self, *args: Any, **kwargs: Any) -> _ChainableNoOp:
599
+ return _ChainableNoOp()
600
+
601
+ drun.log_artifact = _ChainableNoOpField()
581
602
  # attributes
582
603
  drun._backend = None
583
604
  drun._step = 0
@@ -601,7 +622,6 @@ class _WandbInit:
601
622
  use_artifact=drun.use_artifact,
602
623
  log_artifact=drun.log_artifact,
603
624
  define_metric=drun.define_metric,
604
- plot_table=drun.plot_table,
605
625
  alert=drun.alert,
606
626
  watch=drun.watch,
607
627
  unwatch=drun.unwatch,
@@ -617,11 +637,10 @@ class _WandbInit:
617
637
  if logger is None:
618
638
  raise RuntimeError("Logger not initialized")
619
639
  logger.info("calling init triggers")
620
- trigger.call("on_init", **self.kwargs) # type: ignore
640
+ trigger.call("on_init")
621
641
 
622
642
  assert self.settings is not None
623
643
  assert self._wl is not None
624
- assert self._reporter is not None
625
644
 
626
645
  logger.info(
627
646
  f"wandb.init called with sweep_config: {self.sweep_config}\nconfig: {self.config}"
@@ -673,7 +692,7 @@ class _WandbInit:
673
692
  logger.info("sending inform_init request")
674
693
  service.inform_init(
675
694
  settings=self.settings.to_proto(),
676
- run_id=self.settings.run_id,
695
+ run_id=self.settings.run_id, # type: ignore
677
696
  )
678
697
 
679
698
  mailbox = Mailbox()
@@ -684,8 +703,6 @@ class _WandbInit:
684
703
  )
685
704
  backend.ensure_launched()
686
705
  logger.info("backend started and connected")
687
- # Make sure we are logged in
688
- # wandb_login._login(_backend=backend, _settings=self.settings)
689
706
 
690
707
  # resuming needs access to the server, check server_status()?
691
708
  run = Run(
@@ -749,11 +766,11 @@ class _WandbInit:
749
766
 
750
767
  if service:
751
768
  tel.feature.service = True
752
- if self.settings._flow_control_disabled:
769
+ if self.settings.x_flow_control_disabled:
753
770
  tel.feature.flow_control_disabled = True
754
- if self.settings._flow_control_custom:
771
+ if self.settings.x_flow_control_custom:
755
772
  tel.feature.flow_control_custom = True
756
- if not self.settings._require_legacy_service:
773
+ if not self.settings.x_require_legacy_service:
757
774
  tel.feature.core = True
758
775
  if self.settings._shared:
759
776
  wandb.termwarn(
@@ -782,7 +799,6 @@ class _WandbInit:
782
799
 
783
800
  run._set_library(self._wl)
784
801
  run._set_backend(backend)
785
- run._set_reporter(self._reporter)
786
802
  run._set_teardown_hooks(self._teardown_hooks)
787
803
 
788
804
  backend._hack_set_run(run)
@@ -793,7 +809,7 @@ class _WandbInit:
793
809
  # Using GitRepo() blocks & can be slow, depending on user's current git setup.
794
810
  # We don't want to block run initialization/start request, so populate run's git
795
811
  # info beforehand.
796
- if not self.settings.disable_git:
812
+ if not (self.settings.disable_git or self.settings.x_disable_machine_info):
797
813
  run._populate_git_info()
798
814
 
799
815
  run_result: pb.RunUpdateResult | None = None
@@ -859,7 +875,6 @@ class _WandbInit:
859
875
  logger.info("run resumed")
860
876
  with telemetry.context(run=run) as tel:
861
877
  tel.feature.resumed = run_result.run.resumed
862
-
863
878
  run._set_run_obj(run_result.run)
864
879
 
865
880
  run._on_init()
@@ -868,6 +883,7 @@ class _WandbInit:
868
883
  # initiate run (stats and metadata probing)
869
884
 
870
885
  if service:
886
+ assert self.settings.run_id
871
887
  service.inform_start(
872
888
  settings=self.settings.to_proto(),
873
889
  run_id=self.settings.run_id,
@@ -905,8 +921,6 @@ class _WandbInit:
905
921
  run.use_artifact(job_artifact)
906
922
 
907
923
  self.backend = backend
908
- assert self._reporter
909
- self._reporter.set_context(run=run)
910
924
  run._on_start()
911
925
  logger.info("run started, returning control to user process")
912
926
  return run
@@ -956,14 +970,12 @@ def _attach(
956
970
 
957
971
  settings: Settings = copy.copy(_wl._settings)
958
972
 
959
- settings.update(
973
+ settings.update_from_dict(
960
974
  {
961
975
  "run_id": attach_id,
962
- "_start_time": attach_settings._start_time.value,
963
- "_start_datetime": attach_settings._start_datetime.value,
964
- "_offline": attach_settings._offline.value,
965
- },
966
- source=Source.INIT,
976
+ "x_start_time": attach_settings.x_start_time.value,
977
+ "mode": attach_settings.mode.value,
978
+ }
967
979
  )
968
980
 
969
981
  # TODO: consolidate this codepath with wandb.init()
@@ -998,18 +1010,17 @@ def _attach(
998
1010
  return run
999
1011
 
1000
1012
 
1001
- def init(
1013
+ def init( # noqa: C901
1002
1014
  job_type: str | None = None,
1003
1015
  dir: StrPath | None = None,
1004
1016
  config: dict | str | None = None,
1005
1017
  project: str | None = None,
1006
1018
  entity: str | None = None,
1007
1019
  reinit: bool | None = None,
1008
- tags: Sequence | None = None,
1020
+ tags: Sequence[str] | None = None,
1009
1021
  group: str | None = None,
1010
1022
  name: str | None = None,
1011
1023
  notes: str | None = None,
1012
- magic: dict | str | bool | None = None,
1013
1024
  config_exclude_keys: list[str] | None = None,
1014
1025
  config_include_keys: list[str] | None = None,
1015
1026
  anonymous: str | None = None,
@@ -1148,10 +1159,6 @@ def init(
1148
1159
  for more.
1149
1160
  reinit: (bool, optional) Allow multiple `wandb.init()` calls in the same
1150
1161
  process. (default: `False`)
1151
- magic: (bool, dict, or str, optional) The bool controls whether we try to
1152
- auto-instrument your script, capturing basic details of your run
1153
- without you having to add more wandb code. (default: `False`)
1154
- You can also pass a dict, json string, or yaml filename.
1155
1162
  config_exclude_keys: (list, optional) string keys to exclude from
1156
1163
  `wandb.config`.
1157
1164
  config_include_keys: (list, optional) string keys to include in
@@ -1238,21 +1245,63 @@ def init(
1238
1245
  """
1239
1246
  wandb._assert_is_user_process() # type: ignore
1240
1247
 
1241
- kwargs = dict(locals())
1242
-
1243
- num_resume_options_set = (
1244
- (fork_from is not None) # wrap
1245
- + (resume is not None)
1246
- + (resume_from is not None)
1247
- )
1248
- if num_resume_options_set > 1:
1249
- raise ValueError(
1250
- "You cannot specify more than one of `fork_from`, `resume`, or `resume_from`"
1251
- )
1248
+ init_settings = Settings()
1249
+ if isinstance(settings, dict):
1250
+ init_settings = Settings(**settings)
1251
+ elif isinstance(settings, Settings):
1252
+ init_settings = settings
1253
+
1254
+ # Explicit function arguments take precedence over settings
1255
+ if job_type is not None:
1256
+ init_settings.run_job_type = job_type
1257
+ if dir is not None:
1258
+ init_settings.root_dir = dir # type: ignore
1259
+ if project is not None:
1260
+ init_settings.project = project
1261
+ if entity is not None:
1262
+ init_settings.entity = entity
1263
+ if reinit is not None:
1264
+ init_settings.reinit = reinit
1265
+ if tags is not None:
1266
+ init_settings.run_tags = tuple(tags)
1267
+ if group is not None:
1268
+ init_settings.run_group = group
1269
+ if name is not None:
1270
+ init_settings.run_name = name
1271
+ if notes is not None:
1272
+ init_settings.run_notes = notes
1273
+ if anonymous is not None:
1274
+ init_settings.anonymous = anonymous # type: ignore
1275
+ if mode is not None:
1276
+ init_settings.mode = mode # type: ignore
1277
+ if resume is not None:
1278
+ init_settings.resume = resume # type: ignore
1279
+ if force is not None:
1280
+ init_settings.force = force
1281
+ # TODO: deprecate "tensorboard" in favor of "sync_tensorboard"
1282
+ if tensorboard is not None:
1283
+ init_settings.sync_tensorboard = tensorboard
1284
+ if sync_tensorboard is not None:
1285
+ init_settings.sync_tensorboard = sync_tensorboard
1286
+ if save_code is not None:
1287
+ init_settings.save_code = save_code
1288
+ if id is not None:
1289
+ init_settings.run_id = id
1290
+ if fork_from is not None:
1291
+ init_settings.fork_from = fork_from # type: ignore
1292
+ if resume_from is not None:
1293
+ init_settings.resume_from = resume_from # type: ignore
1252
1294
 
1253
1295
  try:
1254
1296
  wi = _WandbInit()
1255
- wi.setup(kwargs)
1297
+ wi.setup(
1298
+ init_settings=init_settings,
1299
+ config=config,
1300
+ config_exclude_keys=config_exclude_keys,
1301
+ config_include_keys=config_include_keys,
1302
+ allow_val_change=allow_val_change,
1303
+ monitor_gym=monitor_gym,
1304
+ )
1256
1305
  return wi.init()
1257
1306
 
1258
1307
  except KeyboardInterrupt as e: