wandb 0.21.0__py3-none-musllinux_1_2_aarch64.whl → 0.21.1__py3-none-musllinux_1_2_aarch64.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 (97) 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 +526 -360
  8. wandb/apis/public/artifacts.py +204 -8
  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/registries_search.py +7 -15
  17. wandb/apis/public/reports.py +83 -5
  18. wandb/apis/public/runs.py +299 -105
  19. wandb/apis/public/sweeps.py +222 -22
  20. wandb/apis/public/teams.py +41 -4
  21. wandb/apis/public/users.py +45 -4
  22. wandb/beta/workflows.py +66 -30
  23. wandb/bin/gpu_stats +0 -0
  24. wandb/bin/wandb-core +0 -0
  25. wandb/cli/cli.py +80 -1
  26. wandb/env.py +8 -0
  27. wandb/errors/errors.py +4 -1
  28. wandb/integration/lightning/fabric/logger.py +3 -4
  29. wandb/integration/metaflow/__init__.py +6 -0
  30. wandb/integration/metaflow/data_pandas.py +74 -0
  31. wandb/integration/metaflow/errors.py +13 -0
  32. wandb/integration/metaflow/metaflow.py +205 -190
  33. wandb/integration/openai/fine_tuning.py +1 -2
  34. wandb/jupyter.py +5 -5
  35. wandb/plot/custom_chart.py +30 -7
  36. wandb/proto/v3/wandb_internal_pb2.py +280 -280
  37. wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
  38. wandb/proto/v4/wandb_internal_pb2.py +280 -280
  39. wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
  40. wandb/proto/v5/wandb_internal_pb2.py +280 -280
  41. wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
  42. wandb/proto/v6/wandb_internal_pb2.py +280 -280
  43. wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
  44. wandb/proto/wandb_deprecated.py +6 -0
  45. wandb/sdk/artifacts/_internal_artifact.py +19 -8
  46. wandb/sdk/artifacts/_validators.py +8 -0
  47. wandb/sdk/artifacts/artifact.py +106 -75
  48. wandb/sdk/data_types/audio.py +38 -10
  49. wandb/sdk/data_types/base_types/media.py +6 -56
  50. wandb/sdk/data_types/graph.py +48 -14
  51. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
  52. wandb/sdk/data_types/helper_types/image_mask.py +1 -3
  53. wandb/sdk/data_types/histogram.py +34 -21
  54. wandb/sdk/data_types/html.py +35 -12
  55. wandb/sdk/data_types/image.py +104 -68
  56. wandb/sdk/data_types/molecule.py +32 -19
  57. wandb/sdk/data_types/object_3d.py +36 -17
  58. wandb/sdk/data_types/plotly.py +18 -5
  59. wandb/sdk/data_types/saved_model.py +4 -6
  60. wandb/sdk/data_types/table.py +59 -30
  61. wandb/sdk/data_types/video.py +53 -26
  62. wandb/sdk/integration_utils/auto_logging.py +2 -2
  63. wandb/sdk/internal/internal_api.py +6 -0
  64. wandb/sdk/internal/job_builder.py +6 -0
  65. wandb/sdk/launch/agent/agent.py +8 -1
  66. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
  67. wandb/sdk/launch/create_job.py +3 -1
  68. wandb/sdk/launch/inputs/internal.py +3 -4
  69. wandb/sdk/launch/inputs/schema.py +1 -0
  70. wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
  71. wandb/sdk/launch/runner/kubernetes_runner.py +328 -1
  72. wandb/sdk/launch/sweeps/scheduler.py +2 -3
  73. wandb/sdk/lib/asyncio_compat.py +3 -0
  74. wandb/sdk/lib/deprecate.py +1 -7
  75. wandb/sdk/lib/disabled.py +1 -1
  76. wandb/sdk/lib/hashutil.py +14 -1
  77. wandb/sdk/lib/module.py +7 -13
  78. wandb/sdk/lib/progress.py +0 -19
  79. wandb/sdk/lib/sock_client.py +0 -4
  80. wandb/sdk/wandb_init.py +66 -91
  81. wandb/sdk/wandb_login.py +18 -14
  82. wandb/sdk/wandb_metric.py +2 -0
  83. wandb/sdk/wandb_run.py +406 -414
  84. wandb/sdk/wandb_settings.py +130 -2
  85. wandb/sdk/wandb_setup.py +28 -28
  86. wandb/sdk/wandb_sweep.py +14 -13
  87. wandb/sdk/wandb_watch.py +4 -6
  88. wandb/sync/sync.py +10 -0
  89. wandb/util.py +57 -0
  90. wandb/wandb_run.py +1 -2
  91. {wandb-0.21.0.dist-info → wandb-0.21.1.dist-info}/METADATA +1 -1
  92. {wandb-0.21.0.dist-info → wandb-0.21.1.dist-info}/RECORD +786 -786
  93. wandb/vendor/pynvml/__init__.py +0 -0
  94. wandb/vendor/pynvml/pynvml.py +0 -4779
  95. {wandb-0.21.0.dist-info → wandb-0.21.1.dist-info}/WHEEL +0 -0
  96. {wandb-0.21.0.dist-info → wandb-0.21.1.dist-info}/entry_points.txt +0 -0
  97. {wandb-0.21.0.dist-info → wandb-0.21.1.dist-info}/licenses/LICENSE +0 -0
