wandb 0.16.6__py3-none-any.whl → 0.17.0rc1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package_readme.md +95 -0
  2. wandb/__init__.py +2 -2
  3. wandb/agents/pyagent.py +0 -1
  4. wandb/analytics/sentry.py +2 -1
  5. wandb/apis/importers/internals/protocols.py +30 -56
  6. wandb/apis/importers/mlflow.py +13 -26
  7. wandb/apis/importers/wandb.py +8 -14
  8. wandb/apis/public/api.py +1 -0
  9. wandb/apis/public/artifacts.py +1 -0
  10. wandb/apis/public/files.py +1 -0
  11. wandb/apis/public/history.py +1 -0
  12. wandb/apis/public/jobs.py +1 -0
  13. wandb/apis/public/projects.py +1 -0
  14. wandb/apis/public/reports.py +1 -0
  15. wandb/apis/public/runs.py +1 -0
  16. wandb/apis/public/sweeps.py +1 -0
  17. wandb/apis/public/teams.py +1 -0
  18. wandb/apis/public/users.py +1 -0
  19. wandb/apis/reports/v1/_blocks.py +2 -6
  20. wandb/apis/reports/v2/gql.py +1 -0
  21. wandb/apis/reports/v2/interface.py +3 -4
  22. wandb/apis/reports/v2/internal.py +5 -8
  23. wandb/cli/cli.py +2 -2
  24. wandb/data_types.py +3 -3
  25. wandb/env.py +35 -5
  26. wandb/errors/__init__.py +5 -0
  27. wandb/integration/catboost/catboost.py +1 -1
  28. wandb/integration/fastai/__init__.py +1 -0
  29. wandb/integration/keras/__init__.py +1 -0
  30. wandb/integration/keras/keras.py +6 -6
  31. wandb/integration/langchain/wandb_tracer.py +1 -0
  32. wandb/integration/lightning/fabric/logger.py +1 -3
  33. wandb/integration/metaflow/metaflow.py +41 -6
  34. wandb/integration/openai/fine_tuning.py +3 -3
  35. wandb/keras/__init__.py +1 -0
  36. wandb/proto/v3/wandb_internal_pb2.py +364 -332
  37. wandb/proto/v3/wandb_settings_pb2.py +1 -1
  38. wandb/proto/v4/wandb_internal_pb2.py +322 -316
  39. wandb/proto/v4/wandb_settings_pb2.py +1 -1
  40. wandb/proto/wandb_internal_codegen.py +0 -25
  41. wandb/sdk/artifacts/artifact.py +16 -4
  42. wandb/sdk/artifacts/artifact_download_logger.py +1 -0
  43. wandb/sdk/artifacts/artifact_file_cache.py +18 -4
  44. wandb/sdk/artifacts/artifact_instance_cache.py +1 -0
  45. wandb/sdk/artifacts/artifact_manifest.py +1 -0
  46. wandb/sdk/artifacts/artifact_manifest_entry.py +1 -0
  47. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -0
  48. wandb/sdk/artifacts/artifact_saver.py +5 -2
  49. wandb/sdk/artifacts/artifact_state.py +1 -0
  50. wandb/sdk/artifacts/artifact_ttl.py +1 -0
  51. wandb/sdk/artifacts/exceptions.py +1 -0
  52. wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
  53. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +13 -18
  54. wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -0
  55. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +1 -0
  56. wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -0
  57. wandb/sdk/artifacts/storage_handlers/s3_handler.py +5 -3
  58. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +1 -0
  59. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +1 -0
  60. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -0
  61. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -0
  62. wandb/sdk/artifacts/storage_policy.py +1 -0
  63. wandb/sdk/data_types/base_types/media.py +3 -6
  64. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +3 -1
  65. wandb/sdk/integration_utils/auto_logging.py +5 -6
  66. wandb/sdk/integration_utils/data_logging.py +5 -1
  67. wandb/sdk/interface/interface.py +54 -31
  68. wandb/sdk/interface/interface_shared.py +7 -13
  69. wandb/sdk/internal/datastore.py +1 -1
  70. wandb/sdk/internal/handler.py +18 -2
  71. wandb/sdk/internal/internal.py +0 -1
  72. wandb/sdk/internal/internal_util.py +0 -1
  73. wandb/sdk/internal/job_builder.py +4 -3
  74. wandb/sdk/internal/profiler.py +1 -0
  75. wandb/sdk/internal/run.py +1 -0
  76. wandb/sdk/internal/sender.py +1 -1
  77. wandb/sdk/internal/system/assets/gpu_amd.py +44 -44
  78. wandb/sdk/internal/system/assets/gpu_apple.py +56 -11
  79. wandb/sdk/internal/system/assets/interfaces.py +6 -8
  80. wandb/sdk/internal/system/assets/open_metrics.py +2 -2
  81. wandb/sdk/internal/system/assets/trainium.py +1 -3
  82. wandb/sdk/launch/_project_spec.py +5 -3
  83. wandb/sdk/launch/agent/agent.py +1 -0
  84. wandb/sdk/launch/agent/config.py +72 -11
  85. wandb/sdk/launch/builder/abstract.py +1 -0
  86. wandb/sdk/launch/builder/build.py +28 -1
  87. wandb/sdk/launch/builder/docker_builder.py +1 -0
  88. wandb/sdk/launch/builder/noop.py +1 -0
  89. wandb/sdk/launch/create_job.py +18 -0
  90. wandb/sdk/launch/environment/abstract.py +1 -0
  91. wandb/sdk/launch/environment/gcp_environment.py +1 -0
  92. wandb/sdk/launch/environment/local_environment.py +1 -0
  93. wandb/sdk/launch/loader.py +1 -0
  94. wandb/sdk/launch/registry/abstract.py +1 -0
  95. wandb/sdk/launch/registry/azure_container_registry.py +1 -0
  96. wandb/sdk/launch/registry/elastic_container_registry.py +1 -0
  97. wandb/sdk/launch/registry/google_artifact_registry.py +1 -0
  98. wandb/sdk/launch/registry/local_registry.py +1 -0
  99. wandb/sdk/launch/runner/abstract.py +1 -0
  100. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  101. wandb/sdk/launch/runner/kubernetes_runner.py +4 -3
  102. wandb/sdk/launch/runner/sagemaker_runner.py +11 -10
  103. wandb/sdk/launch/sweeps/scheduler.py +1 -0
  104. wandb/sdk/launch/sweeps/scheduler_sweep.py +1 -0
  105. wandb/sdk/launch/sweeps/utils.py +1 -1
  106. wandb/sdk/launch/utils.py +3 -3
  107. wandb/sdk/lib/fsm.py +8 -12
  108. wandb/sdk/lib/gitlib.py +4 -4
  109. wandb/sdk/lib/lazyloader.py +0 -1
  110. wandb/sdk/lib/proto_util.py +1 -1
  111. wandb/sdk/lib/retry.py +3 -2
  112. wandb/sdk/service/service.py +17 -15
  113. wandb/sdk/verify/verify.py +2 -1
  114. wandb/sdk/wandb_manager.py +2 -2
  115. wandb/sdk/wandb_require.py +5 -0
  116. wandb/sdk/wandb_run.py +14 -12
  117. wandb/sdk/wandb_settings.py +0 -1
  118. wandb/sklearn/__init__.py +1 -0
  119. wandb/sklearn/plot/__init__.py +1 -0
  120. wandb/sklearn/plot/classifier.py +1 -0
  121. wandb/sklearn/plot/clusterer.py +1 -0
  122. wandb/sklearn/plot/regressor.py +1 -0
  123. wandb/sklearn/plot/shared.py +1 -0
  124. wandb/sklearn/utils.py +1 -0
  125. wandb/testing/relay.py +4 -4
  126. wandb/trigger.py +1 -0
  127. wandb/util.py +40 -17
  128. wandb/wandb_controller.py +0 -1
  129. wandb/wandb_torch.py +1 -2
  130. {wandb-0.16.6.dist-info → wandb-0.17.0rc1.dist-info}/METADATA +68 -69
  131. {wandb-0.16.6.dist-info → wandb-0.17.0rc1.dist-info}/RECORD +134 -135
  132. {wandb-0.16.6.dist-info → wandb-0.17.0rc1.dist-info}/WHEEL +1 -2
  133. wandb/bin/apple_gpu_stats +0 -0
  134. wandb-0.16.6.dist-info/top_level.txt +0 -1
  135. {wandb-0.16.6.dist-info → wandb-0.17.0rc1.dist-info}/entry_points.txt +0 -0
  136. {wandb-0.16.6.dist-info → wandb-0.17.0rc1.dist-info/licenses}/LICENSE +0 -0
