wandb 0.21.0__py3-none-win32.whl → 0.21.2__py3-none-win32.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.
- wandb/__init__.py +16 -14
- wandb/__init__.pyi +427 -450
- wandb/agents/pyagent.py +41 -12
- wandb/analytics/sentry.py +7 -2
- wandb/apis/importers/mlflow.py +1 -1
- wandb/apis/public/__init__.py +1 -1
- wandb/apis/public/api.py +525 -360
- wandb/apis/public/artifacts.py +207 -13
- wandb/apis/public/automations.py +19 -3
- wandb/apis/public/files.py +172 -33
- wandb/apis/public/history.py +67 -15
- wandb/apis/public/integrations.py +25 -2
- wandb/apis/public/jobs.py +90 -2
- wandb/apis/public/projects.py +130 -79
- wandb/apis/public/query_generator.py +11 -1
- wandb/apis/public/registries/_utils.py +14 -16
- wandb/apis/public/registries/registries_search.py +183 -304
- wandb/apis/public/reports.py +96 -15
- wandb/apis/public/runs.py +299 -105
- wandb/apis/public/sweeps.py +222 -22
- wandb/apis/public/teams.py +41 -4
- wandb/apis/public/users.py +45 -4
- wandb/automations/_generated/delete_automation.py +1 -3
- wandb/automations/_generated/enums.py +13 -11
- wandb/beta/workflows.py +66 -30
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +127 -3
- wandb/env.py +8 -0
- wandb/errors/errors.py +4 -1
- wandb/integration/lightning/fabric/logger.py +3 -4
- wandb/integration/metaflow/__init__.py +6 -0
- wandb/integration/metaflow/data_pandas.py +74 -0
- wandb/integration/metaflow/data_pytorch.py +75 -0
- wandb/integration/metaflow/data_sklearn.py +76 -0
- wandb/integration/metaflow/errors.py +13 -0
- wandb/integration/metaflow/metaflow.py +167 -223
- wandb/integration/openai/fine_tuning.py +1 -2
- wandb/integration/weave/__init__.py +6 -0
- wandb/integration/weave/interface.py +49 -0
- wandb/integration/weave/weave.py +63 -0
- wandb/jupyter.py +5 -5
- wandb/plot/custom_chart.py +30 -7
- wandb/proto/v3/wandb_internal_pb2.py +281 -280
- wandb/proto/v3/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v4/wandb_internal_pb2.py +280 -280
- wandb/proto/v4/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v5/wandb_internal_pb2.py +280 -280
- wandb/proto/v5/wandb_telemetry_pb2.py +4 -4
- wandb/proto/v6/wandb_internal_pb2.py +280 -280
- wandb/proto/v6/wandb_telemetry_pb2.py +4 -4
- wandb/proto/wandb_deprecated.py +6 -0
- wandb/sdk/artifacts/_factories.py +17 -0
- wandb/sdk/artifacts/_generated/__init__.py +221 -13
- wandb/sdk/artifacts/_generated/artifact_by_id.py +17 -0
- wandb/sdk/artifacts/_generated/artifact_by_name.py +22 -0
- wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_created_by.py +47 -0
- wandb/sdk/artifacts/_generated/artifact_file_urls.py +22 -0
- wandb/sdk/artifacts/_generated/artifact_type.py +31 -0
- wandb/sdk/artifacts/_generated/artifact_used_by.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +26 -0
- wandb/sdk/artifacts/_generated/delete_artifact.py +28 -0
- wandb/sdk/artifacts/_generated/enums.py +5 -0
- wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +38 -0
- wandb/sdk/artifacts/_generated/fetch_registries.py +32 -0
- wandb/sdk/artifacts/_generated/fragments.py +279 -41
- wandb/sdk/artifacts/_generated/link_artifact.py +6 -0
- wandb/sdk/artifacts/_generated/operations.py +654 -51
- wandb/sdk/artifacts/_generated/registry_collections.py +34 -0
- wandb/sdk/artifacts/_generated/registry_versions.py +34 -0
- wandb/sdk/artifacts/_generated/unlink_artifact.py +25 -0
- wandb/sdk/artifacts/_graphql_fragments.py +3 -86
- wandb/sdk/artifacts/_internal_artifact.py +19 -8
- wandb/sdk/artifacts/_validators.py +14 -4
- wandb/sdk/artifacts/artifact.py +512 -618
- wandb/sdk/artifacts/artifact_file_cache.py +10 -6
- wandb/sdk/artifacts/artifact_manifest.py +10 -9
- wandb/sdk/artifacts/artifact_manifest_entry.py +9 -10
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +5 -3
- wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +1 -1
- wandb/sdk/data_types/audio.py +38 -10
- wandb/sdk/data_types/base_types/media.py +6 -56
- wandb/sdk/data_types/graph.py +48 -14
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +1 -3
- wandb/sdk/data_types/helper_types/image_mask.py +1 -3
- wandb/sdk/data_types/histogram.py +34 -21
- wandb/sdk/data_types/html.py +35 -12
- wandb/sdk/data_types/image.py +104 -68
- wandb/sdk/data_types/molecule.py +32 -19
- wandb/sdk/data_types/object_3d.py +36 -17
- wandb/sdk/data_types/plotly.py +18 -5
- wandb/sdk/data_types/saved_model.py +4 -6
- wandb/sdk/data_types/table.py +59 -30
- wandb/sdk/data_types/video.py +53 -26
- wandb/sdk/integration_utils/auto_logging.py +2 -2
- wandb/sdk/interface/interface_queue.py +1 -4
- wandb/sdk/interface/interface_shared.py +26 -37
- wandb/sdk/interface/interface_sock.py +24 -14
- wandb/sdk/internal/internal_api.py +6 -0
- wandb/sdk/internal/job_builder.py +6 -0
- wandb/sdk/internal/settings_static.py +2 -3
- wandb/sdk/launch/agent/agent.py +8 -1
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -2
- wandb/sdk/launch/create_job.py +15 -2
- wandb/sdk/launch/inputs/internal.py +3 -4
- wandb/sdk/launch/inputs/schema.py +1 -0
- wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +323 -1
- wandb/sdk/launch/sweeps/scheduler.py +2 -3
- wandb/sdk/lib/asyncio_compat.py +19 -16
- wandb/sdk/lib/asyncio_manager.py +252 -0
- wandb/sdk/lib/deprecate.py +1 -7
- wandb/sdk/lib/disabled.py +1 -1
- wandb/sdk/lib/hashutil.py +27 -5
- wandb/sdk/lib/module.py +7 -13
- wandb/sdk/lib/printer.py +2 -2
- wandb/sdk/lib/printer_asyncio.py +3 -1
- wandb/sdk/lib/progress.py +0 -19
- wandb/sdk/lib/retry.py +185 -78
- wandb/sdk/lib/service/service_client.py +106 -0
- wandb/sdk/lib/service/service_connection.py +20 -26
- wandb/sdk/lib/service/service_token.py +30 -13
- wandb/sdk/mailbox/mailbox.py +13 -5
- wandb/sdk/mailbox/mailbox_handle.py +22 -13
- wandb/sdk/mailbox/response_handle.py +42 -106
- wandb/sdk/mailbox/wait_with_progress.py +7 -42
- wandb/sdk/wandb_init.py +77 -116
- wandb/sdk/wandb_login.py +19 -15
- wandb/sdk/wandb_metric.py +2 -0
- wandb/sdk/wandb_run.py +497 -469
- wandb/sdk/wandb_settings.py +145 -4
- wandb/sdk/wandb_setup.py +204 -124
- wandb/sdk/wandb_sweep.py +14 -13
- wandb/sdk/wandb_watch.py +4 -6
- wandb/sync/sync.py +10 -0
- wandb/util.py +58 -1
- wandb/wandb_run.py +1 -2
- {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/METADATA +1 -1
- {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/RECORD +145 -129
- wandb/sdk/interface/interface_relay.py +0 -38
- wandb/sdk/interface/router.py +0 -89
- wandb/sdk/interface/router_queue.py +0 -43
- wandb/sdk/interface/router_relay.py +0 -50
- wandb/sdk/interface/router_sock.py +0 -32
- wandb/sdk/lib/sock_client.py +0 -236
- wandb/vendor/pynvml/__init__.py +0 -0
- wandb/vendor/pynvml/pynvml.py +0 -4779
- {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/WHEEL +0 -0
- {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/entry_points.txt +0 -0
- {wandb-0.21.0.dist-info → wandb-0.21.2.dist-info}/licenses/LICENSE +0 -0
wandb/apis/public/files.py
CHANGED
@@ -1,8 +1,41 @@
|
|
1
|
-
"""Public API
|
1
|
+
"""W&B Public API for File objects.
|
2
|
+
|
3
|
+
This module provides classes for interacting with files stored in W&B.
|
4
|
+
|
5
|
+
Example:
|
6
|
+
```python
|
7
|
+
from wandb.apis.public import Api
|
8
|
+
|
9
|
+
# Get files from a specific run
|
10
|
+
run = Api().run("entity/project/run_id")
|
11
|
+
files = run.files()
|
12
|
+
|
13
|
+
# Work with files
|
14
|
+
for file in files:
|
15
|
+
print(f"File: {file.name}")
|
16
|
+
print(f"Size: {file.size} bytes")
|
17
|
+
print(f"Type: {file.mimetype}")
|
18
|
+
|
19
|
+
# Download file
|
20
|
+
if file.size < 1000000: # Less than 1MB
|
21
|
+
file.download(root="./downloads")
|
22
|
+
|
23
|
+
# Get S3 URI for large files
|
24
|
+
if file.size >= 1000000:
|
25
|
+
print(f"S3 URI: {file.path_uri}")
|
26
|
+
```
|
27
|
+
|
28
|
+
Note:
|
29
|
+
This module is part of the W&B Public API and provides methods to access,
|
30
|
+
download, and manage files stored in W&B. Files are typically associated
|
31
|
+
with specific runs and can include model weights, datasets, visualizations,
|
32
|
+
and other artifacts.
|
33
|
+
"""
|
34
|
+
|
35
|
+
from __future__ import annotations
|
2
36
|
|
3
37
|
import io
|
4
38
|
import os
|
5
|
-
from typing import Optional
|
6
39
|
|
7
40
|
import requests
|
8
41
|
from wandb_gql import gql
|
@@ -14,12 +47,13 @@ from wandb.apis.attrs import Attrs
|
|
14
47
|
from wandb.apis.normalize import normalize_exceptions
|
15
48
|
from wandb.apis.paginator import SizedPaginator
|
16
49
|
from wandb.apis.public import utils
|
17
|
-
from wandb.apis.public.api import Api
|
50
|
+
from wandb.apis.public.api import Api, RetryingClient
|
18
51
|
from wandb.apis.public.const import RETRY_TIMEDELTA
|
52
|
+
from wandb.apis.public.runs import Run
|
19
53
|
from wandb.sdk.lib import retry
|
20
54
|
|
21
55
|
FILE_FRAGMENT = """fragment RunFilesFragment on Run {
|
22
|
-
files(names: $fileNames, after: $fileCursor, first: $fileLimit) {
|
56
|
+
files(names: $fileNames, after: $fileCursor, first: $fileLimit, pattern: $pattern) {
|
23
57
|
edges {
|
24
58
|
node {
|
25
59
|
id
|
@@ -42,12 +76,37 @@ FILE_FRAGMENT = """fragment RunFilesFragment on Run {
|
|
42
76
|
|
43
77
|
|
44
78
|
class Files(SizedPaginator["File"]):
|
45
|
-
"""
|
79
|
+
"""A lazy iterator over a collection of `File` objects.
|
80
|
+
|
81
|
+
Access and manage files uploaded to W&B during a run. Handles pagination
|
82
|
+
automatically when iterating through large collections of files.
|
83
|
+
|
84
|
+
Example:
|
85
|
+
```python
|
86
|
+
from wandb.apis.public.files import Files
|
87
|
+
from wandb.apis.public.api import Api
|
88
|
+
|
89
|
+
# Example run object
|
90
|
+
run = Api().run("entity/project/run-id")
|
91
|
+
|
92
|
+
# Create a Files object to iterate over files in the run
|
93
|
+
files = Files(api.client, run)
|
94
|
+
|
95
|
+
# Iterate over files
|
96
|
+
for file in files:
|
97
|
+
print(file.name)
|
98
|
+
print(file.url)
|
99
|
+
print(file.size)
|
100
|
+
|
101
|
+
# Download the file
|
102
|
+
file.download(root="download_directory", replace=True)
|
103
|
+
```
|
104
|
+
"""
|
46
105
|
|
47
106
|
QUERY = gql(
|
48
107
|
"""
|
49
108
|
query RunFiles($project: String!, $entity: String!, $name: String!, $fileCursor: String,
|
50
|
-
$fileLimit: Int = 50, $fileNames: [String] = [], $upload: Boolean = false) {{
|
109
|
+
$fileLimit: Int = 50, $fileNames: [String] = [], $upload: Boolean = false, $pattern: String) {{
|
51
110
|
project(name: $project, entityName: $entity) {{
|
52
111
|
internalId
|
53
112
|
run(name: $name) {{
|
@@ -60,7 +119,36 @@ class Files(SizedPaginator["File"]):
|
|
60
119
|
""".format(FILE_FRAGMENT)
|
61
120
|
)
|
62
121
|
|
63
|
-
def __init__(
|
122
|
+
def __init__(
|
123
|
+
self,
|
124
|
+
client: RetryingClient,
|
125
|
+
run: Run,
|
126
|
+
names: list[str] | None = None,
|
127
|
+
per_page: int = 50,
|
128
|
+
upload: bool = False,
|
129
|
+
pattern: str | None = None,
|
130
|
+
):
|
131
|
+
"""Initialize a lazy iterator over a collection of `File` objects.
|
132
|
+
|
133
|
+
Files are retrieved in pages from the W&B server as needed.
|
134
|
+
|
135
|
+
Args:
|
136
|
+
client: The run object that contains the files
|
137
|
+
run: The run object that contains the files
|
138
|
+
names (list, optional): A list of file names to filter the files
|
139
|
+
per_page (int, optional): The number of files to fetch per page
|
140
|
+
upload (bool, optional): If `True`, fetch the upload URL for each file
|
141
|
+
pattern (str, optional): Pattern to match when returning files from W&B
|
142
|
+
This pattern uses mySQL's LIKE syntax,
|
143
|
+
so matching all files that end with .json would be "%.json".
|
144
|
+
If both names and pattern are provided, a ValueError will be raised.
|
145
|
+
"""
|
146
|
+
if names and pattern:
|
147
|
+
raise ValueError(
|
148
|
+
"Querying for files by both names and pattern is not supported."
|
149
|
+
" Please provide either a list of names or a pattern to match.",
|
150
|
+
)
|
151
|
+
|
64
152
|
self.run = run
|
65
153
|
variables = {
|
66
154
|
"project": run.project,
|
@@ -68,11 +156,17 @@ class Files(SizedPaginator["File"]):
|
|
68
156
|
"name": run.id,
|
69
157
|
"fileNames": names or [],
|
70
158
|
"upload": upload,
|
159
|
+
"pattern": pattern,
|
71
160
|
}
|
72
161
|
super().__init__(client, variables, per_page)
|
73
162
|
|
74
163
|
@property
|
75
164
|
def _length(self):
|
165
|
+
"""
|
166
|
+
Returns total number of files.
|
167
|
+
|
168
|
+
<!-- lazydoc-ignore: internal -->
|
169
|
+
"""
|
76
170
|
if not self.last_response:
|
77
171
|
self._load_page()
|
78
172
|
|
@@ -80,6 +174,10 @@ class Files(SizedPaginator["File"]):
|
|
80
174
|
|
81
175
|
@property
|
82
176
|
def more(self):
|
177
|
+
"""Returns whether there are more files to fetch.
|
178
|
+
|
179
|
+
<!-- lazydoc-ignore: internal -->
|
180
|
+
"""
|
83
181
|
if self.last_response:
|
84
182
|
return self.last_response["project"]["run"]["files"]["pageInfo"][
|
85
183
|
"hasNextPage"
|
@@ -89,15 +187,27 @@ class Files(SizedPaginator["File"]):
|
|
89
187
|
|
90
188
|
@property
|
91
189
|
def cursor(self):
|
190
|
+
"""Returns the cursor position for pagination of file results.
|
191
|
+
|
192
|
+
<!-- lazydoc-ignore: internal -->
|
193
|
+
"""
|
92
194
|
if self.last_response:
|
93
195
|
return self.last_response["project"]["run"]["files"]["edges"][-1]["cursor"]
|
94
196
|
else:
|
95
197
|
return None
|
96
198
|
|
97
199
|
def update_variables(self):
|
200
|
+
"""Updates the GraphQL query variables for pagination.
|
201
|
+
|
202
|
+
<!-- lazydoc-ignore: internal -->
|
203
|
+
"""
|
98
204
|
self.variables.update({"fileLimit": self.per_page, "fileCursor": self.cursor})
|
99
205
|
|
100
206
|
def convert_objects(self):
|
207
|
+
"""Converts GraphQL edges to File objects.
|
208
|
+
|
209
|
+
<!-- lazydoc-ignore: internal -->
|
210
|
+
"""
|
101
211
|
return [
|
102
212
|
File(self.client, r["node"], self.run)
|
103
213
|
for r in self.last_response["project"]["run"]["files"]["edges"]
|
@@ -108,28 +218,45 @@ class Files(SizedPaginator["File"]):
|
|
108
218
|
|
109
219
|
|
110
220
|
class File(Attrs):
|
111
|
-
"""File
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
221
|
+
"""File saved to W&B.
|
222
|
+
|
223
|
+
Represents a single file stored in W&B. Includes access to file metadata.
|
224
|
+
Files are associated with a specific run and
|
225
|
+
can include text files, model weights, datasets, visualizations, and other
|
226
|
+
artifacts. You can download the file, delete the file, and access file
|
227
|
+
properties.
|
228
|
+
|
229
|
+
Specify one or more attributes in a dictionary to fine a specific
|
230
|
+
file logged to a specific run. You can search using the following keys:
|
231
|
+
|
232
|
+
- id (str): The ID of the run that contains the file
|
233
|
+
- name (str): Name of the file
|
234
|
+
- url (str): path to file
|
235
|
+
- direct_url (str): path to file in the bucket
|
236
|
+
- sizeBytes (int): size of file in bytes
|
237
|
+
- md5 (str): md5 of file
|
238
|
+
- mimetype (str): mimetype of file
|
239
|
+
- updated_at (str): timestamp of last update
|
240
|
+
- path_uri (str): path to file in the bucket, currently only available for S3 objects and reference files
|
241
|
+
|
242
|
+
Args:
|
243
|
+
client: The run object that contains the file
|
244
|
+
attrs (dict): A dictionary of attributes that define the file
|
245
|
+
run: The run object that contains the file
|
246
|
+
|
247
|
+
<!-- lazydoc-ignore-class: internal -->
|
122
248
|
"""
|
123
249
|
|
124
250
|
def __init__(self, client, attrs, run=None):
|
125
251
|
self.client = client
|
126
252
|
self._attrs = attrs
|
127
253
|
self.run = run
|
128
|
-
self.server_supports_delete_file_with_project_id:
|
254
|
+
self.server_supports_delete_file_with_project_id: bool | None = None
|
129
255
|
super().__init__(dict(attrs))
|
130
256
|
|
131
257
|
@property
|
132
258
|
def size(self):
|
259
|
+
"""Returns the size of the file in bytes."""
|
133
260
|
size_bytes = self._attrs["sizeBytes"]
|
134
261
|
if size_bytes is not None:
|
135
262
|
return int(size_bytes)
|
@@ -137,17 +264,25 @@ class File(Attrs):
|
|
137
264
|
|
138
265
|
@property
|
139
266
|
def path_uri(self) -> str:
|
267
|
+
"""Returns the URI path to the file in the storage bucket.
|
268
|
+
|
269
|
+
Returns:
|
270
|
+
str: The S3 URI (e.g., 's3://bucket/path/to/file') if the file is stored in S3,
|
271
|
+
the direct URL if it's a reference file, or an empty string if unavailable.
|
140
272
|
"""
|
141
|
-
|
142
|
-
|
143
|
-
|
273
|
+
if not (direct_url := self._attrs.get("directUrl")):
|
274
|
+
wandb.termwarn("Unable to find direct_url of file")
|
275
|
+
return ""
|
276
|
+
|
277
|
+
# For reference files, both the directUrl and the url are just the path to the file in the bucket
|
278
|
+
if direct_url == self._attrs.get("url"):
|
279
|
+
return direct_url
|
280
|
+
|
144
281
|
try:
|
145
|
-
|
282
|
+
return utils.parse_s3_url_to_s3_uri(direct_url)
|
146
283
|
except ValueError:
|
147
284
|
wandb.termwarn("path_uri is only available for files stored in S3")
|
148
|
-
|
149
|
-
wandb.termwarn("Unable to find direct_url of file")
|
150
|
-
return path_uri
|
285
|
+
return ""
|
151
286
|
|
152
287
|
@normalize_exceptions
|
153
288
|
@retry.retriable(
|
@@ -160,20 +295,23 @@ class File(Attrs):
|
|
160
295
|
root: str = ".",
|
161
296
|
replace: bool = False,
|
162
297
|
exist_ok: bool = False,
|
163
|
-
api:
|
298
|
+
api: Api | None = None,
|
164
299
|
) -> io.TextIOWrapper:
|
165
300
|
"""Downloads a file previously saved by a run from the wandb server.
|
166
301
|
|
167
302
|
Args:
|
168
|
-
|
303
|
+
root: Local directory to save the file. Defaults to the
|
304
|
+
current working directory (".").
|
305
|
+
replace: If `True`, download will overwrite a local file
|
169
306
|
if it exists. Defaults to `False`.
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
api
|
307
|
+
exist_ok: If `True`, will not raise ValueError if file already
|
308
|
+
exists and will not re-download unless replace=True.
|
309
|
+
Defaults to `False`.
|
310
|
+
api: If specified, the `Api` instance used to download the file.
|
174
311
|
|
175
312
|
Raises:
|
176
|
-
`ValueError` if file already exists, replace=False and
|
313
|
+
`ValueError` if file already exists, `replace=False` and
|
314
|
+
`exist_ok=False`.
|
177
315
|
"""
|
178
316
|
if api is None:
|
179
317
|
api = wandb.Api()
|
@@ -192,6 +330,7 @@ class File(Attrs):
|
|
192
330
|
|
193
331
|
@normalize_exceptions
|
194
332
|
def delete(self):
|
333
|
+
"""Delete the file from the W&B server."""
|
195
334
|
project_id_mutation_fragment = ""
|
196
335
|
project_id_variable_fragment = ""
|
197
336
|
variable_values = {
|
wandb/apis/public/history.py
CHANGED
@@ -1,17 +1,28 @@
|
|
1
|
-
"""Public API
|
1
|
+
"""W&B Public API for Run History.
|
2
|
+
|
3
|
+
This module provides classes for efficiently scanning and sampling run
|
4
|
+
history data.
|
5
|
+
|
6
|
+
Note:
|
7
|
+
This module is part of the W&B Public API and provides methods
|
8
|
+
to access run history data. It handles pagination automatically and offers
|
9
|
+
both complete and sampled access to metrics logged during training runs.
|
10
|
+
"""
|
2
11
|
|
3
12
|
import json
|
4
13
|
|
5
|
-
import requests
|
6
14
|
from wandb_gql import gql
|
7
|
-
from wandb_gql.client import RetryError
|
8
15
|
|
9
|
-
from wandb import util
|
10
16
|
from wandb.apis.normalize import normalize_exceptions
|
11
|
-
from wandb.
|
17
|
+
from wandb.apis.public import api, runs
|
12
18
|
|
13
19
|
|
14
20
|
class HistoryScan:
|
21
|
+
"""Iterator for scanning complete run history.
|
22
|
+
|
23
|
+
<!-- lazydoc-ignore-class: internal -->
|
24
|
+
"""
|
25
|
+
|
15
26
|
QUERY = gql(
|
16
27
|
"""
|
17
28
|
query HistoryPage($entity: String!, $project: String!, $run: String!, $minStep: Int64!, $maxStep: Int64!, $pageSize: Int!) {
|
@@ -24,7 +35,24 @@ class HistoryScan:
|
|
24
35
|
"""
|
25
36
|
)
|
26
37
|
|
27
|
-
def __init__(
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
client: api.RetryingClient,
|
41
|
+
run: api.public.runs.Run,
|
42
|
+
min_step: int,
|
43
|
+
max_step: int,
|
44
|
+
page_size: int = 1000,
|
45
|
+
):
|
46
|
+
"""Initialize a HistoryScan instance.
|
47
|
+
|
48
|
+
Args:
|
49
|
+
client: The client instance to use for making API calls to the W&B backend.
|
50
|
+
run: The run object whose history is to be scanned.
|
51
|
+
min_step: The minimum step to start scanning from.
|
52
|
+
max_step: The maximum step to scan up to.
|
53
|
+
page_size: Number of history rows to fetch per page.
|
54
|
+
Default page_size is 1000.
|
55
|
+
"""
|
28
56
|
self.client = client
|
29
57
|
self.run = run
|
30
58
|
self.page_size = page_size
|
@@ -41,6 +69,10 @@ class HistoryScan:
|
|
41
69
|
return self
|
42
70
|
|
43
71
|
def __next__(self):
|
72
|
+
"""Return the next row of history data with automatic pagination.
|
73
|
+
|
74
|
+
<!-- lazydoc-ignore: internal -->
|
75
|
+
"""
|
44
76
|
while True:
|
45
77
|
if self.scan_offset < len(self.rows):
|
46
78
|
row = self.rows[self.scan_offset]
|
@@ -53,10 +85,6 @@ class HistoryScan:
|
|
53
85
|
next = __next__
|
54
86
|
|
55
87
|
@normalize_exceptions
|
56
|
-
@retry.retriable(
|
57
|
-
check_retry_fn=util.no_retry_auth,
|
58
|
-
retryable_exceptions=(RetryError, requests.RequestException),
|
59
|
-
)
|
60
88
|
def _load_next(self):
|
61
89
|
max_step = self.page_offset + self.page_size
|
62
90
|
if max_step > self.max_step:
|
@@ -78,6 +106,11 @@ class HistoryScan:
|
|
78
106
|
|
79
107
|
|
80
108
|
class SampledHistoryScan:
|
109
|
+
"""Iterator for sampling run history data.
|
110
|
+
|
111
|
+
<!-- lazydoc-ignore-class: internal -->
|
112
|
+
"""
|
113
|
+
|
81
114
|
QUERY = gql(
|
82
115
|
"""
|
83
116
|
query SampledHistoryPage($entity: String!, $project: String!, $run: String!, $spec: JSONString!) {
|
@@ -90,7 +123,26 @@ class SampledHistoryScan:
|
|
90
123
|
"""
|
91
124
|
)
|
92
125
|
|
93
|
-
def __init__(
|
126
|
+
def __init__(
|
127
|
+
self,
|
128
|
+
client: api.RetryingClient,
|
129
|
+
run: runs.Run,
|
130
|
+
keys: list,
|
131
|
+
min_step: int,
|
132
|
+
max_step: int,
|
133
|
+
page_size: int = 1000,
|
134
|
+
):
|
135
|
+
"""Initialize a SampledHistoryScan instance.
|
136
|
+
|
137
|
+
Args:
|
138
|
+
client: The client instance to use for making API calls to the W&B backend.
|
139
|
+
run: The run object whose history is to be sampled.
|
140
|
+
keys: List of keys to sample from the history.
|
141
|
+
min_step: The minimum step to start sampling from.
|
142
|
+
max_step: The maximum step to sample up to.
|
143
|
+
page_size: Number of sampled history rows to fetch per page.
|
144
|
+
Default page_size is 1000.
|
145
|
+
"""
|
94
146
|
self.client = client
|
95
147
|
self.run = run
|
96
148
|
self.keys = keys
|
@@ -108,6 +160,10 @@ class SampledHistoryScan:
|
|
108
160
|
return self
|
109
161
|
|
110
162
|
def __next__(self):
|
163
|
+
"""Return the next row of sampled history data with automatic pagination.
|
164
|
+
|
165
|
+
<!-- lazydoc-ignore: internal -->
|
166
|
+
"""
|
111
167
|
while True:
|
112
168
|
if self.scan_offset < len(self.rows):
|
113
169
|
row = self.rows[self.scan_offset]
|
@@ -120,10 +176,6 @@ class SampledHistoryScan:
|
|
120
176
|
next = __next__
|
121
177
|
|
122
178
|
@normalize_exceptions
|
123
|
-
@retry.retriable(
|
124
|
-
check_retry_fn=util.no_retry_auth,
|
125
|
-
retryable_exceptions=(RetryError, requests.RequestException),
|
126
|
-
)
|
127
179
|
def _load_next(self):
|
128
180
|
max_step = self.page_offset + self.page_size
|
129
181
|
if max_step > self.max_step:
|
@@ -1,3 +1,8 @@
|
|
1
|
+
"""W&B Public API for integrations.
|
2
|
+
|
3
|
+
This module provides classes for interacting with W&B integrations.
|
4
|
+
"""
|
5
|
+
|
1
6
|
from __future__ import annotations
|
2
7
|
|
3
8
|
from typing import TYPE_CHECKING, Any, Iterable
|
@@ -20,6 +25,8 @@ if TYPE_CHECKING:
|
|
20
25
|
|
21
26
|
|
22
27
|
class Integrations(Paginator["Integration"]):
|
28
|
+
"""An lazy iterator of `Integration` objects."""
|
29
|
+
|
23
30
|
last_response: IntegrationConnectionFields | None
|
24
31
|
_query: Document
|
25
32
|
|
@@ -32,14 +39,20 @@ class Integrations(Paginator["Integration"]):
|
|
32
39
|
|
33
40
|
@property
|
34
41
|
def more(self) -> bool:
|
35
|
-
"""Whether there are more Integrations to fetch.
|
42
|
+
"""Whether there are more Integrations to fetch.
|
43
|
+
|
44
|
+
<!-- lazydoc-ignore: internal -->
|
45
|
+
"""
|
36
46
|
if self.last_response is None:
|
37
47
|
return True
|
38
48
|
return self.last_response.page_info.has_next_page
|
39
49
|
|
40
50
|
@property
|
41
51
|
def cursor(self) -> str | None:
|
42
|
-
"""The start cursor to use for the next page.
|
52
|
+
"""The start cursor to use for the next page.
|
53
|
+
|
54
|
+
<!-- lazydoc-ignore: internal -->
|
55
|
+
"""
|
43
56
|
if self.last_response is None:
|
44
57
|
return None
|
45
58
|
return self.last_response.page_info.end_cursor
|
@@ -67,6 +80,11 @@ class Integrations(Paginator["Integration"]):
|
|
67
80
|
|
68
81
|
|
69
82
|
class WebhookIntegrations(Paginator["WebhookIntegration"]):
|
83
|
+
"""An lazy iterator of `WebhookIntegration` objects.
|
84
|
+
|
85
|
+
<!-- lazydoc-ignore-class: internal -->
|
86
|
+
"""
|
87
|
+
|
70
88
|
last_response: GenericWebhookIntegrationConnectionFields | None
|
71
89
|
_query: Document
|
72
90
|
|
@@ -126,6 +144,11 @@ class WebhookIntegrations(Paginator["WebhookIntegration"]):
|
|
126
144
|
|
127
145
|
|
128
146
|
class SlackIntegrations(Paginator["SlackIntegration"]):
|
147
|
+
"""An lazy iterator of `SlackIntegration` objects.
|
148
|
+
|
149
|
+
<!-- lazydoc-ignore-class: internal -->
|
150
|
+
"""
|
151
|
+
|
129
152
|
last_response: SlackIntegrationConnectionFields | None
|
130
153
|
_query: Document
|
131
154
|
|