@@ -203,7 +203,7 @@ class Table(Media):
203
203
  This means you can embed `Images`, `Video`, `Audio`, and other sorts of rich, annotated media
204
204
  directly in Tables, alongside other traditional scalar values.
205
205
 
206
- This class is the primary class used to generate the W&B Tables
206
+ This class is the primary class used to generate W&B Tables
207
207
  https://docs.wandb.ai/guides/models/tables/.
208
208
  """
209
209
 
@@ -236,6 +236,7 @@ class Table(Media):
236
236
  data: (List[List[any]]) 2D row-oriented array of values.
237
237
  dataframe: (pandas.DataFrame) DataFrame object used to create the table.
238
238
  When set, `data` and `columns` arguments are ignored.
239
+ rows: (List[List[any]]) 2D row-oriented array of values.
239
240
  optional: (Union[bool,List[bool]]) Determines if `None` values are allowed. Default to True
240
241
  - If a singular bool value, then the optionality is enforced for all
241
242
  columns specified at construction time
@@ -410,13 +411,15 @@ class Table(Media):
410
411
  def cast(self, col_name, dtype, optional=False):
411
412
  """Casts a column to a specific data type.
412
413
 
413
- This can be one of the normal python classes, an internal W&B type, or an
414
- example object, like an instance of wandb.Image or wandb.Classes.
414
+ This can be one of the normal python classes, an internal W&B type,
415
+ or an example object, like an instance of wandb.Image or
416
+ wandb.Classes.
415
417
 
416
418
  Args:
417
- col_name: (str) - The name of the column to cast.
418
- dtype: (class, wandb.wandb_sdk.interface._dtypes.Type, any) - The target dtype.
419
- optional: (bool) - If the column should allow Nones.
419
+ col_name (str): The name of the column to cast.
420
+ dtype (class, wandb.wandb_sdk.interface._dtypes.Type, any): The
421
+ target dtype.
422
+ optional (bool): If the column should allow Nones.
420
423
  """
421
424
  assert col_name in self.columns
422
425
 
@@ -499,14 +502,17 @@ class Table(Media):
499
502
 
500
503
  @allow_relogging_after_mutation
501
504
  def add_row(self, *row):
502
- """Deprecated; use add_data instead."""
505
+ """Deprecated. Use `Table.add_data` method instead."""
503
506
  logging.warning("add_row is deprecated, use add_data")
504
507
  self.add_data(*row)
505
508
 
506
509
  @allow_relogging_after_mutation
507
510
  @allow_incremental_logging_after_append
508
511
  def add_data(self, *data):
509
- """Adds a new row of data to the table. The maximum amount of rows in a table is determined by `wandb.Table.MAX_ARTIFACT_ROWS`.
512
+ """Adds a new row of data to the table.
513
+
514
+ The maximum amount ofrows in a table is determined by
515
+ `wandb.Table.MAX_ARTIFACT_ROWS`.
510
516
 
511
517
  The length of the data should match the length of the table column.
512
518
  """