@@ -80,17 +80,7 @@ class RegistryConfig(BaseModel):
80
80
  @validator("uri") # type: ignore
81
81
  @classmethod
82
82
  def validate_uri(cls, uri: str) -> str:
83
- for regex in [
84
- GCP_ARTIFACT_REGISTRY_URI_REGEX,
85
- AZURE_CONTAINER_REGISTRY_URI_REGEX,
86
- ELASTIC_CONTAINER_REGISTRY_URI_REGEX,
87
- ]:
88
- if regex.match(uri):
89
- return uri
90
- raise ValueError(
91
- "Invalid uri. URI must be a repository URI for an "
92
- "ECR, ACR, or GCP Artifact Registry."
93
- )
83
+ return validate_registry_uri(uri)
94
84
 
95
85
 
96
86
  class EnvironmentConfig(BaseModel):
@@ -186,6 +176,14 @@ class BuilderConfig(BaseModel):
186
176
  """Right now there are no required fields for docker builds."""
187
177
  return values
188
178
 
179
+ @validator("destination") # type: ignore
180
+ @classmethod
181
+ def validate_destination(cls, destination: Optional[str]) -> Optional[str]:
182
+ """Validate that the destination is a valid container registry URI."""
183
+ if destination is None:
184
+ return None
185
+ return validate_registry_uri(destination)
186
+
189
187
 
