wandb 0.21.4__py3-none-win_amd64.whl → 0.22.1__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 +1 -1
- wandb/__init__.pyi +3 -3
- wandb/_pydantic/__init__.py +12 -11
- wandb/_pydantic/base.py +49 -19
- wandb/apis/__init__.py +2 -0
- wandb/apis/attrs.py +2 -0
- wandb/apis/importers/internals/internal.py +16 -23
- wandb/apis/internal.py +2 -0
- wandb/apis/normalize.py +2 -0
- wandb/apis/public/__init__.py +44 -1
- wandb/apis/public/api.py +215 -164
- wandb/apis/public/artifacts.py +23 -20
- wandb/apis/public/const.py +2 -0
- wandb/apis/public/files.py +33 -24
- wandb/apis/public/history.py +2 -0
- wandb/apis/public/jobs.py +20 -18
- wandb/apis/public/projects.py +4 -2
- wandb/apis/public/query_generator.py +3 -0
- wandb/apis/public/registries/__init__.py +7 -0
- wandb/apis/public/registries/_freezable_list.py +9 -12
- wandb/apis/public/registries/registries_search.py +8 -6
- wandb/apis/public/registries/registry.py +22 -17
- wandb/apis/public/reports.py +2 -0
- wandb/apis/public/runs.py +282 -60
- wandb/apis/public/sweeps.py +10 -9
- wandb/apis/public/teams.py +2 -0
- wandb/apis/public/users.py +2 -0
- wandb/apis/public/utils.py +16 -15
- wandb/automations/_generated/__init__.py +54 -127
- wandb/automations/_generated/create_generic_webhook_integration.py +1 -7
- wandb/automations/_generated/fragments.py +26 -91
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/beta_sync.py +9 -11
- wandb/errors/errors.py +3 -3
- wandb/proto/v3/wandb_internal_pb2.py +234 -224
- wandb/proto/v3/wandb_sync_pb2.py +19 -6
- wandb/proto/v4/wandb_internal_pb2.py +226 -224
- wandb/proto/v4/wandb_sync_pb2.py +10 -6
- wandb/proto/v5/wandb_internal_pb2.py +226 -224
- wandb/proto/v5/wandb_sync_pb2.py +10 -6
- wandb/proto/v6/wandb_base_pb2.py +3 -3
- wandb/proto/v6/wandb_internal_pb2.py +229 -227
- wandb/proto/v6/wandb_server_pb2.py +3 -3
- wandb/proto/v6/wandb_settings_pb2.py +3 -3
- wandb/proto/v6/wandb_sync_pb2.py +13 -9
- wandb/proto/v6/wandb_telemetry_pb2.py +3 -3
- wandb/sdk/artifacts/_factories.py +7 -2
- wandb/sdk/artifacts/_generated/__init__.py +112 -412
- wandb/sdk/artifacts/_generated/fragments.py +65 -0
- wandb/sdk/artifacts/_generated/operations.py +52 -22
- wandb/sdk/artifacts/_generated/run_input_artifacts.py +3 -23
- wandb/sdk/artifacts/_generated/run_output_artifacts.py +3 -23
- wandb/sdk/artifacts/_generated/type_info.py +19 -0
- wandb/sdk/artifacts/_gqlutils.py +47 -0
- wandb/sdk/artifacts/_models/__init__.py +4 -0
- wandb/sdk/artifacts/_models/base_model.py +20 -0
- wandb/sdk/artifacts/_validators.py +40 -12
- wandb/sdk/artifacts/artifact.py +69 -88
- wandb/sdk/artifacts/artifact_file_cache.py +6 -1
- wandb/sdk/artifacts/artifact_manifest_entry.py +61 -2
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -3
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +1 -1
- wandb/sdk/artifacts/storage_policies/_factories.py +63 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +69 -124
- wandb/sdk/data_types/bokeh.py +5 -1
- wandb/sdk/data_types/image.py +17 -6
- wandb/sdk/interface/interface.py +41 -4
- wandb/sdk/interface/interface_queue.py +10 -0
- wandb/sdk/interface/interface_shared.py +9 -7
- wandb/sdk/interface/interface_sock.py +9 -3
- wandb/sdk/internal/_generated/__init__.py +2 -12
- wandb/sdk/internal/sender.py +1 -1
- wandb/sdk/internal/settings_static.py +2 -82
- wandb/sdk/launch/runner/kubernetes_runner.py +25 -20
- wandb/sdk/launch/utils.py +82 -1
- wandb/sdk/lib/progress.py +7 -4
- wandb/sdk/lib/service/service_client.py +5 -9
- wandb/sdk/lib/service/service_connection.py +39 -23
- wandb/sdk/mailbox/mailbox_handle.py +2 -0
- wandb/sdk/projects/_generated/__init__.py +12 -33
- wandb/sdk/wandb_init.py +31 -3
- wandb/sdk/wandb_login.py +53 -27
- wandb/sdk/wandb_run.py +5 -3
- wandb/sdk/wandb_settings.py +50 -13
- wandb/sync/sync.py +7 -2
- wandb/util.py +1 -1
- wandb/wandb_agent.py +35 -4
- {wandb-0.21.4.dist-info → wandb-0.22.1.dist-info}/METADATA +1 -1
- {wandb-0.21.4.dist-info → wandb-0.22.1.dist-info}/RECORD +95 -91
- wandb/sdk/artifacts/_graphql_fragments.py +0 -19
- {wandb-0.21.4.dist-info → wandb-0.22.1.dist-info}/WHEEL +0 -0
- {wandb-0.21.4.dist-info → wandb-0.22.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.21.4.dist-info → wandb-0.22.1.dist-info}/licenses/LICENSE +0 -0
wandb/apis/public/artifacts.py
CHANGED
@@ -51,12 +51,13 @@ from wandb.sdk.artifacts._generated import (
|
|
51
51
|
ProjectArtifacts,
|
52
52
|
ProjectArtifactType,
|
53
53
|
ProjectArtifactTypes,
|
54
|
-
|
55
|
-
|
54
|
+
RunInputArtifactConnectionFragment,
|
55
|
+
RunOutputArtifactConnectionFragment,
|
56
56
|
)
|
57
|
-
from wandb.sdk.artifacts.
|
57
|
+
from wandb.sdk.artifacts._gqlutils import omit_artifact_fields
|
58
58
|
from wandb.sdk.artifacts._validators import (
|
59
59
|
SOURCE_ARTIFACT_COLLECTION_TYPE,
|
60
|
+
FullArtifactPath,
|
60
61
|
validate_artifact_name,
|
61
62
|
validate_artifact_type,
|
62
63
|
)
|
@@ -715,7 +716,7 @@ class Artifacts(SizedPaginator["Artifact"]):
|
|
715
716
|
|
716
717
|
self.QUERY = gql_compat(
|
717
718
|
PROJECT_ARTIFACTS_GQL,
|
718
|
-
omit_fields=omit_artifact_fields(),
|
719
|
+
omit_fields=omit_artifact_fields(client),
|
719
720
|
rename_fields=rename_fields,
|
720
721
|
)
|
721
722
|
|
@@ -778,10 +779,12 @@ class Artifacts(SizedPaginator["Artifact"]):
|
|
778
779
|
artifact_edges = (edge for edge in self.last_response.edges if edge.node)
|
779
780
|
artifacts = (
|
780
781
|
wandb.Artifact._from_attrs(
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
782
|
+
path=FullArtifactPath(
|
783
|
+
prefix=self.entity,
|
784
|
+
project=self.project,
|
785
|
+
name=f"{self.collection_name}:{edge.version}",
|
786
|
+
),
|
787
|
+
attrs=edge.node,
|
785
788
|
client=self.client,
|
786
789
|
)
|
787
790
|
for edge in artifact_edges
|
@@ -797,14 +800,12 @@ class RunArtifacts(SizedPaginator["Artifact"]):
|
|
797
800
|
"""
|
798
801
|
|
799
802
|
last_response: (
|
800
|
-
|
801
|
-
| RunInputArtifactsProjectRunInputArtifacts
|
803
|
+
RunOutputArtifactConnectionFragment | RunInputArtifactConnectionFragment
|
802
804
|
)
|
803
805
|
|
804
806
|
#: The pydantic model used to parse the (inner part of the) raw response.
|
805
807
|
_response_cls: type[
|
806
|
-
|
807
|
-
| RunInputArtifactsProjectRunInputArtifacts
|
808
|
+
RunOutputArtifactConnectionFragment | RunInputArtifactConnectionFragment
|
808
809
|
]
|
809
810
|
|
810
811
|
def __init__(
|
@@ -819,15 +820,15 @@ class RunArtifacts(SizedPaginator["Artifact"]):
|
|
819
820
|
if mode == "logged":
|
820
821
|
self.run_key = "outputArtifacts"
|
821
822
|
self.QUERY = gql_compat(
|
822
|
-
RUN_OUTPUT_ARTIFACTS_GQL, omit_fields=omit_artifact_fields()
|
823
|
+
RUN_OUTPUT_ARTIFACTS_GQL, omit_fields=omit_artifact_fields(client)
|
823
824
|
)
|
824
|
-
self._response_cls =
|
825
|
+
self._response_cls = RunOutputArtifactConnectionFragment
|
825
826
|
elif mode == "used":
|
826
827
|
self.run_key = "inputArtifacts"
|
827
828
|
self.QUERY = gql_compat(
|
828
|
-
RUN_INPUT_ARTIFACTS_GQL, omit_fields=omit_artifact_fields()
|
829
|
+
RUN_INPUT_ARTIFACTS_GQL, omit_fields=omit_artifact_fields(client)
|
829
830
|
)
|
830
|
-
self._response_cls =
|
831
|
+
self._response_cls = RunInputArtifactConnectionFragment
|
831
832
|
else:
|
832
833
|
raise ValueError("mode must be logged or used")
|
833
834
|
|
@@ -886,10 +887,12 @@ class RunArtifacts(SizedPaginator["Artifact"]):
|
|
886
887
|
|
887
888
|
return [
|
888
889
|
wandb.Artifact._from_attrs(
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
890
|
+
path=FullArtifactPath(
|
891
|
+
prefix=proj.entity_name,
|
892
|
+
project=proj.name,
|
893
|
+
name=f"{artifact_seq.name}:v{node.version_index}",
|
894
|
+
),
|
895
|
+
attrs=node,
|
893
896
|
client=self.client,
|
894
897
|
)
|
895
898
|
for edge in self.last_response.edges
|
wandb/apis/public/const.py
CHANGED
wandb/apis/public/files.py
CHANGED
@@ -49,7 +49,7 @@ from wandb.apis.paginator import SizedPaginator
|
|
49
49
|
from wandb.apis.public import utils
|
50
50
|
from wandb.apis.public.api import Api, RetryingClient
|
51
51
|
from wandb.apis.public.const import RETRY_TIMEDELTA
|
52
|
-
from wandb.apis.public.runs import Run
|
52
|
+
from wandb.apis.public.runs import Run, _server_provides_internal_id_for_project
|
53
53
|
from wandb.sdk.lib import retry
|
54
54
|
|
55
55
|
FILE_FRAGMENT = """fragment RunFilesFragment on Run {
|
@@ -103,21 +103,24 @@ class Files(SizedPaginator["File"]):
|
|
103
103
|
```
|
104
104
|
"""
|
105
105
|
|
106
|
-
|
107
|
-
"""
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
106
|
+
def _get_query(self):
|
107
|
+
"""Generate query dynamically based on server capabilities."""
|
108
|
+
with_internal_id = _server_provides_internal_id_for_project(self.client)
|
109
|
+
return gql(
|
110
|
+
f"""
|
111
|
+
query RunFiles($project: String!, $entity: String!, $name: String!, $fileCursor: String,
|
112
|
+
$fileLimit: Int = 50, $fileNames: [String] = [], $upload: Boolean = false, $pattern: String) {{
|
113
|
+
project(name: $project, entityName: $entity) {{
|
114
|
+
{"internalId" if with_internal_id else ""}
|
115
|
+
run(name: $name) {{
|
116
|
+
fileCount
|
117
|
+
...RunFilesFragment
|
118
|
+
}}
|
115
119
|
}}
|
116
120
|
}}
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
)
|
121
|
+
{FILE_FRAGMENT}
|
122
|
+
"""
|
123
|
+
)
|
121
124
|
|
122
125
|
def __init__(
|
123
126
|
self,
|
@@ -133,15 +136,15 @@ class Files(SizedPaginator["File"]):
|
|
133
136
|
Files are retrieved in pages from the W&B server as needed.
|
134
137
|
|
135
138
|
Args:
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
139
|
+
client: The run object that contains the files
|
140
|
+
run: The run object that contains the files
|
141
|
+
names (list, optional): A list of file names to filter the files
|
142
|
+
per_page (int, optional): The number of files to fetch per page
|
143
|
+
upload (bool, optional): If `True`, fetch the upload URL for each file
|
144
|
+
pattern (str, optional): Pattern to match when returning files from W&B
|
145
|
+
This pattern uses mySQL's LIKE syntax,
|
146
|
+
so matching all files that end with .json would be "%.json".
|
147
|
+
If both names and pattern are provided, a ValueError will be raised.
|
145
148
|
"""
|
146
149
|
if names and pattern:
|
147
150
|
raise ValueError(
|
@@ -160,6 +163,12 @@ class Files(SizedPaginator["File"]):
|
|
160
163
|
}
|
161
164
|
super().__init__(client, variables, per_page)
|
162
165
|
|
166
|
+
def _update_response(self) -> None:
|
167
|
+
"""Fetch and store the response data for the next page using dynamic query."""
|
168
|
+
self.last_response = self.client.execute(
|
169
|
+
self._get_query(), variable_values=self.variables
|
170
|
+
)
|
171
|
+
|
163
172
|
@property
|
164
173
|
def _length(self):
|
165
174
|
"""
|
@@ -244,7 +253,7 @@ class File(Attrs):
|
|
244
253
|
attrs (dict): A dictionary of attributes that define the file
|
245
254
|
run: The run object that contains the file
|
246
255
|
|
247
|
-
<!-- lazydoc-ignore-
|
256
|
+
<!-- lazydoc-ignore-init: internal -->
|
248
257
|
"""
|
249
258
|
|
250
259
|
def __init__(self, client, attrs, run=None):
|
wandb/apis/public/history.py
CHANGED
wandb/apis/public/jobs.py
CHANGED
@@ -4,11 +4,13 @@ This module provides classes for managing W&B jobs, queued runs, and run
|
|
4
4
|
queues.
|
5
5
|
"""
|
6
6
|
|
7
|
+
from __future__ import annotations
|
8
|
+
|
7
9
|
import json
|
8
10
|
import os
|
9
11
|
import shutil
|
10
12
|
import time
|
11
|
-
from typing import TYPE_CHECKING, Any,
|
13
|
+
from typing import TYPE_CHECKING, Any, Literal, Mapping
|
12
14
|
|
13
15
|
from wandb_gql import gql
|
14
16
|
|
@@ -37,11 +39,11 @@ class Job:
|
|
37
39
|
_output_types: Type
|
38
40
|
_entity: str
|
39
41
|
_project: str
|
40
|
-
_entrypoint:
|
42
|
+
_entrypoint: list[str]
|
41
43
|
_notebook_job: bool
|
42
44
|
_partial: bool
|
43
45
|
|
44
|
-
def __init__(self, api:
|
46
|
+
def __init__(self, api: Api, name, path: str | None = None) -> None:
|
45
47
|
try:
|
46
48
|
self._job_artifact = api._artifact(name, type="job")
|
47
49
|
except CommError:
|
@@ -166,7 +168,7 @@ class Job:
|
|
166
168
|
if self._entrypoint:
|
167
169
|
launch_project.set_job_entry_point(self._entrypoint)
|
168
170
|
|
169
|
-
def set_entrypoint(self, entrypoint:
|
171
|
+
def set_entrypoint(self, entrypoint: list[str]):
|
170
172
|
"""Set the entrypoint for the job."""
|
171
173
|
self._entrypoint = entrypoint
|
172
174
|
|
@@ -307,7 +309,7 @@ class QueuedRun:
|
|
307
309
|
)
|
308
310
|
|
309
311
|
@normalize_exceptions
|
310
|
-
def _get_run_queue_item_legacy(self) ->
|
312
|
+
def _get_run_queue_item_legacy(self) -> dict:
|
311
313
|
query = gql(
|
312
314
|
"""
|
313
315
|
query GetRunQueueItem($projectName: String!, $entityName: String!, $runQueue: String!) {
|
@@ -490,13 +492,13 @@ class RunQueue:
|
|
490
492
|
|
491
493
|
def __init__(
|
492
494
|
self,
|
493
|
-
client:
|
495
|
+
client: RetryingClient,
|
494
496
|
name: str,
|
495
497
|
entity: str,
|
496
|
-
prioritization_mode:
|
497
|
-
_access:
|
498
|
-
_default_resource_config_id:
|
499
|
-
_default_resource_config:
|
498
|
+
prioritization_mode: RunQueuePrioritizationMode | None = None,
|
499
|
+
_access: RunQueueAccessType | None = None,
|
500
|
+
_default_resource_config_id: int | None = None,
|
501
|
+
_default_resource_config: dict | None = None,
|
500
502
|
) -> None:
|
501
503
|
self._name: str = name
|
502
504
|
self._client = client
|
@@ -538,7 +540,7 @@ class RunQueue:
|
|
538
540
|
return self._access
|
539
541
|
|
540
542
|
@property
|
541
|
-
def external_links(self) ->
|
543
|
+
def external_links(self) -> dict[str, str]:
|
542
544
|
"""External resource links for the queue."""
|
543
545
|
if self._external_links is None:
|
544
546
|
self._get_metadata()
|
@@ -579,7 +581,7 @@ class RunQueue:
|
|
579
581
|
return self._id
|
580
582
|
|
581
583
|
@property
|
582
|
-
def items(self) ->
|
584
|
+
def items(self) -> list[QueuedRun]:
|
583
585
|
"""Up to the first 100 queued runs. Modifying this list will not modify the queue or any enqueued items!"""
|
584
586
|
# TODO(np): Add a paginated interface
|
585
587
|
if self._items is None:
|
@@ -716,12 +718,12 @@ class RunQueue:
|
|
716
718
|
def create(
|
717
719
|
cls,
|
718
720
|
name: str,
|
719
|
-
resource:
|
720
|
-
entity:
|
721
|
-
prioritization_mode:
|
722
|
-
config:
|
723
|
-
template_variables:
|
724
|
-
) ->
|
721
|
+
resource: RunQueueResourceType,
|
722
|
+
entity: str | None = None,
|
723
|
+
prioritization_mode: RunQueuePrioritizationMode | None = None,
|
724
|
+
config: dict | None = None,
|
725
|
+
template_variables: dict | None = None,
|
726
|
+
) -> RunQueue:
|
725
727
|
"""Create a RunQueue.
|
726
728
|
|
727
729
|
Args:
|
wandb/apis/public/projects.py
CHANGED
@@ -31,6 +31,8 @@ Note:
|
|
31
31
|
with a new project name.
|
32
32
|
"""
|
33
33
|
|
34
|
+
from __future__ import annotations
|
35
|
+
|
34
36
|
from requests import HTTPError
|
35
37
|
from wandb_gql import gql
|
36
38
|
|
@@ -100,7 +102,7 @@ class Projects(Paginator["Project"]):
|
|
100
102
|
client: RetryingClient,
|
101
103
|
entity: str,
|
102
104
|
per_page: int = 50,
|
103
|
-
) ->
|
105
|
+
) -> Projects:
|
104
106
|
"""An iterable collection of `Project` objects.
|
105
107
|
|
106
108
|
Args:
|
@@ -187,7 +189,7 @@ class Project(Attrs):
|
|
187
189
|
entity: str,
|
188
190
|
project: str,
|
189
191
|
attrs: dict,
|
190
|
-
) ->
|
192
|
+
) -> Project:
|
191
193
|
"""A single project associated with an entity.
|
192
194
|
|
193
195
|
Args:
|
@@ -1,14 +1,13 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from itertools import chain
|
2
4
|
from typing import (
|
3
5
|
Any,
|
4
6
|
Iterable,
|
5
7
|
Iterator,
|
6
|
-
List,
|
7
8
|
MutableSequence,
|
8
9
|
Sequence,
|
9
|
-
Tuple,
|
10
10
|
TypeVar,
|
11
|
-
Union,
|
12
11
|
final,
|
13
12
|
overload,
|
14
13
|
)
|
@@ -29,9 +28,9 @@ class FreezableList(MutableSequence[T]):
|
|
29
28
|
Any initial items passed to the constructor are saved.
|
30
29
|
"""
|
31
30
|
|
32
|
-
def __init__(self, iterable:
|
33
|
-
self._frozen:
|
34
|
-
self._draft:
|
31
|
+
def __init__(self, iterable: Iterable[T] | None = None, /) -> None:
|
32
|
+
self._frozen: tuple[T, ...] = tuple(iterable or ())
|
33
|
+
self._draft: list[T] = []
|
35
34
|
|
36
35
|
def append(self, value: T) -> None:
|
37
36
|
"""Append an item to the draft list. No duplicates are allowed."""
|
@@ -72,7 +71,7 @@ class FreezableList(MutableSequence[T]):
|
|
72
71
|
@overload
|
73
72
|
def __getitem__(self, index: slice) -> Sequence[T]: ...
|
74
73
|
|
75
|
-
def __getitem__(self, index:
|
74
|
+
def __getitem__(self, index: int | slice) -> T | Sequence[T]:
|
76
75
|
return [*self._frozen, *self._draft][index]
|
77
76
|
|
78
77
|
@overload
|
@@ -81,9 +80,7 @@ class FreezableList(MutableSequence[T]):
|
|
81
80
|
@overload
|
82
81
|
def __setitem__(self, index: slice, value: Iterable[T]) -> None: ...
|
83
82
|
|
84
|
-
def __setitem__(
|
85
|
-
self, index: Union[int, slice], value: Union[T, Iterable[T]]
|
86
|
-
) -> None:
|
83
|
+
def __setitem__(self, index: int | slice, value: T | Iterable[T]) -> None:
|
87
84
|
if isinstance(index, slice):
|
88
85
|
# Setting slices might affect saved items, disallow for simplicity
|
89
86
|
raise TypeError(f"{nameof(type(self))!r} does not support slice assignment")
|
@@ -109,7 +106,7 @@ class FreezableList(MutableSequence[T]):
|
|
109
106
|
@overload
|
110
107
|
def __delitem__(self, index: slice) -> None: ...
|
111
108
|
|
112
|
-
def __delitem__(self, index:
|
109
|
+
def __delitem__(self, index: int | slice) -> None:
|
113
110
|
if isinstance(index, slice):
|
114
111
|
raise TypeError(f"{nameof(type(self))!r} does not support slice deletion")
|
115
112
|
else:
|
@@ -161,7 +158,7 @@ class FreezableList(MutableSequence[T]):
|
|
161
158
|
return f"{nameof(type(self))}(frozen={list(self._frozen)!r}, draft={list(self._draft)!r})"
|
162
159
|
|
163
160
|
@property
|
164
|
-
def draft(self) ->
|
161
|
+
def draft(self) -> tuple[T, ...]:
|
165
162
|
"""A read-only, tuple copy of the current draft items."""
|
166
163
|
return tuple(self._draft)
|
167
164
|
|
@@ -24,8 +24,8 @@ from wandb.sdk.artifacts._generated import (
|
|
24
24
|
RegistryVersions,
|
25
25
|
RegistryVersionsPage,
|
26
26
|
)
|
27
|
-
from wandb.sdk.artifacts.
|
28
|
-
from wandb.sdk.artifacts._validators import remove_registry_prefix
|
27
|
+
from wandb.sdk.artifacts._gqlutils import omit_artifact_fields
|
28
|
+
from wandb.sdk.artifacts._validators import FullArtifactPath, remove_registry_prefix
|
29
29
|
|
30
30
|
from ._utils import ensure_registry_prefix_on_names
|
31
31
|
|
@@ -270,7 +270,7 @@ class Versions(Paginator["Artifact"]):
|
|
270
270
|
self.artifact_filter = artifact_filter or {}
|
271
271
|
|
272
272
|
self.QUERY = gql_compat(
|
273
|
-
REGISTRY_VERSIONS_GQL, omit_fields=omit_artifact_fields()
|
273
|
+
REGISTRY_VERSIONS_GQL, omit_fields=omit_artifact_fields(client)
|
274
274
|
)
|
275
275
|
|
276
276
|
variables = {
|
@@ -335,9 +335,11 @@ class Versions(Paginator["Artifact"]):
|
|
335
335
|
nodes = (e.node for e in self.last_response.edges)
|
336
336
|
return [
|
337
337
|
Artifact._from_attrs(
|
338
|
-
|
339
|
-
|
340
|
-
|
338
|
+
path=FullArtifactPath(
|
339
|
+
prefix=project.entity.name,
|
340
|
+
project=project.name,
|
341
|
+
name=f"{collection.name}:v{node.version_index}",
|
342
|
+
),
|
341
343
|
attrs=artifact,
|
342
344
|
client=self.client,
|
343
345
|
aliases=[alias.alias for alias in node.aliases],
|
@@ -1,4 +1,6 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal
|
2
4
|
|
3
5
|
from wandb_gql import gql
|
4
6
|
|
@@ -35,11 +37,11 @@ class Registry:
|
|
35
37
|
|
36
38
|
def __init__(
|
37
39
|
self,
|
38
|
-
client:
|
40
|
+
client: Client,
|
39
41
|
organization: str,
|
40
42
|
entity: str,
|
41
43
|
name: str,
|
42
|
-
attrs:
|
44
|
+
attrs: dict[str, Any] | None = None,
|
43
45
|
):
|
44
46
|
self.client = client
|
45
47
|
self._name = name
|
@@ -49,7 +51,7 @@ class Registry:
|
|
49
51
|
if attrs is not None:
|
50
52
|
self._update_attributes(attrs)
|
51
53
|
|
52
|
-
def _update_attributes(self, attrs:
|
54
|
+
def _update_attributes(self, attrs: dict[str, Any]) -> None:
|
53
55
|
"""Helper method to update instance attributes from a dictionary."""
|
54
56
|
self._id = attrs.get("id", "")
|
55
57
|
if self._id is None:
|
@@ -127,14 +129,17 @@ class Registry:
|
|
127
129
|
Previously saved artifact types cannot be removed.
|
128
130
|
|
129
131
|
Example:
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
```python
|
133
|
+
import wandb
|
134
|
+
|
135
|
+
registry = wandb.Api().create_registry()
|
136
|
+
registry.artifact_types.append("model")
|
137
|
+
registry.save() # once saved, the artifact type `model` cannot be removed
|
138
|
+
registry.artifact_types.append("accidentally_added")
|
139
|
+
registry.artifact_types.remove(
|
140
|
+
"accidentally_added"
|
141
|
+
) # Types can only be removed if it has not been saved yet
|
142
|
+
```
|
138
143
|
"""
|
139
144
|
return self._artifact_types
|
140
145
|
|
@@ -179,7 +184,7 @@ class Registry:
|
|
179
184
|
self._visibility = value
|
180
185
|
|
181
186
|
@tracked
|
182
|
-
def collections(self, filter:
|
187
|
+
def collections(self, filter: dict[str, Any] | None = None) -> Collections:
|
183
188
|
"""Returns the collections belonging to the registry."""
|
184
189
|
registry_filter = {
|
185
190
|
"name": self.full_name,
|
@@ -187,7 +192,7 @@ class Registry:
|
|
187
192
|
return Collections(self.client, self.organization, registry_filter, filter)
|
188
193
|
|
189
194
|
@tracked
|
190
|
-
def versions(self, filter:
|
195
|
+
def versions(self, filter: dict[str, Any] | None = None) -> Versions:
|
191
196
|
"""Returns the versions belonging to the registry."""
|
192
197
|
registry_filter = {
|
193
198
|
"name": self.full_name,
|
@@ -198,12 +203,12 @@ class Registry:
|
|
198
203
|
@tracked
|
199
204
|
def create(
|
200
205
|
cls,
|
201
|
-
client:
|
206
|
+
client: Client,
|
202
207
|
organization: str,
|
203
208
|
name: str,
|
204
209
|
visibility: Literal["organization", "restricted"],
|
205
|
-
description:
|
206
|
-
artifact_types:
|
210
|
+
description: str | None = None,
|
211
|
+
artifact_types: list[str] | None = None,
|
207
212
|
):
|
208
213
|
"""Create a new registry.
|
209
214
|
|