@@ -589,6 +595,10 @@ class Table(Media):
589
595
  return {"columns": self.columns, "data": self.data[:max_rows]}
590
596
 
591
597
  def bind_to_run(self, *args, **kwargs):
598
+ """Bind this object to a run.
599
+
600
+ <!-- lazydoc-ignore: internal -->
601
+ """
592
602
  # We set `warn=False` since Tables will now always be logged to both
593
603
  # files and artifacts. The file limit will never practically matter and
594
604
  # this code path will be ultimately removed. The 10k limit warning confuses
@@ -603,10 +613,18 @@ class Table(Media):
603
613
 
604
614
  @classmethod
605
615
  def get_media_subdir(cls):
616
+ """Get media subdirectory.
617
+
618
+ <!-- lazydoc-ignore-classmethod: internal -->
619
+ """
606
620
  return os.path.join("media", "table")
607
621
 
608
622
  @classmethod
609
623
  def from_json(cls, json_obj, source_artifact: "artifact.Artifact"):
624
+ """Deserialize JSON object into it's class representation.
625
+
626
+ <!-- lazydoc-ignore-classmethod: internal -->
627
+ """
610
628
  data = []
611
629
  column_types = None
612
630
  np_deserialized_columns = {}
@@ -690,6 +708,10 @@ class Table(Media):
690
708
  return new_obj
691
709
 
692
710
  def to_json(self, run_or_artifact):
711
+ """Returns the JSON representation expected by the backend.
712
+
713
+ <!-- lazydoc-ignore: internal -->
714
+ """
693
715
  json_dict = super().to_json(run_or_artifact)
694
716
 
695
717
  if self.log_mode == "INCREMENTAL":
@@ -705,7 +727,7 @@ class Table(Media):
705
727
  }
706
728
  )
707
729
 
708
- if isinstance(run_or_artifact, wandb.wandb_sdk.wandb_run.Run):
730
+ if isinstance(run_or_artifact, wandb.Run):
709
731
  if self.log_mode == "INCREMENTAL":
710
732
  wbvalue_type = "incremental-table-file"
711
733
  else:
@@ -799,11 +821,11 @@ class Table(Media):
799
821
 
800
822
  Yields:
801
823
  ------
802
- index : int
803
- The index of the row. Using this value in other W&B tables
824
+ index: The index of the row. Using this value in other W&B tables
804
825
  will automatically build a relationship between the tables
805
- row : List[any]
806
- The data of the row.
826
+ row: The data of the row.
827
+
828
+ <!-- lazydoc-ignore: internal -->
807
829
  """
808
830
  for ndx in range(len(self.data)):
809
831
  index = _TableIndex(ndx)
@@ -812,12 +834,20 @@ class Table(Media):
812
834
 
813
835
  @allow_relogging_after_mutation
814
836
  def set_pk(self, col_name):
837
+ """Set primary key type for Table object.
838
+
839
+ <!-- lazydoc-ignore: internal -->
840
+ """
815
841
  # TODO: Docs
816
842
  assert col_name in self.columns
817
843
  self.cast(col_name, _PrimaryKeyType())
818
844
 
819
845
  @allow_relogging_after_mutation
820
846
  def set_fk(self, col_name, table, table_col):
847
+ """Set foreign key type for Table object.
848
+
849
+ <!-- lazydoc-ignore: internal -->
850
+ """
821
851
  # TODO: Docs
822
852
  assert col_name in self.columns
823
853
  assert col_name != self._pk_col
@@ -1003,7 +1033,10 @@ class Table(Media):
1003
1033
  return pd.DataFrame.from_records(self.data, columns=self.columns)
1004
1034
 
1005
1035
  def index_ref(self, index):
1006
- """Gets a reference of the index of a row in the table."""
1036
+ """Gets a reference of the index of a row in the table.
1037
+
1038
+ <!-- lazydoc-ignore: internal -->
1039
+ """
1007
1040
  assert index < len(self.data)
1008
1041
  _index = _TableIndex(index)
1009
1042
  _index.set_table(self)
@@ -1015,14 +1048,12 @@ class Table(Media):
1015
1048
  """Adds one or more computed columns based on existing data.