190
188
  class AgentConfig(BaseModel):
191
189
  """Configuration for the Launch agent."""
@@ -236,3 +234,66 @@ class AgentConfig(BaseModel):
236
234
 
237
235
  class Config:
238
236
  extra = "forbid"
237
+
238
+
239
+ def validate_registry_uri(uri: str) -> str:
240
+ """Validate that the registry URI is a valid container registry URI.
241
+
242
+ The URI should resolve to an image name in a container registry. The recognized
243
+ formats are for ECR, ACR, and GCP Artifact Registry. If the URI does not match
244
+ any of these formats, a warning is printed indicating the registry type is not
245
+ recognized and the agent can't guarantee that images can be pushed.
246
+
247
+ If the format is recognized but does not resolve to an image name, an
248
+ error is raised. For example, if the URI is an ECR URI but does not include
249
+ an image name or includes a tag as well as an image name, an error is raised.
250
+ """
251
+ tag_msg = (
252
+ "Destination for built images may not include a tag, but the URI provided "
253
+ "includes the suffix '{tag}'. Please remove the tag and try again. The agent "
254
+ "will automatically tag each image with a unique hash of the source code."
255
+ )
256
+ if uri.startswith("https://"):
257
+ uri = uri[8:]
258
+
259
+ match = GCP_ARTIFACT_REGISTRY_URI_REGEX.match(uri)
260
+ if match:
261
+ if match.group("tag"):
262
+ raise ValueError(tag_msg.format(tag=match.group("tag")))
263
+ if not match.group("image_name"):
264
+ raise ValueError(
265
+ "An image name must be specified in the URI for a GCP Artifact Registry. "
266
+ "Please provide a uri with the format "
267
+ "'https://<region>-docker.pkg.dev/<project>/<repository>/<image>'."
268
+ )
269
+ return uri
270
+
271
+ match = AZURE_CONTAINER_REGISTRY_URI_REGEX.match(uri)
272
+ if match:
273
+ if match.group("tag"):
274
+ raise ValueError(tag_msg.format(tag=match.group("tag")))
275
+ if not match.group("repository"):
276
+ raise ValueError(
277
+ "A repository name must be specified in the URI for an "
278
+ "Azure Container Registry. Please provide a uri with the format "
279
+ "'https://<registry-name>.azurecr.io/<repository>'."
280
+ )
281
+ return uri
282
+
283
+ match = ELASTIC_CONTAINER_REGISTRY_URI_REGEX.match(uri)
284
+ if match:
285
+ if match.group("tag"):
286
+ raise ValueError(tag_msg.format(tag=match.group("tag")))
287
+ if not match.group("repository"):
288
+ raise ValueError(
289
+ "A repository name must be specified in the URI for an "
290
+ "Elastic Container Registry. Please provide a uri with the format "
291
+ "'https://<account-id>.dkr.ecr.<region>.amazonaws.com/<repository>'."
292
+ )
293
+ return uri
294
+
295
+ wandb.termwarn(
296
+ f"Unable to recognize registry type in URI {uri}. You are responsible "
297
+ "for ensuring the agent can push images to this registry."
298
+ )
299
+ return uri
@@ -1,4 +1,5 @@
1
1
  """Abstract plugin class defining the interface needed to build container images for W&B Launch."""
