wandb 0.21.0__py3-none-win_amd64.whl → 0.21.2__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. wandb/__init__.py +16 -14
  2. wandb/__init__.pyi +427 -450
  3. wandb/agents/pyagent.py +41 -12
  4. wandb/analytics/sentry.py +7 -2
  5. wandb/apis/importers/mlflow.py +1 -1
  6. wandb/apis/public/__init__.py +1 -1
  7. wandb/apis/public/api.py +525 -360
  8. wandb/apis/public/artifacts.py +207 -13
  9. wandb/apis/public/automations.py +19 -3
  10. wandb/apis/public/files.py +172 -33
  11. wandb/apis/public/history.py +67 -15
  12. wandb/apis/public/integrations.py +25 -2
  13. wandb/apis/public/jobs.py +90 -2
  14. wandb/apis/public/projects.py +130 -79
  15. wandb/apis/public/query_generator.py +11 -1
  16. wandb/apis/public/registries/_utils.py +14 -16
  17. wandb/apis/public/registries/registries_search.py +183 -304
  18. wandb/apis/public/reports.py +96 -15
  19. wandb/apis/public/runs.py +299 -105
  20. wandb/apis/public/sweeps.py +222 -22
  21. wandb/apis/public/teams.py +41 -4
  22. wandb/apis/public/users.py +45 -4
  23. wandb/automations/_generated/delete_automation.py +1 -3
  24. wandb/automations/_generated/enums.py +13 -11
  25. wandb/beta/workflows.py +66 -30
  26. wandb/bin/gpu_stats.exe +0 -0
  27. wandb/bin/wandb-core +0 -0
  28. wandb/cli/cli.py +127 -3
  29. wandb/env.py +8 -0
  30. wandb/errors/errors.py +4 -1
  31. wandb/integration/lightning/fabric/logger.py +3 -4
  32. wandb/integration/metaflow/__init__.py +6 -0
  33. wandb/integration/metaflow/data_pandas.py +74 -0
  34. wandb/integration/metaflow/data_pytorch.py +75 -0
  35. wandb/integration/metaflow/data_sklearn.py +76 -0
  36. wandb/integration/metaflow/errors.py +13 -0
  37. wandb/integration/metaflow/metaflow.py +167 -223
  38. wandb/integration/openai/fine_tuning.py +1 -2
  39. wandb/integration/weave/__init__.py +6 -0
  40. wandb/integration/weave/interface.py +49 -0
  41. wandb/integration/weave/weave.py +63 -0
  42. wandb/jupyter.py +5 -5
  43. wandb/plot/custom_chart.py +30 -7
  44. wandb/proto/v3/wandb_internal_pb2.py +281 -280
  45. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  46. wandb/proto/v4/wandb_internal_pb2.py +280 -280
  47. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  48. wandb/proto/v5/wandb_internal_pb2.py +280 -280
  49. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  50. wandb/proto/v6/wandb_internal_pb2.py +280 -280
  51. wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
  52. wandb/proto/wandb_deprecated.py +6 -0
  53. wandb/sdk/artifacts/_factories.py +17 -0
  54. wandb/sdk/artifacts/_generated/__init__.py +221 -13
  55. wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
  56. wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
  57. wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
  58. wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
  59. wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
  60. wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
  61. wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
  62. wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
  63. wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
  64. wandb/sdk/artifacts/_generated/enums.py +5 -0
  65. wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
  66. wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
  67. wandb/sdk/artifacts/_generated/fragments.py +279 -41
  68. wandb/sdk/artifacts/_generated/link_artifact.py +6 -0
  69. wandb/sdk/artifacts/_generated/operations.py +654 -51
  70. wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
  71. wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
  72. wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
  73. wandb/sdk/artifacts/_graphql_fragments.py +3 -86
  74. wandb/sdk/artifacts/_internal_artifact.py +19 -8
  75. wandb/sdk/artifacts/_validators.py +14 -4
  76. wandb/sdk/artifacts/artifact.py +512 -618
  77. wandb/sdk/artifacts/artifact_file_cache.py +10 -6
  78. wandb/sdk/artifacts/artifact_manifest.py +10 -9
  79. wandb/sdk/artifacts/artifact_manifest_entry.py +9 -10
  80. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +5 -3
  81. wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -1
  82. wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
  83. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -1
  84. wandb/sdk/data_types/audio.py +38 -10
  85. wandb/sdk/data_types/base_types/media.py +6 -56
  86. wandb/sdk/data_types/graph.py +48 -14
  87. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
  88. wandb/sdk/data_types/helper_types/image_mask.py +1 -3
  89. wandb/sdk/data_types/histogram.py +34 -21
  90. wandb/sdk/data_types/html.py +35 -12
  91. wandb/sdk/data_types/image.py +104 -68
  92. wandb/sdk/data_types/molecule.py +32 -19
  93. wandb/sdk/data_types/object_3d.py +36 -17
  94. wandb/sdk/data_types/plotly.py +18 -5
  95. wandb/sdk/data_types/saved_model.py +4 -6
  96. wandb/sdk/data_types/table.py +59 -30
  97. wandb/sdk/data_types/video.py +53 -26
  98. wandb/sdk/integration_utils/auto_logging.py +2 -2
  99. wandb/sdk/interface/interface_queue.py +1 -4
  100. wandb/sdk/interface/interface_shared.py +26 -37
  101. wandb/sdk/interface/interface_sock.py +24 -14
  102. wandb/sdk/internal/internal_api.py +6 -0
  103. wandb/sdk/internal/job_builder.py +6 -0
  104. wandb/sdk/internal/settings_static.py +2 -3
  105. wandb/sdk/launch/agent/agent.py +8 -1
  106. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
  107. wandb/sdk/launch/create_job.py +15 -2
  108. wandb/sdk/launch/inputs/internal.py +3 -4
  109. wandb/sdk/launch/inputs/schema.py +1 -0
  110. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  111. wandb/sdk/launch/runner/kubernetes_runner.py +323 -1
  112. wandb/sdk/launch/sweeps/scheduler.py +2 -3
  113. wandb/sdk/lib/asyncio_compat.py +19 -16
  114. wandb/sdk/lib/asyncio_manager.py +252 -0
  115. wandb/sdk/lib/deprecate.py +1 -7
  116. wandb/sdk/lib/disabled.py +1 -1
  117. wandb/sdk/lib/hashutil.py +27 -5
  118. wandb/sdk/lib/module.py +7 -13
  119. wandb/sdk/lib/printer.py +2 -2
  120. wandb/sdk/lib/printer_asyncio.py +3 -1
  121. wandb/sdk/lib/progress.py +0 -19
  122. wandb/sdk/lib/retry.py +185 -78
  123. wandb/sdk/lib/service/service_client.py +106 -0
  124. wandb/sdk/lib/service/service_connection.py +20 -26
  125. wandb/sdk/lib/service/service_token.py +30 -13
  126. wandb/sdk/mailbox/mailbox.py +13 -5
  127. wandb/sdk/mailbox/mailbox_handle.py +22 -13
  128. wandb/sdk/mailbox/response_handle.py +42 -106
  129. wandb/sdk/mailbox/wait_with_progress.py +7 -42
  130. wandb/sdk/wandb_init.py +77 -116
  131. wandb/sdk/wandb_login.py +19 -15
  132. wandb/sdk/wandb_metric.py +2 -0
  133. wandb/sdk/wandb_run.py +497 -469
  134. wandb/sdk/wandb_settings.py +145 -4
  135. wandb/sdk/wandb_setup.py +204 -124
  136. wandb/sdk/wandb_sweep.py +14 -13
  137. wandb/sdk/wandb_watch.py +4 -6
  138. wandb/sync/sync.py +10 -0
  139. wandb/util.py +58 -1
  140. wandb/wandb_run.py +1 -2
  141. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/METADATA +1 -1
  142. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/RECORD +145 -129
  143. wandb/sdk/interface/interface_relay.py +0 -38
  144. wandb/sdk/interface/router.py +0 -89
  145. wandb/sdk/interface/router_queue.py +0 -43
  146. wandb/sdk/interface/router_relay.py +0 -50
  147. wandb/sdk/interface/router_sock.py +0 -32
  148. wandb/sdk/lib/sock_client.py +0 -236
  149. wandb/vendor/pynvml/__init__.py +0 -0
  150. wandb/vendor/pynvml/pynvml.py +0 -4779
  151. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/WHEEL +0 -0
  152. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/entry_points.txt +0 -0
  153. {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/licenses/LICENSE +0 -0
wandb/beta/workflows.py CHANGED
@@ -1,21 +1,31 @@
1
+ from __future__ import annotations
2
+
1
3
  import json
2
4
  import os
3
- from typing import Any, Dict, List, Optional, Union
5
+ import warnings
6
+ from typing import Any
7
+
8
+ from typing_extensions import deprecated
4
9
 
5
10
  import wandb
6
- import wandb.data_types as data_types
7
- from wandb.data_types import _SavedModel
11
+ from wandb.data_types import WBValue, _SavedModel
12
+ from wandb.proto.wandb_deprecated import Deprecated
8
13
  from wandb.sdk import wandb_setup
9
14
  from wandb.sdk.artifacts.artifact import Artifact
10
15
  from wandb.sdk.artifacts.artifact_manifest_entry import ArtifactManifestEntry
16
+ from wandb.sdk.lib.deprecate import deprecate as wandb_deprecate
17
+
18
+ warnings.warn(
19
+ message=f"The {__name__!r} module is deprecated and will be removed in a future version. Please use the equivalent 'wandb.Run' methods instead.",
20
+ category=DeprecationWarning,
21
+ stacklevel=2,
22
+ )
11
23
 
12
24
 
13
25
  def _add_any(
14
26
  artifact: Artifact,
15
- path_or_obj: Union[
16
- str, ArtifactManifestEntry, data_types.WBValue
17
- ], # todo: add dataframe
18
- name: Optional[str],
27
+ path_or_obj: str | ArtifactManifestEntry | WBValue, # todo: add dataframe
28
+ name: str | None,
19
29
  ) -> Any:
20
30
  """Add an object to an artifact.
21
31
 
@@ -24,11 +34,10 @@ def _add_any(
24
34
  be moved to the Artifact class in the future.
25
35
 
26
36
  Args:
27
- artifact: `Artifact` - artifact created with `wandb.Artifact(...)`
28
- path_or_obj: `Union[str, ArtifactManifestEntry, data_types.WBValue]` - either a
29
- str or valid object which indicates what to add to an artifact.
30
-
31
- name: `str` - the name of the object which is added to an artifact.
37
+ artifact: artifact created with `wandb.Artifact(...)`
38
+ path_or_obj: either a str or valid object which indicates what to add
39
+ to an artifact.
40
+ name: the name of the object which is added to an artifact.
32
41
 
33
42
  Returns:
34
43
  Type[Any] - Union[None, ArtifactManifestEntry, etc]
@@ -36,7 +45,7 @@ def _add_any(
36
45
  """
37
46
  if isinstance(path_or_obj, ArtifactManifestEntry):
38
47
  return artifact.add_reference(path_or_obj, name)
39
- elif isinstance(path_or_obj, data_types.WBValue):
48
+ elif isinstance(path_or_obj, WBValue):
40
49
  return artifact.add(path_or_obj, name)
41
50
  elif isinstance(path_or_obj, str):
42
51
  if os.path.isdir(path_or_obj):
@@ -56,12 +65,12 @@ def _add_any(
56
65
  def _log_artifact_version(
57
66
  name: str,
58
67
  type: str,
59
- entries: Dict[str, Union[str, ArtifactManifestEntry, data_types.WBValue]],
60
- aliases: Optional[Union[str, List[str]]] = None,
61
- description: Optional[str] = None,
62
- metadata: Optional[dict] = None,
63
- project: Optional[str] = None,
64
- scope_project: Optional[bool] = None,
68
+ entries: dict[str, str | ArtifactManifestEntry | WBValue],
69
+ aliases: str | list[str] | None = None,
70
+ description: str | None = None,
71
+ metadata: dict | None = None,
72
+ project: str | None = None,
73
+ scope_project: bool | None = None,
65
74
  job_type: str = "auto",
66
75
  ) -> Artifact:
67
76
  """Create an artifact, populate it, and log it with a run.
@@ -113,16 +122,20 @@ def _log_artifact_version(
113
122
  return art
114
123
 
115
124
 
125
+ _LOG_MODEL_DEPRECATION_MSG = "`log_model` is deprecated and will be removed in a future version. Please use `Run.log_artifact` instead."
126
+
127
+
128
+ @deprecated(_LOG_MODEL_DEPRECATION_MSG)
116
129
  def log_model(
117
130
  model_obj: Any,
118
131
  name: str = "model",
119
- aliases: Optional[Union[str, List[str]]] = None,
120
- description: Optional[str] = None,
121
- metadata: Optional[dict] = None,
122
- project: Optional[str] = None,
123
- scope_project: Optional[bool] = None,
124
- **kwargs: Dict[str, Any],
125
- ) -> "_SavedModel":
132
+ aliases: str | list[str] | None = None,
133
+ description: str | None = None,
134
+ metadata: dict | None = None,
135
+ project: str | None = None,
136
+ scope_project: bool | None = None,
137
+ **kwargs: dict[str, Any],
138
+ ) -> _SavedModel:
126
139
  """Log a model object to enable model-centric workflows in the UI.
127
140
 
128
141
  Supported frameworks include PyTorch, Keras, Tensorflow, Scikit-learn, etc. Under
@@ -168,7 +181,12 @@ def log_model(
168
181
  ```
169
182
 
170
183
  """
171
- model = data_types._SavedModel.init(model_obj, **kwargs)
184
+ wandb_deprecate(
185
+ field_name=Deprecated.beta__workflows__log_model,
186
+ warning_message=_LOG_MODEL_DEPRECATION_MSG,
187
+ )
188
+
189
+ model = _SavedModel.init(model_obj, **kwargs)
172
190
  _ = _log_artifact_version(
173
191
  name=name,
174
192
  type="model",
@@ -186,7 +204,11 @@ def log_model(
186
204
  return model
187
205
 
188
206
 
189
- def use_model(aliased_path: str, unsafe: bool = False) -> "_SavedModel":
207
+ _USE_MODEL_DEPRECATION_MSG = "`use_model` is deprecated and will be removed in a future version. Please update your code to use `Run.use_artifact` instead."
208
+
209
+
210
+ @deprecated(_USE_MODEL_DEPRECATION_MSG)
211
+ def use_model(aliased_path: str, unsafe: bool = False) -> _SavedModel:
190
212
  """Fetch a saved model from an alias.
191
213
 
192
214
  Under the hood, we use the alias to fetch the model artifact containing the
@@ -209,6 +231,11 @@ def use_model(aliased_path: str, unsafe: bool = False) -> "_SavedModel":
209
231
  model = sm.model_obj()
210
232
  ```
211
233
  """
234
+ wandb_deprecate(
235
+ field_name=Deprecated.beta__workflows__use_model,
236
+ warning_message=_USE_MODEL_DEPRECATION_MSG,
237
+ )
238
+
212
239
  if not unsafe:
213
240
  raise ValueError("The 'unsafe' parameter must be set to True to load a model.")
214
241
 
@@ -234,10 +261,14 @@ def use_model(aliased_path: str, unsafe: bool = False) -> "_SavedModel":
234
261
  )
235
262
 
236
263
 
264
+ _LINK_MODEL_DEPRECATION_MSG = "`link_model` is deprecated and will be removed in a future version. Please use `Run.link_artifact` instead."
265
+
266
+
267
+ @deprecated(_LINK_MODEL_DEPRECATION_MSG)
237
268
  def link_model(
238
- model: "_SavedModel",
269
+ model: _SavedModel,
239
270
  target_path: str,
240
- aliases: Optional[Union[str, List[str]]] = None,
271
+ aliases: str | list[str] | None = None,
241
272
  ) -> None:
242
273
  """Link the given model to a portfolio.
243
274
 
@@ -261,6 +292,11 @@ def link_model(
261
292
  link_model(sm, "my-portfolio")
262
293
 
263
294
  """
295
+ wandb_deprecate(
296
+ field_name=Deprecated.beta__workflows__link_model,
297
+ warning_message=_LINK_MODEL_DEPRECATION_MSG,
298
+ )
299
+
264
300
  aliases = wandb.util._resolve_aliases(aliases)
265
301
 
266
302
  if run := wandb_setup.singleton().most_recent_active_run:
wandb/bin/gpu_stats.exe CHANGED
Binary file
wandb/bin/wandb-core CHANGED
Binary file
wandb/cli/cli.py CHANGED
@@ -14,7 +14,7 @@ import textwrap
14
14
  import time
15
15
  import traceback
16
16
  from functools import wraps
17
- from typing import Any, Dict, Optional
17
+ from typing import Any, Dict, Optional, Tuple
18
18
 
19
19
  import click
20
20
  import yaml
@@ -95,6 +95,39 @@ class ClickWandbException(ClickException):
95
95
  )
96
96
 
97
97
 
98
+ def parse_service_config(
99
+ ctx: Optional[click.Context],
100
+ param: Optional[click.Parameter],
101
+ value: Optional[Tuple[str, ...]],
102
+ ) -> Dict[str, str]:
103
+ """Parse service configurations in format serviceName=policy."""
104
+ if not value:
105
+ return {}
106
+
107
+ result = {}
108
+ for config in value:
109
+ if "=" not in config:
110
+ raise click.BadParameter(
111
+ f"Service must be in format 'serviceName=policy', got '{config}'"
112
+ )
113
+
114
+ service_name, policy = config.split("=", 1)
115
+ service_name = service_name.strip()
116
+ policy = policy.strip()
117
+ if not service_name:
118
+ raise click.BadParameter("Service name cannot be empty")
119
+
120
+ # Simple validation for two policies
121
+ if policy not in ["always", "never"]:
122
+ raise click.BadParameter(
123
+ f"Policy must be 'always' or 'never', got '{policy}'"
124
+ )
125
+
126
+ result[service_name] = policy
127
+
128
+ return result
129
+
130
+
98
131
  def display_error(func):
99
132
  """Function decorator for catching common errors and re-raising as wandb.Error."""
100
133
 
@@ -454,6 +487,10 @@ def init(ctx, project, entity, reset, mode):
454
487
  @click.option("--show", default=5, help="Number of runs to show")
455
488
  @click.option("--append", is_flag=True, default=False, help="Append run")
456
489
  @click.option("--skip-console", is_flag=True, default=False, help="Skip console logs")
490
+ @click.option(
491
+ "--replace-tags",
492
+ help="Replace tags in the format 'old_tag1=new_tag1,old_tag2=new_tag2'",
493
+ )
457
494
  @display_error
458
495
  def sync(
459
496
  ctx,
@@ -479,6 +516,7 @@ def sync(
479
516
  clean_force=None,
480
517
  append=None,
481
518
  skip_console=None,
519
+ replace_tags=None,
482
520
  ):
483
521
  api = _get_cling_api()
484
522
  if not api.is_authenticated:
@@ -493,6 +531,10 @@ def sync(
493
531
  if exclude_globs:
494
532
  exclude_globs = exclude_globs.split(",")
495
533
 
534
+ replace_tags_dict = _parse_sync_replace_tags(replace_tags)
535
+ if replace_tags and replace_tags_dict is None:
536
+ return # Error already printed by helper function
537
+
496
538
  def _summary():
497
539
  all_items = get_runs(
498
540
  include_online=True,
@@ -548,6 +590,7 @@ def sync(
548
590
  log_path=_wandb_log_path,
549
591
  append=append,
550
592
  skip_console=skip_console,
593
+ replace_tags=replace_tags_dict,
551
594
  )
552
595
  for p in _path:
553
596
  sm.add(p)
@@ -633,6 +676,31 @@ def sync(
633
676
  _summary()
634
677
 
635
678
 
679
+ def _parse_sync_replace_tags(replace_tags: str) -> Optional[Dict[str, str]]:
680
+ """Parse replace_tags string into a dictionary.
681
+
682
+ Args:
683
+ replace_tags: String in format 'old_tag1=new_tag1,old_tag2=new_tag2'
684
+
685
+ Returns:
686
+ Mapping of old tags to new tags, or None if format is invalid
687
+ """
688
+ if not replace_tags:
689
+ return {}
690
+
691
+ replace_tags_dict = {}
692
+ for pair in replace_tags.split(","):
693
+ if "=" not in pair:
694
+ wandb.termerror(
695
+ f"Invalid replace-tags format: {pair}. Use 'old_tag=new_tag' format."
696
+ )
697
+ return None
698
+ old_tag, new_tag = pair.split("=", 1)
699
+ replace_tags_dict[old_tag.strip()] = new_tag.strip()
700
+
701
+ return replace_tags_dict
702
+
703
+
636
704
  @cli.command(
637
705
  context_settings=CONTEXT,
638
706
  help="Initialize a hyperparameter sweep. Search for hyperparameters that optimizes a cost function of a machine learning model by testing various combinations.",
@@ -1829,6 +1897,21 @@ def describe(job):
1829
1897
  "job_type",
1830
1898
  type=click.Choice(("git", "code", "image")),
1831
1899
  )
1900
+ @click.option(
1901
+ "--service",
1902
+ "-s",
1903
+ "services",
1904
+ multiple=True,
1905
+ callback=parse_service_config,
1906
+ help="Service configurations in format serviceName=policy. Valid policies: always, never",
1907
+ hidden=True,
1908
+ )
1909
+ @click.option(
1910
+ "--schema",
1911
+ type=str,
1912
+ help="Path to the schema file for the job.",
1913
+ hidden=True,
1914
+ )
1832
1915
  @click.argument("path")
1833
1916
  def create(
1834
1917
  path,
@@ -1844,6 +1927,8 @@ def create(
1844
1927
  build_context,
1845
1928
  base_image,
1846
1929
  dockerfile,
1930
+ services,
1931
+ schema,
1847
1932
  ):
1848
1933
  """Create a job from a source, without a wandb run.
1849
1934
 
@@ -1878,6 +1963,12 @@ def create(
1878
1963
  wandb.termerror("Cannot provide --base-image/-B for an `image` job")
1879
1964
  return
1880
1965
 
1966
+ if schema:
1967
+ schema_dict = util.load_json_yaml_dict(schema)
1968
+ if schema_dict is None:
1969
+ wandb.termerror(f"Invalid format for schema file: {schema}")
1970
+ return
1971
+
1881
1972
  artifact, action, aliases = _create_job(
1882
1973
  api=api,
1883
1974
  path=path,
@@ -1893,6 +1984,8 @@ def create(
1893
1984
  build_context=build_context,
1894
1985
  base_image=base_image,
1895
1986
  dockerfile=dockerfile,
1987
+ services=services,
1988
+ schema=schema_dict,
1896
1989
  )
1897
1990
  if not artifact:
1898
1991
  wandb.termerror("Job creation failed")
@@ -2460,7 +2553,8 @@ def pull(run, project, entity):
2460
2553
 
2461
2554
 
2462
2555
  @cli.command(
2463
- context_settings=CONTEXT, help="Restore code, config and docker state for a run"
2556
+ context_settings=CONTEXT,
2557
+ help="Restore code, config and docker state for a run. Retrieves code from latest commit if code was not saved with `wandb.save()` or `wandb.init(save_code=True)`.",
2464
2558
  )
2465
2559
  @click.pass_context
2466
2560
  @click.argument("run", envvar=env.RUN_ID)
@@ -2700,7 +2794,37 @@ def enabled(service):
2700
2794
  )
2701
2795
 
2702
2796
 
2703
- @cli.command(context_settings=CONTEXT, help="Verify your local instance")
2797
+ @cli.command(
2798
+ context_settings=CONTEXT,
2799
+ help="""Checks and verifies local instance of W&B. W&B checks for:
2800
+
2801
+ Checks that the host is not `api.wandb.ai` (host check).
2802
+
2803
+ Verifies if the user is logged in correctly using the provided API key (login check).
2804
+
2805
+ Checks that requests are made over HTTPS (secure requests).
2806
+
2807
+ Validates the CORS (Cross-Origin Resource Sharing) configuration of the
2808
+ object store (CORS configuration).
2809
+
2810
+ Logs metrics, saves, and downloads files to check if runs are correctly
2811
+ recorded and accessible (run check).
2812
+
2813
+ Saves and downloads artifacts to verify that the artifact storage and
2814
+ retrieval system is working as expected (artifact check).
2815
+
2816
+ Tests the GraphQL endpoint by uploading a file to ensure it can handle
2817
+ signed URL uploads (GraphQL PUT check).
2818
+
2819
+ Checks the ability to send large payloads through the proxy (large payload check).
2820
+
2821
+ Verifies that the installed version of the W&B package is up-to-date and
2822
+ compatible with the server (W&B version check).
2823
+
2824
+ Creates and executes a sweep to ensure that sweep functionality is
2825
+ working correctly (sweeps check).
2826
+ """,
2827
+ )
2704
2828
  @click.option("--host", default=None, help="Test a specific instance of W&B")
2705
2829
  def verify(host):
2706
2830
  # TODO: (kdg) Build this all into a WandbVerify object, and clean this up.
wandb/env.py CHANGED
@@ -159,6 +159,14 @@ def is_offline(env: MutableMapping | None = None) -> bool:
159
159
  return env.get(MODE) == "offline"
160
160
 
161
161
 
162
+ def is_quiet() -> bool:
163
+ return _env_as_bool(QUIET, default="false")
164
+
165
+
166
+ def is_silent() -> bool:
167
+ return _env_as_bool(SILENT, default="false")
168
+
169
+
162
170
  def error_reporting_enabled() -> bool:
163
171
  return _env_as_bool(ERROR_REPORTING, default="True")
164
172
 
wandb/errors/errors.py CHANGED
@@ -2,7 +2,10 @@ from typing import Optional
2
2
 
3
3
 
4
4
  class Error(Exception):
5
- """Base W&B Error."""
5
+ """Base W&B Error.
6
+
7
+ <!-- lazydoc-ignore-class: internal -->
8
+ """
6
9
 
7
10
  def __init__(self, message, context: Optional[dict] = None) -> None:
8
11
  super().__init__(message)
@@ -9,7 +9,6 @@ from typing_extensions import override
9
9
  import wandb
10
10
  from wandb import Artifact
11
11
  from wandb.sdk.lib import telemetry
12
- from wandb.sdk.wandb_run import Run
13
12
 
14
13
  try:
15
14
  import lightning
@@ -295,7 +294,7 @@ class WandbLogger(Logger):
295
294
  anonymous: Optional[bool] = None,
296
295
  project: Optional[str] = None,
297
296
  log_model: Union[Literal["all"], bool] = False,
298
- experiment: Optional["Run"] = None,
297
+ experiment: Optional["wandb.Run"] = None,
299
298
  prefix: str = "",
300
299
  checkpoint_name: Optional[str] = None,
301
300
  log_checkpoint_on: Union[Literal["success"], Literal["all"]] = "success",
@@ -362,7 +361,7 @@ class WandbLogger(Logger):
362
361
 
363
362
  @property
364
363
  @rank_zero_experiment
365
- def experiment(self) -> "Run":
364
+ def experiment(self) -> "wandb.Run":
366
365
  r"""Actual wandb object.
367
366
 
368
367
  To use wandb features in your :class:`~lightning.pytorch.core.LightningModule`, do the
@@ -395,7 +394,7 @@ class WandbLogger(Logger):
395
394
  self._experiment = wandb.init(**self._wandb_init)
396
395
 
397
396
  # define default x-axis
398
- if isinstance(self._experiment, Run) and getattr(
397
+ if isinstance(self._experiment, wandb.Run) and getattr(
399
398
  self._experiment, "define_metric", None
400
399
  ):
401
400
  self._experiment.define_metric("trainer/global_step")
@@ -1,3 +1,9 @@
1
+ """W&B Integration for Metaflow.
2
+
3
+ Defines a custom step and flow decorator `wandb_log` that automatically logs
4
+ flow parameters and artifacts to W&B.
5
+ """
6
+
1
7
  from .metaflow import wandb_log, wandb_track, wandb_use
2
8
 
3
9
  __all__ = ["wandb_log", "wandb_track", "wandb_use"]
@@ -0,0 +1,74 @@
1
+ """Support for Pandas datatypes.
2
+
3
+ May raise MissingDependencyError on import.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing_extensions import Any, TypeIs
9
+
10
+ import wandb
11
+
12
+ from . import errors
13
+
14
+ try:
15
+ import pandas as pd
16
+ except ImportError as e:
17
+ warning = (
18
+ "`pandas` not installed >>"
19
+ " @wandb_log(datasets=True) may not auto log your dataset!"
20
+ )
21
+ raise errors.MissingDependencyError(warning=warning) from e
22
+
23
+
24
+ def is_dataframe(data: Any) -> TypeIs[pd.DataFrame]:
25
+ """Returns whether the data is a Pandas DataFrame."""
26
+ return isinstance(data, pd.DataFrame)
27
+
28
+
29
+ def use_dataframe(
30
+ name: str,
31
+ run: wandb.Run | None,
32
+ testing: bool = False,
33
+ ) -> str | None:
34
+ """Log a dependency on a DataFrame input.
35
+
36
+ Args:
37
+ name: Name of the input.
38
+ run: The run to update.
39
+ testing: True in unit tests.
40
+ """
41
+ if testing:
42
+ return "datasets"
43
+ assert run
44
+
45
+ wandb.termlog(f"Using artifact: {name} (Pandas DataFrame)")
46
+ run.use_artifact(f"{name}:latest")
47
+ return None
48
+
49
+
50
+ def track_dataframe(
51
+ name: str,
52
+ data: pd.DataFrame,
53
+ run: wandb.Run | None,
54
+ testing: bool = False,
55
+ ) -> str | None:
56
+ """Log a DataFrame output as an artifact.
57
+
58
+ Args:
59
+ name: The output's name.
60
+ data: The output's value.
61
+ run: The run to update.
62
+ testing: True in unit tests.
63
+ """
64
+ if testing:
65
+ return "pd.DataFrame"
66
+ assert run
67
+
68
+ artifact = wandb.Artifact(name, type="dataset")
69
+ with artifact.new_file(f"{name}.parquet", "wb") as f:
70
+ data.to_parquet(f, engine="pyarrow")
71
+
72
+ wandb.termlog(f"Logging artifact: {name} (Pandas DataFrame)")
73
+ run.log_artifact(artifact)
74
+ return None
@@ -0,0 +1,75 @@
1
+ """Support for PyTorch datatypes.
2
+
3
+ May raise MissingDependencyError on import.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing_extensions import Any, TypeIs
9
+
10
+ import wandb
11
+
12
+ from . import errors
13
+
14
+ try:
15
+ import torch
16
+ import torch.nn as nn
17
+ except ImportError as e:
18
+ warning = (
19
+ "`torch` (PyTorch) not installed >>"
20
+ " @wandb_log(models=True) may not auto log your model!"
21
+ )
22
+ raise errors.MissingDependencyError(warning=warning) from e
23
+
24
+
25
+ def is_nn_module(data: Any) -> TypeIs[nn.Module]:
26
+ """Returns whether the data is a PyTorch nn.Module."""
27
+ return isinstance(data, nn.Module)
28
+
29
+
30
+ def use_nn_module(
31
+ name: str,
32
+ run: wandb.Run | None,
33
+ testing: bool = False,
34
+ ) -> str | None:
35
+ """Log a dependency on a PyTorch model input.
36
+
37
+ Args:
38
+ name: Name of the input.
39
+ run: The run to update.
40
+ testing: True in unit tests.
41
+ """
42
+ if testing:
43
+ return "models"
44
+ assert run
45
+
46
+ wandb.termlog(f"Using artifact: {name} (PyTorch nn.Module)")
47
+ run.use_artifact(f"{name}:latest")
48
+ return None
49
+
50
+
51
+ def track_nn_module(
52
+ name: str,
53
+ data: nn.Module,
54
+ run: wandb.Run | None,
55
+ testing: bool = False,
56
+ ) -> str | None:
57
+ """Log a PyTorch model output as an artifact.
58
+
59
+ Args:
60
+ name: The output's name.
61
+ data: The output's value.
62
+ run: The run to update.
63
+ testing: True in unit tests.
64
+ """
65
+ if testing:
66
+ return "nn.Module"
67
+ assert run
68
+
69
+ artifact = wandb.Artifact(name, type="model")
70
+ with artifact.new_file(f"{name}.pkl", "wb") as f:
71
+ torch.save(data, f)
72
+
73
+ wandb.termlog(f"Logging artifact: {name} (PyTorch nn.Module)")
74
+ run.log_artifact(artifact)
75
+ return None
@@ -0,0 +1,76 @@
1
+ """Support for sklearn datatypes.
2
+
3
+ May raise MissingDependencyError on import.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import pickle
9
+
10
+ from typing_extensions import Any, TypeIs
11
+
12
+ import wandb
13
+
14
+ from . import errors
15
+
16
+ try:
17
+ from sklearn.base import BaseEstimator
18
+ except ImportError as e:
19
+ warning = (
20
+ "`sklearn` not installed >>"
21
+ " @wandb_log(models=True) may not auto log your model!"
22
+ )
23
+ raise errors.MissingDependencyError(warning=warning) from e
24
+
25
+
26
+ def is_estimator(data: Any) -> TypeIs[BaseEstimator]:
27
+ """Returns whether the data is an sklearn BaseEstimator."""
28
+ return isinstance(data, BaseEstimator)
29
+
30
+
31
+ def use_estimator(
32
+ name: str,
33
+ run: wandb.Run | None,
34
+ testing: bool = False,
35
+ ) -> str | None:
36
+ """Log a dependency on an sklearn estimator.
37
+
38
+ Args:
39
+ name: Name of the input.
40
+ run: The run to update.
41
+ testing: True in unit tests.
42
+ """
43
+ if testing:
44
+ return "models"
45
+ assert run
46
+
47
+ wandb.termlog(f"Using artifact: {name} (sklearn BaseEstimator)")
48
+ run.use_artifact(f"{name}:latest")
49
+ return None
50
+
51
+
52
+ def track_estimator(
53
+ name: str,
54
+ data: BaseEstimator,
55
+ run: wandb.Run | None,
56
+ testing: bool = False,
57
+ ) -> str | None:
58
+ """Log an sklearn estimator output as an artifact.
59
+
60
+ Args:
61
+ name: The output's name.
62
+ data: The output's value.
63
+ run: The run to update.
64
+ testing: True in unit tests.
65
+ """
66
+ if testing:
67
+ return "BaseEstimator"
68
+ assert run
69
+
70
+ artifact = wandb.Artifact(name, type="model")
71
+ with artifact.new_file(f"{name}.pkl", "wb") as f:
72
+ pickle.dump(data, f)
73
+
74
+ wandb.termlog(f"Logging artifact: {name} (sklearn BaseEstimator)")
75
+ run.log_artifact(artifact)
76
+ return None