1016
1049
 
1017
1050
  Args:
1018
- fn: A function which accepts one or two parameters, ndx (int) and row (dict),
1019
- which is expected to return a dict representing new columns for that row, keyed
1020
- by the new column names.
1021
-
1022
- `ndx` is an integer representing the index of the row. Only included if `include_ndx`
1051
+ fn: A function which accepts one or two parameters, ndx (int) and
1052
+ row (dict), which is expected to return a dict representing
1053
+ new columns for that row, keyed by the new column names.
1054
+ - `ndx` is an integer representing the index of the row. Only included if `include_ndx`
1023
1055
  is set to `True`.
1024
-
1025
- `row` is a dictionary keyed by existing columns
1056
+ - `row` is a dictionary keyed by existing columns
1026
1057
  """
1027
1058
  new_columns = {}
1028
1059
  for ndx, row in self.iterrows():
@@ -1056,7 +1087,8 @@ class _PartitionTablePartEntry:
1056
1087
  class PartitionedTable(Media):
1057
1088
  """A table which is composed of multiple sub-tables.
1058
1089
 
1059
- Currently, PartitionedTable is designed to point to a directory within an artifact.
1090
+ Currently, PartitionedTable is designed to point to a directory within an
1091
+ artifact.
1060
1092
  """
1061
1093
 
1062
1094
  _log_type = "partitioned-table"
@@ -1075,7 +1107,7 @@ class PartitionedTable(Media):
1075
1107
  json_obj = {
1076
1108
  "_type": PartitionedTable._log_type,
1077
1109
  }
1078
- if isinstance(artifact_or_run, wandb.wandb_sdk.wandb_run.Run):
1110
+ if isinstance(artifact_or_run, wandb.Run):
1079
1111
  artifact_entry_url = self._get_artifact_entry_ref_url()
1080
1112
  if artifact_entry_url is None:
1081
1113
  raise ValueError(
@@ -1099,12 +1131,9 @@ class PartitionedTable(Media):
1099
1131
  def iterrows(self):
1100
1132
  """Iterate over rows as (ndx, row).
1101
1133
 
1102
- Yields:
1103
- ------
1104
- index : int
1105
- The index of the row.
1106
- row : List[any]
1107
- The data of the row.
1134
+ Args:
1135
+ index (int): The index of the row.
1136
+ row (List[any]): The data of the row.
1108
1137
  """
1109
1138
  columns = None
1110
1139
  ndx = 0
@@ -1233,7 +1262,7 @@ class JoinedTable(Media):
1233
1262
  json_obj = {
1234
1263
  "_type": JoinedTable._log_type,
1235
1264
  }
1236
- if isinstance(artifact_or_run, wandb.wandb_sdk.wandb_run.Run):
1265
+ if isinstance(artifact_or_run, wandb.Run):
1237
1266
  artifact_entry_url = self._get_artifact_entry_ref_url()
1238
1267
  if artifact_entry_url is None:
1239
1268
  raise ValueError(
@@ -6,7 +6,8 @@ from io import BytesIO
6
6
  from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type, Union
7
7
 
8
8
  import wandb
9
- from wandb import util
9
+ from wandb import env, util
10
+ from wandb.sdk import wandb_setup
10
11
  from wandb.sdk.lib import filesystem, printer, printer_asyncio, runid
11
12
 
12
13
  from . import _dtypes
@@ -23,6 +24,14 @@ if TYPE_CHECKING: # pragma: no cover
23
24
  from ..wandb_run import Run as LocalRun
24
25
 
25
26
 
27
+ def _should_print_spinner() -> bool:
28
+ singleton = wandb_setup.singleton_if_setup()
29
+ if singleton and (singleton.settings.quiet or singleton.settings.silent):
30
+ return False
31
+
32
+ return not env.is_quiet() and not env.is_silent()
33
+
34
+
26
35
  # This helper function is a workaround for the issue discussed here:
27
36
  # https://github.com/wandb/wandb/issues/3472
28
37
  #
@@ -80,40 +89,38 @@ class Video(BatchableMedia):
80
89
  """Initialize a W&B Video object.