2
+
2
3
  from abc import ABC, abstractmethod
3
4
  from typing import TYPE_CHECKING, Any, Dict, Optional
4
5
 
@@ -237,7 +237,11 @@ def get_base_setup(
237
237
 
238
238
  CPU version is built on python, Accelerator version is built on user provided.
239
239
  """
240
- python_base_image = f"python:{py_version}-buster"
240
+ minor = int(py_version.split(".")[1])
241
+ if minor < 12:
242
+ python_base_image = f"python:{py_version}-buster"
243
+ else:
244
+ python_base_image = f"python:{py_version}-bookworm"
241
245
  if launch_project.accelerator_base_image:
242
246
  _logger.info(
243
247
  f"Using accelerator base image: {launch_project.accelerator_base_image}"
@@ -311,6 +315,11 @@ def get_env_vars_dict(
311
315
  _inject_wandb_config_env_vars(
312
316
  launch_project.override_config, env_vars, max_env_length
313
317
  )
318
+
319
+ _inject_file_overrides_env_vars(
320
+ launch_project.override_files, env_vars, max_env_length
321
+ )
322
+
314
323
  artifacts = {}
315
324
  # if we're spinning up a launch process from a job
316
325
  # we should tell the run to use that artifact
@@ -677,3 +686,21 @@ def _inject_wandb_config_env_vars(
677
686
  ]
678
687
  config_chunks_dict = {f"WANDB_CONFIG_{i}": chunk for i, chunk in enumerate(chunks)}
679
688
  env_dict.update(config_chunks_dict)
689
+
690
+
691
+ def _inject_file_overrides_env_vars(
692
+ overrides: Dict[str, Any], env_dict: Dict[str, Any], maximum_env_length: int
693
+ ) -> None:
694
+ str_overrides = json.dumps(overrides)
695
+ if len(str_overrides) <= maximum_env_length:
696
+ env_dict["WANDB_LAUNCH_FILE_OVERRIDES"] = str_overrides
697
+ return
698
+
699
+ chunks = [
700
+ str_overrides[i : i + maximum_env_length]
701
+ for i in range(0, len(str_overrides), maximum_env_length)
702
+ ]
703
+ overrides_chunks_dict = {
704
+ f"WANDB_LAUNCH_FILE_OVERRIDES_{i}": chunk for i, chunk in enumerate(chunks)
705
+ }
706
+ env_dict.update(overrides_chunks_dict)
@@ -1,4 +1,5 @@
1
1
  """Implementation of the docker builder."""
2
+
2
3
  import logging
3
4
  import os
4
5
  from typing import Any, Dict, Optional
@@ -1,4 +1,5 @@
1
1
  """NoOp builder implementation."""
2
+
2
3
  from typing import Any, Dict, Optional
3
4
 
4
5
  from wandb.sdk.launch.builder.abstract import AbstractBuilder
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import logging
3
3
  import os
4
+ import re
4
5
  import sys
5
6
  import tempfile
6
7
  from typing import Any, Dict, List, Optional, Tuple
@@ -19,6 +20,9 @@ logging.basicConfig(stream=sys.stdout, level=logging.INFO)
19
20
  _logger = logging.getLogger("wandb")
20
21
 
21
22
 
23
+ CODE_ARTIFACT_EXCLUDE_PATHS = ["wandb", ".git"]
24
+
25
+
22
26
  def create_job(
23
27
  path: str,
24
28
  job_type: str,
@@ -107,6 +111,13 @@ def _create_job(
107
111
  )
108
112
  return None, "", []
109
113
 
114
+ if runtime is not None:
115
+ if not re.match(r"^3\.\d+$", runtime):
116
+ wandb.termerror(
117
+ f"Runtime (-r, --runtime) must be a minor version of Python 3, "
118
+ f"e.g. 3.9 or 3.10, received {runtime}"
119
+ )
120
+ return None, "", []
110
121
  aliases = aliases or []
111
122
  tempdir = tempfile.TemporaryDirectory()
112
123
  try:
@@ -436,6 +447,13 @@ def _make_code_artifact(
436
447
  wandb.termerror(f"Error adding to code artifact: {e}")
437
448
  return None
438
449
 
450
+ # Remove paths we don't want to include, if present
451
+ for item in CODE_ARTIFACT_EXCLUDE_PATHS:
452
+ try:
453
+ code_artifact.remove(item)
454
+ except FileNotFoundError:
455
+ pass
456
+
439
457
  res, _ = api.create_artifact(
440
458
  artifact_type_name="code",
441
459
  artifact_collection_name=artifact_name,
@@ -1,4 +1,5 @@
1
1
  """Abstract base class for environments."""
2
+
2
3
  from abc import ABC, abstractmethod
3
4
 
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Implementation of the GCP environment for wandb launch."""
2
+
2
3
  import logging
3
4
  import os
4
5
  import subprocess
@@ -1,4 +1,5 @@
1
1
  """Dummy local environment implementation. This is the default environment."""
2
+
2
3
  from typing import Any, Dict, Union
3
4
 
4
5
  from wandb.sdk.launch.errors import LaunchError
@@ -1,4 +1,5 @@
1
1
  """Utilities for the agent."""
2
+
2
3
  from typing import Any, Dict, Optional
3
4
 
4
5
  import wandb
@@ -1,4 +1,5 @@
1
1
  """Abstract base class for registries."""
2
+
2
3
  from abc import ABC, abstractmethod
3
4
  from typing import Tuple
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Implementation of AzureContainerRegistry class."""
2
+
2
3
  import re
3
4
  from typing import TYPE_CHECKING, Optional, Tuple
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Implementation of Elastic Container Registry class for wandb launch."""
2
+
2
3
  import base64
3
4
  import logging
4
5
  from typing import Dict, Optional, Tuple
@@ -1,4 +1,5 @@
1
1
  """Implementation of Google Artifact Registry for wandb launch."""
2
+
2
3
  import logging
3
4
  from typing import Optional, Tuple
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Local registry implementation."""
2
+
2
3
  import logging
3
4
  from typing import Tuple
4
5
 
@@ -3,6 +3,7 @@
3
3
  This class defines the interface that the W&B launch runner uses to manage the lifecycle
4
4
  of runs launched in different environments (e.g. runs launched locally or in a cluster).
5
5
  """
6
+
6
7
  import logging
7
8
  import os
8
9
  import subprocess
@@ -1,4 +1,5 @@
1
1
  """Monitors kubernetes resources managed by the launch agent."""
2
+
2
3
  import asyncio
3
4
  import logging
4
5
  import sys
@@ -1,4 +1,5 @@
1
1
  """Implementation of KubernetesRunner class for wandb launch."""
2
+
2
3
  import asyncio
3
4
  import base64
4
5
  import datetime
@@ -539,9 +540,9 @@ class KubernetesRunner(AbstractRunner):
539
540
  WANDB_K8S_LABEL_MONITOR,
540
541
  LaunchAgent.name(),
541
542
  )
