wandb 0.15.4__py3-none-any.whl → 0.15.5__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. wandb/__init__.py +1 -1
  2. wandb/analytics/sentry.py +1 -0
  3. wandb/apis/internal.py +3 -0
  4. wandb/apis/public.py +18 -20
  5. wandb/beta/workflows.py +5 -6
  6. wandb/cli/cli.py +27 -27
  7. wandb/data_types.py +2 -0
  8. wandb/integration/langchain/wandb_tracer.py +16 -179
  9. wandb/integration/sagemaker/config.py +2 -2
  10. wandb/integration/tensorboard/log.py +4 -4
  11. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  12. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  13. wandb/proto/wandb_deprecated.py +3 -1
  14. wandb/sdk/__init__.py +1 -4
  15. wandb/sdk/artifacts/__init__.py +0 -14
  16. wandb/sdk/artifacts/artifact.py +1757 -277
  17. wandb/sdk/artifacts/artifact_manifest_entry.py +26 -6
  18. wandb/sdk/artifacts/artifact_state.py +10 -0
  19. wandb/sdk/artifacts/artifacts_cache.py +7 -8
  20. wandb/sdk/artifacts/exceptions.py +4 -4
  21. wandb/sdk/artifacts/storage_handler.py +2 -2
  22. wandb/sdk/artifacts/storage_handlers/azure_handler.py +16 -6
  23. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +2 -2
  24. wandb/sdk/artifacts/storage_handlers/http_handler.py +2 -2
  25. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +2 -2
  26. wandb/sdk/artifacts/storage_handlers/multi_handler.py +2 -2
  27. wandb/sdk/artifacts/storage_handlers/s3_handler.py +35 -32
  28. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +2 -2
  29. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +5 -9
  30. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +2 -2
  31. wandb/sdk/artifacts/storage_policies/s3_bucket_policy.py +2 -2
  32. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +24 -16
  33. wandb/sdk/artifacts/storage_policy.py +3 -3
  34. wandb/sdk/data_types/_dtypes.py +7 -12
  35. wandb/sdk/data_types/base_types/json_metadata.py +2 -2
  36. wandb/sdk/data_types/base_types/media.py +5 -6
  37. wandb/sdk/data_types/base_types/wb_value.py +12 -13
  38. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +4 -5
  39. wandb/sdk/data_types/helper_types/classes.py +5 -8
  40. wandb/sdk/data_types/helper_types/image_mask.py +4 -5
  41. wandb/sdk/data_types/histogram.py +3 -3
  42. wandb/sdk/data_types/html.py +3 -4
  43. wandb/sdk/data_types/image.py +4 -5
  44. wandb/sdk/data_types/molecule.py +2 -2
  45. wandb/sdk/data_types/object_3d.py +3 -3
  46. wandb/sdk/data_types/plotly.py +2 -2
  47. wandb/sdk/data_types/saved_model.py +7 -8
  48. wandb/sdk/data_types/trace_tree.py +4 -4
  49. wandb/sdk/data_types/video.py +4 -4
  50. wandb/sdk/interface/interface.py +8 -10
  51. wandb/sdk/internal/file_stream.py +2 -3
  52. wandb/sdk/internal/internal_api.py +99 -4
  53. wandb/sdk/internal/job_builder.py +15 -7
  54. wandb/sdk/internal/sender.py +4 -0
  55. wandb/sdk/internal/settings_static.py +1 -0
  56. wandb/sdk/launch/_project_spec.py +9 -7
  57. wandb/sdk/launch/agent/agent.py +115 -58
  58. wandb/sdk/launch/agent/job_status_tracker.py +34 -0
  59. wandb/sdk/launch/agent/run_queue_item_file_saver.py +45 -0
  60. wandb/sdk/launch/builder/abstract.py +5 -1
  61. wandb/sdk/launch/builder/build.py +16 -10
  62. wandb/sdk/launch/builder/docker_builder.py +9 -2
  63. wandb/sdk/launch/builder/kaniko_builder.py +108 -22
  64. wandb/sdk/launch/builder/noop.py +3 -1
  65. wandb/sdk/launch/environment/aws_environment.py +2 -1
  66. wandb/sdk/launch/environment/azure_environment.py +124 -0
  67. wandb/sdk/launch/github_reference.py +30 -18
  68. wandb/sdk/launch/launch.py +1 -1
  69. wandb/sdk/launch/loader.py +15 -0
  70. wandb/sdk/launch/registry/azure_container_registry.py +132 -0
  71. wandb/sdk/launch/registry/elastic_container_registry.py +38 -4
  72. wandb/sdk/launch/registry/google_artifact_registry.py +46 -7
  73. wandb/sdk/launch/runner/abstract.py +19 -3
  74. wandb/sdk/launch/runner/kubernetes_runner.py +111 -47
  75. wandb/sdk/launch/runner/local_container.py +101 -48
  76. wandb/sdk/launch/runner/sagemaker_runner.py +59 -9
  77. wandb/sdk/launch/runner/vertex_runner.py +8 -4
  78. wandb/sdk/launch/sweeps/scheduler.py +102 -27
  79. wandb/sdk/launch/sweeps/utils.py +21 -0
  80. wandb/sdk/launch/utils.py +19 -7
  81. wandb/sdk/lib/_settings_toposort_generated.py +3 -0
  82. wandb/sdk/service/server.py +22 -9
  83. wandb/sdk/service/service.py +27 -8
  84. wandb/sdk/verify/verify.py +6 -9
  85. wandb/sdk/wandb_config.py +2 -4
  86. wandb/sdk/wandb_init.py +2 -0
  87. wandb/sdk/wandb_require.py +7 -0
  88. wandb/sdk/wandb_run.py +32 -35
  89. wandb/sdk/wandb_settings.py +10 -3
  90. wandb/testing/relay.py +15 -2
  91. wandb/util.py +55 -23
  92. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/METADATA +11 -8
  93. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/RECORD +97 -97
  94. wandb/integration/langchain/util.py +0 -191
  95. wandb/sdk/artifacts/invalid_artifact.py +0 -23
  96. wandb/sdk/artifacts/lazy_artifact.py +0 -162
  97. wandb/sdk/artifacts/local_artifact.py +0 -719
  98. wandb/sdk/artifacts/public_artifact.py +0 -1188
  99. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/LICENSE +0 -0
  100. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/WHEEL +0 -0
  101. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/entry_points.txt +0 -0
  102. {wandb-0.15.4.dist-info → wandb-0.15.5.dist-info}/top_level.txt +0 -0