81
90
 
82
91
  Args:
83
- data_or_path:
84
- Video can be initialized with a path to a file or an io object.
85
- Video can be initialized with a numpy tensor.
86
- The numpy tensor must be either 4 dimensional or 5 dimensional.
92
+ data_or_path: Video can be initialized with a path to a file or an io object.
93
+ Video can be initialized with a numpy tensor. The numpy tensor
94
+ must be either 4 dimensional or 5 dimensional.
87
95
  The dimensions should be (number of frames, channel, height, width) or
88
96
  (batch, number of frames, channel, height, width)
89
97
  The format parameter must be specified with the format argument
90
98
  when initializing with a numpy array
91
99
  or io object.
92
100
  caption: Caption associated with the video for display.
93
- fps:
94
- The frame rate to use when encoding raw video frames.
101
+ fps: The frame rate to use when encoding raw video frames.
95
102
  Default value is 4.
96
103
  This parameter has no effect when data_or_path is a string, or bytes.
97
- format:
98
- Format of video, necessary if initializing with a numpy array
104
+ format: Format of video, necessary if initializing with a numpy array
99
105
  or io object. This parameter will be used to determine the format
100
106
  to use when encoding the video data. Accepted values are "gif",
101
107
  "mp4", "webm", or "ogg".
102
108
  If no value is provided, the default format will be "gif".
103
109
 
104
110
  Examples:
105
- ### Log a numpy array as a video
106
- ```python
107
- import numpy as np
108
- import wandb
109
-
110
- with wandb.init() as run:
111
- # axes are (number of frames, channel, height, width)
112
- frames = np.random.randint(
113
- low=0, high=256, size=(10, 3, 100, 100), dtype=np.uint8
114
- )
115
- run.log({"video": wandb.Video(frames, format="mp4", fps=4)})
116
- ```
111
+ Log a numpy array as a video
112
+
113
+ ```python
114
+ import numpy as np
115
+ import wandb
116
+
117
+ with wandb.init() as run:
118
+ # axes are (number of frames, channel, height, width)
119
+ frames = np.random.randint(
120
+ low=0, high=256, size=(10, 3, 100, 100), dtype=np.uint8
121
+ )
122
+ run.log({"video": wandb.Video(frames, format="mp4", fps=4)})
123
+ ```
117
124
  """
118
125
  super().__init__(caption=caption)
119
126
 
@@ -167,13 +174,21 @@ class Video(BatchableMedia):
167
174
  "wandb.Video accepts a file path or numpy like data as input"
168
175
  )
169
176
  fps = fps or 4
170
- printer_asyncio.run_async_with_spinner(
171
- printer.new_printer(),
172
- "Encoding video...",
173
- functools.partial(self.encode, fps=fps),
174
- )
177
+
178
+ if _should_print_spinner():
179
+ printer_asyncio.run_async_with_spinner(
180
+ printer.new_printer(),
181
+ "Encoding video...",
182
+ functools.partial(self.encode, fps=fps),
183
+ )
184
+ else:
185
+ self.encode(fps=fps)
175
186
 
176
187
  def encode(self, fps: int = 4) -> None:
188
+ """Encode the video data to a file.
189
+
190
+ <!-- lazydoc-ignore: internal -->
191
+ """
177
192
  # import ImageSequenceClip from the appropriate MoviePy module
178
193
  mpy = util.get_module(
179
194
  "moviepy.video.io.ImageSequenceClip",
@@ -199,9 +214,17 @@ class Video(BatchableMedia):
199
214
 
200
215
  @classmethod
201
216
  def get_media_subdir(cls: Type["Video"]) -> str:
217
+ """Get media subdirectory for video files.
218
+
219
+ <!-- lazydoc-ignore-classmethod: internal -->
220
+ """
202
221
  return os.path.join("media", "videos")
203
222
 
204
223
  def to_json(self, run_or_artifact: Union["LocalRun", "Artifact"]) -> dict:
224
+ """Returns the JSON representation expected by the backend.
225
+
226
+ <!-- lazydoc-ignore: internal -->
227
+ """
205
228
  json_dict = super().to_json(run_or_artifact)
206
229
  json_dict["_type"] = self._log_type
207
230
 
@@ -256,6 +279,10 @@ class Video(BatchableMedia):
256
279
  key: str,
257
280
  step: Union[int, str],
258
281
  ) -> dict:
282
+ """Convert a sequence of Video objects to a JSON representation.
283
+
284
+ <!-- lazydoc-ignore-classmethod: internal -->
285
+ """
259
286
  base_path = os.path.join(run.dir, cls.get_media_subdir())
260
287
  filesystem.mkdir_exists_ok(base_path)
261
288
 
@@ -71,7 +71,7 @@ class PatchAPI:
71
71
  )
72
72
  return self._api
73
73
 
74
- def patch(self, run: "wandb.sdk.wandb_run.Run") -> None:
74
+ def patch(self, run: "wandb.Run") -> None:
75
75
  """Patches the API to log media or metrics to W&B."""
76
76
  for symbol in self.symbols:
77
77
  # split on dots, e.g. "Client.generate" -> ["Client", "generate"]
@@ -163,7 +163,7 @@ class AutologAPI:
163
163
  resolver=resolver,
164
164
  )
165
165
  self._name = self._patch_api.name
166
- self._run: Optional[wandb.sdk.wandb_run.Run] = None
166
+ self._run: Optional[wandb.Run] = None
167
167
  self.__run_created_by_autolog: bool = False
168
168
 
169
169
  @property
@@ -284,6 +284,7 @@ class Api:
284
284
  self._extra_http_headers.update(_thread_local_api_settings.headers or {})
285
285
 
286
286
  auth = None
287
+ api_key = api_key or self.default_settings.get("api_key")
287
288
  if api_key:
288
289
  auth = ("api", api_key)
289
290
  elif self.access_token is not None:
@@ -3234,6 +3235,7 @@ class Api:
3234
3235
  entity: Optional[str] = None,
3235
3236
  state: Optional[str] = None,
3236
3237
  prior_runs: Optional[List[str]] = None,
3238
+ display_name: Optional[str] = None,
3237
3239
  template_variable_values: Optional[Dict[str, Any]] = None,
3238
3240
  ) -> Tuple[str, List[str]]:
3239
3241
  """Upsert a sweep object.
@@ -3248,6 +3250,7 @@ class Api:
3248
3250
  entity (str): entity to use
3249
3251
  state (str): state
3250
3252
  prior_runs (list): IDs of existing runs to add to the sweep
3253
+ display_name (str): display name for the sweep
3251
3254
  template_variable_values (dict): template variable values
3252
3255
  """
3253
3256
  project_query = """
@@ -3271,6 +3274,7 @@ class Api:
3271
3274
  $scheduler: JSONString,
3272
3275
  $state: String,
3273
3276
  $priorRunsFilters: JSONString,
