wandb 0.13.10__py3-none-any.whl → 0.14.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. wandb/__init__.py +2 -3
  2. wandb/apis/__init__.py +1 -3
  3. wandb/apis/importers/__init__.py +4 -0
  4. wandb/apis/importers/base.py +312 -0
  5. wandb/apis/importers/mlflow.py +113 -0
  6. wandb/apis/internal.py +29 -2
  7. wandb/apis/normalize.py +6 -5
  8. wandb/apis/public.py +163 -180
  9. wandb/apis/reports/_templates.py +6 -12
  10. wandb/apis/reports/report.py +1 -1
  11. wandb/apis/reports/runset.py +1 -3
  12. wandb/apis/reports/util.py +12 -10
  13. wandb/beta/workflows.py +57 -34
  14. wandb/catboost/__init__.py +1 -2
  15. wandb/cli/cli.py +215 -133
  16. wandb/data_types.py +63 -56
  17. wandb/docker/__init__.py +78 -16
  18. wandb/docker/auth.py +21 -22
  19. wandb/env.py +0 -1
  20. wandb/errors/__init__.py +8 -116
  21. wandb/errors/term.py +1 -1
  22. wandb/fastai/__init__.py +1 -2
  23. wandb/filesync/dir_watcher.py +8 -5
  24. wandb/filesync/step_prepare.py +76 -75
  25. wandb/filesync/step_upload.py +1 -2
  26. wandb/integration/catboost/__init__.py +1 -3
  27. wandb/integration/catboost/catboost.py +8 -14
  28. wandb/integration/fastai/__init__.py +7 -13
  29. wandb/integration/gym/__init__.py +35 -4
  30. wandb/integration/keras/__init__.py +3 -3
  31. wandb/integration/keras/callbacks/metrics_logger.py +9 -8
  32. wandb/integration/keras/callbacks/model_checkpoint.py +9 -9
  33. wandb/integration/keras/callbacks/tables_builder.py +31 -19
  34. wandb/integration/kfp/kfp_patch.py +20 -17
  35. wandb/integration/kfp/wandb_logging.py +1 -2
  36. wandb/integration/lightgbm/__init__.py +21 -19
  37. wandb/integration/prodigy/prodigy.py +6 -7
  38. wandb/integration/sacred/__init__.py +9 -12
  39. wandb/integration/sagemaker/__init__.py +1 -3
  40. wandb/integration/sagemaker/auth.py +0 -1
  41. wandb/integration/sagemaker/config.py +1 -1
  42. wandb/integration/sagemaker/resources.py +1 -1
  43. wandb/integration/sb3/sb3.py +8 -4
  44. wandb/integration/tensorboard/__init__.py +1 -3
  45. wandb/integration/tensorboard/log.py +8 -8
  46. wandb/integration/tensorboard/monkeypatch.py +11 -9
  47. wandb/integration/tensorflow/__init__.py +1 -3
  48. wandb/integration/xgboost/__init__.py +4 -6
  49. wandb/integration/yolov8/__init__.py +7 -0
  50. wandb/integration/yolov8/yolov8.py +250 -0
  51. wandb/jupyter.py +31 -35
  52. wandb/lightgbm/__init__.py +1 -2
  53. wandb/old/settings.py +2 -2
  54. wandb/plot/bar.py +1 -2
  55. wandb/plot/confusion_matrix.py +1 -3
  56. wandb/plot/histogram.py +1 -2
  57. wandb/plot/line.py +1 -2
  58. wandb/plot/line_series.py +4 -4
  59. wandb/plot/pr_curve.py +17 -20
  60. wandb/plot/roc_curve.py +1 -3
  61. wandb/plot/scatter.py +1 -2
  62. wandb/proto/v3/wandb_server_pb2.py +85 -39
  63. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  64. wandb/proto/v4/wandb_server_pb2.py +51 -39
  65. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  66. wandb/sdk/__init__.py +1 -3
  67. wandb/sdk/backend/backend.py +1 -1
  68. wandb/sdk/data_types/_dtypes.py +38 -30
  69. wandb/sdk/data_types/base_types/json_metadata.py +1 -3
  70. wandb/sdk/data_types/base_types/media.py +17 -17
  71. wandb/sdk/data_types/base_types/wb_value.py +33 -26
  72. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +91 -125
  73. wandb/sdk/data_types/helper_types/classes.py +1 -1
  74. wandb/sdk/data_types/helper_types/image_mask.py +12 -12
  75. wandb/sdk/data_types/histogram.py +5 -4
  76. wandb/sdk/data_types/html.py +1 -2
  77. wandb/sdk/data_types/image.py +11 -11
  78. wandb/sdk/data_types/molecule.py +3 -6
  79. wandb/sdk/data_types/object_3d.py +1 -2
  80. wandb/sdk/data_types/plotly.py +1 -2
  81. wandb/sdk/data_types/saved_model.py +10 -8
  82. wandb/sdk/data_types/video.py +1 -1
  83. wandb/sdk/integration_utils/data_logging.py +5 -5
  84. wandb/sdk/interface/artifacts.py +288 -266
  85. wandb/sdk/interface/interface.py +2 -3
  86. wandb/sdk/interface/interface_grpc.py +1 -1
  87. wandb/sdk/interface/interface_queue.py +1 -1
  88. wandb/sdk/interface/interface_relay.py +1 -1
  89. wandb/sdk/interface/interface_shared.py +1 -2
  90. wandb/sdk/interface/interface_sock.py +1 -1
  91. wandb/sdk/interface/message_future.py +1 -1
  92. wandb/sdk/interface/message_future_poll.py +1 -1
  93. wandb/sdk/interface/router.py +1 -1
  94. wandb/sdk/interface/router_queue.py +1 -1
  95. wandb/sdk/interface/router_relay.py +1 -1
  96. wandb/sdk/interface/router_sock.py +1 -1
  97. wandb/sdk/interface/summary_record.py +1 -1
  98. wandb/sdk/internal/artifacts.py +1 -1
  99. wandb/sdk/internal/datastore.py +2 -3
  100. wandb/sdk/internal/file_pusher.py +5 -3
  101. wandb/sdk/internal/file_stream.py +22 -19
  102. wandb/sdk/internal/handler.py +5 -4
  103. wandb/sdk/internal/internal.py +1 -1
  104. wandb/sdk/internal/internal_api.py +115 -55
  105. wandb/sdk/internal/job_builder.py +1 -3
  106. wandb/sdk/internal/profiler.py +1 -1
  107. wandb/sdk/internal/progress.py +4 -6
  108. wandb/sdk/internal/sample.py +1 -3
  109. wandb/sdk/internal/sender.py +28 -16
  110. wandb/sdk/internal/settings_static.py +5 -5
  111. wandb/sdk/internal/system/assets/__init__.py +1 -0
  112. wandb/sdk/internal/system/assets/cpu.py +3 -9
  113. wandb/sdk/internal/system/assets/disk.py +2 -4
  114. wandb/sdk/internal/system/assets/gpu.py +6 -18
  115. wandb/sdk/internal/system/assets/gpu_apple.py +2 -4
  116. wandb/sdk/internal/system/assets/interfaces.py +50 -22
  117. wandb/sdk/internal/system/assets/ipu.py +1 -3
  118. wandb/sdk/internal/system/assets/memory.py +7 -13
  119. wandb/sdk/internal/system/assets/network.py +4 -8
  120. wandb/sdk/internal/system/assets/open_metrics.py +283 -0
  121. wandb/sdk/internal/system/assets/tpu.py +1 -4
  122. wandb/sdk/internal/system/assets/trainium.py +26 -14
  123. wandb/sdk/internal/system/system_info.py +2 -3
  124. wandb/sdk/internal/system/system_monitor.py +52 -20
  125. wandb/sdk/internal/tb_watcher.py +12 -13
  126. wandb/sdk/launch/_project_spec.py +54 -65
  127. wandb/sdk/launch/agent/agent.py +374 -90
  128. wandb/sdk/launch/builder/abstract.py +61 -7
  129. wandb/sdk/launch/builder/build.py +81 -110
  130. wandb/sdk/launch/builder/docker_builder.py +181 -0
  131. wandb/sdk/launch/builder/kaniko_builder.py +419 -0
  132. wandb/sdk/launch/builder/noop.py +31 -12
  133. wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +70 -20
  134. wandb/sdk/launch/environment/abstract.py +28 -0
  135. wandb/sdk/launch/environment/aws_environment.py +276 -0
  136. wandb/sdk/launch/environment/gcp_environment.py +271 -0
  137. wandb/sdk/launch/environment/local_environment.py +65 -0
  138. wandb/sdk/launch/github_reference.py +3 -8
  139. wandb/sdk/launch/launch.py +38 -29
  140. wandb/sdk/launch/launch_add.py +6 -8
  141. wandb/sdk/launch/loader.py +230 -0
  142. wandb/sdk/launch/registry/abstract.py +54 -0
  143. wandb/sdk/launch/registry/elastic_container_registry.py +163 -0
  144. wandb/sdk/launch/registry/google_artifact_registry.py +203 -0
  145. wandb/sdk/launch/registry/local_registry.py +62 -0
  146. wandb/sdk/launch/runner/abstract.py +1 -16
  147. wandb/sdk/launch/runner/{kubernetes.py → kubernetes_runner.py} +83 -95
  148. wandb/sdk/launch/runner/local_container.py +46 -22
  149. wandb/sdk/launch/runner/local_process.py +1 -4
  150. wandb/sdk/launch/runner/{aws.py → sagemaker_runner.py} +53 -212
  151. wandb/sdk/launch/runner/{gcp_vertex.py → vertex_runner.py} +38 -55
  152. wandb/sdk/launch/sweeps/__init__.py +3 -2
  153. wandb/sdk/launch/sweeps/scheduler.py +132 -39
  154. wandb/sdk/launch/sweeps/scheduler_sweep.py +80 -89
  155. wandb/sdk/launch/utils.py +101 -30
  156. wandb/sdk/launch/wandb_reference.py +2 -7
  157. wandb/sdk/lib/_settings_toposort_generate.py +166 -0
  158. wandb/sdk/lib/_settings_toposort_generated.py +201 -0
  159. wandb/sdk/lib/apikey.py +2 -4
  160. wandb/sdk/lib/config_util.py +4 -1
  161. wandb/sdk/lib/console.py +1 -3
  162. wandb/sdk/lib/deprecate.py +3 -3
  163. wandb/sdk/lib/file_stream_utils.py +7 -5
  164. wandb/sdk/lib/filenames.py +1 -1
  165. wandb/sdk/lib/filesystem.py +61 -5
  166. wandb/sdk/lib/git.py +1 -3
  167. wandb/sdk/lib/import_hooks.py +4 -7
  168. wandb/sdk/lib/ipython.py +8 -5
  169. wandb/sdk/lib/lazyloader.py +1 -3
  170. wandb/sdk/lib/mailbox.py +14 -4
  171. wandb/sdk/lib/proto_util.py +10 -5
  172. wandb/sdk/lib/redirect.py +15 -22
  173. wandb/sdk/lib/reporting.py +1 -3
  174. wandb/sdk/lib/retry.py +4 -5
  175. wandb/sdk/lib/runid.py +1 -3
  176. wandb/sdk/lib/server.py +15 -9
  177. wandb/sdk/lib/sock_client.py +1 -1
  178. wandb/sdk/lib/sparkline.py +1 -1
  179. wandb/sdk/lib/wburls.py +1 -1
  180. wandb/sdk/service/port_file.py +1 -2
  181. wandb/sdk/service/service.py +36 -13
  182. wandb/sdk/service/service_base.py +12 -1
  183. wandb/sdk/verify/verify.py +5 -7
  184. wandb/sdk/wandb_artifacts.py +142 -177
  185. wandb/sdk/wandb_config.py +5 -8
  186. wandb/sdk/wandb_helper.py +1 -1
  187. wandb/sdk/wandb_init.py +24 -13
  188. wandb/sdk/wandb_login.py +9 -9
  189. wandb/sdk/wandb_manager.py +39 -4
  190. wandb/sdk/wandb_metric.py +2 -6
  191. wandb/sdk/wandb_require.py +4 -15
  192. wandb/sdk/wandb_require_helpers.py +1 -9
  193. wandb/sdk/wandb_run.py +95 -141
  194. wandb/sdk/wandb_save.py +1 -3
  195. wandb/sdk/wandb_settings.py +149 -54
  196. wandb/sdk/wandb_setup.py +66 -46
  197. wandb/sdk/wandb_summary.py +13 -10
  198. wandb/sdk/wandb_sweep.py +6 -7
  199. wandb/sdk/wandb_watch.py +1 -1
  200. wandb/sklearn/calculate/confusion_matrix.py +1 -1
  201. wandb/sklearn/calculate/learning_curve.py +1 -1
  202. wandb/sklearn/calculate/summary_metrics.py +1 -3
  203. wandb/sklearn/plot/__init__.py +1 -1
  204. wandb/sklearn/plot/classifier.py +27 -18
  205. wandb/sklearn/plot/clusterer.py +4 -5
  206. wandb/sklearn/plot/regressor.py +4 -4
  207. wandb/sklearn/plot/shared.py +2 -2
  208. wandb/sync/__init__.py +1 -3
  209. wandb/sync/sync.py +4 -5
  210. wandb/testing/relay.py +11 -10
  211. wandb/trigger.py +1 -1
  212. wandb/util.py +106 -81
  213. wandb/viz.py +4 -4
  214. wandb/wandb_agent.py +50 -50
  215. wandb/wandb_controller.py +2 -3
  216. wandb/wandb_run.py +1 -2
  217. wandb/wandb_torch.py +1 -1
  218. wandb/xgboost/__init__.py +1 -2
  219. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/METADATA +6 -2
  220. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/RECORD +224 -209
  221. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/WHEEL +1 -1
  222. wandb/sdk/launch/builder/docker.py +0 -80
  223. wandb/sdk/launch/builder/kaniko.py +0 -393
  224. wandb/sdk/launch/builder/loader.py +0 -32
  225. wandb/sdk/launch/runner/loader.py +0 -50
  226. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/LICENSE +0 -0
  227. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/entry_points.txt +0 -0
  228. {wandb-0.13.10.dist-info → wandb-0.14.0.dist-info}/top_level.txt +0 -0
