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.
- 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
@@ -1,56 +1,53 @@
|
|
1
1
|
"""Public API: registries search."""
|
2
2
|
|
3
|
-
import
|
4
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional
|
3
|
+
from __future__ import annotations
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
import json
|
6
|
+
from typing import TYPE_CHECKING, Any
|
8
7
|
|
8
|
+
from pydantic import ValidationError
|
9
|
+
from typing_extensions import override
|
9
10
|
from wandb_gql import gql
|
10
11
|
|
11
|
-
import wandb
|
12
12
|
from wandb.apis.paginator import Paginator
|
13
|
-
from wandb.
|
14
|
-
|
15
|
-
|
13
|
+
from wandb.apis.public.utils import gql_compat
|
14
|
+
from wandb.sdk.artifacts._generated import (
|
15
|
+
FETCH_REGISTRIES_GQL,
|
16
|
+
REGISTRY_COLLECTIONS_GQL,
|
17
|
+
REGISTRY_VERSIONS_GQL,
|
18
|
+
ArtifactCollectionType,
|
19
|
+
FetchRegistries,
|
20
|
+
RegistriesPage,
|
21
|
+
RegistryCollections,
|
22
|
+
RegistryCollectionsPage,
|
23
|
+
RegistryVersions,
|
24
|
+
RegistryVersionsPage,
|
16
25
|
)
|
26
|
+
from wandb.sdk.artifacts._graphql_fragments import omit_artifact_fields
|
27
|
+
from wandb.sdk.artifacts._validators import remove_registry_prefix
|
17
28
|
|
18
29
|
from ._utils import ensure_registry_prefix_on_names
|
19
30
|
|
31
|
+
if TYPE_CHECKING:
|
32
|
+
from wandb_gql import Client
|
33
|
+
|
34
|
+
from wandb.sdk.artifacts.artifact import Artifact
|
35
|
+
|
20
36
|
|
21
37
|
class Registries(Paginator):
|
22
|
-
"""
|
23
|
-
|
24
|
-
QUERY = gql(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
orgEntity {
|
29
|
-
name
|
30
|
-
projects(filters: $filters, after: $cursor, first: $perPage) {
|
31
|
-
pageInfo {
|
32
|
-
endCursor
|
33
|
-
hasNextPage
|
34
|
-
}
|
35
|
-
edges {
|
36
|
-
node {
|
37
|
-
...RegistryFragment
|
38
|
-
}
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
"""
|
45
|
-
+ _gql_registry_fragment()
|
46
|
-
)
|
38
|
+
"""An lazy iterator of `Registry` objects."""
|
39
|
+
|
40
|
+
QUERY = gql(FETCH_REGISTRIES_GQL)
|
41
|
+
|
42
|
+
last_response: RegistriesPage | None
|
43
|
+
_last_org_entity: str | None
|
47
44
|
|
48
45
|
def __init__(
|
49
46
|
self,
|
50
|
-
client:
|
47
|
+
client: Client,
|
51
48
|
organization: str,
|
52
|
-
filter:
|
53
|
-
per_page:
|
49
|
+
filter: dict[str, Any] | None = None,
|
50
|
+
per_page: int | None = 100,
|
54
51
|
):
|
55
52
|
self.client = client
|
56
53
|
self.organization = organization
|
@@ -62,8 +59,7 @@ class Registries(Paginator):
|
|
62
59
|
|
63
60
|
super().__init__(client, variables, per_page)
|
64
61
|
|
65
|
-
|
66
|
-
return bool(self.objects)
|
62
|
+
self._last_org_entity = None
|
67
63
|
|
68
64
|
def __next__(self):
|
69
65
|
# Implement custom next since its possible to load empty pages because of auth
|
@@ -73,18 +69,18 @@ class Registries(Paginator):
|
|
73
69
|
raise StopIteration
|
74
70
|
return self.objects[self.index]
|
75
71
|
|
76
|
-
def collections(self, filter:
|
72
|
+
def collections(self, filter: dict[str, Any] | None = None) -> Collections:
|
77
73
|
return Collections(
|
78
|
-
self.client,
|
79
|
-
self.organization,
|
74
|
+
client=self.client,
|
75
|
+
organization=self.organization,
|
80
76
|
registry_filter=self.filter,
|
81
77
|
collection_filter=filter,
|
82
78
|
)
|
83
79
|
|
84
|
-
def versions(self, filter:
|
80
|
+
def versions(self, filter: dict[str, Any] | None = None) -> Versions:
|
85
81
|
return Versions(
|
86
|
-
self.client,
|
87
|
-
self.organization,
|
82
|
+
client=self.client,
|
83
|
+
organization=self.organization,
|
88
84
|
registry_filter=self.filter,
|
89
85
|
collection_filter=None,
|
90
86
|
artifact_filter=filter,
|
@@ -92,132 +88,71 @@ class Registries(Paginator):
|
|
92
88
|
|
93
89
|
@property
|
94
90
|
def length(self):
|
95
|
-
if self.last_response:
|
96
|
-
return len(
|
97
|
-
self.last_response["organization"]["orgEntity"]["projects"]["edges"]
|
98
|
-
)
|
99
|
-
else:
|
91
|
+
if self.last_response is None:
|
100
92
|
return None
|
93
|
+
return len(self.last_response.edges)
|
101
94
|
|
102
95
|
@property
|
103
96
|
def more(self):
|
104
|
-
if self.last_response:
|
105
|
-
return self.last_response["organization"]["orgEntity"]["projects"][
|
106
|
-
"pageInfo"
|
107
|
-
]["hasNextPage"]
|
108
|
-
else:
|
97
|
+
if self.last_response is None:
|
109
98
|
return True
|
99
|
+
return self.last_response.page_info.has_next_page
|
110
100
|
|
111
101
|
@property
|
112
102
|
def cursor(self):
|
113
|
-
if self.last_response:
|
114
|
-
return self.last_response["organization"]["orgEntity"]["projects"][
|
115
|
-
"pageInfo"
|
116
|
-
]["endCursor"]
|
117
|
-
else:
|
103
|
+
if self.last_response is None:
|
118
104
|
return None
|
105
|
+
return self.last_response.page_info.end_cursor
|
119
106
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
or not self.last_response["organization"]["orgEntity"]
|
126
|
-
):
|
107
|
+
@override
|
108
|
+
def _update_response(self) -> None:
|
109
|
+
data = self.client.execute(self.QUERY, variable_values=self.variables)
|
110
|
+
result = FetchRegistries.model_validate(data)
|
111
|
+
if not ((org := result.organization) and (org_entity := org.org_entity)):
|
127
112
|
raise ValueError(
|
128
|
-
f"Organization
|
113
|
+
f"Organization {self.organization!r} not found. Please verify the organization name is correct."
|
129
114
|
)
|
130
115
|
|
116
|
+
try:
|
117
|
+
page_data = org_entity.projects
|
118
|
+
self.last_response = RegistriesPage.model_validate(page_data)
|
119
|
+
self._last_org_entity = org_entity.name
|
120
|
+
except (LookupError, AttributeError, ValidationError) as e:
|
121
|
+
raise ValueError("Unexpected response data") from e
|
122
|
+
|
123
|
+
def convert_objects(self):
|
131
124
|
from wandb.apis.public.registries.registry import Registry
|
132
125
|
|
126
|
+
if (self.last_response is None) or (self._last_org_entity is None):
|
127
|
+
return []
|
128
|
+
|
129
|
+
nodes = (e.node for e in self.last_response.edges)
|
133
130
|
return [
|
134
131
|
Registry(
|
135
|
-
self.client,
|
136
|
-
self.organization,
|
137
|
-
self.
|
138
|
-
|
139
|
-
|
132
|
+
client=self.client,
|
133
|
+
organization=self.organization,
|
134
|
+
entity=self._last_org_entity,
|
135
|
+
name=remove_registry_prefix(node.name),
|
136
|
+
attrs=node.model_dump(),
|
140
137
|
)
|
141
|
-
for
|
142
|
-
"edges"
|
143
|
-
]
|
138
|
+
for node in nodes
|
144
139
|
]
|
145
140
|
|
146
141
|
|
147
|
-
class Collections(Paginator):
|
148
|
-
"""
|
149
|
-
|
150
|
-
QUERY = gql(
|
151
|
-
|
152
|
-
|
153
|
-
$organization: String!,
|
154
|
-
$registryFilter: JSONString,
|
155
|
-
$collectionFilter: JSONString,
|
156
|
-
$collectionTypes: [ArtifactCollectionType!],
|
157
|
-
$cursor: String,
|
158
|
-
$perPage: Int
|
159
|
-
) {
|
160
|
-
organization(name: $organization) {
|
161
|
-
orgEntity {
|
162
|
-
name
|
163
|
-
artifactCollections(
|
164
|
-
projectFilters: $registryFilter,
|
165
|
-
filters: $collectionFilter,
|
166
|
-
collectionTypes: $collectionTypes,
|
167
|
-
after: $cursor,
|
168
|
-
first: $perPage
|
169
|
-
) {
|
170
|
-
totalCount
|
171
|
-
pageInfo {
|
172
|
-
endCursor
|
173
|
-
hasNextPage
|
174
|
-
}
|
175
|
-
edges {
|
176
|
-
cursor
|
177
|
-
node {
|
178
|
-
id
|
179
|
-
name
|
180
|
-
description
|
181
|
-
createdAt
|
182
|
-
tags {
|
183
|
-
edges {
|
184
|
-
node {
|
185
|
-
name
|
186
|
-
}
|
187
|
-
}
|
188
|
-
}
|
189
|
-
project {
|
190
|
-
name
|
191
|
-
entity {
|
192
|
-
name
|
193
|
-
}
|
194
|
-
}
|
195
|
-
defaultArtifactType {
|
196
|
-
name
|
197
|
-
}
|
198
|
-
aliases {
|
199
|
-
edges {
|
200
|
-
node {
|
201
|
-
alias
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
}
|
206
|
-
}
|
207
|
-
}
|
208
|
-
}
|
209
|
-
}
|
210
|
-
}
|
211
|
-
"""
|
212
|
-
)
|
142
|
+
class Collections(Paginator["ArtifactCollection"]):
|
143
|
+
"""An lazy iterator of `ArtifactCollection` objects in a Registry."""
|
144
|
+
|
145
|
+
QUERY = gql(REGISTRY_COLLECTIONS_GQL)
|
146
|
+
|
147
|
+
last_response: RegistryCollectionsPage | None
|
213
148
|
|
214
149
|
def __init__(
|
215
150
|
self,
|
216
|
-
client:
|
151
|
+
client: Client,
|
217
152
|
organization: str,
|
218
|
-
registry_filter:
|
219
|
-
collection_filter:
|
220
|
-
per_page:
|
153
|
+
registry_filter: dict[str, Any] | None = None,
|
154
|
+
collection_filter: dict[str, Any] | None = None,
|
155
|
+
per_page: int | None = 100,
|
221
156
|
):
|
222
157
|
self.client = client
|
223
158
|
self.organization = organization
|
@@ -225,22 +160,15 @@ class Collections(Paginator):
|
|
225
160
|
self.collection_filter = collection_filter or {}
|
226
161
|
|
227
162
|
variables = {
|
228
|
-
"registryFilter": (
|
229
|
-
|
230
|
-
|
231
|
-
"
|
232
|
-
json.dumps(self.collection_filter) if self.collection_filter else None
|
233
|
-
),
|
234
|
-
"organization": self.organization,
|
235
|
-
"collectionTypes": ["PORTFOLIO"],
|
163
|
+
"registryFilter": json.dumps(f) if (f := registry_filter) else None,
|
164
|
+
"collectionFilter": json.dumps(f) if (f := collection_filter) else None,
|
165
|
+
"organization": organization,
|
166
|
+
"collectionTypes": [ArtifactCollectionType.PORTFOLIO],
|
236
167
|
"perPage": per_page,
|
237
168
|
}
|
238
169
|
|
239
170
|
super().__init__(client, variables, per_page)
|
240
171
|
|
241
|
-
def __bool__(self):
|
242
|
-
return len(self) > 0 or len(self.objects) > 0
|
243
|
-
|
244
172
|
def __next__(self):
|
245
173
|
# Implement custom next since its possible to load empty pages because of auth
|
246
174
|
self.index += 1
|
@@ -249,10 +177,10 @@ class Collections(Paginator):
|
|
249
177
|
raise StopIteration
|
250
178
|
return self.objects[self.index]
|
251
179
|
|
252
|
-
def versions(self, filter:
|
180
|
+
def versions(self, filter: dict[str, Any] | None = None) -> Versions:
|
253
181
|
return Versions(
|
254
|
-
self.client,
|
255
|
-
self.organization,
|
182
|
+
client=self.client,
|
183
|
+
organization=self.organization,
|
256
184
|
registry_filter=self.registry_filter,
|
257
185
|
collection_filter=self.collection_filter,
|
258
186
|
artifact_filter=filter,
|
@@ -260,71 +188,75 @@ class Collections(Paginator):
|
|
260
188
|
|
261
189
|
@property
|
262
190
|
def length(self):
|
263
|
-
if self.last_response:
|
264
|
-
return self.last_response["organization"]["orgEntity"][
|
265
|
-
"artifactCollections"
|
266
|
-
]["totalCount"]
|
267
|
-
else:
|
191
|
+
if self.last_response is None:
|
268
192
|
return None
|
193
|
+
return self.last_response.total_count
|
269
194
|
|
270
195
|
@property
|
271
196
|
def more(self):
|
272
|
-
if self.last_response:
|
273
|
-
return self.last_response["organization"]["orgEntity"][
|
274
|
-
"artifactCollections"
|
275
|
-
]["pageInfo"]["hasNextPage"]
|
276
|
-
else:
|
197
|
+
if self.last_response is None:
|
277
198
|
return True
|
199
|
+
return self.last_response.page_info.has_next_page
|
278
200
|
|
279
201
|
@property
|
280
202
|
def cursor(self):
|
281
|
-
if self.last_response:
|
282
|
-
return self.last_response["organization"]["orgEntity"][
|
283
|
-
"artifactCollections"
|
284
|
-
]["pageInfo"]["endCursor"]
|
285
|
-
else:
|
203
|
+
if self.last_response is None:
|
286
204
|
return None
|
205
|
+
return self.last_response.page_info.end_cursor
|
206
|
+
|
207
|
+
@override
|
208
|
+
def _update_response(self) -> None:
|
209
|
+
data = self.client.execute(self.QUERY, variable_values=self.variables)
|
210
|
+
result = RegistryCollections.model_validate(data)
|
211
|
+
if not (
|
212
|
+
(org_data := result.organization)
|
213
|
+
and (org_entity_data := org_data.org_entity)
|
214
|
+
):
|
215
|
+
raise ValueError(
|
216
|
+
f"Organization {self.organization!r} not found. Please verify the organization name is correct."
|
217
|
+
)
|
218
|
+
|
219
|
+
try:
|
220
|
+
page_data = org_entity_data.artifact_collections
|
221
|
+
self.last_response = RegistryCollectionsPage.model_validate(page_data)
|
222
|
+
except (LookupError, AttributeError, ValidationError) as e:
|
223
|
+
raise ValueError("Unexpected response data") from e
|
287
224
|
|
288
225
|
def convert_objects(self):
|
289
226
|
from wandb.apis.public import ArtifactCollection
|
290
227
|
|
291
|
-
if
|
228
|
+
if self.last_response is None:
|
292
229
|
return []
|
293
|
-
if (
|
294
|
-
not self.last_response["organization"]
|
295
|
-
or not self.last_response["organization"]["orgEntity"]
|
296
|
-
):
|
297
|
-
raise ValueError(
|
298
|
-
f"Organization '{self.organization}' not found. Please verify the organization name is correct"
|
299
|
-
)
|
300
230
|
|
231
|
+
nodes = (e.node for e in self.last_response.edges)
|
301
232
|
return [
|
302
233
|
ArtifactCollection(
|
303
|
-
self.client,
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
self.organization,
|
309
|
-
|
234
|
+
client=self.client,
|
235
|
+
entity=project.entity.name,
|
236
|
+
project=project.name,
|
237
|
+
name=node.name,
|
238
|
+
type=node.default_artifact_type.name,
|
239
|
+
organization=self.organization,
|
240
|
+
attrs=node.model_dump(),
|
310
241
|
is_sequence=False,
|
311
242
|
)
|
312
|
-
for
|
313
|
-
|
314
|
-
]["edges"]
|
243
|
+
for node in nodes
|
244
|
+
if (project := node.project)
|
315
245
|
]
|
316
246
|
|
317
247
|
|
318
|
-
class Versions(Paginator):
|
319
|
-
"""
|
248
|
+
class Versions(Paginator["Artifact"]):
|
249
|
+
"""An lazy iterator of `Artifact` objects in a Registry."""
|
250
|
+
|
251
|
+
last_response: RegistryVersionsPage | None
|
320
252
|
|
321
253
|
def __init__(
|
322
254
|
self,
|
323
|
-
client:
|
255
|
+
client: Client,
|
324
256
|
organization: str,
|
325
|
-
registry_filter:
|
326
|
-
collection_filter:
|
327
|
-
artifact_filter:
|
257
|
+
registry_filter: dict[str, Any] | None = None,
|
258
|
+
collection_filter: dict[str, Any] | None = None,
|
259
|
+
artifact_filter: dict[str, Any] | None = None,
|
328
260
|
per_page: int = 100,
|
329
261
|
):
|
330
262
|
self.client = client
|
@@ -332,69 +264,16 @@ class Versions(Paginator):
|
|
332
264
|
self.registry_filter = registry_filter
|
333
265
|
self.collection_filter = collection_filter
|
334
266
|
self.artifact_filter = artifact_filter or {}
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
$organization: String!,
|
339
|
-
$registryFilter: JSONString,
|
340
|
-
$collectionFilter: JSONString,
|
341
|
-
$artifactFilter: JSONString,
|
342
|
-
$cursor: String,
|
343
|
-
$perPage: Int
|
344
|
-
) {
|
345
|
-
organization(name: $organization) {
|
346
|
-
orgEntity {
|
347
|
-
name
|
348
|
-
artifactMemberships(
|
349
|
-
projectFilters: $registryFilter,
|
350
|
-
collectionFilters: $collectionFilter,
|
351
|
-
filters: $artifactFilter,
|
352
|
-
after: $cursor,
|
353
|
-
first: $perPage
|
354
|
-
) {
|
355
|
-
pageInfo {
|
356
|
-
endCursor
|
357
|
-
hasNextPage
|
358
|
-
}
|
359
|
-
edges {
|
360
|
-
node {
|
361
|
-
artifactCollection {
|
362
|
-
project {
|
363
|
-
name
|
364
|
-
entity {
|
365
|
-
name
|
366
|
-
}
|
367
|
-
}
|
368
|
-
name
|
369
|
-
}
|
370
|
-
versionIndex
|
371
|
-
artifact {
|
372
|
-
...ArtifactFragment
|
373
|
-
}
|
374
|
-
aliases {
|
375
|
-
alias
|
376
|
-
}
|
377
|
-
}
|
378
|
-
}
|
379
|
-
}
|
380
|
-
}
|
381
|
-
}
|
382
|
-
}
|
383
|
-
"""
|
384
|
-
+ _gql_artifact_fragment(include_aliases=False)
|
267
|
+
|
268
|
+
self.QUERY = gql_compat(
|
269
|
+
REGISTRY_VERSIONS_GQL, omit_fields=omit_artifact_fields()
|
385
270
|
)
|
386
271
|
|
387
272
|
variables = {
|
388
|
-
"registryFilter": (
|
389
|
-
|
390
|
-
),
|
391
|
-
"
|
392
|
-
json.dumps(self.collection_filter) if self.collection_filter else None
|
393
|
-
),
|
394
|
-
"artifactFilter": (
|
395
|
-
json.dumps(self.artifact_filter) if self.artifact_filter else None
|
396
|
-
),
|
397
|
-
"organization": self.organization,
|
273
|
+
"registryFilter": json.dumps(f) if (f := registry_filter) else None,
|
274
|
+
"collectionFilter": json.dumps(f) if (f := collection_filter) else None,
|
275
|
+
"artifactFilter": json.dumps(f) if (f := artifact_filter) else None,
|
276
|
+
"organization": organization,
|
398
277
|
}
|
399
278
|
|
400
279
|
super().__init__(client, variables, per_page)
|
@@ -407,62 +286,62 @@ class Versions(Paginator):
|
|
407
286
|
raise StopIteration
|
408
287
|
return self.objects[self.index]
|
409
288
|
|
410
|
-
def __bool__(self):
|
411
|
-
return len(self) > 0 or len(self.objects) > 0
|
412
|
-
|
413
289
|
@property
|
414
|
-
def length(self):
|
415
|
-
if self.last_response:
|
416
|
-
return len(
|
417
|
-
self.last_response["organization"]["orgEntity"]["artifactMemberships"][
|
418
|
-
"edges"
|
419
|
-
]
|
420
|
-
)
|
421
|
-
else:
|
290
|
+
def length(self) -> int | None:
|
291
|
+
if self.last_response is None:
|
422
292
|
return None
|
293
|
+
return len(self.last_response.edges)
|
423
294
|
|
424
295
|
@property
|
425
|
-
def more(self):
|
426
|
-
if self.last_response:
|
427
|
-
return self.last_response["organization"]["orgEntity"][
|
428
|
-
"artifactMemberships"
|
429
|
-
]["pageInfo"]["hasNextPage"]
|
430
|
-
else:
|
296
|
+
def more(self) -> bool:
|
297
|
+
if self.last_response is None:
|
431
298
|
return True
|
299
|
+
return self.last_response.page_info.has_next_page
|
432
300
|
|
433
301
|
@property
|
434
|
-
def cursor(self):
|
435
|
-
if self.last_response:
|
436
|
-
return self.last_response["organization"]["orgEntity"][
|
437
|
-
"artifactMemberships"
|
438
|
-
]["pageInfo"]["endCursor"]
|
439
|
-
else:
|
302
|
+
def cursor(self) -> str | None:
|
303
|
+
if self.last_response is None:
|
440
304
|
return None
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
305
|
+
return self.last_response.page_info.end_cursor
|
306
|
+
|
307
|
+
@override
|
308
|
+
def _update_response(self) -> None:
|
309
|
+
data = self.client.execute(self.QUERY, variable_values=self.variables)
|
310
|
+
result = RegistryVersions.model_validate(data)
|
311
|
+
if not (
|
312
|
+
(org_data := result.organization)
|
313
|
+
and (org_entity_data := org_data.org_entity)
|
448
314
|
):
|
449
315
|
raise ValueError(
|
450
|
-
f"Organization
|
316
|
+
f"Organization {self.organization!r} not found. Please verify the organization name is correct."
|
451
317
|
)
|
452
318
|
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
319
|
+
try:
|
320
|
+
page_data = org_entity_data.artifact_memberships
|
321
|
+
self.last_response = RegistryVersionsPage.model_validate(page_data)
|
322
|
+
except (LookupError, AttributeError, ValidationError) as e:
|
323
|
+
raise ValueError("Unexpected response data") from e
|
324
|
+
|
325
|
+
def convert_objects(self) -> list[Artifact]:
|
326
|
+
from wandb.sdk.artifacts.artifact import Artifact
|
327
|
+
|
328
|
+
if self.last_response is None:
|
329
|
+
return []
|
330
|
+
|
331
|
+
nodes = (e.node for e in self.last_response.edges)
|
332
|
+
return [
|
333
|
+
Artifact._from_attrs(
|
334
|
+
entity=project.entity.name,
|
335
|
+
project=project.name,
|
336
|
+
name=f"{collection.name}:v{node.version_index}",
|
337
|
+
attrs=artifact,
|
338
|
+
client=self.client,
|
339
|
+
aliases=[alias.alias for alias in node.aliases],
|
463
340
|
)
|
464
|
-
for
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
341
|
+
for node in nodes
|
342
|
+
if (
|
343
|
+
(collection := node.artifact_collection)
|
344
|
+
and (project := collection.project)
|
345
|
+
and (artifact := node.artifact)
|
346
|
+
)
|
347
|
+
]
|