@@ -23,6 +23,7 @@ _Setting = Literal[
23
23
  "_disable_service",
24
24
  "_disable_stats",
25
25
  "_disable_viewer",
26
+ "_disable_setproctitle",
26
27
  "_except_exit",
27
28
  "_executable",
28
29
  "_extra_http_headers",
@@ -48,6 +49,7 @@ _Setting = Literal[
48
49
  "_platform",
49
50
  "_python",
50
51
  "_runqueue_item_id",
52
+ "_require_nexus",
51
53
  "_save_requirements",
52
54
  "_service_transport",
53
55
  "_service_wait",
@@ -67,6 +69,7 @@ _Setting = Literal[
67
69
  "allow_val_change",
68
70
  "anonymous",
69
71
  "api_key",
72
+ "azure_account_url_to_access_key",
70
73
  "base_url",
71
74
  "code_dir",
72
75
  "config_paths",
@@ -129,15 +129,15 @@ class WandbServer:
129
129
  return
130
130
  _startup_debug.print_message(message)
131
131
 
132
- def serve(self) -> None:
133
- self._setup_tracelog()
134
- mux = StreamMux()
135
- self._startup_debug_print("before_network")
136
- grpc_port = self._start_grpc(mux=mux) if self._serve_grpc else None
137
- sock_port = self._start_sock(mux=mux) if self._serve_sock else None
138
- self._startup_debug_print("after_network")
139
- self._inform_used_ports(grpc_port=grpc_port, sock_port=sock_port)
140
- self._startup_debug_print("after_inform")
132
+ def _setup_proctitle(
133
+ self, grpc_port: Optional[int], sock_port: Optional[int]
134
+ ) -> None:
135
+ # TODO: similar to _setup_tracelog, the internal_process should have
136
+ # a better way to have access to settings.
137
+ disable_setproctitle = os.environ.get("WANDB__DISABLE_SETPROCTITLE")
138
+ if disable_setproctitle:
139
+ return
140
+
141
141
  setproctitle = wandb.util.get_optional_module("setproctitle")
142
142
  if setproctitle:
143
143
  service_ver = 2
@@ -148,7 +148,20 @@ class WandbServer:
148
148
  # (consider unifying this in the future)
149
149
  service_id = f"{service_ver}-{pid}-{transport}-{port}"
150
150
  proc_title = f"wandb-service({service_id})"
151
+ self._startup_debug_print("before_setproctitle")
151
152
  setproctitle.setproctitle(proc_title)
153
+ self._startup_debug_print("after_setproctitle")
154
+
155
+ def serve(self) -> None:
156
+ self._setup_tracelog()
157
+ mux = StreamMux()
158
+ self._startup_debug_print("before_network")
159
+ grpc_port = self._start_grpc(mux=mux) if self._serve_grpc else None
160
+ sock_port = self._start_sock(mux=mux) if self._serve_sock else None
161
+ self._startup_debug_print("after_network")
162
+ self._inform_used_ports(grpc_port=grpc_port, sock_port=sock_port)
163
+ self._startup_debug_print("after_inform")
164
+ self._setup_proctitle(grpc_port=grpc_port, sock_port=sock_port)
152
165
  self._startup_debug_print("before_loop")
153
166
  mux.loop()
154
167
  self._stop_servers()
@@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional
14
14
 
15
15
  from wandb import _sentry
16
16
  from wandb.errors import Error
17
+ from wandb.util import get_module
17
18
 
18
19
  from . import _startup_debug, port_file
19
20
  from .service_base import ServiceInterface
@@ -168,9 +169,24 @@ class _Service:
168
169
  # Add coverage collection if needed
169
170
  if os.environ.get("YEA_RUN_COVERAGE") and os.environ.get("COVERAGE_RCFILE"):
170
171
  exec_cmd_list += ["coverage", "run", "-m"]
171
- service_args = [
172
- "wandb",
173
- "service",
172
+
173
+ service_args = []
174
+ if self._settings._require_nexus:
175
+ # NOTE: the wandb_core module will be distributed at first as an alpha
176
+ # package as "wandb-core-alpha" to avoid polluting the pypi namespace.
177
+ # When the package reaches compatibility milestones, it will be released
178
+ # as "wandb-core".
179
+ wandb_nexus = get_module(
180
+ "wandb_core",
181
+ required="The nexus experiment requires the wandb_core module.",
182
+ )
183
+ nexus_path = wandb_nexus.get_nexus_path()
184
+ service_args.extend([nexus_path])
185
+ exec_cmd_list = []
186
+ else:
187
+ service_args.extend(["wandb", "service"])
188
+
189
+ service_args += [
174
190
  "--port-filename",
175
191
  fname,
176
192
  "--pid",
@@ -181,11 +197,14 @@ class _Service:
181
197
  service_args.append("--serve-grpc")
182
198
  else:
183
199
  service_args.append("--serve-sock")
184
- internal_proc = subprocess.Popen(
185
- exec_cmd_list + service_args,
186
- env=os.environ,
187
- **kwargs,
188
- )
200
+ try:
201
+ internal_proc = subprocess.Popen(
202
+ exec_cmd_list + service_args,
203
+ env=os.environ,
204
+ **kwargs,
205
+ )
206
+ except Exception as e:
207
+ _sentry.reraise(e)
189
208
  self._startup_debug_print("wait_ports")
190
209
  try:
191
210
  self._wait_for_ports(fname, proc=internal_proc)
@@ -12,8 +12,7 @@ from pkg_resources import parse_version
12
12
  from wandb_gql import gql
13
13
 
14
14
  import wandb
15
- from wandb.sdk.artifacts.local_artifact import Artifact as LocalArtifact
16
- from wandb.sdk.artifacts.public_artifact import Artifact as PublicArtifact
15
+ from wandb.sdk.artifacts.artifact import Artifact
17
16
  from wandb.sdk.lib import runid
18
17
 
19
18
  from ...apis.internal import Api
@@ -224,7 +223,7 @@ def verify_manifest(
224
223
 
225
224
 
226
225
  def verify_digest(
227
- downloaded: "PublicArtifact", computed: "PublicArtifact", fails_list: List[str]
226
+ downloaded: "Artifact", computed: "Artifact", fails_list: List[str]
228
227
  ) -> None:
229
228
  if downloaded.digest != computed.digest:
230
229
  fails_list.append(
@@ -234,7 +233,7 @@ def verify_digest(
234
233
 
235
234
  def artifact_with_path_or_paths(
236
235
  name: str, verify_dir: Optional[str] = None, singular: bool = False
237
- ) -> "LocalArtifact":
236
+ ) -> "Artifact":
238
237
  art = wandb.Artifact(type="artsy", name=name)
239
238
  # internal file
240
239
  with open("verify_int_test.txt", "w") as f:
@@ -262,13 +261,13 @@ def artifact_with_path_or_paths(
262
261
 
263
262
 
264
263
  def log_use_download_artifact(
265
- artifact: "LocalArtifact",
264
+ artifact: "Artifact",
266
265
  alias: str,
267
266
  name: str,
268
267
  download_dir: str,
269
268
  failed_test_strings: List[str],
270
269
  add_extra_file: bool,
271
- ) -> Tuple[bool, Optional["PublicArtifact"], List[str]]:
270
+ ) -> Tuple[bool, Optional["Artifact"], List[str]]:
272
271
  with wandb.init(
273
272
  id=nice_id("log_artifact"),
274
273
  reinit=True,
@@ -357,9 +356,7 @@ def check_artifacts() -> bool:
357
356
  verify_digest(download_artifact, computed, failed_test_strings)
358
357
 
359
358
  computed_manifest = computed.manifest.to_manifest_json()["contents"]
360
- downloaded_manifest = download_artifact._load_manifest().to_manifest_json()[
361
- "contents"
362
- ]
359
+ downloaded_manifest = download_artifact.manifest.to_manifest_json()["contents"]
363
360
  verify_manifest(downloaded_manifest, computed_manifest, failed_test_strings)
364
361
 
365
362
  print_results(failed_test_strings, False)
wandb/sdk/wandb_config.py CHANGED
@@ -4,7 +4,6 @@ import logging
4
4
  from typing import Optional
5
5
 
6
6
  import wandb
7
- from wandb.sdk.artifacts.public_artifact import Artifact as PublicArtifact
8
7
  from wandb.util import (
9
8
  _is_artifact_representation,
10
9
  check_dict_contains_nested_artifact,
@@ -252,7 +251,7 @@ class Config:
252
251
  if _is_artifact_representation(val):
253
252
  val = self._artifact_callback(key, val)
254
253
  # if the user inserts an artifact into the config
255
- if not (isinstance(val, wandb.Artifact) or isinstance(val, PublicArtifact)):
254
+ if not isinstance(val, wandb.Artifact):
256
255
  val = json_friendly_val(val)
257
256
  if not allow_val_change:
258
257
  if key in self._items and val != self._items[key]:
@@ -271,8 +270,7 @@ class Config:
271
270
  # best if we don't allow nested artifacts until we can lock nested keys in the config
272
271
  if isinstance(v, dict) and check_dict_contains_nested_artifact(v, nested):
273
272
  raise ValueError(
274
- "Instances of wandb.Artifact and PublicArtifact"
275
- " can only be top level keys in wandb.config"
273
+ "Instances of wandb.Artifact can only be top level keys in wandb.config"
276
274
  )
277
275
 
278
276
 
wandb/sdk/wandb_init.py CHANGED
@@ -675,6 +675,8 @@ class _WandbInit:
675
675
  tel.feature.flow_control_disabled = True
676
676
  if self.settings._flow_control_custom:
677
677
  tel.feature.flow_control_custom = True
678
+ if self.settings._require_nexus:
679
+ tel.feature.nexus = True
678
680
 
679
681
  tel.env.maybe_mp = _maybe_mp_process(backend)
680
682
 
@@ -9,6 +9,7 @@ Example:
9
9
  wandb.require("incremental-artifacts@beta")
10
10
  """
11
11
 
12
+ import os
12
13
  from typing import Optional, Sequence, Union
13
14
 
14
15
  import wandb
@@ -38,6 +39,12 @@ class _Requires:
38
39
  def require_service(self) -> None:
39
40
  self._require_service()
40
41
 
42
+ def _require_nexus(self) -> None:
43
+ os.environ["WANDB_REQUIRE_NEXUS"] = "True"
44
+
45
+ def require_nexus(self) -> None:
46
+ self._require_nexus()
47
+
41
48
  def apply(self) -> None:
42
49
  """Call require_* method for supported features."""
43
50
  last_message: str = ""
wandb/sdk/wandb_run.py CHANGED
@@ -47,9 +47,7 @@ from wandb.proto.wandb_internal_pb2 import (
47
47
  RunRecord,
48
48
  ServerInfoResponse,
49
49
  )
50
- from wandb.sdk.artifacts.lazy_artifact import LazyArtifact
51
- from wandb.sdk.artifacts.local_artifact import Artifact as LocalArtifact
52
- from wandb.sdk.artifacts.public_artifact import Artifact as PublicArtifact
50
+ from wandb.sdk.artifacts.artifact import Artifact
53
51
  from wandb.sdk.internal import job_builder
54
52
  from wandb.sdk.lib.import_hooks import (
55
53
  register_post_import_hook,
@@ -1051,7 +1049,7 @@ class Run:
1051
1049
  name: Optional[str] = None,
1052
1050
  include_fn: Callable[[str], bool] = _is_py_path,
1053
1051
  exclude_fn: Callable[[str], bool] = filenames.exclude_wandb_fn,
1054
- ) -> Optional[LocalArtifact]:
1052
+ ) -> Optional[Artifact]:
1055
1053
  """Save the current state of your code to a W&B Artifact.
1056
1054
 
1057
1055
  By default, it walks the current directory and logs all files that end with `.py`.
@@ -1285,15 +1283,15 @@ class Run:
1285
1283
  self._backend.interface.publish_config(key=key, val=val, data=data)
1286
1284
 
1287
1285
  def _config_artifact_callback(
1288
- self, key: str, val: Union[str, LocalArtifact, dict]
1289
- ) -> Union[LocalArtifact, PublicArtifact]:
1286
+ self, key: str, val: Union[str, Artifact, dict]
1287
+ ) -> Artifact:
1290
1288
  # artifacts can look like dicts as they are passed into the run config
1291
1289
  # since the run config stores them on the backend as a dict with fields shown
1292
1290
  # in wandb.util.artifact_to_json
1293
1291
  if _is_artifact_version_weave_dict(val):
1294
1292
  assert isinstance(val, dict)
1295
1293
  public_api = self._public_api()
1296
- artifact = PublicArtifact.from_id(val["id"], public_api.client)
1294
+ artifact = Artifact._from_id(val["id"], public_api.client)
1297
1295
  return self.use_artifact(artifact, use_as=key)
1298
1296
  elif _is_artifact_string(val):
1299
1297
  # this will never fail, but is required to make mypy happy
@@ -1306,12 +1304,11 @@ class Run:
1306
1304
  else:
1307
1305
  public_api = self._public_api()
1308
1306
  if is_id:
1309
- artifact = PublicArtifact.from_id(artifact_string, public_api._client)
1307
+ artifact = Artifact._from_id(artifact_string, public_api._client)
1310
1308
  else:
1311
1309
  artifact = public_api.artifact(name=artifact_string)
1312
1310
  # in the future we'll need to support using artifacts from
1313
- # different instances of wandb. simplest way to do that is
1314
- # likely to convert the retrieved PublicArtifact to a LocalArtifact
1311
+ # different instances of wandb.
1315
1312
 
1316
1313
  return self.use_artifact(artifact, use_as=key)
1317
1314
  elif _is_artifact_object(val):
@@ -2272,7 +2269,7 @@ class Run:
2272
2269
  source_dict: "JobSourceDict",
2273
2270
  installed_packages_list: List[str],
2274
2271
  patch_path: Optional[os.PathLike] = None,
2275
- ) -> "LocalArtifact":
2272
+ ) -> "Artifact":
2276
2273
  job_artifact = job_builder.JobArtifact(name)
2277
2274
  if patch_path and os.path.exists(patch_path):
2278
2275
  job_artifact.add_file(FilePathStr(str(patch_path)), "diff.patch")
@@ -2290,7 +2287,7 @@ class Run:
2290
2287
  installed_packages_list: List[str],
2291
2288
  docker_image_name: Optional[str] = None,
2292
2289
  args: Optional[List[str]] = None,
2293
- ) -> Optional["LocalArtifact"]:
2290
+ ) -> Optional["Artifact"]:
2294
2291
  docker_image_name = docker_image_name or os.getenv("WANDB_DOCKER")
2295
2292
 
2296
2293
  if not docker_image_name:
@@ -2314,7 +2311,7 @@ class Run:
2314
2311
 
2315
2312
  def _log_job_artifact_with_image(
2316
2313
  self, docker_image_name: str, args: Optional[List[str]] = None
2317
- ) -> LocalArtifact:
2314
+ ) -> Artifact:
2318
2315
  packages, in_types, out_types = self._make_job_source_reqs()
2319
2316
  job_artifact = self._create_image_job(
2320
2317
  in_types,
@@ -2590,7 +2587,7 @@ class Run:
2590
2587
  @_run_decorator._attach
2591
2588
  def link_artifact(
2592
2589
  self,
2593
- artifact: Union[PublicArtifact, LocalArtifact],
2590
+ artifact: Artifact,
2594
2591
  target_path: str,
2595
2592
  aliases: Optional[List[str]] = None,
2596
2593
  ) -> None:
@@ -2615,7 +2612,7 @@ class Run:
2615
2612
  aliases = []
2616
2613
 
2617
2614
  if self._backend and self._backend.interface:
2618
- if isinstance(artifact, LocalArtifact) and not artifact._logged_artifact:
2615
+ if artifact.is_draft() and not artifact._is_draft_save_started():
2619
2616
  artifact = self._log_artifact(artifact)
2620
2617
  if not self._settings._offline:
2621
2618
  self._backend.interface.publish_link_artifact(
@@ -2634,11 +2631,11 @@ class Run:
2634
2631
  @_run_decorator._attach
2635
2632
  def use_artifact(
2636
2633
  self,
2637
- artifact_or_name: Union[str, PublicArtifact, LocalArtifact],
2634
+ artifact_or_name: Union[str, Artifact],
2638
2635
  type: Optional[str] = None,
2639
2636
  aliases: Optional[List[str]] = None,
2640
2637
  use_as: Optional[str] = None,
2641
- ) -> Union[PublicArtifact, LocalArtifact]:
2638
+ ) -> Artifact:
2642
2639
  """Declare an artifact as an input to a run.
2643
2640
 
2644
2641
  Call `download` or `file` on the returned object to get the contents locally.
@@ -2703,10 +2700,10 @@ class Run:
2703
2700
  aliases = []
2704
2701
  elif isinstance(aliases, str):
2705
2702
  aliases = [aliases]
2706
- if isinstance(artifact_or_name, wandb.Artifact):
2703
+ if isinstance(artifact_or_name, Artifact) and artifact.is_draft():
2707
2704
  if use_as is not None:
2708
2705
  wandb.termwarn(
2709
- "Indicating use_as is not supported when using an artifact with an instance of `wandb.Artifact`"
2706
+ "Indicating use_as is not supported when using a draft artifact"
2710
2707
  )
2711
2708
  self._log_artifact(
2712
2709
  artifact,
@@ -2716,13 +2713,13 @@ class Run:
2716
2713
  )
2717
2714
  artifact.wait()
2718
2715
  artifact._use_as = use_as or artifact.name
2719
- elif isinstance(artifact, PublicArtifact):
2716
+ elif isinstance(artifact, Artifact) and not artifact.is_draft():
2720
2717
  if (
2721
2718
  self._launch_artifact_mapping
2722
2719
  and artifact.name in self._launch_artifact_mapping.keys()
2723
2720
  ):
2724
2721
  wandb.termwarn(
2725
- "Swapping artifacts is not supported when using an instance of `PublicArtifact`. "
2722
+ "Swapping artifacts is not supported when using a non-draft artifact. "
2726
2723
  f"Using {artifact.name}."
2727
2724
  )
2728
2725
  artifact._use_as = use_as or artifact.name
@@ -2742,11 +2739,11 @@ class Run:
2742
2739
  @_run_decorator._attach
2743
2740
  def log_artifact(
2744
2741
  self,
2745
- artifact_or_path: Union[LocalArtifact, StrPath],
2742
+ artifact_or_path: Union[Artifact, StrPath],
2746
2743
  name: Optional[str] = None,
2747
2744
  type: Optional[str] = None,
2748
2745
  aliases: Optional[List[str]] = None,
2749
- ) -> LocalArtifact:
2746
+ ) -> Artifact:
2750
2747
  """Declare an artifact as an output of a run.
2751
2748
 
2752
2749
  Arguments:
@@ -2779,12 +2776,12 @@ class Run:
2779
2776
  @_run_decorator._attach
2780
2777
  def upsert_artifact(
2781
2778
  self,
2782
- artifact_or_path: Union[LocalArtifact, str],
2779
+ artifact_or_path: Union[Artifact, str],
2783
2780
  name: Optional[str] = None,
2784
2781
  type: Optional[str] = None,
2785
2782
  aliases: Optional[List[str]] = None,
2786
2783
  distributed_id: Optional[str] = None,
2787
- ) -> LocalArtifact:
2784
+ ) -> Artifact:
2788
2785
  """Declare (or append to) a non-finalized artifact as output of a run.
2789
2786
 
2790
2787
  Note that you must call run.finish_artifact() to finalize the artifact.
@@ -2833,12 +2830,12 @@ class Run:
2833
2830
  @_run_decorator._attach
2834
2831
  def finish_artifact(
2835
2832
  self,
2836
- artifact_or_path: Union[LocalArtifact, str],
2833
+ artifact_or_path: Union[Artifact, str],
2837
2834
  name: Optional[str] = None,
2838
2835
  type: Optional[str] = None,
2839
2836
  aliases: Optional[List[str]] = None,
2840
2837
  distributed_id: Optional[str] = None,
2841
- ) -> LocalArtifact:
2838
+ ) -> Artifact:
2842
2839
  """Finishes a non-finalized artifact as output of a run.
2843
2840
 
2844
2841
  Subsequent "upserts" with the same distributed ID will result in a new version.
@@ -2885,7 +2882,7 @@ class Run:
2885
2882
 
2886
2883
  def _log_artifact(
2887
2884
  self,
2888
- artifact_or_path: Union[LocalArtifact, StrPath],
2885
+ artifact_or_path: Union[Artifact, StrPath],
2889
2886
  name: Optional[str] = None,
2890
2887
  type: Optional[str] = None,
2891
2888
  aliases: Optional[List[str]] = None,
@@ -2893,7 +2890,7 @@ class Run:
2893
2890
  finalize: bool = True,
2894
2891
  is_user_created: bool = False,
2895
2892
  use_after_commit: bool = False,
2896
- ) -> LocalArtifact:
2893
+ ) -> Artifact:
2897
2894
  api = internal.Api()
2898
2895
  if api.settings().get("anonymous") == "true":
2899
2896
  wandb.termwarn(
@@ -2922,7 +2919,7 @@ class Run:
2922
2919
  is_user_created=is_user_created,
2923
2920
  use_after_commit=use_after_commit,
2924
2921
  )
2925
- artifact._logged_artifact = LazyArtifact(self._public_api(), future)
2922
+ artifact._set_save_future(future, self._public_api().client)
2926
2923
  else:
2927
2924
  self._backend.interface.publish_artifact(
2928
2925
  self,
@@ -2955,11 +2952,11 @@ class Run:
2955
2952
  if not self._settings._offline:
2956
2953
  try:
2957
2954
  public_api = self._public_api()
2958
- expected_type = PublicArtifact.expected_type(
2959
- public_api.client,
2960
- artifact.name,
2955
+ expected_type = Artifact._expected_type(
2961
2956
  public_api.settings["entity"],
2962
2957
  public_api.settings["project"],
2958
+ artifact.name,
2959
+ public_api.client,
2963
2960
  )
2964
2961
  except requests.exceptions.RequestException:
2965
2962
  # Just return early if there is a network error. This is
@@ -2974,11 +2971,11 @@ class Run:
2974
2971
 
2975
2972
  def _prepare_artifact(
2976
2973
  self,
2977
- artifact_or_path: Union[LocalArtifact, StrPath],
2974
+ artifact_or_path: Union[Artifact, StrPath],
2978
2975
  name: Optional[str] = None,
2979
2976
  type: Optional[str] = None,
2980
2977
  aliases: Optional[List[str]] = None,
2981
- ) -> Tuple[LocalArtifact, List[str]]:
2978
+ ) -> Tuple[Artifact, List[str]]:
2982
2979
  if isinstance(artifact_or_path, (str, os.PathLike)):
2983
2980
  name = name or f"run-{self._run_id}-{os.path.basename(artifact_or_path)}"
2984
2981
  artifact = wandb.Artifact(name, type or "unspecified")
@@ -457,10 +457,11 @@ class Settings:
457
457
  _config_dict: Config
458
458
  _console: SettingsConsole
459
459
  _cuda: str
460
- _disable_meta: bool
461
- _disable_service: bool
462
- _disable_stats: bool
460
+ _disable_meta: bool # Do not collect system metadata
461
+ _disable_service: bool # Disable wandb-service, spin up internal process the old way
462
+ _disable_stats: bool # Do not collect system metrics
463
463
  _disable_viewer: bool # Prevent early viewer query
464
+ _disable_setproctitle: bool # Do not use setproctitle on internal process
464
465
  _except_exit: bool
465
466
  _executable: str
466
467
  _extra_http_headers: Mapping[str, str]
@@ -486,6 +487,7 @@ class Settings:
486
487
  _platform: str
487
488
  _python: str
488
489
  _runqueue_item_id: str
490
+ _require_nexus: bool
489
491
  _save_requirements: bool
490
492
  _service_transport: str
491
493
  _service_wait: float
@@ -508,6 +510,7 @@ class Settings:
508
510
  allow_val_change: bool
509
511
  anonymous: str
510
512
  api_key: str
513
+ azure_account_url_to_access_key: Dict[str, str]
511
514
  base_url: str # The base url for the wandb api
512
515
  code_dir: str
513
516
  config_paths: Sequence[str]
@@ -616,6 +619,7 @@ class Settings:
616
619
  "preprocessor": _str_as_bool,
617
620
  "is_policy": True,
618
621
  },
622
+ _disable_setproctitle={"value": False, "preprocessor": _str_as_bool},
619
623
  _disable_stats={"preprocessor": _str_as_bool},
620
624
  _disable_viewer={"preprocessor": _str_as_bool},
621
625
  _extra_http_headers={"preprocessor": _str_as_json},
@@ -662,6 +666,7 @@ class Settings:
662
666
  },
663
667
  _sync={"value": False},
664
668
  _platform={"value": util.get_platform_name()},
669
+ _require_nexus={"value": False, "preprocessor": _str_as_bool},
665
670
  _save_requirements={"value": True, "preprocessor": _str_as_bool},
666
671
  _service_wait={
667
672
  "value": 30,
@@ -700,6 +705,7 @@ class Settings:
700
705
  },
701
706
  anonymous={"validator": self._validate_anonymous},
702
707
  api_key={"validator": self._validate_api_key},
708
+ azure_account_url_to_access_key={"value": {}},
703
709
  base_url={
704
710
  "value": "https://api.wandb.ai",
705
711
  "preprocessor": lambda x: str(x).strip().rstrip("/"),
@@ -1559,6 +1565,7 @@ class Settings:
1559
1565
  "WANDB_TRACELOG": "_tracelog",
1560
1566
  "WANDB_DISABLE_SERVICE": "_disable_service",
1561
1567
  "WANDB_SERVICE_TRANSPORT": "_service_transport",
1568
+ "WANDB_REQUIRE_NEXUS": "_require_nexus",
1562
1569
  "WANDB_DIR": "root_dir",
1563
1570
  "WANDB_NAME": "run_name",
1564
1571
  "WANDB_NOTES": "run_notes",
wandb/testing/relay.py CHANGED
@@ -4,6 +4,7 @@ import logging
4
4
  import socket
5
5
  import sys
6
6
  import threading
7
+ import traceback
7
8
  import urllib.parse
8
9
  from collections import defaultdict, deque
9
10
  from copy import deepcopy
@@ -294,7 +295,9 @@ class QueryResolver:
294
295
  }
295
296
  post_processed_data = {
296
297
  "name": name,
297
- "dropped": [request_data["dropped"]],
298
+ "dropped": [request_data["dropped"]]
299
+ if "dropped" in request_data
300
+ else [],
298
301
  "files": files,
299
302
  }
300
303
  return post_processed_data
@@ -642,7 +645,17 @@ class RelayServer:
642
645
  }
643
646
  self.context.raw_data.append(raw_data)
644
647
 
645
- snooped_context = self.resolver.resolve(request_data, response_data, **kwargs)
648
+ try:
649
+ snooped_context = self.resolver.resolve(
650
+ request_data,
651
+ response_data,
652
+ **kwargs,
653
+ )
654
+ except Exception as e:
655
+ print("Failed to resolve context: ", e)
656
+ traceback.print_exc()
657
+ snooped_context = None
658
+
646
659
  if snooped_context is not None:
647
660
  self.context.upsert(snooped_context)
648
661