wandb 0.19.12rc1__py3-none-win32.whl → 0.20.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 (172) hide show
  1. wandb/__init__.py +1 -2
  2. wandb/__init__.pyi +3 -6
  3. wandb/_iterutils.py +26 -7
  4. wandb/_pydantic/__init__.py +2 -1
  5. wandb/_pydantic/utils.py +7 -0
  6. wandb/agents/pyagent.py +9 -15
  7. wandb/analytics/sentry.py +1 -2
  8. wandb/apis/attrs.py +3 -4
  9. wandb/apis/importers/internals/util.py +1 -1
  10. wandb/apis/importers/validation.py +2 -2
  11. wandb/apis/importers/wandb.py +30 -25
  12. wandb/apis/normalize.py +2 -2
  13. wandb/apis/public/__init__.py +1 -0
  14. wandb/apis/public/api.py +37 -33
  15. wandb/apis/public/artifacts.py +103 -72
  16. wandb/apis/public/jobs.py +3 -2
  17. wandb/apis/public/registries/registries_search.py +4 -2
  18. wandb/apis/public/registries/registry.py +1 -1
  19. wandb/apis/public/registries/utils.py +9 -9
  20. wandb/apis/public/runs.py +18 -6
  21. wandb/automations/_filters/expressions.py +1 -1
  22. wandb/automations/_filters/operators.py +1 -1
  23. wandb/automations/_filters/run_metrics.py +1 -1
  24. wandb/beta/workflows.py +6 -5
  25. wandb/bin/gpu_stats.exe +0 -0
  26. wandb/bin/wandb-core +0 -0
  27. wandb/cli/cli.py +54 -73
  28. wandb/docker/__init__.py +21 -74
  29. wandb/docker/names.py +40 -0
  30. wandb/env.py +0 -1
  31. wandb/errors/util.py +1 -1
  32. wandb/filesync/step_checksum.py +1 -1
  33. wandb/filesync/step_upload.py +1 -1
  34. wandb/integration/diffusers/resolvers/multimodal.py +1 -2
  35. wandb/integration/gym/__init__.py +5 -6
  36. wandb/integration/keras/callbacks/model_checkpoint.py +2 -2
  37. wandb/integration/keras/keras.py +13 -19
  38. wandb/integration/kfp/kfp_patch.py +2 -3
  39. wandb/integration/langchain/wandb_tracer.py +1 -1
  40. wandb/integration/metaflow/metaflow.py +13 -13
  41. wandb/integration/openai/fine_tuning.py +3 -2
  42. wandb/integration/sagemaker/auth.py +2 -1
  43. wandb/integration/sklearn/utils.py +2 -1
  44. wandb/integration/tensorboard/__init__.py +1 -1
  45. wandb/integration/tensorboard/log.py +2 -5
  46. wandb/integration/tensorflow/__init__.py +2 -2
  47. wandb/jupyter.py +20 -17
  48. wandb/plot/confusion_matrix.py +1 -1
  49. wandb/plot/utils.py +8 -7
  50. wandb/proto/v3/wandb_internal_pb2.py +355 -335
  51. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  52. wandb/proto/v3/wandb_telemetry_pb2.py +12 -12
  53. wandb/proto/v4/wandb_internal_pb2.py +339 -335
  54. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  55. wandb/proto/v4/wandb_telemetry_pb2.py +12 -12
  56. wandb/proto/v5/wandb_internal_pb2.py +339 -335
  57. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  58. wandb/proto/v5/wandb_telemetry_pb2.py +12 -12
  59. wandb/proto/v6/wandb_internal_pb2.py +339 -335
  60. wandb/proto/v6/wandb_settings_pb2.py +2 -2
  61. wandb/proto/v6/wandb_telemetry_pb2.py +12 -12
  62. wandb/proto/wandb_deprecated.py +6 -8
  63. wandb/sdk/artifacts/_internal_artifact.py +43 -0
  64. wandb/sdk/artifacts/_validators.py +55 -35
  65. wandb/sdk/artifacts/artifact.py +117 -115
  66. wandb/sdk/artifacts/artifact_download_logger.py +2 -0
  67. wandb/sdk/artifacts/artifact_saver.py +1 -3
  68. wandb/sdk/artifacts/artifact_state.py +2 -0
  69. wandb/sdk/artifacts/artifact_ttl.py +2 -0
  70. wandb/sdk/artifacts/exceptions.py +14 -0
  71. wandb/sdk/artifacts/staging.py +2 -0
  72. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +2 -6
  73. wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
  74. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +2 -6
  75. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +1 -5
  76. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -1
  77. wandb/sdk/artifacts/storage_layout.py +2 -0
  78. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +3 -3
  79. wandb/sdk/backend/backend.py +11 -182
  80. wandb/sdk/data_types/_dtypes.py +2 -6
  81. wandb/sdk/data_types/audio.py +20 -3
  82. wandb/sdk/data_types/base_types/media.py +12 -7
  83. wandb/sdk/data_types/base_types/wb_value.py +8 -18
  84. wandb/sdk/data_types/bokeh.py +19 -2
  85. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +17 -1
  86. wandb/sdk/data_types/helper_types/image_mask.py +7 -1
  87. wandb/sdk/data_types/html.py +4 -4
  88. wandb/sdk/data_types/image.py +178 -103
  89. wandb/sdk/data_types/molecule.py +6 -6
  90. wandb/sdk/data_types/object_3d.py +10 -5
  91. wandb/sdk/data_types/saved_model.py +11 -6
  92. wandb/sdk/data_types/table.py +313 -83
  93. wandb/sdk/data_types/table_decorators.py +108 -0
  94. wandb/sdk/data_types/utils.py +43 -7
  95. wandb/sdk/data_types/video.py +21 -3
  96. wandb/sdk/interface/interface.py +10 -0
  97. wandb/sdk/internal/datastore.py +2 -6
  98. wandb/sdk/internal/file_pusher.py +1 -5
  99. wandb/sdk/internal/file_stream.py +8 -17
  100. wandb/sdk/internal/handler.py +2 -2
  101. wandb/sdk/internal/incremental_table_util.py +53 -0
  102. wandb/sdk/internal/internal.py +3 -5
  103. wandb/sdk/internal/internal_api.py +66 -89
  104. wandb/sdk/internal/job_builder.py +2 -7
  105. wandb/sdk/internal/profiler.py +2 -2
  106. wandb/sdk/internal/progress.py +1 -3
  107. wandb/sdk/internal/run.py +1 -6
  108. wandb/sdk/internal/sender.py +24 -36
  109. wandb/sdk/internal/system/assets/aggregators.py +1 -7
  110. wandb/sdk/internal/system/assets/disk.py +3 -3
  111. wandb/sdk/internal/system/assets/gpu.py +4 -4
  112. wandb/sdk/internal/system/assets/gpu_amd.py +4 -4
  113. wandb/sdk/internal/system/assets/interfaces.py +6 -6
  114. wandb/sdk/internal/system/assets/tpu.py +1 -1
  115. wandb/sdk/internal/system/assets/trainium.py +6 -6
  116. wandb/sdk/internal/system/system_info.py +5 -7
  117. wandb/sdk/internal/system/system_monitor.py +4 -4
  118. wandb/sdk/internal/tb_watcher.py +5 -7
  119. wandb/sdk/launch/_launch.py +1 -1
  120. wandb/sdk/launch/_project_spec.py +19 -20
  121. wandb/sdk/launch/agent/agent.py +3 -3
  122. wandb/sdk/launch/agent/config.py +1 -1
  123. wandb/sdk/launch/agent/job_status_tracker.py +2 -2
  124. wandb/sdk/launch/builder/build.py +2 -3
  125. wandb/sdk/launch/builder/kaniko_builder.py +5 -4
  126. wandb/sdk/launch/environment/gcp_environment.py +1 -2
  127. wandb/sdk/launch/registry/azure_container_registry.py +2 -2
  128. wandb/sdk/launch/registry/elastic_container_registry.py +2 -2
  129. wandb/sdk/launch/registry/google_artifact_registry.py +3 -3
  130. wandb/sdk/launch/runner/abstract.py +5 -5
  131. wandb/sdk/launch/runner/kubernetes_monitor.py +2 -2
  132. wandb/sdk/launch/runner/kubernetes_runner.py +1 -1
  133. wandb/sdk/launch/runner/sagemaker_runner.py +2 -4
  134. wandb/sdk/launch/runner/vertex_runner.py +2 -7
  135. wandb/sdk/launch/sweeps/__init__.py +1 -1
  136. wandb/sdk/launch/sweeps/scheduler.py +2 -2
  137. wandb/sdk/launch/sweeps/utils.py +3 -3
  138. wandb/sdk/launch/utils.py +3 -4
  139. wandb/sdk/lib/apikey.py +5 -8
  140. wandb/sdk/lib/config_util.py +3 -3
  141. wandb/sdk/lib/fsm.py +3 -18
  142. wandb/sdk/lib/gitlib.py +6 -5
  143. wandb/sdk/lib/ipython.py +2 -2
  144. wandb/sdk/lib/json_util.py +9 -14
  145. wandb/sdk/lib/printer.py +3 -8
  146. wandb/sdk/lib/redirect.py +1 -1
  147. wandb/sdk/lib/retry.py +3 -7
  148. wandb/sdk/lib/run_moment.py +2 -2
  149. wandb/sdk/lib/service_connection.py +3 -1
  150. wandb/sdk/lib/service_token.py +1 -2
  151. wandb/sdk/mailbox/mailbox_handle.py +3 -7
  152. wandb/sdk/mailbox/response_handle.py +2 -6
  153. wandb/sdk/service/streams.py +3 -7
  154. wandb/sdk/verify/verify.py +5 -6
  155. wandb/sdk/wandb_config.py +1 -1
  156. wandb/sdk/wandb_init.py +38 -106
  157. wandb/sdk/wandb_login.py +7 -6
  158. wandb/sdk/wandb_run.py +52 -240
  159. wandb/sdk/wandb_settings.py +71 -60
  160. wandb/sdk/wandb_setup.py +40 -14
  161. wandb/sdk/wandb_watch.py +5 -7
  162. wandb/sync/__init__.py +1 -1
  163. wandb/sync/sync.py +13 -13
  164. wandb/util.py +17 -35
  165. wandb/wandb_agent.py +8 -11
  166. {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/METADATA +5 -5
  167. {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/RECORD +170 -168
  168. wandb/docker/auth.py +0 -435
  169. wandb/docker/www_authenticate.py +0 -94
  170. {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/WHEEL +0 -0
  171. {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/entry_points.txt +0 -0
  172. {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import configparser
4
4
  import json
5
5
  import logging
6
- import multiprocessing
7
6
  import os
8
7
  import pathlib
9
8
  import platform
@@ -25,7 +24,7 @@ from pydantic import BaseModel, ConfigDict, Field
25
24
  from typing_extensions import Self
26
25
 
27
26
  import wandb
28
- from wandb import env, termwarn, util
27
+ from wandb import env, util
29
28
  from wandb._pydantic import (
30
29
  IS_PYDANTIC_V2,
31
30
  AliasChoices,
@@ -529,11 +528,6 @@ class Settings(BaseModel, validate_assignment=True):
529
528
  x_disable_meta: bool = False
530
529
  """Flag to disable the collection of system metadata."""
531
530
 
532
- x_disable_service: bool = False
533
- """Flag to disable the W&B service.
534
-
535
- This is deprecated and will be removed in future versions."""
536
-
537
531
  x_disable_setproctitle: bool = False
538
532
  """Flag to disable using setproctitle for the internal process in the legacy service.
539
533
 
@@ -704,6 +698,15 @@ class Settings(BaseModel, validate_assignment=True):
704
698
  x_service_wait: float = 30.0
705
699
  """Time in seconds to wait for the wandb-core internal service to start."""
706
700
 
701
+ x_skip_transaction_log: bool = False
702
+ """Whether to skip saving the run events to the transaction log.
703
+
704
+ This is only relevant for online runs. Can be used to reduce the amount of
705
+ data written to disk.
706
+
707
+ Should be used with caution, as it removes the gurantees about
708
+ recoverability."""
709
+
707
710
  x_start_time: Optional[float] = None
708
711
  """The start time of the run in seconds since the Unix epoch."""
709
712
 
@@ -769,6 +772,19 @@ class Settings(BaseModel, validate_assignment=True):
769
772
  Can be accessed via run._system_metrics.
770
773
  """
771
774
 
775
+ x_stats_coreweave_metadata_base_url: str = "http://169.254.169.254"
776
+ """The scheme and hostname for contacting the CoreWeave metadata server.
777
+
778
+ Only accessible from within a CoreWeave cluster.
779
+ """
780
+
781
+ x_stats_coreweave_metadata_endpoint: str = "/api/v2/cloud-init/meta-data"
782
+ """The relative path on the CoreWeave metadata server to which to make requests.
783
+
784
+ This must not include the schema and hostname prefix.
785
+ Only accessible from within a CoreWeave cluster.
786
+ """
787
+
772
788
  x_sync: bool = False
773
789
  """Flag to indicate whether we are syncing a run from the transaction log."""
774
790
 
@@ -812,6 +828,12 @@ class Settings(BaseModel, validate_assignment=True):
812
828
  "Please specify only one of them."
813
829
  )
814
830
  return self
831
+
832
+ @model_validator(mode="after")
833
+ def validate_skip_transaction_log(self):
834
+ if self._offline and self.x_skip_transaction_log:
835
+ raise ValueError("Cannot skip transaction log in offline mode")
836
+ return self
815
837
  else:
816
838
 
817
839
  @root_validator(pre=False) # type: ignore [call-overload]
@@ -830,19 +852,14 @@ class Settings(BaseModel, validate_assignment=True):
830
852
  )
831
853
  return values
832
854
 
833
- # Field validators.
834
-
835
- @field_validator("x_disable_service", mode="after")
836
- @classmethod
837
- def validate_disable_service(cls, value):
838
- if value:
839
- termwarn(
840
- "Disabling the wandb service is deprecated as of version 0.18.0 "
841
- "and will be removed in future versions. ",
842
- repeat=False,
843
- )
844
- return value
855
+ @root_validator(pre=False) # type: ignore [call-overload]
856
+ @classmethod
857
+ def validate_skip_transaction_log(cls, values):
858
+ if values.get("_offline") and values.get("x_skip_transaction_log"):
859
+ raise ValueError("Cannot skip transaction log in offline mode")
860
+ return values
845
861
 
862
+ # Field validators.
846
863
  @field_validator("api_key", mode="after")
847
864
  @classmethod
848
865
  def validate_api_key(cls, value):
@@ -878,23 +895,7 @@ class Settings(BaseModel, validate_assignment=True):
878
895
  if value != "auto":
879
896
  return value
880
897
 
881
- if hasattr(values, "data"):
882
- # pydantic v2
883
- values = values.data
884
- else:
885
- # pydantic v1
886
- values = values
887
-
888
- if (
889
- ipython.in_jupyter()
890
- or (values.get("start_method") == "thread")
891
- or not values.get("x_disable_service")
892
- or platform.system() == "Windows"
893
- ):
894
- value = "wrap"
895
- else:
896
- value = "redirect"
897
- return value
898
+ return "wrap"
898
899
 
899
900
  @field_validator("x_executable", mode="before")
900
901
  @classmethod
@@ -1080,15 +1081,19 @@ class Settings(BaseModel, validate_assignment=True):
1080
1081
  def validate_start_method(cls, value):
1081
1082
  if value is None:
1082
1083
  return value
1083
- available_methods = ["thread"]
1084
- if hasattr(multiprocessing, "get_all_start_methods"):
1085
- available_methods += multiprocessing.get_all_start_methods()
1086
- if value not in available_methods:
1087
- raise UsageError(
1088
- f"Settings field `start_method`: {value!r} not in {available_methods}"
1089
- )
1084
+ wandb.termwarn(
1085
+ "`start_method` is deprecated and will be removed in a future version "
1086
+ "of wandb. This setting is currently non-functional and safely ignored.",
1087
+ repeat=False,
1088
+ )
1090
1089
  return value
1091
1090
 
1091
+ @field_validator("x_stats_coreweave_metadata_base_url", mode="after")
1092
+ @classmethod
1093
+ def validate_x_stats_coreweave_metadata_base_url(cls, value):
1094
+ validate_url(value)
1095
+ return value.rstrip("/")
1096
+
1092
1097
  @field_validator("x_stats_gpu_device_ids", mode="before")
1093
1098
  @classmethod
1094
1099
  def validate_x_stats_gpu_device_ids(cls, value):
@@ -1441,7 +1446,6 @@ class Settings(BaseModel, validate_assignment=True):
1441
1446
  env_prefix: str = "WANDB_"
1442
1447
  private_env_prefix: str = env_prefix + "_"
1443
1448
  special_env_var_names = {
1444
- "WANDB_DISABLE_SERVICE": "x_disable_service",
1445
1449
  "WANDB_SERVICE_TRANSPORT": "x_service_transport",
1446
1450
  "WANDB_DIR": "root_dir",
1447
1451
  "WANDB_NAME": "run_name",
@@ -1637,21 +1641,7 @@ class Settings(BaseModel, validate_assignment=True):
1637
1641
 
1638
1642
  def _get_program(self) -> Optional[str]:
1639
1643
  """Get the program that started the current process."""
1640
- if not self._jupyter:
1641
- # If not in a notebook, try to get the program from the environment
1642
- # or the __main__ module for scripts run as `python -m ...`.
1643
- program = os.getenv(env.PROGRAM)
1644
- if program is not None:
1645
- return program
1646
- try:
1647
- import __main__
1648
-
1649
- if __main__.__spec__ is None:
1650
- return __main__.__file__
1651
- return f"-m {__main__.__spec__.name}"
1652
- except (ImportError, AttributeError):
1653
- return None
1654
- else:
1644
+ if self._jupyter:
1655
1645
  # If in a notebook, try to get the program from the notebook metadata.
1656
1646
  if self.notebook_name:
1657
1647
  return self.notebook_name
@@ -1661,8 +1651,29 @@ class Settings(BaseModel, validate_assignment=True):
1661
1651
 
1662
1652
  if self.x_jupyter_path.startswith("fileId="):
1663
1653
  return self.x_jupyter_name
1654
+
1655
+ return self.x_jupyter_path
1656
+
1657
+ # If not in a notebook, try to get the program from the environment
1658
+ # or the __main__ module for scripts run as `python -m ...`.
1659
+ program = os.getenv(env.PROGRAM)
1660
+ if program is not None:
1661
+ return program
1662
+
1663
+ try:
1664
+ import __main__
1665
+ except ImportError:
1666
+ return None
1667
+
1668
+ try:
1669
+ if __main__.__spec__ is None:
1670
+ python_args = __main__.__file__
1664
1671
  else:
1665
- return self.x_jupyter_path
1672
+ python_args = f"-m {__main__.__spec__.name}"
1673
+ except AttributeError:
1674
+ return None
1675
+
1676
+ return python_args
1666
1677
 
1667
1678
  @staticmethod
1668
1679
  def _get_program_relpath(program: str, root: Optional[str] = None) -> Optional[str]:
wandb/sdk/wandb_setup.py CHANGED
@@ -1,14 +1,25 @@
1
- #
2
- """Setup wandb session.
3
-
4
- This module configures a wandb session which can extend to multiple wandb runs.
5
-
6
- Functions:
7
- setup(): Configure wandb session.
8
-
9
- Early logging keeps track of logger output until the call to wandb.init() when the
10
- run_id can be resolved.
11
-
1
+ """Global W&B library state.
2
+
3
+ This module manages global state, which for wandb includes:
4
+
5
+ - Settings configured through `wandb.setup()`
6
+ - The list of active runs
7
+ - A subprocess ("the internal service") that asynchronously uploads metrics
8
+
9
+ This module is fork-aware: in a forked process such as that spawned by the
10
+ `multiprocessing` module, `wandb.singleton()` returns a new object, not the
11
+ one inherited from the parent process. This requirement comes from backward
12
+ compatibility with old design choices: the hardest one to fix is that wandb
13
+ was originally designed to have a single run for the entire process that
14
+ `wandb.init()` was meant to return. Back then, the only way to create
15
+ multiple simultaneous runs in a single script was to run subprocesses, and since
16
+ the built-in `multiprocessing` module forks by default, this required a PID
17
+ check to make `wandb.init()` ignore the inherited global run.
18
+
19
+ Another reason for fork-awareness is that the process that starts up
20
+ the internal service owns it and is responsible for shutting it down,
21
+ and child processes shouldn't also try to do that. This is easier to
22
+ redesign.
12
23
  """
13
24
 
14
25
  from __future__ import annotations
@@ -344,10 +355,25 @@ The value is invalid and must not be used if `os.getpid() != _singleton._pid`.
344
355
  """
345
356
 
346
357
 
347
- def singleton() -> _WandbSetup | None:
348
- """Returns the W&B singleton if it exists for the current process.
358
+ def singleton() -> _WandbSetup:
359
+ """The W&B singleton for the current process.
360
+
361
+ The first call to this in this process (which may be a fork of another
362
+ process) creates the singleton, and all subsequent calls return it
363
+ until teardown(). This does not start the service process.
364
+ """
365
+ return _setup(start_service=False)
366
+
367
+
368
+ def singleton_if_setup() -> _WandbSetup | None:
369
+ """The W&B singleton for the current process or None if it isn't set up.
370
+
371
+ Always prefer singleton() over this function.
349
372
 
350
- Unlike setup(), this does not create the singleton if it doesn't exist.
373
+ Unlike singleton(), this never creates the singleton and therefore never
374
+ initializes global settings from the environment. This is useful only
375
+ during tests, which may modify the environment after having imported wandb
376
+ and called certain functions.
351
377
  """
352
378
  if _singleton and _singleton._pid == os.getpid():
353
379
  return _singleton
wandb/sdk/wandb_watch.py CHANGED
@@ -59,9 +59,8 @@ def _watch(
59
59
  The graph object, which will be populated after the first backward pass.
60
60
 
61
61
  Raises:
62
- ValueError:
63
- If `wandb.init` has not been called or if any of the models are not instances
64
- of `torch.nn.Module`.
62
+ ValueError: If `wandb.init` has not been called.
63
+ TypeError: If any of the models are not instances of `torch.nn.Module`.
65
64
  """
66
65
  global _global_watch_idx
67
66
 
@@ -85,9 +84,8 @@ def _watch(
85
84
 
86
85
  for model in models:
87
86
  if not isinstance(model, torch.nn.Module):
88
- raise ValueError(
89
- "Expected a pytorch model (torch.nn.Module). Received "
90
- + str(type(model))
87
+ raise TypeError(
88
+ f"Expected a pytorch model (torch.nn.Module). Received {type(model)}"
91
89
  )
92
90
 
93
91
  graphs = []
@@ -139,7 +137,7 @@ def _unwatch(
139
137
  models = (models,)
140
138
  for model in models:
141
139
  if not hasattr(model, "_wandb_hook_names"):
142
- wandb.termwarn("{} model has not been watched".format(model))
140
+ wandb.termwarn(f"{model} model has not been watched")
143
141
  else:
144
142
  for name in model._wandb_hook_names:
145
143
  run._torch.unhook(name)
wandb/sync/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """module sync."""
2
2
 
3
- from .sync import SyncManager, get_run_from_path, get_runs # noqa: F401
3
+ from .sync import SyncManager, get_run_from_path, get_runs
wandb/sync/sync.py CHANGED
@@ -157,13 +157,13 @@ class SyncThread(threading.Thread):
157
157
  proto_run.entity = self._entity
158
158
  proto_run.telemetry.feature.sync_tfevents = True
159
159
 
160
- url = "{}/{}/{}/runs/{}".format(
161
- self._app_url,
162
- url_quote(proto_run.entity),
163
- url_quote(proto_run.project),
164
- url_quote(proto_run.run_id),
160
+ url = (
161
+ f"{self._app_url}"
162
+ f"/{url_quote(proto_run.entity)}"
163
+ f"/{url_quote(proto_run.project)}"
164
+ f"/runs/{url_quote(proto_run.run_id)}"
165
165
  )
166
- print("Syncing: {} ...".format(url)) # noqa: T201
166
+ print(f"Syncing: {url} ...") # noqa: T201
167
167
  sys.stdout.flush()
168
168
  # using a handler here automatically handles the step
169
169
  # logic, adds summaries to the run, and handles different
@@ -241,7 +241,7 @@ class SyncThread(threading.Thread):
241
241
  )
242
242
  return None
243
243
  else:
244
- raise e
244
+ raise
245
245
 
246
246
  def run(self):
247
247
  if self._log_path is not None:
@@ -305,13 +305,13 @@ class SyncThread(threading.Thread):
305
305
  if not shown and result_type == "run_result":
306
306
  r = result.run_result.run
307
307
  # TODO(jhr): hardcode until we have settings in sync
308
- url = "{}/{}/{}/runs/{}".format(
309
- self._app_url,
310
- url_quote(r.entity),
311
- url_quote(r.project),
312
- url_quote(r.run_id),
308
+ url = (
309
+ f"{self._app_url}"
310
+ f"/{url_quote(r.entity)}"
311
+ f"/{url_quote(r.project)}"
312
+ f"/runs/{url_quote(r.run_id)}"
313
313
  )
314
- print("Syncing: {} ... ".format(url), end="") # noqa: T201
314
+ print(f"Syncing: {url} ... ", end="") # noqa: T201
315
315
  sys.stdout.flush()
316
316
  shown = True
317
317
  sm.finish()
wandb/util.py CHANGED
@@ -36,10 +36,8 @@ from types import ModuleType
36
36
  from typing import (
37
37
  IO,
38
38
  TYPE_CHECKING,
39
- Any,
40
39
  Callable,
41
40
  Dict,
42
- Generator,
43
41
  Iterable,
44
42
  List,
45
43
  Mapping,
@@ -47,17 +45,12 @@ from typing import (
47
45
  Sequence,
48
46
  TextIO,
49
47
  Tuple,
50
- TypeVar,
51
48
  Union,
52
49
  )
53
50
 
54
- if sys.version_info < (3, 10):
55
- from typing_extensions import TypeGuard
56
- else:
57
- from typing import TypeGuard
58
-
59
51
  import requests
60
52
  import yaml
53
+ from typing_extensions import Any, Generator, TypeGuard, TypeVar
61
54
 
62
55
  import wandb
63
56
  import wandb.env
@@ -74,8 +67,6 @@ from wandb.sdk.lib.json_util import dump, dumps
74
67
  from wandb.sdk.lib.paths import FilePathStr, StrPath
75
68
 
76
69
  if TYPE_CHECKING:
77
- import packaging.version # type: ignore[import-not-found]
78
-
79
70
  import wandb.sdk.internal.settings_static
80
71
  import wandb.sdk.wandb_settings
81
72
  from wandb.sdk.artifacts.artifact import Artifact
@@ -628,9 +619,7 @@ def json_friendly( # noqa: C901
628
619
  converted = False
629
620
  if getsizeof(obj) > VALUE_BYTES_LIMIT:
630
621
  wandb.termwarn(
631
- "Serializing object of type {} that is {} bytes".format(
632
- type(obj).__name__, getsizeof(obj)
633
- )
622
+ f"Serializing object of type {type(obj).__name__} that is {getsizeof(obj)} bytes"
634
623
  )
635
624
  return obj, converted
636
625
 
@@ -1226,14 +1215,16 @@ def async_call(
1226
1215
  )
1227
1216
  thread.daemon = True
1228
1217
  thread.start()
1218
+
1229
1219
  try:
1230
1220
  result = q.get(True, timeout)
1231
- if isinstance(result, Exception):
1232
- raise result.with_traceback(sys.exc_info()[2])
1233
- return result, thread
1234
1221
  except queue.Empty:
1235
1222
  return None, thread
1236
1223
 
1224
+ if isinstance(result, Exception):
1225
+ raise result.with_traceback(sys.exc_info()[2])
1226
+ return result, thread
1227
+
1237
1228
  return wrapper
1238
1229
 
1239
1230
 
@@ -1450,11 +1441,12 @@ def are_paths_on_same_drive(path1: str, path2: str) -> bool:
1450
1441
  try:
1451
1442
  path1_drive = pathlib.Path(path1).resolve().drive
1452
1443
  path2_drive = pathlib.Path(path2).resolve().drive
1453
- return path1_drive == path2_drive
1454
- # If either path is not a valid windows path, an OSError is raised.
1455
1444
  except OSError:
1445
+ # If either path is not a valid Windows path, an OSError is raised.
1456
1446
  return False
1457
1447
 
1448
+ return path1_drive == path2_drive
1449
+
1458
1450
 
1459
1451
  # TODO(hugh): Deprecate version here and use wandb/sdk/lib/paths.py
1460
1452
  def to_forward_slash_path(path: str) -> str:
@@ -1548,14 +1540,19 @@ def is_unicode_safe(stream: TextIO) -> bool:
1548
1540
 
1549
1541
 
1550
1542
  def _has_internet() -> bool:
1551
- """Attempt to open a DNS connection to Googles root servers."""
1543
+ """Returns whether we have internet access.
1544
+
1545
+ Checks for internet access by attempting to open a DNS connection to
1546
+ Google's root servers.
1547
+ """
1552
1548
  try:
1553
1549
  s = socket.create_connection(("8.8.8.8", 53), 0.5)
1554
1550
  s.close()
1555
- return True
1556
1551
  except OSError:
1557
1552
  return False
1558
1553
 
1554
+ return True
1555
+
1559
1556
 
1560
1557
  def rand_alphanumeric(
1561
1558
  length: int = 8, rand: Optional[Union[ModuleType, random.Random]] = None
@@ -1943,21 +1940,6 @@ def working_set() -> Iterable[InstalledDistribution]:
1943
1940
  pass
1944
1941
 
1945
1942
 
1946
- def parse_version(version: str) -> "packaging.version.Version":
1947
- """Parse a version string into a version object.
1948
-
1949
- This function is a wrapper around the `packaging.version.parse` function, which
1950
- is used to parse version strings into version objects. If the `packaging` library
1951
- is not installed, it falls back to the `pkg_resources` library.
1952
- """
1953
- try:
1954
- from packaging.version import parse as parse_version # type: ignore
1955
- except ImportError:
1956
- from pkg_resources import parse_version # type: ignore[assignment]
1957
-
1958
- return parse_version(version)
1959
-
1960
-
1961
1943
  def get_core_path() -> str:
1962
1944
  """Returns the path to the wandb-core binary.
1963
1945
 
wandb/wandb_agent.py CHANGED
@@ -94,14 +94,11 @@ class AgentProcess:
94
94
  if self._popen:
95
95
  # if on windows, wait() will block and we won't be able to interrupt
96
96
  if platform.system() == "Windows":
97
- try:
98
- while True:
99
- p = self._popen.poll()
100
- if p is not None:
101
- return p
102
- time.sleep(1)
103
- except KeyboardInterrupt:
104
- raise
97
+ while True:
98
+ p = self._popen.poll()
99
+ if p is not None:
100
+ return p
101
+ time.sleep(1)
105
102
  return self._popen.wait()
106
103
  return self._proc.join()
107
104
 
@@ -332,7 +329,7 @@ class Agent:
332
329
  elif command_type == "resume":
333
330
  result = self._command_run(command)
334
331
  else:
335
- raise AgentError("No such command: {}".format(command_type))
332
+ raise AgentError(f"No such command: {command_type}") # noqa: TRY301
336
333
  response["result"] = result
337
334
  except Exception:
338
335
  logger.exception("Exception while processing command: %s", command)
@@ -415,7 +412,7 @@ class Agent:
415
412
  command_list += [c]
416
413
  logger.info(
417
414
  "About to run command: {}".format(
418
- " ".join('"{}"'.format(c) if " " in c else c for c in command_list)
415
+ " ".join(f'"{c}"' if " " in c else c for c in command_list)
419
416
  )
420
417
  )
421
418
  proc = AgentProcess(command=command_list, env=env)
@@ -466,7 +463,7 @@ class AgentApi:
466
463
 
467
464
  def command(self, command):
468
465
  command["origin"] = "local"
469
- command["id"] = "local-{}".format(self._command_id)
466
+ command["id"] = f"local-{self._command_id}"
470
467
  self._command_id += 1
471
468
  resp_queue = self._multiproc_manager.Queue()
472
469
  command["resp_queue"] = resp_queue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: wandb
3
- Version: 0.19.12rc1
3
+ Version: 0.20.1
4
4
  Summary: A CLI and library for interacting with the Weights & Biases API.
5
5
  Project-URL: Source, https://github.com/wandb/wandb
6
6
  Project-URL: Bug Reports, https://github.com/wandb/wandb/issues
@@ -48,9 +48,9 @@ Classifier: Topic :: System :: Logging
48
48
  Classifier: Topic :: System :: Monitoring
49
49
  Requires-Python: >=3.8
50
50
  Requires-Dist: click!=8.0.0,>=7.1
51
- Requires-Dist: docker-pycreds>=0.4.0
52
51
  Requires-Dist: eval-type-backport; python_version < '3.10'
53
52
  Requires-Dist: gitpython!=3.1.29,>=1.0.0
53
+ Requires-Dist: packaging
54
54
  Requires-Dist: platformdirs
55
55
  Requires-Dist: protobuf!=4.21.0,!=5.28.0,<7,>=3.12.0; python_version < '3.9' and sys_platform == 'linux'
56
56
  Requires-Dist: protobuf!=4.21.0,!=5.28.0,<7,>=3.15.0; python_version == '3.9' and sys_platform == 'linux'
@@ -62,8 +62,7 @@ Requires-Dist: pyyaml
62
62
  Requires-Dist: requests<3,>=2.0.0
63
63
  Requires-Dist: sentry-sdk>=2.0.0
64
64
  Requires-Dist: setproctitle
65
- Requires-Dist: setuptools
66
- Requires-Dist: typing-extensions<5,>=4.4
65
+ Requires-Dist: typing-extensions<5,>=4.8
67
66
  Provides-Extra: aws
68
67
  Requires-Dist: boto3; extra == 'aws'
69
68
  Requires-Dist: botocore>=1.5.76; extra == 'aws'
@@ -106,10 +105,11 @@ Requires-Dist: optuna; extra == 'launch'
106
105
  Requires-Dist: pydantic; extra == 'launch'
107
106
  Requires-Dist: pyyaml>=6.0.0; extra == 'launch'
108
107
  Requires-Dist: tomli; extra == 'launch'
108
+ Requires-Dist: tornado>=6.5.0; (python_version >= '3.9') and extra == 'launch'
109
109
  Requires-Dist: typing-extensions; extra == 'launch'
110
110
  Provides-Extra: media
111
111
  Requires-Dist: bokeh; extra == 'media'
112
- Requires-Dist: imageio; extra == 'media'
112
+ Requires-Dist: imageio>=2.28.1; extra == 'media'
113
113
  Requires-Dist: moviepy>=1.0.0; extra == 'media'
114
114
  Requires-Dist: numpy; extra == 'media'
115
115
  Requires-Dist: pillow; extra == 'media'