wandb 0.18.6__py3-none-win32.whl → 0.19.0rc1__py3-none-win32.whl

Sign up to get free protection for your applications and to get access to all the features.
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.0rc1.dist-info}/METADATA +14 -4
  111. {wandb-0.18.6.dist-info → wandb-0.19.0rc1.dist-info}/RECORD +114 -120
  112. {wandb-0.18.6.dist-info → wandb-0.19.0rc1.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.0rc1.dist-info}/entry_points.txt +0 -0
  120. {wandb-0.18.6.dist-info → wandb-0.19.0rc1.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: