wandb 0.20.2rc20250616__py3-none-win32.whl → 0.21.1__py3-none-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. wandb/__init__.py +16 -14
  2. wandb/__init__.pyi +450 -472
  3. wandb/agents/pyagent.py +41 -12
  4. wandb/analytics/sentry.py +7 -2
  5. wandb/apis/importers/mlflow.py +1 -1
  6. wandb/apis/internal.py +3 -0
  7. wandb/apis/paginator.py +17 -4
  8. wandb/apis/public/__init__.py +1 -1
  9. wandb/apis/public/api.py +606 -359
  10. wandb/apis/public/artifacts.py +214 -16
  11. wandb/apis/public/automations.py +19 -3
  12. wandb/apis/public/files.py +177 -38
  13. wandb/apis/public/history.py +67 -15
  14. wandb/apis/public/integrations.py +25 -2
  15. wandb/apis/public/jobs.py +90 -2
  16. wandb/apis/public/projects.py +161 -69
  17. wandb/apis/public/query_generator.py +11 -1
  18. wandb/apis/public/registries/registries_search.py +7 -15
  19. wandb/apis/public/reports.py +147 -13
  20. wandb/apis/public/runs.py +315 -128
  21. wandb/apis/public/sweeps.py +222 -22
  22. wandb/apis/public/teams.py +41 -4
  23. wandb/apis/public/users.py +45 -4
  24. wandb/automations/__init__.py +10 -10
  25. wandb/automations/_filters/run_metrics.py +0 -2
  26. wandb/automations/_utils.py +0 -2
  27. wandb/automations/actions.py +0 -2
  28. wandb/automations/automations.py +0 -2
  29. wandb/automations/events.py +0 -2
  30. wandb/beta/workflows.py +66 -30
  31. wandb/bin/gpu_stats.exe +0 -0
  32. wandb/bin/wandb-core +0 -0
  33. wandb/cli/cli.py +80 -1
  34. wandb/env.py +8 -0
  35. wandb/errors/errors.py +4 -1
  36. wandb/integration/catboost/catboost.py +6 -2
  37. wandb/integration/kfp/kfp_patch.py +3 -1
  38. wandb/integration/lightning/fabric/logger.py +3 -4
  39. wandb/integration/metaflow/__init__.py +6 -0
  40. wandb/integration/metaflow/data_pandas.py +74 -0
  41. wandb/integration/metaflow/errors.py +13 -0
  42. wandb/integration/metaflow/metaflow.py +205 -190
  43. wandb/integration/openai/fine_tuning.py +1 -2
  44. wandb/integration/sb3/sb3.py +3 -3
  45. wandb/integration/ultralytics/callback.py +6 -2
  46. wandb/jupyter.py +5 -5
  47. wandb/plot/__init__.py +2 -0
  48. wandb/plot/bar.py +30 -29
  49. wandb/plot/confusion_matrix.py +75 -71
  50. wandb/plot/custom_chart.py +30 -7
  51. wandb/plot/histogram.py +26 -25
  52. wandb/plot/line.py +33 -32
  53. wandb/plot/line_series.py +100 -103
  54. wandb/plot/pr_curve.py +33 -32
  55. wandb/plot/roc_curve.py +38 -38
  56. wandb/plot/scatter.py +27 -27
  57. wandb/proto/v3/wandb_internal_pb2.py +366 -385
  58. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  59. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  60. wandb/proto/v4/wandb_internal_pb2.py +352 -356
  61. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  62. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  63. wandb/proto/v5/wandb_internal_pb2.py +352 -356
  64. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  65. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  66. wandb/proto/v6/wandb_internal_pb2.py +352 -356
  67. wandb/proto/v6/wandb_settings_pb2.py +2 -2
  68. wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
  69. wandb/proto/wandb_deprecated.py +6 -0
  70. wandb/sdk/artifacts/_generated/__init__.py +12 -1
  71. wandb/sdk/artifacts/_generated/input_types.py +20 -2
  72. wandb/sdk/artifacts/_generated/link_artifact.py +21 -0
  73. wandb/sdk/artifacts/_generated/operations.py +9 -0
  74. wandb/sdk/artifacts/_internal_artifact.py +19 -8
  75. wandb/sdk/artifacts/_validators.py +48 -2
  76. wandb/sdk/artifacts/artifact.py +269 -96
  77. wandb/sdk/data_types/audio.py +38 -10
  78. wandb/sdk/data_types/base_types/media.py +15 -63
  79. wandb/sdk/data_types/base_types/wb_value.py +6 -6
  80. wandb/sdk/data_types/graph.py +48 -14
  81. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
  82. wandb/sdk/data_types/helper_types/image_mask.py +1 -3
  83. wandb/sdk/data_types/histogram.py +34 -21
  84. wandb/sdk/data_types/html.py +35 -12
  85. wandb/sdk/data_types/image.py +104 -68
  86. wandb/sdk/data_types/molecule.py +32 -19
  87. wandb/sdk/data_types/object_3d.py +36 -17
  88. wandb/sdk/data_types/plotly.py +18 -5
  89. wandb/sdk/data_types/saved_model.py +7 -9
  90. wandb/sdk/data_types/table.py +99 -70
  91. wandb/sdk/data_types/trace_tree.py +12 -12
  92. wandb/sdk/data_types/video.py +53 -26
  93. wandb/sdk/integration_utils/auto_logging.py +2 -2
  94. wandb/sdk/interface/interface.py +8 -19
  95. wandb/sdk/interface/interface_shared.py +7 -16
  96. wandb/sdk/internal/datastore.py +18 -18
  97. wandb/sdk/internal/handler.py +3 -5
  98. wandb/sdk/internal/internal_api.py +60 -0
  99. wandb/sdk/internal/job_builder.py +6 -0
  100. wandb/sdk/internal/sender.py +23 -3
  101. wandb/sdk/internal/sender_config.py +9 -0
  102. wandb/sdk/launch/_project_spec.py +3 -3
  103. wandb/sdk/launch/agent/agent.py +11 -4
  104. wandb/sdk/launch/agent/job_status_tracker.py +3 -1
  105. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
  106. wandb/sdk/launch/create_job.py +3 -1
  107. wandb/sdk/launch/inputs/internal.py +3 -4
  108. wandb/sdk/launch/inputs/schema.py +1 -0
  109. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  110. wandb/sdk/launch/runner/kubernetes_runner.py +328 -1
  111. wandb/sdk/launch/sweeps/scheduler.py +2 -3
  112. wandb/sdk/launch/utils.py +3 -3
  113. wandb/sdk/lib/asyncio_compat.py +3 -0
  114. wandb/sdk/lib/console_capture.py +66 -19
  115. wandb/sdk/lib/deprecate.py +1 -7
  116. wandb/sdk/lib/disabled.py +1 -1
  117. wandb/sdk/lib/hashutil.py +14 -1
  118. wandb/sdk/lib/module.py +7 -13
  119. wandb/sdk/lib/progress.py +0 -19
  120. wandb/sdk/lib/sock_client.py +0 -4
  121. wandb/sdk/wandb_init.py +67 -93
  122. wandb/sdk/wandb_login.py +18 -14
  123. wandb/sdk/wandb_metric.py +2 -0
  124. wandb/sdk/wandb_require.py +0 -1
  125. wandb/sdk/wandb_run.py +429 -527
  126. wandb/sdk/wandb_settings.py +364 -74
  127. wandb/sdk/wandb_setup.py +28 -28
  128. wandb/sdk/wandb_sweep.py +14 -13
  129. wandb/sdk/wandb_watch.py +4 -6
  130. wandb/sync/sync.py +10 -0
  131. wandb/util.py +57 -0
  132. wandb/wandb_run.py +1 -2
  133. {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/METADATA +1 -1
  134. {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/RECORD +137 -137
  135. wandb/sdk/wandb_metadata.py +0 -623
  136. wandb/vendor/pynvml/__init__.py +0 -0
  137. wandb/vendor/pynvml/pynvml.py +0 -4779
  138. {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/WHEEL +0 -0
  139. {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/entry_points.txt +0 -0
  140. {wandb-0.20.2rc20250616.dist-info → wandb-0.21.1.dist-info}/licenses/LICENSE +0 -0
@@ -162,7 +162,7 @@ class Settings(BaseModel, validate_assignment=True):
162
162
  This class manages configuration settings for the W&B SDK,
163
163
  ensuring type safety and validation of all settings. Settings are accessible
164
164
  as attributes and can be initialized programmatically, through environment
165
- variables (WANDB_ prefix), and via configuration files.
165
+ variables (`WANDB_ prefix`), and with configuration files.
166
166
 
167
167
  The settings are organized into three categories:
168
168
  1. Public settings: Core configuration options that users can safely modify to customize
@@ -230,7 +230,7 @@ class Settings(BaseModel, validate_assignment=True):
230
230
  """The type of console capture to be applied.
231
231
 
232
232
  Possible values are:
233
- "auto" - Automatically selects the console capture method based on the
233
+ "auto" - Automatically selects the console capture method based on the
234
234
  system environment and settings.
235
235
 
236
236
  "off" - Disables console capture.
@@ -299,7 +299,10 @@ class Settings(BaseModel, validate_assignment=True):
299
299
  """Root directory of the git repository."""
300
300
 
301
301
  heartbeat_seconds: int = 30
302
- """Interval in seconds between heartbeat signals sent to the W&B servers."""
302
+ """Interval in seconds between heartbeat signals sent to the W&B servers.
303
+
304
+ <!-- lazydoc-ignore-class-attributes -->
305
+ """
303
306
 
304
307
  host: Optional[str] = None
305
308
  """Hostname of the machine running the script."""
@@ -310,7 +313,6 @@ class Settings(BaseModel, validate_assignment=True):
310
313
  https_proxy: Optional[str] = None
311
314
  """Custom proxy servers for https requests to W&B."""
312
315
 
313
- # Path to file containing an identity token (JWT) for authentication.
314
316
  identity_token_file: Optional[str] = None
315
317
  """Path to file containing an identity token (JWT) for authentication."""
316
318
 
@@ -333,7 +335,10 @@ class Settings(BaseModel, validate_assignment=True):
333
335
  """Whether to disable automatic labeling features."""
334
336
 
335
337
  launch: bool = False
336
- """Flag to indicate if the run is being launched through W&B Launch."""
338
+ """Flag to indicate if the run is being launched through W&B Launch.
339
+
340
+ <!-- lazydoc-ignore-class-attributes -->
341
+ """
337
342
 
338
343
  launch_config_path: Optional[str] = None
339
344
  """Path to the launch configuration file."""
@@ -341,7 +346,7 @@ class Settings(BaseModel, validate_assignment=True):
341
346
  login_timeout: Optional[float] = None
342
347
  """Time in seconds to wait for login operations before timing out."""
343
348
 
344
- mode: Literal["online", "offline", "dryrun", "disabled", "run", "shared"] = Field(
349
+ mode: Literal["online", "offline", "shared", "disabled", "dryrun", "run"] = Field(
345
350
  default="online",
346
351
  validate_default=True,
347
352
  )
@@ -403,19 +408,15 @@ class Settings(BaseModel, validate_assignment=True):
403
408
  resume: Optional[Literal["allow", "must", "never", "auto"]] = None
404
409
  """Specifies the resume behavior for the run.
405
410
 
406
- The available options are:
407
-
408
- "must": Resumes from an existing run with the same ID. If no such run exists,
409
- it will result in failure.
410
-
411
- "allow": Attempts to resume from an existing run with the same ID. If none is
412
- found, a new run will be created.
413
-
414
- "never": Always starts a new run. If a run with the same ID already exists,
415
- it will result in failure.
416
-
417
- "auto": Automatically resumes from the most recent failed run on the same
418
- machine.
411
+ Options:
412
+ - "must": Resumes from an existing run with the same ID. If no such run exists,
413
+ it will result in failure.
414
+ - "allow": Attempts to resume from an existing run with the same ID. If none is
415
+ found, a new run will be created.
416
+ - "never": Always starts a new run. If a run with the same ID already exists,
417
+ it will result in failure.
418
+ - "auto": Automatically resumes from the most recent failed run on the same
419
+ machine.
419
420
  """
420
421
 
421
422
  resume_from: Optional[RunMoment] = None
@@ -429,6 +430,7 @@ class Settings(BaseModel, validate_assignment=True):
429
430
  """Indication from the server about the state of the run.
430
431
 
431
432
  This is different from resume, a user provided flag.
433
+ <!-- lazydoc-ignore-class-attributes -->
432
434
  """
433
435
 
434
436
  root_dir: str = Field(default_factory=lambda: os.path.abspath(os.getcwd()))
@@ -468,10 +470,16 @@ class Settings(BaseModel, validate_assignment=True):
468
470
  """Path to the system-wide settings file."""
469
471
 
470
472
  show_colors: Optional[bool] = None
471
- """Whether to use colored output in the console."""
473
+ """Whether to use colored output in the console.
474
+
475
+ <!-- lazydoc-ignore-class-attributes -->
476
+ """
472
477
 
473
478
  show_emoji: Optional[bool] = None
474
- """Whether to show emoji in the console output."""
479
+ """Whether to show emoji in the console output.
480
+
481
+ <!-- lazydoc-ignore-class-attributes -->
482
+ """
475
483
 
476
484
  show_errors: bool = True
477
485
  """Whether to display error messages."""
@@ -486,7 +494,11 @@ class Settings(BaseModel, validate_assignment=True):
486
494
  """Flag to suppress all output."""
487
495
 
488
496
  start_method: Optional[str] = None
489
- """Method to use for starting subprocesses."""
497
+ """Method to use for starting subprocesses.
498
+
499
+ This is deprecated and will be removed in a future release.
500
+ <!-- lazydoc-ignore-class-attributes -->
501
+ """
490
502
 
491
503
  strict: Optional[bool] = None
492
504
  """Whether to enable strict mode for validation and error checking."""
@@ -494,8 +506,11 @@ class Settings(BaseModel, validate_assignment=True):
494
506
  summary_timeout: int = 60
495
507
  """Time in seconds to wait for summary operations before timing out."""
496
508
 
497
- summary_warnings: int = 5 # TODO: kill this with fire
498
- """Maximum number of summary warnings to display."""
509
+ summary_warnings: int = 5
510
+ """Maximum number of summary warnings to display.
511
+
512
+ <!-- lazydoc-ignore-class-attributes -->
513
+ """
499
514
 
500
515
  sweep_id: Optional[str] = None
501
516
  """Identifier of the sweep this run belongs to."""
@@ -523,7 +538,10 @@ class Settings(BaseModel, validate_assignment=True):
523
538
  # a part of the public API as they may change or be removed in future versions.
524
539
 
525
540
  x_cli_only_mode: bool = False
526
- """Flag to indicate that the SDK is running in CLI-only mode."""
541
+ """Flag to indicate that the SDK is running in CLI-only mode.
542
+
543
+ <!-- lazydoc-ignore-class-attributes -->
544
+ """
527
545
 
528
546
  x_disable_meta: bool = False
529
547
  """Flag to disable the collection of system metadata."""
@@ -532,13 +550,22 @@ class Settings(BaseModel, validate_assignment=True):
532
550
  """Flag to disable the collection of system metrics."""
533
551
 
534
552
  x_disable_viewer: bool = False
535
- """Flag to disable the early viewer query."""
553
+ """Flag to disable the early viewer query.
554
+
555
+ <!-- lazydoc-ignore-class-attributes -->
556
+ """
536
557
 
537
558
  x_disable_machine_info: bool = False
538
- """Flag to disable automatic machine info collection."""
559
+ """Flag to disable automatic machine info collection.
560
+
561
+ <!-- lazydoc-ignore-class-attributes -->
562
+ """
539
563
 
540
564
  x_executable: Optional[str] = None
541
- """Path to the Python executable."""
565
+ """Path to the Python executable.
566
+
567
+ <!-- lazydoc-ignore-class-attributes -->
568
+ """
542
569
 
543
570
  x_extra_http_headers: Optional[Dict[str, str]] = None
544
571
  """Additional headers to add to all outgoing HTTP requests."""
@@ -549,82 +576,142 @@ class Settings(BaseModel, validate_assignment=True):
549
576
  Its purpose is to prevent HTTP requests from failing due to
550
577
  containing too much data. This number is approximate:
551
578
  requests will be slightly larger.
579
+ <!-- lazydoc-ignore-class-attributes -->
552
580
  """
553
581
 
554
582
  x_file_stream_max_line_bytes: Optional[int] = None
555
- """Maximum line length for filestream JSONL files."""
583
+ """Maximum line length for filestream JSONL files.
584
+
585
+ <!-- lazydoc-ignore-class-attributes -->
586
+ """
556
587
 
557
588
  x_file_stream_transmit_interval: Optional[float] = None
558
- """Interval in seconds between filestream transmissions."""
589
+ """Interval in seconds between filestream transmissions.
590
+
591
+ <!-- lazydoc-ignore-class-attributes -->
592
+ """
559
593
 
560
594
  # Filestream retry client configuration.
561
595
 
562
596
  x_file_stream_retry_max: Optional[int] = None
563
- """Max number of retries for filestream operations."""
597
+ """Max number of retries for filestream operations.
598
+
599
+ <!-- lazydoc-ignore-class-attributes -->
600
+ """
564
601
 
565
602
  x_file_stream_retry_wait_min_seconds: Optional[float] = None
566
- """Minimum wait time between retries for filestream operations."""
603
+ """Minimum wait time between retries for filestream operations.
604
+
605
+ <!-- lazydoc-ignore-class-attributes -->
606
+ """
567
607
 
568
608
  x_file_stream_retry_wait_max_seconds: Optional[float] = None
569
- """Maximum wait time between retries for filestream operations."""
609
+ """Maximum wait time between retries for filestream operations.
610
+
611
+ <!-- lazydoc-ignore-class-attributes -->
612
+ """
570
613
 
571
614
  x_file_stream_timeout_seconds: Optional[float] = None
572
- """Timeout in seconds for individual filestream HTTP requests."""
615
+ """Timeout in seconds for individual filestream HTTP requests.
616
+
617
+ <!-- lazydoc-ignore-class-attributes -->
618
+ """
573
619
 
574
620
  # file transfer retry client configuration
575
621
 
576
622
  x_file_transfer_retry_max: Optional[int] = None
577
- """Max number of retries for file transfer operations."""
623
+ """Max number of retries for file transfer operations.
624
+
625
+ <!-- lazydoc-ignore-class-attributes -->
626
+ """
578
627
 
579
628
  x_file_transfer_retry_wait_min_seconds: Optional[float] = None
580
- """Minimum wait time between retries for file transfer operations."""
629
+ """Minimum wait time between retries for file transfer operations.
630
+
631
+ <!-- lazydoc-ignore-class-attributes -->
632
+ """
581
633
 
582
634
  x_file_transfer_retry_wait_max_seconds: Optional[float] = None
583
- """Maximum wait time between retries for file transfer operations."""
635
+ """Maximum wait time between retries for file transfer operations.
636
+
637
+ <!-- lazydoc-ignore-class-attributes -->
638
+ """
584
639
 
585
640
  x_file_transfer_timeout_seconds: Optional[float] = None
586
- """Timeout in seconds for individual file transfer HTTP requests."""
641
+ """Timeout in seconds for individual file transfer HTTP requests.
642
+
643
+ <!-- lazydoc-ignore-class-attributes -->
644
+ """
587
645
 
588
646
  x_files_dir: Optional[str] = None
589
- """Override setting for the computed files_dir.."""
647
+ """Override setting for the computed files_dir.
648
+
649
+ <!-- lazydoc-ignore-class-attributes -->
650
+ """
590
651
 
591
652
  x_flow_control_custom: Optional[bool] = None
592
653
  """Flag indicating custom flow control for filestream.
593
654
 
594
655
  TODO: Not implemented in wandb-core.
656
+ <!-- lazydoc-ignore-class-attributes -->
595
657
  """
596
658
 
597
659
  x_flow_control_disabled: Optional[bool] = None
598
660
  """Flag indicating flow control is disabled for filestream.
599
661
 
600
662
  TODO: Not implemented in wandb-core.
663
+ <!-- lazydoc-ignore-class-attributes -->
601
664
  """
602
665
 
603
666
  # graphql retry client configuration
604
667
 
605
668
  x_graphql_retry_max: Optional[int] = None
606
- """Max number of retries for GraphQL operations."""
669
+ """Max number of retries for GraphQL operations.
670
+
671
+ <!-- lazydoc-ignore-class-attributes -->
672
+ """
607
673
 
608
674
  x_graphql_retry_wait_min_seconds: Optional[float] = None
609
- """Minimum wait time between retries for GraphQL operations."""
675
+ """Minimum wait time between retries for GraphQL operations.
676
+
677
+ <!-- lazydoc-ignore-class-attributes -->
678
+ """
610
679
 
611
680
  x_graphql_retry_wait_max_seconds: Optional[float] = None
612
- """Maximum wait time between retries for GraphQL operations."""
681
+ """Maximum wait time between retries for GraphQL operations.
682
+
683
+ <!-- lazydoc-ignore-class-attributes -->
684
+ """
613
685
 
614
686
  x_graphql_timeout_seconds: Optional[float] = None
615
- """Timeout in seconds for individual GraphQL requests."""
687
+ """Timeout in seconds for individual GraphQL requests.
688
+
689
+ <!-- lazydoc-ignore-class-attributes -->
690
+ """
616
691
 
617
692
  x_internal_check_process: float = 8.0
618
- """Interval for internal process health checks in seconds."""
693
+ """Interval for internal process health checks in seconds.
694
+
695
+ <!-- lazydoc-ignore-class-attributes -->
696
+ """
619
697
 
620
698
  x_jupyter_name: Optional[str] = None
621
- """Name of the Jupyter notebook."""
699
+ """Name of the Jupyter notebook.
700
+
701
+ <!-- lazydoc-ignore-class-attributes -->
702
+ """
622
703
 
623
704
  x_jupyter_path: Optional[str] = None
624
- """Path to the Jupyter notebook."""
705
+ """Path to the Jupyter notebook.
706
+
707
+ <!-- lazydoc-ignore-class-attributes -->
708
+ """
625
709
 
626
710
  x_jupyter_root: Optional[str] = None
627
- """Root directory of the Jupyter notebook."""
711
+ """Root directory of the Jupyter notebook.
712
+
713
+ <!-- lazydoc-ignore-class-attributes -->
714
+ """
628
715
 
629
716
  x_label: Optional[str] = None
630
717
  """Label to assign to system metrics and console logs collected for the run.
@@ -634,18 +721,28 @@ class Settings(BaseModel, validate_assignment=True):
634
721
  """
635
722
 
636
723
  x_live_policy_rate_limit: Optional[int] = None
637
- """Rate limit for live policy updates in seconds."""
724
+ """Rate limit for live policy updates in seconds.
725
+
726
+ <!-- lazydoc-ignore-class-attributes -->
727
+ """
638
728
 
639
729
  x_live_policy_wait_time: Optional[int] = None
640
- """Wait time between live policy updates in seconds."""
730
+ """Wait time between live policy updates in seconds.
731
+
732
+ <!-- lazydoc-ignore-class-attributes -->
733
+ """
641
734
 
642
735
  x_log_level: int = logging.INFO
643
- """Logging level for internal operations."""
736
+ """Logging level for internal operations.
737
+
738
+ <!-- lazydoc-ignore-class-attributes -->
739
+ """
644
740
 
645
741
  x_network_buffer: Optional[int] = None
646
742
  """Size of the network buffer used in flow control.
647
743
 
648
744
  TODO: Not implemented in wandb-core.
745
+ <!-- lazydoc-ignore-class-attributes -->
649
746
  """
650
747
 
651
748
  x_primary: bool = Field(
@@ -661,12 +758,16 @@ class Settings(BaseModel, validate_assignment=True):
661
758
  x_proxies: Optional[Dict[str, str]] = None
662
759
  """Custom proxy servers for requests to W&B.
663
760
 
664
- This is deprecated and will be removed in future versions.
761
+ This is deprecated and will be removed in a future release.
665
762
  Please use `http_proxy` and `https_proxy` instead.
763
+ <!-- lazydoc-ignore-class-attributes -->
666
764
  """
667
765
 
668
766
  x_runqueue_item_id: Optional[str] = None
669
- """ID of the Launch run queue item being processed."""
767
+ """ID of the Launch run queue item being processed.
768
+
769
+ <!-- lazydoc-ignore-class-attributes -->
770
+ """
670
771
 
671
772
  x_save_requirements: bool = True
672
773
  """Flag to save the requirements file."""
@@ -677,14 +778,18 @@ class Settings(BaseModel, validate_assignment=True):
677
778
  This does not disable user-provided summary updates.
678
779
  """
679
780
 
680
- x_server_side_expand_glob_metrics: bool = False
781
+ x_server_side_expand_glob_metrics: bool = True
681
782
  """Flag to delegate glob matching of metrics in define_metric to the server.
682
783
 
683
784
  If the server does not support this, the client will perform the glob matching.
785
+ <!-- lazydoc-ignore-class-attributes -->
684
786
  """
685
787
 
686
788
  x_service_transport: Optional[str] = None
687
- """Transport method for communication with the wandb service."""
789
+ """Transport method for communication with the wandb service.
790
+
791
+ <!-- lazydoc-ignore-class-attributes -->
792
+ """
688
793
 
689
794
  x_service_wait: float = 30.0
690
795
  """Time in seconds to wait for the wandb-core internal service to start."""
@@ -696,13 +801,20 @@ class Settings(BaseModel, validate_assignment=True):
696
801
  data written to disk.
697
802
 
698
803
  Should be used with caution, as it removes the gurantees about
699
- recoverability."""
804
+ recoverability.
805
+ """
700
806
 
701
807
  x_start_time: Optional[float] = None
702
- """The start time of the run in seconds since the Unix epoch."""
808
+ """The start time of the run in seconds since the Unix epoch.
809
+
810
+ <!-- lazydoc-ignore-class-attributes -->
811
+ """
703
812
 
704
813
  x_stats_pid: int = os.getpid()
705
- """PID of the process that started the wandb-core process to collect system stats for."""
814
+ """PID of the process that started the wandb-core process to collect system stats for.
815
+
816
+ <!-- lazydoc-ignore-class-attributes -->
817
+ """
706
818
 
707
819
  x_stats_sampling_interval: float = Field(default=15.0)
708
820
  """Sampling interval for the system monitor in seconds."""
@@ -711,20 +823,22 @@ class Settings(BaseModel, validate_assignment=True):
711
823
  """Path to the default config file for the neuron-monitor tool.
712
824
 
713
825
  This is used to monitor AWS Trainium devices.
826
+ <!-- lazydoc-ignore-class-attributes -->
714
827
  """
715
828
 
716
829
  x_stats_dcgm_exporter: Optional[str] = None
717
830
  """Endpoint to extract Nvidia DCGM metrics from.
718
831
 
719
- Two options are supported:
720
- - Extract DCGM-related metrics from a query to the Prometheus `/api/v1/query` endpoint.
721
- It is a common practice to aggregate metrics reported by the instances of the DCGM Exporter
722
- running on different nodes in a cluster using Prometheus.
723
- - TODO: Parse metrics directly from the `/metrics` endpoint of the DCGM Exporter.
832
+ Options:
833
+ - Extract DCGM-related metrics from a query to the Prometheus `/api/v1/query` endpoint.
834
+ It is a common practice to aggregate metrics reported by the instances of the DCGM Exporter
835
+ running on different nodes in a cluster using Prometheus.
836
+ - TODO: Parse metrics directly from the `/metrics` endpoint of the DCGM Exporter.
724
837
 
725
838
  Examples:
726
- - `http://localhost:9400/api/v1/query?query=DCGM_FI_DEV_GPU_TEMP{node="l1337", cluster="globular"}`.
727
- - TODO: `http://192.168.0.1:9400/metrics`.
839
+ - `http://localhost:9400/api/v1/query?query=DCGM_FI_DEV_GPU_TEMP{node="l1337", cluster="globular"}`.
840
+ - TODO: `http://192.168.0.1:9400/metrics`.
841
+ <!-- lazydoc-ignore-class-attributes -->
728
842
  """
729
843
 
730
844
  x_stats_open_metrics_endpoints: Optional[Dict[str, str]] = None
@@ -736,24 +850,44 @@ class Settings(BaseModel, validate_assignment=True):
736
850
  """Filter to apply to metrics collected from OpenMetrics `/metrics` endpoints.
737
851
 
738
852
  Supports two formats:
739
- - {"metric regex pattern, including endpoint name as prefix": {"label": "label value regex pattern"}}
740
- - ("metric regex pattern 1", "metric regex pattern 2", ...)
853
+ - {"metric regex pattern, including endpoint name as prefix": {"label": "label value regex pattern"}}
854
+ - ("metric regex pattern 1", "metric regex pattern 2", ...)
741
855
  """
742
856
 
743
857
  x_stats_open_metrics_http_headers: Optional[Dict[str, str]] = None
744
858
  """HTTP headers to add to OpenMetrics requests."""
745
859
 
746
- x_stats_disk_paths: Optional[Sequence[str]] = Field(
747
- default_factory=lambda: ("/", "/System/Volumes/Data")
748
- if platform.system() == "Darwin"
749
- else ("/",)
750
- )
860
+ x_stats_disk_paths: Optional[Sequence[str]] = ("/",)
751
861
  """System paths to monitor for disk usage."""
752
862
 
863
+ x_stats_cpu_count: Optional[int] = None
864
+ """System CPU count.
865
+
866
+ If set, overrides the auto-detected value in the run metadata.
867
+ """
868
+
869
+ x_stats_cpu_logical_count: Optional[int] = None
870
+ """Logical CPU count.
871
+
872
+ If set, overrides the auto-detected value in the run metadata.
873
+ """
874
+
875
+ x_stats_gpu_count: Optional[int] = None
876
+ """GPU device count.
877
+
878
+ If set, overrides the auto-detected value in the run metadata.
879
+ """
880
+
881
+ x_stats_gpu_type: Optional[str] = None
882
+ """GPU device type.
883
+
884
+ If set, overrides the auto-detected value in the run metadata.
885
+ """
886
+
753
887
  x_stats_gpu_device_ids: Optional[Sequence[int]] = None
754
888
  """GPU device indices to monitor.
755
889
 
756
- If not set, captures metrics for all GPUs.
890
+ If not set, the system monitor captures metrics for all GPUs.
757
891
  Assumes 0-based indexing matching CUDA/ROCm device enumeration.
758
892
  """
759
893
 
@@ -761,12 +895,14 @@ class Settings(BaseModel, validate_assignment=True):
761
895
  """Number of system metric samples to buffer in memory in the wandb-core process.
762
896
 
763
897
  Can be accessed via run._system_metrics.
898
+ <!-- lazydoc-ignore-class-attributes -->
764
899
  """
765
900
 
766
901
  x_stats_coreweave_metadata_base_url: str = "http://169.254.169.254"
767
902
  """The scheme and hostname for contacting the CoreWeave metadata server.
768
903
 
769
904
  Only accessible from within a CoreWeave cluster.
905
+ <!-- lazydoc-ignore-class-attributes -->
770
906
  """
771
907
 
772
908
  x_stats_coreweave_metadata_endpoint: str = "/api/v2/cloud-init/meta-data"
@@ -774,10 +910,22 @@ class Settings(BaseModel, validate_assignment=True):
774
910
 
775
911
  This must not include the schema and hostname prefix.
776
912
  Only accessible from within a CoreWeave cluster.
913
+ <!-- lazydoc-ignore-class-attributes -->
914
+ """
915
+
916
+ x_stats_track_process_tree: bool = False
917
+ """Monitor the entire process tree for resource usage, starting from `x_stats_pid`.
918
+
919
+ When `True`, the system monitor aggregates the RSS, CPU%, and thread count
920
+ from the process with PID `x_stats_pid` and all of its descendants.
921
+ This can have a performance overhead and is disabled by default.
777
922
  """
778
923
 
779
924
  x_sync: bool = False
780
- """Flag to indicate whether we are syncing a run from the transaction log."""
925
+ """Flag to indicate whether we are syncing a run from the transaction log.
926
+
927
+ <!-- lazydoc-ignore-class-attributes -->
928
+ """
781
929
 
782
930
  x_update_finish_state: bool = True
783
931
  """Flag to indicate whether this process can update the run's final state on the server.
@@ -807,6 +955,10 @@ class Settings(BaseModel, validate_assignment=True):
807
955
 
808
956
  @model_validator(mode="after")
809
957
  def validate_mutual_exclusion_of_branching_args(self) -> Self:
958
+ """Check if `fork_from`, `resume`, and `resume_from` are mutually exclusive.
959
+
960
+ <!-- lazydoc-ignore: internal -->
961
+ """
810
962
  if (
811
963
  sum(
812
964
  o is not None
@@ -854,6 +1006,10 @@ class Settings(BaseModel, validate_assignment=True):
854
1006
  @field_validator("api_key", mode="after")
855
1007
  @classmethod
856
1008
  def validate_api_key(cls, value):
1009
+ """Validate the API key.
1010
+
1011
+ <!-- lazydoc-ignore: internal -->
1012
+ """
857
1013
  if value is not None and (len(value) > len(value.strip())):
858
1014
  raise UsageError("API key cannot start or end with whitespace")
859
1015
  return value
@@ -861,6 +1017,10 @@ class Settings(BaseModel, validate_assignment=True):
861
1017
  @field_validator("base_url", mode="after")
862
1018
  @classmethod
863
1019
  def validate_base_url(cls, value):
1020
+ """Validate the base URL.
1021
+
1022
+ <!-- lazydoc-ignore: internal -->
1023
+ """
864
1024
  validate_url(value)
865
1025
  # wandb.ai-specific checks
866
1026
  if re.match(r".*wandb\.ai[^\.]*$", value) and "api." not in value:
@@ -875,6 +1035,10 @@ class Settings(BaseModel, validate_assignment=True):
875
1035
  @field_validator("code_dir", mode="before")
876
1036
  @classmethod
877
1037
  def validate_code_dir(cls, value):
1038
+ """Validate the code directory.
1039
+
1040
+ <!-- lazydoc-ignore: internal -->
1041
+ """
878
1042
  # TODO: add native support for pathlib.Path
879
1043
  if isinstance(value, pathlib.Path):
880
1044
  return str(value)
@@ -883,6 +1047,10 @@ class Settings(BaseModel, validate_assignment=True):
883
1047
  @field_validator("console", mode="after")
884
1048
  @classmethod
885
1049
  def validate_console(cls, value, values):
1050
+ """Validate the console capture method.
1051
+
1052
+ <!-- lazydoc-ignore: internal -->
1053
+ """
886
1054
  if value != "auto":
887
1055
  return value
888
1056
 
@@ -891,14 +1059,29 @@ class Settings(BaseModel, validate_assignment=True):
891
1059
  @field_validator("x_executable", mode="before")
892
1060
  @classmethod
893
1061
  def validate_x_executable(cls, value):
1062
+ """Validate the Python executable path.
1063
+
1064
+ <!-- lazydoc-ignore: internal -->
1065
+ """
894
1066
  # TODO: add native support for pathlib.Path
895
1067
  if isinstance(value, pathlib.Path):
896
1068
  return str(value)
897
1069
  return value
898
1070
 
1071
+ @field_validator("x_extra_http_headers", mode="before")
1072
+ @classmethod
1073
+ def validate_x_extra_http_headers(cls, value):
1074
+ if isinstance(value, str):
1075
+ return json.loads(value)
1076
+ return value
1077
+
899
1078
  @field_validator("x_file_stream_max_line_bytes", mode="after")
900
1079
  @classmethod
901
1080
  def validate_file_stream_max_line_bytes(cls, value):
1081
+ """Validate the maximum line length for filestream JSONL files.
1082
+
1083
+ <!-- lazydoc-ignore: internal -->
1084
+ """
902
1085
  if value is not None and value < 1:
903
1086
  raise ValueError("File stream max line bytes must be greater than 0")
904
1087
  return value
@@ -906,6 +1089,10 @@ class Settings(BaseModel, validate_assignment=True):
906
1089
  @field_validator("x_files_dir", mode="before")
907
1090
  @classmethod
908
1091
  def validate_x_files_dir(cls, value):
1092
+ """Validate the files directory.
1093
+
1094
+ <!-- lazydoc-ignore: internal -->
1095
+ """
909
1096
  # TODO: add native support for pathlib.Path
910
1097
  if isinstance(value, pathlib.Path):
911
1098
  return str(value)
@@ -914,6 +1101,10 @@ class Settings(BaseModel, validate_assignment=True):
914
1101
  @field_validator("fork_from", mode="before")
915
1102
  @classmethod
916
1103
  def validate_fork_from(cls, value, values) -> Optional[RunMoment]:
1104
+ """Validate the fork_from field.
1105
+
1106
+ <!-- lazydoc-ignore: internal -->
1107
+ """
917
1108
  run_moment = cls._runmoment_preprocessor(value)
918
1109
 
919
1110
  if hasattr(values, "data"):
@@ -938,6 +1129,10 @@ class Settings(BaseModel, validate_assignment=True):
938
1129
  @field_validator("http_proxy", mode="after")
939
1130
  @classmethod
940
1131
  def validate_http_proxy(cls, value):
1132
+ """Validate the HTTP proxy.
1133
+
1134
+ <!-- lazydoc-ignore: internal -->
1135
+ """
941
1136
  if value is None:
942
1137
  return None
943
1138
  validate_url(value)
@@ -946,6 +1141,10 @@ class Settings(BaseModel, validate_assignment=True):
946
1141
  @field_validator("https_proxy", mode="after")
947
1142
  @classmethod
948
1143
  def validate_https_proxy(cls, value):
1144
+ """Validate the HTTPS proxy.
1145
+
1146
+ <!-- lazydoc-ignore: internal -->
1147
+ """
949
1148
  if value is None:
950
1149
  return None
951
1150
  validate_url(value)
@@ -954,11 +1153,19 @@ class Settings(BaseModel, validate_assignment=True):
954
1153
  @field_validator("ignore_globs", mode="after")
955
1154
  @classmethod
956
1155
  def validate_ignore_globs(cls, value):
1156
+ """Validate the ignore globs.
1157
+
1158
+ <!-- lazydoc-ignore: internal -->
1159
+ """
957
1160
  return tuple(value) if not isinstance(value, tuple) else value
958
1161
 
959
1162
  @field_validator("program", mode="before")
960
1163
  @classmethod
961
1164
  def validate_program(cls, value):
1165
+ """Validate the program path.
1166
+
1167
+ <!-- lazydoc-ignore: internal -->
1168
+ """
962
1169
  # TODO: add native support for pathlib.Path
963
1170
  if isinstance(value, pathlib.Path):
964
1171
  return str(value)
@@ -967,6 +1174,10 @@ class Settings(BaseModel, validate_assignment=True):
967
1174
  @field_validator("program_abspath", mode="before")
968
1175
  @classmethod
969
1176
  def validate_program_abspath(cls, value):
1177
+ """Validate the absolute program path.
1178
+
1179
+ <!-- lazydoc-ignore: internal -->
1180
+ """
970
1181
  # TODO: add native support for pathlib.Path
971
1182
  if isinstance(value, pathlib.Path):
972
1183
  return str(value)
@@ -975,6 +1186,10 @@ class Settings(BaseModel, validate_assignment=True):
975
1186
  @field_validator("program_relpath", mode="before")
976
1187
  @classmethod
977
1188
  def validate_program_relpath(cls, value):
1189
+ """Validate the relative program path.
1190
+
1191
+ <!-- lazydoc-ignore: internal -->
1192
+ """
978
1193
  # TODO: add native support for pathlib.Path
979
1194
  if isinstance(value, pathlib.Path):
980
1195
  return str(value)
@@ -983,6 +1198,10 @@ class Settings(BaseModel, validate_assignment=True):
983
1198
  @field_validator("project", mode="after")
984
1199
  @classmethod
985
1200
  def validate_project(cls, value, values):
1201
+ """Validate the project name.
1202
+
1203
+ <!-- lazydoc-ignore: internal -->
1204
+ """
986
1205
  if value is None:
987
1206
  return None
988
1207
  invalid_chars_list = list("/\\#?%:")
@@ -1000,6 +1219,10 @@ class Settings(BaseModel, validate_assignment=True):
1000
1219
  @field_validator("resume", mode="before")
1001
1220
  @classmethod
1002
1221
  def validate_resume(cls, value):
1222
+ """Validate the resume behavior.
1223
+
1224
+ <!-- lazydoc-ignore: internal -->
1225
+ """
1003
1226
  if value is False:
1004
1227
  return None
1005
1228
  if value is True:
@@ -1009,6 +1232,10 @@ class Settings(BaseModel, validate_assignment=True):
1009
1232
  @field_validator("resume_from", mode="before")
1010
1233
  @classmethod
1011
1234
  def validate_resume_from(cls, value, values) -> Optional[RunMoment]:
1235
+ """Validate the resume_from field.
1236
+
1237
+ <!-- lazydoc-ignore: internal -->
1238
+ """
1012
1239
  run_moment = cls._runmoment_preprocessor(value)
1013
1240
 
1014
1241
  if hasattr(values, "data"):
@@ -1031,6 +1258,10 @@ class Settings(BaseModel, validate_assignment=True):
1031
1258
  @field_validator("root_dir", mode="before")
1032
1259
  @classmethod
1033
1260
  def validate_root_dir(cls, value):
1261
+ """Validate the root directory.
1262
+
1263
+ <!-- lazydoc-ignore: internal -->
1264
+ """
1034
1265
  # TODO: add native support for pathlib.Path
1035
1266
  if isinstance(value, pathlib.Path):
1036
1267
  return str(value)
@@ -1039,6 +1270,10 @@ class Settings(BaseModel, validate_assignment=True):
1039
1270
  @field_validator("run_id", mode="after")
1040
1271
  @classmethod
1041
1272
  def validate_run_id(cls, value, values):
1273
+ """Validate the run ID.
1274
+
1275
+ <!-- lazydoc-ignore: internal -->
1276
+ """
1042
1277
  if value is None:
1043
1278
  return None
1044
1279
 
@@ -1048,11 +1283,20 @@ class Settings(BaseModel, validate_assignment=True):
1048
1283
  raise UsageError("Run ID cannot start or end with whitespace")
1049
1284
  if not bool(value.strip()):
1050
1285
  raise UsageError("Run ID cannot contain only whitespace")
1286
+
1287
+ # check if the run id contains any reserved characters
1288
+ reserved_chars = ":;,#?/'"
1289
+ if any(char in reserved_chars for char in value):
1290
+ raise UsageError(f"Run ID cannot contain the characters: {reserved_chars}")
1051
1291
  return value
1052
1292
 
1053
1293
  @field_validator("settings_system", mode="after")
1054
1294
  @classmethod
1055
1295
  def validate_settings_system(cls, value):
1296
+ """Validate the system settings file path.
1297
+
1298
+ <!-- lazydoc-ignore: internal -->
1299
+ """
1056
1300
  if value is None:
1057
1301
  return None
1058
1302
  elif isinstance(value, pathlib.Path):
@@ -1063,6 +1307,10 @@ class Settings(BaseModel, validate_assignment=True):
1063
1307
  @field_validator("x_service_wait", mode="after")
1064
1308
  @classmethod
1065
1309
  def validate_service_wait(cls, value):
1310
+ """Validate the service wait time.
1311
+
1312
+ <!-- lazydoc-ignore: internal -->
1313
+ """
1066
1314
  if value < 0:
1067
1315
  raise UsageError("Service wait time cannot be negative")
1068
1316
  return value
@@ -1070,6 +1318,10 @@ class Settings(BaseModel, validate_assignment=True):
1070
1318
  @field_validator("start_method", mode="after")
1071
1319
  @classmethod
1072
1320
  def validate_start_method(cls, value):
1321
+ """Validate the start method for subprocesses.
1322
+
1323
+ <!-- lazydoc-ignore: internal -->
1324
+ """
1073
1325
  if value is None:
1074
1326
  return value
1075
1327
  wandb.termwarn(
@@ -1088,6 +1340,10 @@ class Settings(BaseModel, validate_assignment=True):
1088
1340
  @field_validator("x_stats_gpu_device_ids", mode="before")
1089
1341
  @classmethod
1090
1342
  def validate_x_stats_gpu_device_ids(cls, value):
1343
+ """Validate the GPU device IDs.
1344
+
1345
+ <!-- lazydoc-ignore: internal -->
1346
+ """
1091
1347
  if isinstance(value, str):
1092
1348
  return json.loads(value)
1093
1349
  return value
@@ -1095,6 +1351,10 @@ class Settings(BaseModel, validate_assignment=True):
1095
1351
  @field_validator("x_stats_neuron_monitor_config_path", mode="before")
1096
1352
  @classmethod
1097
1353
  def validate_x_stats_neuron_monitor_config_path(cls, value):
1354
+ """Validate the path to the neuron-monitor config file.
1355
+
1356
+ <!-- lazydoc-ignore: internal -->
1357
+ """
1098
1358
  # TODO: add native support for pathlib.Path
1099
1359
  if isinstance(value, pathlib.Path):
1100
1360
  return str(value)
@@ -1103,6 +1363,10 @@ class Settings(BaseModel, validate_assignment=True):
1103
1363
  @field_validator("x_stats_open_metrics_endpoints", mode="before")
1104
1364
  @classmethod
1105
1365
  def validate_stats_open_metrics_endpoints(cls, value):
1366
+ """Validate the OpenMetrics endpoints.
1367
+
1368
+ <!-- lazydoc-ignore: internal -->
1369
+ """
1106
1370
  if isinstance(value, str):
1107
1371
  return json.loads(value)
1108
1372
  return value
@@ -1110,6 +1374,10 @@ class Settings(BaseModel, validate_assignment=True):
1110
1374
  @field_validator("x_stats_open_metrics_filters", mode="before")
1111
1375
  @classmethod
1112
1376
  def validate_stats_open_metrics_filters(cls, value):
1377
+ """Validate the OpenMetrics filters.
1378
+
1379
+ <!-- lazydoc-ignore: internal -->
1380
+ """
1113
1381
  if isinstance(value, str):
1114
1382
  return json.loads(value)
1115
1383
  return value
@@ -1117,6 +1385,10 @@ class Settings(BaseModel, validate_assignment=True):
1117
1385
  @field_validator("x_stats_open_metrics_http_headers", mode="before")
1118
1386
  @classmethod
1119
1387
  def validate_stats_open_metrics_http_headers(cls, value):
1388
+ """Validate the OpenMetrics HTTP headers.
1389
+
1390
+ <!-- lazydoc-ignore: internal -->
1391
+ """
1120
1392
  if isinstance(value, str):
1121
1393
  return json.loads(value)
1122
1394
  return value
@@ -1124,6 +1396,10 @@ class Settings(BaseModel, validate_assignment=True):
1124
1396
  @field_validator("x_stats_sampling_interval", mode="after")
1125
1397
  @classmethod
1126
1398
  def validate_stats_sampling_interval(cls, value):
1399
+ """Validate the stats sampling interval.
1400
+
1401
+ <!-- lazydoc-ignore: internal -->
1402
+ """
1127
1403
  if value < 0.1:
1128
1404
  raise UsageError("Stats sampling interval cannot be less than 0.1 seconds")
1129
1405
  return value
@@ -1131,6 +1407,10 @@ class Settings(BaseModel, validate_assignment=True):
1131
1407
  @field_validator("sweep_id", mode="after")
1132
1408
  @classmethod
1133
1409
  def validate_sweep_id(cls, value):
1410
+ """Validate the sweep ID.
1411
+
1412
+ <!-- lazydoc-ignore: internal -->
1413
+ """
1134
1414
  if value is None:
1135
1415
  return None
1136
1416
  if len(value) == 0:
@@ -1144,6 +1424,10 @@ class Settings(BaseModel, validate_assignment=True):
1144
1424
  @field_validator("sweep_param_path", mode="before")
1145
1425
  @classmethod
1146
1426
  def validate_sweep_param_path(cls, value):
1427
+ """Validate the sweep parameter path.
1428
+
1429
+ <!-- lazydoc-ignore: internal -->
1430
+ """
1147
1431
  # TODO: add native support for pathlib.Path
1148
1432
  if isinstance(value, pathlib.Path):
1149
1433
  return str(value)
@@ -1343,6 +1627,7 @@ class Settings(BaseModel, validate_assignment=True):
1343
1627
  @computed_field # type: ignore[prop-decorator]
1344
1628
  @property
1345
1629
  def run_mode(self) -> Literal["run", "offline-run"]:
1630
+ """The mode of the run. Can be either "run" or "offline-run"."""
1346
1631
  return "run" if not self._offline else "offline-run"
1347
1632
 
1348
1633
  @computed_field # type: ignore[prop-decorator]
@@ -1354,7 +1639,9 @@ class Settings(BaseModel, validate_assignment=True):
1354
1639
  return ""
1355
1640
 
1356
1641
  query = self._get_url_query_string()
1357
- return f"{project_url}/runs/{quote(self.run_id or '')}{query}"
1642
+ # Exclude specific safe characters from URL encoding to prevent 404 errors
1643
+ safe_chars = "=+&$@"
1644
+ return f"{project_url}/runs/{quote(self.run_id or '', safe=safe_chars)}{query}"
1358
1645
 
1359
1646
  @computed_field # type: ignore[prop-decorator]
1360
1647
  @property
@@ -1376,6 +1663,7 @@ class Settings(BaseModel, validate_assignment=True):
1376
1663
  @computed_field # type: ignore[prop-decorator]
1377
1664
  @property
1378
1665
  def sync_dir(self) -> str:
1666
+ """The directory for storing the run's files."""
1379
1667
  return _path_convert(
1380
1668
  self.wandb_dir,
1381
1669
  f"{self.run_mode}-{self.timespec}-{self.run_id}",
@@ -1390,11 +1678,13 @@ class Settings(BaseModel, validate_assignment=True):
1390
1678
  @computed_field # type: ignore[prop-decorator]
1391
1679
  @property
1392
1680
  def sync_symlink_latest(self) -> str:
1681
+ """Path to the symlink to the most recent run's transaction log file."""
1393
1682
  return _path_convert(self.wandb_dir, "latest-run")
1394
1683
 
1395
1684
  @computed_field # type: ignore[prop-decorator]
1396
1685
  @property
1397
1686
  def timespec(self) -> str:
1687
+ """The time specification for the run."""
1398
1688
  return self._start_datetime
1399
1689
 
1400
1690
  @computed_field # type: ignore[prop-decorator]