542
- resource_args["metadata"]["labels"][
543
- WANDB_K8S_LABEL_AGENT
544
- ] = LaunchAgent.name()
543
+ resource_args["metadata"]["labels"][WANDB_K8S_LABEL_AGENT] = (
544
+ LaunchAgent.name()
545
+ )
545
546
 
546
547
  overrides = {}
547
548
  if launch_project.override_args:
@@ -1,4 +1,5 @@
1
1
  """Implementation of the SageMakerRunner class."""
2
+
2
3
  import asyncio
3
4
  import logging
4
5
  from typing import Any, Dict, List, Optional, cast
@@ -324,16 +325,16 @@ def build_sagemaker_args(
324
325
  sagemaker_args["TrainingJobName"] = training_job_name
325
326
  entry_cmd = entry_point.command if entry_point else []
326
327
 
327
- sagemaker_args[
328
- "AlgorithmSpecification"
329
- ] = merge_image_uri_with_algorithm_specification(
330
- given_sagemaker_args.get(
331
- "AlgorithmSpecification",
332
- given_sagemaker_args.get("algorithm_specification"),
333
- ),
334
- image_uri,
335
- entry_cmd,
336
- args,
328
+ sagemaker_args["AlgorithmSpecification"] = (
329
+ merge_image_uri_with_algorithm_specification(
330
+ given_sagemaker_args.get(
331
+ "AlgorithmSpecification",
332
+ given_sagemaker_args.get("algorithm_specification"),
333
+ ),
334
+ image_uri,
335
+ entry_cmd,
336
+ args,
337
+ )
337
338
  )
338
339
 
339
340
  sagemaker_args["RoleArn"] = role_arn
@@ -1,4 +1,5 @@
1
1
  """Abstract Scheduler class."""
2
+
2
3
  import asyncio
3
4
  import base64
4
5
  import copy
@@ -1,4 +1,5 @@
1
1
  """Scheduler for classic wandb Sweeps."""
2
+
2
3
  import logging
3
4
  from pprint import pformat as pf
4
5
  from typing import Any, Dict, List, Optional
@@ -296,7 +296,7 @@ def check_job_exists(public_api: "PublicApi", job: Optional[str]) -> bool:
296
296
 
297
297
 
298
298
  def get_previous_args(
299
- run_spec: Dict[str, Any]
299
+ run_spec: Dict[str, Any],
300
300
  ) -> Tuple[Dict[str, Any], Dict[str, Any]]:
301
301
  """Parse through previous scheduler run_spec.
302
302
 
wandb/sdk/launch/utils.py CHANGED
@@ -57,15 +57,15 @@ API_KEY_REGEX = r"WANDB_API_KEY=\w+(-\w+)?"
57
57
  MACRO_REGEX = re.compile(r"\$\{(\w+)\}")
58
58
 
59
59
  AZURE_CONTAINER_REGISTRY_URI_REGEX = re.compile(
60
- r"(?:https://)?([\w]+)\.azurecr\.io/([\w\-]+):?(.*)"
60
+ r"^(?:https://)?([\w]+)\.azurecr\.io/(?P<repository>[\w\-]+):?(?P<tag>.*)"
61
61
  )
62
62
 
63
63
  ELASTIC_CONTAINER_REGISTRY_URI_REGEX = re.compile(
64
- r"^(?P<account>.*)\.dkr\.ecr\.(?P<region>.*)\.amazonaws\.com/(?P<repository>.*)/?$"
64
+ r"^(?:https://)?(?P<account>[\w-]+)\.dkr\.ecr\.(?P<region>[\w-]+)\.amazonaws\.com/(?P<repository>[\w-]+):?(?P<tag>.*)$"
65
65
  )
66
66
 
67
67
  GCP_ARTIFACT_REGISTRY_URI_REGEX = re.compile(
68
- r"^(?P<region>[\w-]+)-docker\.pkg\.dev/(?P<project>[\w-]+)/(?P<repository>[\w-]+)/(?P<image_name>[\w-]+)$",
68
+ r"^(?:https://)?(?P<region>[\w-]+)-docker\.pkg\.dev/(?P<project>[\w-]+)/(?P<repository>[\w-]+)/?(?P<image_name>[\w-]+)?(?P<tag>:.*)?$",
69
69
  re.IGNORECASE,
70
70
  )
71
71
 
wandb/sdk/lib/fsm.py CHANGED
@@ -52,43 +52,39 @@ T_FsmContext_contra = TypeVar("T_FsmContext_contra", contravariant=True)
52
52
  @runtime_checkable
53
53
  class FsmStateCheck(Protocol[T_FsmInputs]):
54
54
  @abstractmethod
55
- def on_check(self, inputs: T_FsmInputs) -> None:
56
- ... # pragma: no cover
55
+ def on_check(self, inputs: T_FsmInputs) -> None: ... # pragma: no cover
57
56
 
58
57
 
59
58
  @runtime_checkable
60
59
  class FsmStateOutput(Protocol[T_FsmInputs]):
61
60
  @abstractmethod
62
- def on_state(self, inputs: T_FsmInputs) -> None:
63
- ... # pragma: no cover
61
+ def on_state(self, inputs: T_FsmInputs) -> None: ... # pragma: no cover
64
62
 
65
63
 
66
64
  @runtime_checkable
67
65
  class FsmStateEnter(Protocol[T_FsmInputs]):
68
66
  @abstractmethod
69
- def on_enter(self, inputs: T_FsmInputs) -> None:
70
- ... # pragma: no cover
67
+ def on_enter(self, inputs: T_FsmInputs) -> None: ... # pragma: no cover
71
68
 
72
69
 
73
70
  @runtime_checkable
74
71
  class FsmStateEnterWithContext(Protocol[T_FsmInputs, T_FsmContext_contra]):
75
72
  @abstractmethod
76
- def on_enter(self, inputs: T_FsmInputs, context: T_FsmContext_contra) -> None:
77
- ... # pragma: no cover
73
+ def on_enter(
74
+ self, inputs: T_FsmInputs, context: T_FsmContext_contra
75
+ ) -> None: ... # pragma: no cover
78
76
 
79
77
 
80
78
  @runtime_checkable
81
79
  class FsmStateStay(Protocol[T_FsmInputs]):
82
80
  @abstractmethod
83
- def on_stay(self, inputs: T_FsmInputs) -> None:
84
- ... # pragma: no cover
81
+ def on_stay(self, inputs: T_FsmInputs) -> None: ... # pragma: no cover
85
82
 
86
83
 
87
84
  @runtime_checkable
88
85
  class FsmStateExit(Protocol[T_FsmInputs, T_FsmContext_cov]):
89
86
  @abstractmethod
90
- def on_exit(self, inputs: T_FsmInputs) -> T_FsmContext_cov:
91
- ... # pragma: no cover
87
+ def on_exit(self, inputs: T_FsmInputs) -> T_FsmContext_cov: ... # pragma: no cover
92
88
 
93
89
 
94
90
  # It would be nice if python provided optional protocol members, but it doesnt as described here:
wandb/sdk/lib/gitlib.py CHANGED
@@ -14,7 +14,7 @@ try:
14
14
  Repo,
15
15
  )
16
16
  except ImportError:
17
- Repo = None
17
+ Repo = None # type: ignore
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from git import Repo
@@ -121,7 +121,7 @@ class GitRepo:
121
121
  # TODO: Saw a user getting a Unicode decode error when parsing refs,
122
122
  # more details on implementing a real fix in [WB-4064]
123
123
  try:
124
- if len(self.repo.refs) > 0:
124
+ if len(self.repo.refs) > 0: # type: ignore[arg-type]
125
125
  return self.repo.head.commit.hexsha
126
126
  else:
127
127
  return self.repo.git.show_ref("--head").split(" ")[0]
@@ -140,7 +140,7 @@ class GitRepo:
140
140
  if not self.repo:
141
141
  return None
142
142
  try:
143
- return self.repo.remotes[self.remote_name]
143
+ return self.repo.remotes[self.remote_name] # type: ignore[index]
144
144
  except IndexError:
145
145
  return None
146
146
 
@@ -200,7 +200,7 @@ class GitRepo:
200
200
  possible_relatives.append(tracking_branch.commit)
201
201
 
202
202
  if not possible_relatives:
203
- for branch in self.repo.branches:
203
+ for branch in self.repo.branches: # type: ignore[attr-defined]
204
204
  tracking_branch = branch.tracking_branch()
205
205
  if tracking_branch is not None:
206
206
  possible_relatives.append(tracking_branch.commit)
@@ -1,6 +1,5 @@
1
1
  """module lazyloader."""
2
2
 
3
-
4
3
  import importlib
5
4
  import sys
6
5
  import types
@@ -29,7 +29,7 @@ def _assign_end_offset(record: "pb.Record", end_offset: int) -> None:
29
29
 
30
30
 
31
31
  def proto_encode_to_dict(
32
- pb_obj: Union["tpb.TelemetryRecord", "pb.MetricRecord"]
32
+ pb_obj: Union["tpb.TelemetryRecord", "pb.MetricRecord"],
33
33
  ) -> Dict[int, Any]:
34
34
  data: Dict[int, Any] = dict()
35
35
  fields = pb_obj.ListFields()
wandb/sdk/lib/retry.py CHANGED
@@ -248,8 +248,9 @@ class ExponentialBackoff(Backoff):
248
248
  if self._timeout_at is not None and NOW_FN() > self._timeout_at:
249
249
  raise exc
250
250
 
251
- result, self._next_sleep = self._next_sleep, min(
252
- self._max_sleep, self._next_sleep * (1 + random.random())
251
+ result, self._next_sleep = (
252
+ self._next_sleep,
253
+ min(self._max_sleep, self._next_sleep * (1 + random.random())),
253
254
  )
254
255
 
255
256
  return result
@@ -2,6 +2,7 @@
2
2
 
3
3
  Backend server process can be connected to using tcp sockets transport.
4
4
  """
5
+
5
6
  import datetime
6
7
  import os
7
8
  import pathlib
@@ -14,8 +15,8 @@ import time
14
15
  from typing import TYPE_CHECKING, Any, Dict, Optional
15
16
 
16
17
  from wandb import _sentry, termlog
17
- from wandb.env import error_reporting_enabled
18
- from wandb.errors import Error
18
+ from wandb.env import core_debug, core_error_reporting_enabled, is_require_core
19
+ from wandb.errors import Error, WandbCoreNotAvailableError
19
20
  from wandb.sdk.lib.wburls import wburls
20
21
  from wandb.util import get_core_path, get_module
21
22
 
@@ -161,28 +162,29 @@ class _Service:
161
162
  exec_cmd_list += ["coverage", "run", "-m"]
162
163
 
163
164
  service_args = []
164
- # NOTE: "wandb-core" is the name of the package that will be distributed
165
- # as the stable version of the wandb core library.
166
- #
167
- # Environment variable _WANDB_CORE_PATH is a temporary development feature
168
- # to assist in running the core service from a live development directory.
169
- core_path = get_core_path()
170
- if core_path:
165
+
166
+ if is_require_core():
167
+ try:
168
+ core_path = get_core_path()
169
+ except WandbCoreNotAvailableError as e:
170
+ _sentry.reraise(e)
171
+
171
172
  service_args.extend([core_path])
172
- if not error_reporting_enabled():
173
+
174
+ if not core_error_reporting_enabled(default="True"):
173
175
  service_args.append("--no-observability")
174
- if os.environ.get("WANDB_CORE_DEBUG", False):
176
+
177
+ if core_debug(default="False"):
175
178
  service_args.append("--debug")
179
+
176
180
  trace_filename = os.environ.get("_WANDB_TRACE")
177
181
  if trace_filename is not None:
178
182
  service_args.extend(["--trace", trace_filename])
179
183
 
180
184
  exec_cmd_list = []
181
- # TODO: remove this after the wandb-core GA release
182
- wandb_core = get_module("wandb_core")
183
185
  termlog(
184
- f"Using wandb-core version {wandb_core.__version__} as the SDK backend. "
185
- f"Please refer to {wburls.get('wandb_core')} for more information.",
186
+ "Using wandb-core as the SDK backend."
187
+ f" Please refer to {wburls.get('wandb_core')} for more information.",
186
188
  repeat=False,
187
189
  )
188
190
  else:
@@ -1,4 +1,5 @@
1
1
  """Utilities for wandb verify."""
2
+
2
3
  import getpass
3
4
  import os
4
5
  import time
@@ -20,7 +21,7 @@ PROJECT_NAME = "verify"
20
21
  GET_RUN_MAX_TIME = 10
21
22
  MIN_RETRYS = 3
22
23
  CHECKMARK = "\u2705"
23
- RED_X = "\u274C"
24
+ RED_X = "\u274c"
24
25
  ID_PREFIX = runid.generate_id()
25
26
 
26
27
 
@@ -5,7 +5,7 @@ Create a manager channel.
5
5
 
6
6
  import atexit
7
7
  import os
8
- from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
8
+ from typing import TYPE_CHECKING, Callable, Optional
9
9
 
10
10
  import psutil
11
11
 
@@ -205,7 +205,7 @@ class _Manager:
205
205
  svc_iface = self._get_service_interface()
206
206
  svc_iface._svc_inform_start(settings=settings, run_id=run_id)
207
207
 
208
- def _inform_attach(self, attach_id: str) -> Optional[Dict[str, Any]]:
208
+ def _inform_attach(self, attach_id: str) -> Optional["wandb_settings_pb2.Settings"]:
209
209
  svc_iface = self._get_service_interface()
210
210
  try:
211
211
  response = svc_iface._svc_inform_attach(attach_id=attach_id)
@@ -9,9 +9,11 @@ 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
16
+ from wandb.env import _REQUIRE_CORE
15
17
  from wandb.errors import UnsupportedError
16
18
  from wandb.sdk import wandb_run
17
19
  from wandb.sdk.lib.wburls import wburls
@@ -38,6 +40,9 @@ class _Requires:
38
40
  def require_service(self) -> None:
39
41
  self._require_service()
40
42
 
43
+ def require_core(self) -> None:
44
+ os.environ[_REQUIRE_CORE] = "true"
45
+
41
46
  def apply(self) -> None:
42
47
  """Call require_* method for supported features."""
43
48
  last_message: str = ""