wandb/sdk/wandb_run.py CHANGED
@@ -39,7 +39,6 @@ from wandb._globals import _datatypes_set_callback
39
39
  from wandb.apis import internal, public
40
40
  from wandb.apis.internal import Api
41
41
  from wandb.apis.public import Api as PublicApi
42
- from wandb.errors import MailboxError
43
42
  from wandb.proto.wandb_internal_pb2 import (
44
43
  MetricRecord,
45
44
  PollExitResponse,
@@ -67,6 +66,7 @@ from wandb.viz import CustomChart, Visualize, custom_chart
67
66
  from . import wandb_artifacts, wandb_config, wandb_metric, wandb_summary
68
67
  from .data_types._dtypes import TypeRegistry
69
68
  from .interface.artifacts import Artifact as ArtifactInterface
69
+ from .interface.artifacts import ArtifactNotLoggedError
70
70
  from .interface.interface import GlobStr, InterfaceBase
71
71
  from .interface.summary_record import SummaryRecord
72
72
  from .lib import (
@@ -82,7 +82,7 @@ from .lib import (
82
82
  )
83
83
  from .lib.exit_hooks import ExitHooks
84
84
  from .lib.git import GitRepo
85
- from .lib.mailbox import MailboxHandle, MailboxProbe, MailboxProgress
85
+ from .lib.mailbox import MailboxError, MailboxHandle, MailboxProbe, MailboxProgress
86
86
  from .lib.printer import get_printer
87
87
  from .lib.proto_util import message_to_dict
88
88
  from .lib.reporting import Reporter
@@ -233,6 +233,8 @@ class RunStatusChecker:
233
233
 
234
234
  if result:
235
235
  process(result)
236
+ # if request finished, clear the handle to send on the next interval
237
+ local_handle = None
236
238
 
237
239
  time_elapsed = time.monotonic() - time_probe
238
240
  wait_time = max(self._stop_polling_interval - time_elapsed, 0)
@@ -295,7 +297,6 @@ class RunStatusChecker:
295
297
 
296
298
 
297
299
  class _run_decorator: # noqa: N801
298
-
299
300
  _is_attaching: str = ""
300
301
 
301
302
  class Dummy:
@@ -305,7 +306,6 @@ class _run_decorator: # noqa: N801
305
306
  def _attach(cls, func: Callable) -> Callable:
306
307
  @functools.wraps(func)
307
308
  def wrapper(self: Type["Run"], *args: Any, **kwargs: Any) -> Any:
308
-
309
309
  # * `_attach_id` is only assigned in service hence for all non-service cases
310
310
  # it will be a passthrough.
311
311
  # * `_attach_pid` is only assigned in _init (using _attach_pid guarantees single attach):
@@ -315,7 +315,6 @@ class _run_decorator: # noqa: N801
315
315
  getattr(self, "_attach_id", None)
316
316
  and getattr(self, "_attach_pid", None) != os.getpid()
317
317
  ):
318
-
319
318
  if cls._is_attaching:
320
319
  message = (
321
320
  f"Trying to attach `{func.__name__}` "
@@ -362,7 +361,7 @@ class _run_decorator: # noqa: N801
362
361
  settings = getattr(self, "_settings", None)
363
362
  if settings and settings["strict"]:
364
363
  wandb.termerror(message, repeat=False)
365
- raise errors.MultiprocessError(
364
+ raise errors.UnsupportedError(
366
365
  f"`{func.__name__}` does not support multiprocessing"
367
366
  )
368
367
  wandb.termwarn(message, repeat=False)
@@ -430,7 +429,7 @@ class Run:
430
429
  and then log information only from that process, or you can create a run in each process,
431
430
  logging from each separately, and group the results together with the `group` argument
432
431
  to `wandb.init`. For more details on distributed training with W&B, check out
433
- [our guide](https://docs.wandb.ai/guides/track/advanced/distributed-training).
432
+ [our guide](https://docs.wandb.ai/guides/track/log/distributed-training).
434
433
 
435
434
  Currently, there is a parallel `Run` object in the `wandb.Api`. Eventually these
436
435
  two objects will be merged.
@@ -528,7 +527,6 @@ class Run:
528
527
  sweep_config: Optional[Dict[str, Any]] = None,
529
528
  launch_config: Optional[Dict[str, Any]] = None,
530
529
  ) -> None:
531
-
532
530
  self._settings = settings
533
531
  self._config = wandb_config.Config()
534
532
  self._config._set_callback(self._config_callback)
@@ -643,7 +641,7 @@ class Run:
643
641
  self._attach_pid = os.getpid()
644
642
 
645
643
  # for now, use runid as attach id, this could/should be versioned in the future
646
- if self._settings._require_service:
644
+ if not self._settings._disable_service:
647
645
  self._attach_id = self._settings.run_id
648
646
 
649
647
  def _set_iface_pid(self, iface_pid: int) -> None:
@@ -774,10 +772,13 @@ class Run:
774
772
  except Exception:
775
773
  wandb.termwarn("Cannot find valid git repo associated with this directory.")
776
774
 
775
+ def __deepcopy__(self, memo: Dict[int, Any]) -> "Run":
776
+ return self
777
+
777
778
  def __getstate__(self) -> Any:
778
- """Custom pickler."""
779
+ """Return run state as a custom pickle."""
779
780
  # We only pickle in service mode
780
- if not self._settings or not self._settings._require_service:
781
+ if not self._settings or self._settings._disable_service:
781
782
  return
782
783
 
783
784
  _attach_id = self._attach_id
@@ -787,7 +788,7 @@ class Run:
787
788
  return dict(_attach_id=self._attach_id, _init_pid=self._init_pid)
788
789
 
789
790
  def __setstate__(self, state: Any) -> None:
790
- """Custom unpickler."""
791
+ """Set run state from a custom pickle."""
791
792
  if not state:
792
793
  return
793
794
 
@@ -809,7 +810,7 @@ class Run:
809
810
  @property
810
811
  @_run_decorator._attach
811
812
  def settings(self) -> Settings:
812
- """Returns a frozen copy of run's Settings object."""
813
+ """A frozen copy of run's Settings object."""
813
814
  cp = self._settings.copy()
814
815
  cp.freeze()
815
816
  return cp
@@ -817,13 +818,13 @@ class Run:
817
818
  @property
818
819
  @_run_decorator._attach
819
820
  def dir(self) -> str:
820
- """Returns the directory where files associated with the run are saved."""
821
+ """The directory where files associated with the run are saved."""
821
822
  return self._settings.files_dir
822
823
 
823
824
  @property
824
825
  @_run_decorator._attach
825
826
  def config(self) -> wandb_config.Config:
826
- """Returns the config object associated with this run."""
827
+ """Config object associated with this run."""
827
828
  return self._config
828
829
 
829
830
  @property
@@ -834,7 +835,7 @@ class Run:
834
835
  @property
835
836
  @_run_decorator._attach
836
837
  def name(self) -> Optional[str]:
837
- """Returns the display name of the run.
838
+ """Display name of the run.
838
839
 
839
840
  Display names are not guaranteed to be unique and may be descriptive.
840
841
  By default, they are randomly generated.
@@ -857,7 +858,7 @@ class Run:
857
858
  @property
858
859
  @_run_decorator._attach
859
860
  def notes(self) -> Optional[str]:
860
- """Returns the notes associated with the run, if there are any.
861
+ """Notes associated with the run, if there are any.
861
862
 
862
863
  Notes can be a multiline string and can also use markdown and latex equations
863
864
  inside `$$`, like `$x + 3$`.
@@ -878,7 +879,7 @@ class Run:
878
879
  @property
879
880
  @_run_decorator._attach
880
881
  def tags(self) -> Optional[Tuple]:
881
- """Returns the tags associated with the run, if there are any."""
882
+ """Tags associated with the run, if there are any."""
882
883
  if self._tags:
883
884
  return self._tags
884
885
  run_obj = self._run_obj or self._run_obj_offline
@@ -898,7 +899,7 @@ class Run:
898
899
  @property
899
900
  @_run_decorator._attach
900
901
  def id(self) -> str:
901
- """Returns the identifier for this run."""
902
+ """Identifier for this run."""
902
903
  if TYPE_CHECKING:
903
904
  assert self._run_id is not None
904
905
  return self._run_id
@@ -906,7 +907,7 @@ class Run:
906
907
  @property
907
908
  @_run_decorator._attach
908
909
  def sweep_id(self) -> Optional[str]:
909
- """Returns the ID of the sweep associated with the run, if there is one."""
910
+ """ID of the sweep associated with the run, if there is one."""
910
911
  if not self._run_obj:
911
912
  return None
912
913
  return self._run_obj.sweep_id or None
@@ -920,7 +921,7 @@ class Run:
920
921
  @property
921
922
  @_run_decorator._attach
922
923
  def path(self) -> str:
923
- """Returns the path to the run.
924
+ """Path to the run.
924
925
 
925
926
  Run paths include entity, project, and run ID, in the format
926
927
  `entity/project/run_id`.
@@ -937,7 +938,7 @@ class Run:
937
938
  @property
938
939
  @_run_decorator._attach
939
940
  def start_time(self) -> float:
940
- """Returns the unix time stamp, in seconds, when the run started."""
941
+ """Unix timestamp (in seconds) of when the run started."""
941
942
  return self._get_start_time()
942
943
 
943
944
  def _get_starting_step(self) -> int:
@@ -946,19 +947,19 @@ class Run:
946
947
  @property
947
948
  @_run_decorator._attach
948
949
  def starting_step(self) -> int:
949
- """Returns the first step of the run."""
950
+ """The first step of the run."""
950
951
  return self._get_starting_step()
951
952
 
952
953
  @property
953
954
  @_run_decorator._attach
954
955
  def resumed(self) -> bool:
955
- """Returns True if the run was resumed, False otherwise."""
956
+ """True if the run was resumed, False otherwise."""
956
957
  return self._run_obj.resumed if self._run_obj else False
957
958
 
958
959
  @property
959
960
  @_run_decorator._attach
960
961
  def step(self) -> int:
961
- """Returns the current value of the step.
962
+ """Current value of the step.
962
963
 
963
964
  This counter is incremented by `wandb.log`.
964
965
  """
@@ -998,7 +999,7 @@ class Run:
998
999
  @property
999
1000
  @_run_decorator._attach
1000
1001
  def group(self) -> str:
1001
- """Returns the name of the group associated with the run.
1002
+ """Name of the group associated with the run.
1002
1003
 
1003
1004
  Setting a group helps the W&B UI organize runs in a sensible way.
1004
1005
 
@@ -1018,7 +1019,7 @@ class Run:
1018
1019
  @property
1019
1020
  @_run_decorator._attach
1020
1021
  def project(self) -> str:
1021
- """Returns the name of the W&B project associated with the run."""
1022
+ """Name of the W&B project associated with the run."""
1022
1023
  return self.project_name()
1023
1024
 
1024
1025
  @_run_decorator._attach
@@ -1029,7 +1030,7 @@ class Run:
1029
1030
  include_fn: Callable[[str], bool] = _is_py_path,
1030
1031
  exclude_fn: Callable[[str], bool] = filenames.exclude_wandb_fn,
1031
1032
  ) -> Optional[Artifact]:
1032
- """Saves the current state of your code to a W&B Artifact.
1033
+ """Save the current state of your code to a W&B Artifact.
1033
1034
 
1034
1035
  By default, it walks the current directory and logs all files that end with `.py`.
1035
1036
 
@@ -1086,7 +1087,7 @@ class Run:
1086
1087
  return self._log_artifact(art)
1087
1088
 
1088
1089
  def get_url(self) -> Optional[str]:
1089
- """Returns the url for the W&B run, if there is one.
1090
+ """Return the url for the W&B run, if there is one.
1090
1091
 
1091
1092
  Offline runs will not have a url.
1092
1093
  """
@@ -1096,7 +1097,7 @@ class Run:
1096
1097
  return self._settings.run_url
1097
1098
 
1098
1099
  def get_project_url(self) -> Optional[str]:
1099
- """Returns the url for the W&B project associated with the run, if there is one.
1100
+ """Return the url for the W&B project associated with the run, if there is one.
1100
1101
 
1101
1102
  Offline runs will not have a project url.
1102
1103
  """
@@ -1106,7 +1107,7 @@ class Run:
1106
1107
  return self._settings.project_url
1107
1108
 
1108
1109
  def get_sweep_url(self) -> Optional[str]:
1109
- """Returns the url for the sweep associated with the run, if there is one."""
1110
+ """Return the url for the sweep associated with the run, if there is one."""
1110
1111
  if self._settings._offline:
1111
1112
  wandb.termwarn("URL not available in offline run")
1112
1113
  return None
@@ -1115,13 +1116,13 @@ class Run:
1115
1116
  @property
1116
1117
  @_run_decorator._attach
1117
1118
  def url(self) -> Optional[str]:
1118
- """Returns the W&B url associated with the run."""
1119
+ """The W&B url associated with the run."""
1119
1120
  return self.get_url()
1120
1121
 
1121
1122
  @property
1122
1123
  @_run_decorator._attach
1123
1124
  def entity(self) -> str:
1124
- """Returns the name of the W&B entity associated with the run.
1125
+ """The name of the W&B entity associated with the run.
1125
1126
 
1126
1127
  Entity can be a user name or the name of a team or organization.
1127
1128
  """
@@ -1217,7 +1218,7 @@ class Run:
1217
1218
 
1218
1219
  @_run_decorator._attach
1219
1220
  def display(self, height: int = 420, hidden: bool = False) -> bool:
1220
- """Displays this run in jupyter."""
1221
+ """Display this run in jupyter."""
1221
1222
  if self._settings._jupyter and ipython.in_jupyter():
1222
1223
  ipython.display_html(self.to_html(height, hidden))
1223
1224
  return True
@@ -1227,7 +1228,7 @@ class Run:
1227
1228
 
1228
1229
  @_run_decorator._attach
1229
1230
  def to_html(self, height: int = 420, hidden: bool = False) -> str:
1230
- """Generates HTML containing an iframe displaying the current run."""
1231
+ """Generate HTML containing an iframe displaying the current run."""
1231
1232
  url = self._settings.run_url + "?jupyter=true"
1232
1233
  style = f"border:none;width:100%;height:{height}px;"
1233
1234
  prefix = ""
@@ -1454,7 +1455,7 @@ class Run:
1454
1455
  def _add_singleton(
1455
1456
  self, data_type: str, key: str, value: Dict[Union[int, str], str]
1456
1457
  ) -> None:
1457
- """Stores a singleton item to wandb config.
1458
+ """Store a singleton item to wandb config.
1458
1459
 
1459
1460
  A singleton in this context is a piece of data that is continually
1460
1461
  logged with the same value in each history step, but represented
@@ -1525,7 +1526,7 @@ class Run:
1525
1526
  commit: Optional[bool] = None,
1526
1527
  sync: Optional[bool] = None,
1527
1528
  ) -> None:
1528
- """Logs a dictonary of data to the current run's history.
1529
+ """Log a dictonary of data to the current run's history.
1529
1530
 
1530
1531
  Use `wandb.log` to log data from runs, such as scalars, images, video,
1531
1532
  histograms, plots, and tables.
@@ -1538,7 +1539,7 @@ class Run:
1538
1539
  the summary values for these metrics.
1539
1540
 
1540
1541
  Visualize logged data in the workspace at [wandb.ai](https://wandb.ai),
1541
- or locally on a [self-hosted instance](https://docs.wandb.ai/self-hosted)
1542
+ or locally on a [self-hosted instance](https://docs.wandb.ai/guides/hosting)
1542
1543
  of the W&B app, or export data to visualize and explore locally, e.g. in
1543
1544
  Jupyter notebooks, with [our API](https://docs.wandb.ai/guides/track/public-api-guide).
1544
1545
 
@@ -1548,7 +1549,7 @@ class Run:
1548
1549
  Logged values don't have to be scalars. Logging any wandb object is supported.
1549
1550
  For example `wandb.log({"example": wandb.Image("myimage.jpg")})` will log an
1550
1551
  example image which will be displayed nicely in the W&B UI.
1551
- See the [reference documentation](https://docs.wandb.com/library/reference/data_types)
1552
+ See the [reference documentation](https://docs.wandb.com/ref/python/data-types)
1552
1553
  for all of the different supported types or check out our
1553
1554
  [guides to logging](https://docs.wandb.ai/guides/track/log) for examples,
1554
1555
  from 3D molecular structures and segmentation masks to PR curves and histograms.
@@ -1749,7 +1750,6 @@ class Run:
1749
1750
  base_path: Optional[str] = None,
1750
1751
  policy: "PolicyName" = "live",
1751
1752
  ) -> Union[bool, List[str]]:
1752
-
1753
1753
  if policy not in ("live", "end", "now"):
1754
1754
  raise ValueError(
1755
1755
  'Only "live" "end" and "now" policies are currently supported.'
@@ -1833,7 +1833,7 @@ class Run:
1833
1833
  def finish(
1834
1834
  self, exit_code: Optional[int] = None, quiet: Optional[bool] = None
1835
1835
  ) -> None:
1836
- """Marks a run as finished, and finishes uploading all data.
1836
+ """Mark a run as finished, and finishe uploading all data.
1837
1837
 
1838
1838
  This is used when creating multiple runs in the same process. We automatically
1839
1839
  call this method when your script exits or if you use the run context manager.
@@ -1875,7 +1875,7 @@ class Run:
1875
1875
  @_run_decorator._noop
1876
1876
  @_run_decorator._attach
1877
1877
  def join(self, exit_code: Optional[int] = None) -> None:
1878
- """Deprecated alias for `finish()` - please use finish."""
1878
+ """Deprecated alias for `finish()` - use finish instead."""
1879
1879
  deprecate.deprecate(
1880
1880
  field_name=deprecate.Deprecated.run__join,
1881
1881
  warning_message=(
@@ -1915,7 +1915,7 @@ class Run:
1915
1915
  fields: Dict[str, Any],
1916
1916
  string_fields: Optional[Dict[str, Any]] = None,
1917
1917
  ) -> CustomChart:
1918
- """Creates a custom plot on a table.
1918
+ """Create a custom plot on a table.
1919
1919
 
1920
1920
  Arguments:
1921
1921
  vega_spec_name: the name of the spec for the plot
@@ -1962,7 +1962,7 @@ class Run:
1962
1962
  console = self._settings._console
1963
1963
  # only use raw for service to minimize potential changes
1964
1964
  if console == SettingsConsole.WRAP:
1965
- if self._settings._require_service:
1965
+ if not self._settings._disable_service:
1966
1966
  console = SettingsConsole.WRAP_RAW
1967
1967
  else:
1968
1968
  console = SettingsConsole.WRAP_EMU
@@ -2129,7 +2129,6 @@ class Run:
2129
2129
  self._output_writer = None
2130
2130
 
2131
2131
  def _on_init(self) -> None:
2132
-
2133
2132
  if self._backend and self._backend.interface:
2134
2133
  logger.info("communicating current version")
2135
2134
  version_handle = self._backend.interface.deliver_check_version(
@@ -2501,6 +2500,7 @@ class Run:
2501
2500
  def unwatch(self, models=None) -> None: # type: ignore
2502
2501
  wandb.unwatch(models=models)
2503
2502
 
2503
+ # TODO(kdg): remove all artifact swapping logic
2504
2504
  def _swap_artifact_name(self, artifact_name: str, use_as: Optional[str]) -> str:
2505
2505
  artifact_key_string = use_as or artifact_name
2506
2506
  replacement_artifact_info = self._launch_artifact_mapping.get(
@@ -2516,10 +2516,6 @@ class Run:
2516
2516
  )
2517
2517
  return f"{entity}/{project}/{new_name}"
2518
2518
  elif replacement_artifact_info is None and use_as is None:
2519
- wandb.termwarn(
2520
- f"Could not find {artifact_name} in launch artifact mapping. "
2521
- f"Searching for unique artifacts with sequence name: {artifact_name}"
2522
- )
2523
2519
  sequence_name = artifact_name.split(":")[0].split("/")[-1]
2524
2520
  unique_artifact_replacement_info = (
2525
2521
  self._unique_launch_artifact_sequence_names.get(sequence_name)
@@ -2535,14 +2531,8 @@ class Run:
2535
2531
  return f"{entity}/{project}/{new_name}"
2536
2532
 
2537
2533
  else:
2538
- wandb.termwarn(
2539
- f"Could not find swappable artifact at key: {use_as}. Using {artifact_name}"
2540
- )
2541
2534
  return artifact_name
2542
2535
 
2543
- wandb.termwarn(
2544
- f"Could not find {artifact_key_string} in launch artifact mapping. Using {artifact_name}"
2545
- )
2546
2536
  return artifact_name
2547
2537
 
2548
2538
  def _detach(self) -> None:
@@ -2555,7 +2545,7 @@ class Run:
2555
2545
  target_path: str,
2556
2546
  aliases: Optional[List[str]] = None,
2557
2547
  ) -> None:
2558
- """Links the given artifact to a portfolio (a promoted collection of artifacts).
2548
+ """Link the given artifact to a portfolio (a promoted collection of artifacts).
2559
2549
 
2560
2550
  The linked artifact will be visible in the UI for the specified portfolio.
2561
2551
 
@@ -2692,7 +2682,7 @@ class Run:
2692
2682
  else:
2693
2683
  raise ValueError(
2694
2684
  'You must pass an artifact name (e.g. "pedestrian-dataset:v1"), '
2695
- "an instance of `wandb.Artifact`, or `wandb.Api().artifact()` to `use_artifact`" # noqa: E501
2685
+ "an instance of `wandb.Artifact`, or `wandb.Api().artifact()` to `use_artifact`"
2696
2686
  )
2697
2687
  if self._backend and self._backend.interface:
2698
2688
  self._backend.interface.publish_use_artifact(artifact)
@@ -3011,7 +3001,7 @@ class Run:
3011
3001
 
3012
3002
  @_run_decorator._attach
3013
3003
  def mark_preempting(self) -> None:
3014
- """Marks this run as preempting.
3004
+ """Mark this run as preempting.
3015
3005
 
3016
3006
  Also tells the internal process to immediately report this to server.
3017
3007
  """
@@ -3045,7 +3035,6 @@ class Run:
3045
3035
  settings: "Settings",
3046
3036
  printer: Union["PrinterTerm", "PrinterJupyter"],
3047
3037
  ) -> None:
3048
-
3049
3038
  if not check_version or settings._offline:
3050
3039
  return
3051
3040
 
@@ -3080,7 +3069,6 @@ class Run:
3080
3069
  settings: "Settings",
3081
3070
  printer: Union["PrinterTerm", "PrinterJupyter"],
3082
3071
  ) -> None:
3083
-
3084
3072
  # printer = printer or get_printer(settings._jupyter)
3085
3073
  if settings._offline:
3086
3074
  printer.display(
@@ -3104,7 +3092,6 @@ class Run:
3104
3092
  settings: "Settings",
3105
3093
  printer: Union["PrinterTerm", "PrinterJupyter"],
3106
3094
  ) -> None:
3107
-
3108
3095
  if settings._offline or settings.silent:
3109
3096
  return
3110
3097
 
@@ -3120,13 +3107,11 @@ class Run:
3120
3107
  # printer = printer or get_printer(settings._jupyter)
3121
3108
  if printer._html:
3122
3109
  if not wandb.jupyter.maybe_display():
3123
-
3124
3110
  run_line = f"<strong>{printer.link(run_url, run_name)}</strong>"
3125
3111
  project_line, sweep_line = "", ""
3126
3112
 
3127
3113
  # TODO(settings): make settings the source of truth
3128
3114
  if not wandb.jupyter.quiet():
3129
-
3130
3115
  doc_html = printer.link(wburls.get("doc_run"), "docs")
3131
3116
 
3132
3117
  project_html = printer.link(project_url, "Weights & Biases")
@@ -3224,7 +3209,6 @@ class Run:
3224
3209
  settings: "Settings",
3225
3210
  printer: Union["PrinterTerm", "PrinterJupyter"],
3226
3211
  ) -> None:
3227
-
3228
3212
  if settings.silent:
3229
3213
  return
3230
3214
 
@@ -3320,7 +3304,6 @@ class Run:
3320
3304
  *,
3321
3305
  printer: Union["PrinterTerm", "PrinterJupyter"],
3322
3306
  ) -> None:
3323
-
3324
3307
  # todo: is this same as settings._offline?
3325
3308
  if not all(poll_exit_responses):
3326
3309
  return
@@ -3374,7 +3357,6 @@ class Run:
3374
3357
  settings: "Settings",
3375
3358
  printer: Union["PrinterTerm", "PrinterJupyter"],
3376
3359
  ) -> None:
3377
-
3378
3360
  if settings.silent:
3379
3361
  return
3380
3362
 
@@ -3410,7 +3392,6 @@ class Run:
3410
3392
  settings: "Settings",
3411
3393
  printer: Union["PrinterTerm", "PrinterJupyter"],
3412
3394
  ) -> None:
3413
-
3414
3395
  if (quiet or settings.quiet) or settings.silent:
3415
3396
  return
3416
3397
 
@@ -3430,7 +3411,6 @@ class Run:
3430
3411
  settings: "Settings",
3431
3412
  printer: Union["PrinterTerm", "PrinterJupyter"],
3432
3413
  ) -> None:
3433
-
3434
3414
  if (quiet or settings.quiet) or settings.silent:
3435
3415
  return
3436
3416
 
@@ -3502,7 +3482,6 @@ class Run:
3502
3482
  settings: "Settings",
3503
3483
  printer: Union["PrinterTerm", "PrinterJupyter"],
3504
3484
  ) -> None:
3505
-
3506
3485
  if (quiet or settings.quiet) or settings.silent:
3507
3486
  return
3508
3487
 
@@ -3531,7 +3510,6 @@ class Run:
3531
3510
  settings: "Settings",
3532
3511
  printer: Union["PrinterTerm", "PrinterJupyter"],
3533
3512
  ) -> None:
3534
-
3535
3513
  if (quiet or settings.quiet) or settings.silent:
3536
3514
  return
3537
3515
 
@@ -3555,7 +3533,6 @@ class Run:
3555
3533
  settings: "Settings",
3556
3534
  printer: Union["PrinterTerm", "PrinterJupyter"],
3557
3535
  ) -> None:
3558
-
3559
3536
  if not check_version:
3560
3537
  return
3561
3538
 
@@ -3584,7 +3561,6 @@ class Run:
3584
3561
  settings: "Settings",
3585
3562
  printer: Union["PrinterTerm", "PrinterJupyter"],
3586
3563
  ) -> None:
3587
-
3588
3564
  if (quiet or settings.quiet) or settings.silent:
3589
3565
  return
3590
3566
 
@@ -3615,7 +3591,7 @@ def restore(
3615
3591
  replace: bool = False,
3616
3592
  root: Optional[str] = None,
3617
3593
  ) -> Union[None, TextIO]:
3618
- """Downloads the specified file from cloud storage.
3594
+ """Download the specified file from cloud storage.
3619
3595
 
3620
3596
  File is placed into the current directory or run directory.
3621
3597
  By default, will only download the file if it doesn't already exist.
@@ -3673,7 +3649,7 @@ except AttributeError:
3673
3649
 
3674
3650
 
3675
3651
  def finish(exit_code: Optional[int] = None, quiet: Optional[bool] = None) -> None:
3676
- """Marks a run as finished, and finishes uploading all data.
3652
+ """Mark a run as finished, and finish uploading all data.
3677
3653
 
3678
3654
  This is used when creating multiple runs in the same process.
3679
3655
  We automatically call this method when your script exits.
@@ -3686,25 +3662,33 @@ def finish(exit_code: Optional[int] = None, quiet: Optional[bool] = None) -> Non
3686
3662
  wandb.run.finish(exit_code=exit_code, quiet=quiet)
3687
3663
 
3688
3664
 
3689
- class _LazyArtifact(ArtifactInterface):
3665
+ class InvalidArtifact:
3666
+ """An "artifact" that raises an error when any properties are accessed."""
3667
+
3668
+ def __init__(self, base_artifact: "ArtifactInterface"):
3669
+ super().__setattr__("base_artifact", base_artifact)
3670
+
3671
+ def __getattr__(self, __name: str) -> Any:
3672
+ raise ArtifactNotLoggedError(artifact=self.base_artifact, attr=__name)
3690
3673
 
3674
+ def __setattr__(self, __name: str, __value: Any) -> None:
3675
+ raise ArtifactNotLoggedError(artifact=self.base_artifact, attr=__name)
3676
+
3677
+ def __bool__(self) -> bool:
3678
+ return False
3679
+
3680
+
3681
+ class _LazyArtifact(ArtifactInterface):
3691
3682
  _api: PublicApi
3692
- _instance: Optional[ArtifactInterface] = None
3683
+ _instance: Union[ArtifactInterface, InvalidArtifact]
3693
3684
  _future: Any
3694
3685
 
3695
3686
  def __init__(self, api: PublicApi, future: Any):
3696
3687
  self._api = api
3688
+ self._instance = InvalidArtifact(self)
3697
3689
  self._future = future
3698
3690
 
3699
- def _assert_instance(self) -> ArtifactInterface:
3700
- if not self._instance:
3701
- raise ValueError(
3702
- "Must call wait() before accessing logged artifact properties"
3703
- )
3704
- return self._instance
3705
-
3706
3691
  def __getattr__(self, item: str) -> Any:
3707
- self._assert_instance()
3708
3692
  return getattr(self._instance, item)
3709
3693
 
3710
3694
  def wait(self, timeout: Optional[int] = None) -> ArtifactInterface:
@@ -3727,131 +3711,101 @@ class _LazyArtifact(ArtifactInterface):
3727
3711
 
3728
3712
  @property
3729
3713
  def id(self) -> Optional[str]:
3730
- return self._assert_instance().id
3714
+ return self._instance.id
3731
3715
 
3732
3716
  @property
3733
3717
  def source_version(self) -> Optional[str]:
3734
- return self._assert_instance().source_version
3718
+ return self._instance.source_version
3735
3719
 
3736
3720
  @property
3737
3721
  def version(self) -> str:
3738
- return self._assert_instance().version
3722
+ return self._instance.version
3739
3723
 
3740
3724
  @property
3741
3725
  def name(self) -> str:
3742
- return self._assert_instance().name
3726
+ return self._instance.name
3743
3727
 
3744
3728
  @property
3745
3729
  def type(self) -> str:
3746
- return self._assert_instance().type
3730
+ return self._instance.type
3747
3731
 
3748
3732
  @property
3749
3733
  def entity(self) -> str:
3750
- return self._assert_instance().entity
3734
+ return self._instance.entity
3751
3735
 
3752
3736
  @property
3753
3737
  def project(self) -> str:
3754
- return self._assert_instance().project
3738
+ return self._instance.project
3755
3739
 
3756
3740
  @property
3757
3741
  def manifest(self) -> "ArtifactManifest":
3758
- return self._assert_instance().manifest
3742
+ return self._instance.manifest
3759
3743
 
3760
3744
  @property
3761
3745
  def digest(self) -> str:
3762
- return self._assert_instance().digest
3746
+ return self._instance.digest
3763
3747
 
3764
3748
  @property
3765
3749
  def state(self) -> str:
3766
- return self._assert_instance().state
3750
+ return self._instance.state
3767
3751
 
3768
3752
  @property
3769
3753
  def size(self) -> int:
3770
- return self._assert_instance().size
3754
+ return self._instance.size
3771
3755
 
3772
3756
  @property
3773
3757
  def commit_hash(self) -> str:
3774
- return self._assert_instance().commit_hash
3758
+ return self._instance.commit_hash
3775
3759
 
3776
3760
  @property
3777
3761
  def description(self) -> Optional[str]:
3778
- return self._assert_instance().description
3762
+ return self._instance.description
3779
3763
 
3780
3764
  @description.setter
3781
3765
  def description(self, desc: Optional[str]) -> None:
3782
- self._assert_instance().description = desc
3766
+ self._instance.description = desc
3783
3767
 
3784
3768
  @property
3785
3769
  def metadata(self) -> dict:
3786
- return self._assert_instance().metadata
3770
+ return self._instance.metadata
3787
3771
 
3788
3772
  @metadata.setter
3789
3773
  def metadata(self, metadata: dict) -> None:
3790
- self._assert_instance().metadata = metadata
3774
+ self._instance.metadata = metadata
3791
3775
 
3792
3776
  @property
3793
3777
  def aliases(self) -> List[str]:
3794
- return self._assert_instance().aliases
3778
+ return self._instance.aliases
3795
3779
 
3796
3780
  @aliases.setter
3797
3781
  def aliases(self, aliases: List[str]) -> None:
3798
- self._assert_instance().aliases = aliases
3782
+ self._instance.aliases = aliases
3799
3783
 
3800
3784
  def used_by(self) -> List["wandb.apis.public.Run"]:
3801
- return self._assert_instance().used_by()
3785
+ return self._instance.used_by()
3802
3786
 
3803
3787
  def logged_by(self) -> "wandb.apis.public.Run":
3804
- return self._assert_instance().logged_by()
3805
-
3806
- # Commenting this block out since this code is unreachable since LocalArtifact
3807
- # overrides them and therefore untestable.
3808
- # Leaving behind as we may want to support these in the future.
3809
-
3810
- # def new_file(self, name: str, mode: str = "w") -> Any: # TODO: Refine Type
3811
- # return self._assert_instance().new_file(name, mode)
3812
-
3813
- # def add_file(
3814
- # self,
3815
- # local_path: str,
3816
- # name: Optional[str] = None,
3817
- # is_tmp: Optional[bool] = False,
3818
- # ) -> Any: # TODO: Refine Type
3819
- # return self._assert_instance().add_file(local_path, name, is_tmp)
3820
-
3821
- # def add_dir(self, local_path: str, name: Optional[str] = None) -> None:
3822
- # return self._assert_instance().add_dir(local_path, name)
3823
-
3824
- # def add_reference(
3825
- # self,
3826
- # uri: Union["ArtifactManifestEntry", str],
3827
- # name: Optional[str] = None,
3828
- # checksum: bool = True,
3829
- # max_objects: Optional[int] = None,
3830
- # ) -> Any: # TODO: Refine Type
3831
- # return self._assert_instance().add_reference(uri, name, checksum, max_objects)
3832
-
3833
- # def add(self, obj: "WBValue", name: str) -> Any: # TODO: Refine Type
3834
- # return self._assert_instance().add(obj, name)
3788
+ return self._instance.logged_by()
3835
3789
 
3836
3790
  def get_path(self, name: str) -> "ArtifactManifestEntry":
3837
- return self._assert_instance().get_path(name)
3791
+ return self._instance.get_path(name)
3838
3792
 
3839
3793
  def get(self, name: str) -> "WBValue":
3840
- return self._assert_instance().get(name)
3794
+ return self._instance.get(name)
3841
3795
 
3842
3796
  def download(
3843
3797
  self, root: Optional[str] = None, recursive: bool = False
3844
3798
  ) -> util.FilePathStr:
3845
- return self._assert_instance().download(root, recursive)
3799
+ return self._instance.download(root, recursive)
3846
3800
 
3847
3801
  def checkout(self, root: Optional[str] = None) -> str:
3848
- return self._assert_instance().checkout(root)
3802
+ return self._instance.checkout(root)
3849
3803
 
3850
3804
  def verify(self, root: Optional[str] = None) -> Any:
3851
- return self._assert_instance().verify(root)
3805
+ return self._instance.verify(root)
3852
3806
 
3853
3807
  def save(self) -> None:
3854
- return self._assert_instance().save()
3808
+ self._instance.save()
3855
3809
 
3856
3810
  def delete(self) -> None:
3857
- return self._assert_instance().delete()
3811
+ self._instance.delete()