3277
+ $displayName: String,
3274
3278
  ) {
3275
3279
  upsertSweep(input: {
3276
3280
  id: $id,
@@ -3282,6 +3286,7 @@ class Api:
3282
3286
  scheduler: $scheduler,
3283
3287
  state: $state,
3284
3288
  priorRunsFilters: $priorRunsFilters,
3289
+ displayName: $displayName,
3285
3290
  }) {
3286
3291
  sweep {
3287
3292
  name
@@ -3358,6 +3363,7 @@ class Api:
3358
3363
  "templateVariableValues": json.dumps(template_variable_values),
3359
3364
  "scheduler": scheduler,
3360
3365
  "priorRunsFilters": filters,
3366
+ "displayName": display_name,
3361
3367
  }
3362
3368
  if state:
3363
3369
  variables["state"] = state
@@ -109,6 +109,7 @@ class JobSourceDict(TypedDict, total=False):
109
109
  input_types: Dict[str, Any]
110
110
  output_types: Dict[str, Any]
111
111
  runtime: Optional[str]
112
+ services: Dict[str, str]
112
113
 
113
114
 
114
115
  class ArtifactInfoForJob(TypedDict):
@@ -143,6 +144,7 @@ class JobBuilder:
143
144
  _job_version_alias: Optional[str]
144
145
  _is_notebook_run: bool
145
146
  _verbose: bool
147
+ _services: Dict[str, str]
146
148
 
147
149
  def __init__(self, settings: SettingsStatic, verbose: bool = False):
148
150
  self._settings = settings
@@ -162,6 +164,7 @@ class JobBuilder:
162
164
  self._is_notebook_run = self._get_is_notebook_run()
163
165
  self._verbose = verbose
164
166
  self._partial = False
167
+ self._services = {}
165
168
 
166
169
  def set_config(self, config: Dict[str, Any]) -> None:
167
170
  self._config = config
@@ -544,6 +547,9 @@ class JobBuilder:
544
547
  "runtime": runtime,
545
548
  }
546
549
 
550
+ if self._services:
551
+ source_info["services"] = self._services
552
+
547
553
  assert source_info is not None
548
554
  assert name is not None
549
555
 
@@ -1,6 +1,7 @@
1
1
  """Implementation of launch agent."""
2
2
 
3
3
  import asyncio
4
+ import copy
4
5
  import logging
5
6
  import os
6
7
  import pprint
@@ -421,6 +422,7 @@ class LaunchAgent:
421
422
  """Removes the job from our list for now."""
422
423
  with self._jobs_lock:
423
424
  job_and_run_status = self._jobs[thread_id]
425
+
424
426
  if (
425
427
  job_and_run_status.entity is not None
426
428
  and job_and_run_status.entity != self._entity
@@ -516,7 +518,11 @@ class LaunchAgent:
516
518
  Arguments:
517
519
  job: Job to run.
518
520
  """
519
- _msg = f"{LOG_PREFIX}Launch agent received job:\n{pprint.pformat(job)}\n"
521
+ job_copy = copy.deepcopy(job)
522
+ if "runSpec" in job_copy and "_wandb_api_key" in job_copy["runSpec"]:
523
+ job_copy["runSpec"]["_wandb_api_key"] = "<redacted>"
524
+
525
+ _msg = f"{LOG_PREFIX}Launch agent received job:\n{pprint.pformat(job_copy)}\n"
520
526
  wandb.termlog(_msg)
521
527
  _logger.info(_msg)
522
528
  # update agent status
@@ -727,6 +733,7 @@ class LaunchAgent:
727
733
  backend = loader.runner_from_config(
728
734
  resource, api, backend_config, environment, registry
729
735
  )
736
+
730
737
  if not (
731
738
  project.docker_image
732
739
  or project.job_base_image
@@ -11,7 +11,7 @@ FileSubtypes = Literal["warning", "error"]
11
11
  class RunQueueItemFileSaver:
12
12
  def __init__(
13
13
  self,
14
- agent_run: Optional["wandb.sdk.wandb_run.Run"],
14
+ agent_run: Optional["wandb.Run"],
15
15
  run_queue_item_id: str,
16
16
  ):
17
17
  self.run_queue_item_id = run_queue_item_id
@@ -20,7 +20,7 @@ class RunQueueItemFileSaver:
20
20
  def save_contents(
21
21
  self, contents: str, fname: str, file_sub_type: FileSubtypes
22
22
  ) -> Optional[List[str]]:
23
- if not isinstance(self.run, wandb.sdk.wandb_run.Run):
23
+ if not isinstance(self.run, wandb.Run):
24
24
  wandb.termwarn("Not saving file contents because agent has no run")
25
25
  return None
26
26
  root_dir = self.run._settings.files_dir
@@ -115,6 +115,7 @@ def _create_job(
115
115
  build_context: Optional[str] = None,
116
116
  dockerfile: Optional[str] = None,
117
117
  base_image: Optional[str] = None,
118
+ services: Optional[Dict[str, str]] = None,
118
119
  ) -> Tuple[Optional[Artifact], str, List[str]]:
119
120
  wandb.termlog(f"Creating launch job of type: {job_type}...")
120
121
 
@@ -169,6 +170,7 @@ def _create_job(
169
170
 
170
171
  job_builder = _configure_job_builder_for_partial(tempdir.name, job_source=job_type)
171
172
  job_builder._settings.job_name = name
173
+ job_builder._services = services or {}
172
174
  if job_type == "code":
173
175
  assert entrypoint is not None
174
176
  job_name = _make_code_artifact(
@@ -421,7 +423,7 @@ def _configure_job_builder_for_partial(tmpdir: str, job_source: str) -> JobBuild
421
423
  def _make_code_artifact(
422
424
  api: Api,
423
425
  job_builder: JobBuilder,
424
- run: "wandb.sdk.wandb_run.Run",
426
+ run: "wandb.Run",
425
427
  path: str,
426
428
  entrypoint: str,
427
429
  entity: Optional[str],
@@ -17,7 +17,6 @@ import wandb
17
17
  import wandb.data_types
18
18
  from wandb.sdk.launch.errors import LaunchError
19
19
  from wandb.sdk.launch.inputs.schema import META_SCHEMA
20
- from wandb.sdk.wandb_run import Run
21
20
  from wandb.util import get_module
22
21
 
23
22
  from .files import config_path_is_valid, override_file
@@ -93,7 +92,7 @@ class StagedLaunchInputs:
93
92
  ):
94
93
  self._staged_inputs.append(input_arguments)
95
94
 
96
- def apply(self, run: Run):
95
+ def apply(self, run: wandb.Run):
97
96
  """Apply the staged inputs to the given run."""
98
97
  for input in self._staged_inputs:
99
98
  _publish_job_input(input, run)
@@ -101,13 +100,13 @@ class StagedLaunchInputs:
101
100
 
102
101
  def _publish_job_input(
103
102
  input: JobInputArguments,
104
- run: Run,
103
+ run: wandb.Run,
105
104
  ) -> None:
106
105
  """Publish a job input to the backend interface of the given run.
107
106
 
108
107
  Arguments:
109
108
  input (JobInputArguments): The arguments for the job input.
110
- run (Run): The run to publish the job input to.
109
+ run (wandb.Run): The run to publish the job input to.
111
110
  """
112
111
  assert run._backend is not None
113
112
  assert run._backend.interface is not None
@@ -7,6 +7,7 @@ META_SCHEMA = {
7
7
  },
8
8
  "title": {"type": "string"},
9
9
  "description": {"type": "string"},
10
+ "format": {"type": "string"},
10
11
  "enum": {"type": "array", "items": {"type": ["integer", "number", "string"]}},
11
12
  "properties": {"type": "object", "patternProperties": {".*": {"$ref": "#"}}},
12
13
  "allOf": {"type": "array", "items": {"$ref": "#"}},
@@ -27,6 +27,7 @@ WANDB_K8S_LABEL_NAMESPACE = "wandb.ai"
27
27
  WANDB_K8S_RUN_ID = f"{WANDB_K8S_LABEL_NAMESPACE}/run-id"
28
28
  WANDB_K8S_LABEL_AGENT = f"{WANDB_K8S_LABEL_NAMESPACE}/agent"
29
29
  WANDB_K8S_LABEL_MONITOR = f"{WANDB_K8S_LABEL_NAMESPACE}/monitor"
30
+ WANDB_K8S_LABEL_AUXILIARY_RESOURCE = f"{WANDB_K8S_LABEL_NAMESPACE}/auxiliary-resource"
30
31
 
31
32
 
32
33
  class Resources: