wandb 0.22.2__py3-none-musllinux_1_2_aarch64.whl → 0.22.3__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.
- wandb/__init__.py +1 -1
 - wandb/__init__.pyi +2 -2
 - wandb/_pydantic/__init__.py +8 -1
 - wandb/_pydantic/base.py +54 -18
 - wandb/_pydantic/field_types.py +8 -3
 - wandb/_pydantic/pagination.py +46 -0
 - wandb/_pydantic/utils.py +2 -2
 - wandb/apis/public/api.py +24 -19
 - wandb/apis/public/artifacts.py +259 -270
 - wandb/apis/public/registries/_utils.py +40 -54
 - wandb/apis/public/registries/registries_search.py +70 -85
 - wandb/apis/public/registries/registry.py +173 -156
 - wandb/apis/public/runs.py +27 -6
 - wandb/apis/public/utils.py +43 -20
 - wandb/automations/_generated/create_automation.py +2 -2
 - wandb/automations/_generated/create_generic_webhook_integration.py +4 -4
 - wandb/automations/_generated/delete_automation.py +2 -2
 - wandb/automations/_generated/fragments.py +31 -52
 - wandb/automations/_generated/generic_webhook_integrations_by_entity.py +3 -3
 - wandb/automations/_generated/get_automations.py +3 -3
 - wandb/automations/_generated/get_automations_by_entity.py +3 -3
 - wandb/automations/_generated/input_types.py +9 -9
 - wandb/automations/_generated/integrations_by_entity.py +3 -3
 - wandb/automations/_generated/operations.py +6 -6
 - wandb/automations/_generated/slack_integrations_by_entity.py +3 -3
 - wandb/automations/_generated/update_automation.py +2 -2
 - wandb/automations/_utils.py +3 -3
 - wandb/automations/actions.py +3 -3
 - wandb/automations/automations.py +6 -5
 - wandb/bin/gpu_stats +0 -0
 - wandb/bin/wandb-core +0 -0
 - wandb/cli/beta.py +8 -2
 - wandb/cli/beta_leet.py +2 -1
 - wandb/cli/beta_sync.py +1 -1
 - wandb/errors/term.py +8 -8
 - wandb/jupyter.py +0 -51
 - wandb/old/settings.py +6 -6
 - wandb/proto/v3/wandb_internal_pb2.py +351 -352
 - wandb/proto/v3/wandb_server_pb2.py +38 -37
 - wandb/proto/v3/wandb_settings_pb2.py +2 -2
 - wandb/proto/v3/wandb_sync_pb2.py +19 -6
 - wandb/proto/v4/wandb_internal_pb2.py +351 -352
 - wandb/proto/v4/wandb_server_pb2.py +38 -37
 - wandb/proto/v4/wandb_settings_pb2.py +2 -2
 - wandb/proto/v4/wandb_sync_pb2.py +10 -6
 - wandb/proto/v5/wandb_internal_pb2.py +351 -352
 - wandb/proto/v5/wandb_server_pb2.py +38 -37
 - wandb/proto/v5/wandb_settings_pb2.py +2 -2
 - wandb/proto/v5/wandb_sync_pb2.py +10 -6
 - wandb/proto/v6/wandb_internal_pb2.py +351 -352
 - wandb/proto/v6/wandb_server_pb2.py +38 -37
 - wandb/proto/v6/wandb_settings_pb2.py +2 -2
 - wandb/proto/v6/wandb_sync_pb2.py +10 -6
 - wandb/sdk/artifacts/_generated/__init__.py +96 -40
 - wandb/sdk/artifacts/_generated/add_aliases.py +3 -3
 - wandb/sdk/artifacts/_generated/add_artifact_collection_tags.py +26 -0
 - wandb/sdk/artifacts/_generated/artifact_by_id.py +2 -2
 - wandb/sdk/artifacts/_generated/artifact_by_name.py +3 -3
 - wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +27 -8
 - wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +27 -8
 - wandb/sdk/artifacts/_generated/artifact_created_by.py +7 -20
 - wandb/sdk/artifacts/_generated/artifact_file_urls.py +19 -6
 - wandb/sdk/artifacts/_generated/artifact_membership_by_name.py +26 -0
 - wandb/sdk/artifacts/_generated/artifact_type.py +5 -5
 - wandb/sdk/artifacts/_generated/artifact_used_by.py +8 -17
 - wandb/sdk/artifacts/_generated/artifact_version_files.py +19 -8
 - wandb/sdk/artifacts/_generated/delete_aliases.py +3 -3
 - wandb/sdk/artifacts/_generated/delete_artifact.py +4 -4
 - wandb/sdk/artifacts/_generated/delete_artifact_collection_tags.py +23 -0
 - wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +4 -4
 - wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +4 -4
 - wandb/sdk/artifacts/_generated/delete_registry.py +21 -0
 - wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +8 -20
 - wandb/sdk/artifacts/_generated/fetch_linked_artifacts.py +13 -35
 - wandb/sdk/artifacts/_generated/fetch_org_info_from_entity.py +28 -0
 - wandb/sdk/artifacts/_generated/fetch_registries.py +18 -8
 - wandb/sdk/{projects → artifacts}/_generated/fetch_registry.py +4 -4
 - wandb/sdk/artifacts/_generated/fragments.py +183 -333
 - wandb/sdk/artifacts/_generated/input_types.py +133 -7
 - wandb/sdk/artifacts/_generated/link_artifact.py +5 -5
 - wandb/sdk/artifacts/_generated/operations.py +1053 -548
 - wandb/sdk/artifacts/_generated/project_artifact_collection.py +9 -77
 - wandb/sdk/artifacts/_generated/project_artifact_collections.py +21 -9
 - wandb/sdk/artifacts/_generated/project_artifact_type.py +3 -3
 - wandb/sdk/artifacts/_generated/project_artifact_types.py +19 -6
 - wandb/sdk/artifacts/_generated/project_artifacts.py +7 -8
 - wandb/sdk/artifacts/_generated/registry_collections.py +21 -9
 - wandb/sdk/artifacts/_generated/registry_versions.py +20 -9
 - wandb/sdk/artifacts/_generated/rename_registry.py +25 -0
 - wandb/sdk/artifacts/_generated/run_input_artifacts.py +5 -9
 - wandb/sdk/artifacts/_generated/run_output_artifacts.py +5 -9
 - wandb/sdk/artifacts/_generated/type_info.py +2 -2
 - wandb/sdk/artifacts/_generated/unlink_artifact.py +3 -5
 - wandb/sdk/artifacts/_generated/update_artifact.py +3 -3
 - wandb/sdk/artifacts/_generated/update_artifact_collection_type.py +28 -0
 - wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +7 -16
 - wandb/sdk/artifacts/_generated/update_artifact_sequence.py +7 -16
 - wandb/sdk/artifacts/_generated/upsert_registry.py +25 -0
 - wandb/sdk/artifacts/_gqlutils.py +170 -6
 - wandb/sdk/artifacts/_models/__init__.py +9 -0
 - wandb/sdk/artifacts/_models/artifact_collection.py +109 -0
 - wandb/sdk/artifacts/_models/manifest.py +26 -0
 - wandb/sdk/artifacts/_models/pagination.py +26 -0
 - wandb/sdk/artifacts/_models/registry.py +100 -0
 - wandb/sdk/artifacts/_validators.py +45 -27
 - wandb/sdk/artifacts/artifact.py +220 -215
 - wandb/sdk/artifacts/artifact_file_cache.py +1 -1
 - wandb/sdk/artifacts/artifact_manifest.py +37 -32
 - wandb/sdk/artifacts/artifact_manifest_entry.py +80 -125
 - wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +43 -61
 - wandb/sdk/artifacts/storage_handlers/gcs_handler.py +8 -6
 - wandb/sdk/data_types/image.py +2 -2
 - wandb/sdk/interface/interface.py +72 -64
 - wandb/sdk/interface/interface_queue.py +27 -18
 - wandb/sdk/interface/interface_shared.py +61 -23
 - wandb/sdk/interface/interface_sock.py +9 -5
 - wandb/sdk/internal/_generated/server_features_query.py +4 -4
 - wandb/sdk/launch/inputs/schema.py +13 -10
 - wandb/sdk/lib/apikey.py +8 -12
 - wandb/sdk/lib/asyncio_compat.py +1 -1
 - wandb/sdk/lib/asyncio_manager.py +5 -5
 - wandb/sdk/lib/console_capture.py +38 -30
 - wandb/sdk/lib/progress.py +159 -64
 - wandb/sdk/lib/retry.py +3 -2
 - wandb/sdk/lib/service/service_connection.py +2 -2
 - wandb/sdk/lib/wb_logging.py +2 -1
 - wandb/sdk/mailbox/mailbox.py +1 -1
 - wandb/sdk/wandb_init.py +10 -13
 - wandb/sdk/wandb_run.py +9 -46
 - wandb/sdk/wandb_settings.py +102 -19
 - {wandb-0.22.2.dist-info → wandb-0.22.3.dist-info}/METADATA +2 -1
 - {wandb-0.22.2.dist-info → wandb-0.22.3.dist-info}/RECORD +135 -134
 - wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +0 -26
 - wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +0 -36
 - wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +0 -25
 - wandb/sdk/artifacts/_generated/move_artifact_collection.py +0 -35
 - wandb/sdk/projects/_generated/__init__.py +0 -26
 - wandb/sdk/projects/_generated/delete_project.py +0 -22
 - wandb/sdk/projects/_generated/enums.py +0 -4
 - wandb/sdk/projects/_generated/fragments.py +0 -41
 - wandb/sdk/projects/_generated/input_types.py +0 -13
 - wandb/sdk/projects/_generated/operations.py +0 -88
 - wandb/sdk/projects/_generated/rename_project.py +0 -27
 - wandb/sdk/projects/_generated/upsert_registry_project.py +0 -27
 - {wandb-0.22.2.dist-info → wandb-0.22.3.dist-info}/WHEEL +0 -0
 - {wandb-0.22.2.dist-info → wandb-0.22.3.dist-info}/entry_points.txt +0 -0
 - {wandb-0.22.2.dist-info → wandb-0.22.3.dist-info}/licenses/LICENSE +0 -0
 
| 
         @@ -1,14 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            from enum import Enum
         
     | 
| 
       4 
     | 
    
         
            -
            from functools import lru_cache
         
     | 
| 
       5 
     | 
    
         
            -
            from typing import TYPE_CHECKING, Any,  
     | 
| 
      
 4 
     | 
    
         
            +
            from functools import lru_cache, partial
         
     | 
| 
      
 5 
     | 
    
         
            +
            from typing import TYPE_CHECKING, Any, Collection
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            from wandb._strutils import ensureprefix
         
     | 
| 
       8 
     | 
    
         
            -
            from wandb.sdk.artifacts._validators import  
     | 
| 
       9 
     | 
    
         
            -
                REGISTRY_PREFIX,
         
     | 
| 
       10 
     | 
    
         
            -
                validate_artifact_types_list,
         
     | 
| 
       11 
     | 
    
         
            -
            )
         
     | 
| 
      
 8 
     | 
    
         
            +
            from wandb.sdk.artifacts._validators import REGISTRY_PREFIX, validate_artifact_types
         
     | 
| 
       12 
9 
     | 
    
         | 
| 
       13 
10 
     | 
    
         
             
            if TYPE_CHECKING:
         
     | 
| 
       14 
11 
     | 
    
         
             
                from wandb_gql import Client
         
     | 
| 
         @@ -24,12 +21,35 @@ class Visibility(str, Enum): 
     | 
|
| 
       24 
21 
     | 
    
         | 
| 
       25 
22 
     | 
    
         
             
                @classmethod
         
     | 
| 
       26 
23 
     | 
    
         
             
                def _missing_(cls, value: object) -> Any:
         
     | 
| 
       27 
     | 
    
         
            -
                     
     | 
| 
      
 24 
     | 
    
         
            +
                    # Allow instantiation from enum names too (e.g. "organization" or "restricted")
         
     | 
| 
      
 25 
     | 
    
         
            +
                    return cls.__members__.get(value)
         
     | 
| 
       28 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
                @classmethod
         
     | 
| 
      
 28 
     | 
    
         
            +
                def from_gql(cls, value: str) -> Visibility:
         
     | 
| 
      
 29 
     | 
    
         
            +
                    """Convert a GraphQL `visibility` value to a Visibility enum."""
         
     | 
| 
      
 30 
     | 
    
         
            +
                    try:
         
     | 
| 
      
 31 
     | 
    
         
            +
                        return cls(value)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    except ValueError:
         
     | 
| 
      
 33 
     | 
    
         
            +
                        expected = ",".join(repr(e.value) for e in cls)
         
     | 
| 
      
 34 
     | 
    
         
            +
                        raise ValueError(
         
     | 
| 
      
 35 
     | 
    
         
            +
                            f"Invalid visibility {value!r} from backend. Expected one of: {expected}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                        ) from None
         
     | 
| 
       29 
37 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
       32 
     | 
    
         
            -
            )  
     | 
| 
      
 38 
     | 
    
         
            +
                @classmethod
         
     | 
| 
      
 39 
     | 
    
         
            +
                def from_python(cls, name: str) -> Visibility:
         
     | 
| 
      
 40 
     | 
    
         
            +
                    """Convert a visibility string (e.g. user-provided or python default value) to a Visibility enum."""
         
     | 
| 
      
 41 
     | 
    
         
            +
                    try:
         
     | 
| 
      
 42 
     | 
    
         
            +
                        return cls(name)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    except ValueError:
         
     | 
| 
      
 44 
     | 
    
         
            +
                        expected = ",".join(repr(e.name) for e in cls)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        raise ValueError(
         
     | 
| 
      
 46 
     | 
    
         
            +
                            f"Invalid visibility {name!r}. Expected one of: {expected}"
         
     | 
| 
      
 47 
     | 
    
         
            +
                        ) from None
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            def prepare_artifact_types_input(
         
     | 
| 
      
 51 
     | 
    
         
            +
                artifact_types: Collection[str] | None,
         
     | 
| 
      
 52 
     | 
    
         
            +
            ) -> list[dict[str, str]] | None:
         
     | 
| 
       33 
53 
     | 
    
         
             
                """Format the artifact types for the GQL input.
         
     | 
| 
       34 
54 
     | 
    
         | 
| 
       35 
55 
     | 
    
         
             
                Args:
         
     | 
| 
         @@ -38,39 +58,9 @@ def format_gql_artifact_types_input( 
     | 
|
| 
       38 
58 
     | 
    
         
             
                Returns:
         
     | 
| 
       39 
59 
     | 
    
         
             
                    The artifact types for the GQL input.
         
     | 
| 
       40 
60 
     | 
    
         
             
                """
         
     | 
| 
       41 
     | 
    
         
            -
                if artifact_types 
     | 
| 
       42 
     | 
    
         
            -
                    return []
         
     | 
| 
       43 
     | 
    
         
            -
                return  
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
            def gql_to_registry_visibility(
         
     | 
| 
       47 
     | 
    
         
            -
                visibility: str,
         
     | 
| 
       48 
     | 
    
         
            -
            ) -> Literal["organization", "restricted"]:
         
     | 
| 
       49 
     | 
    
         
            -
                """Convert the GQL visibility to the registry visibility.
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                Args:
         
     | 
| 
       52 
     | 
    
         
            -
                    visibility: The GQL visibility.
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                Returns:
         
     | 
| 
       55 
     | 
    
         
            -
                    The registry visibility.
         
     | 
| 
       56 
     | 
    
         
            -
                """
         
     | 
| 
       57 
     | 
    
         
            -
                try:
         
     | 
| 
       58 
     | 
    
         
            -
                    return Visibility(visibility).name
         
     | 
| 
       59 
     | 
    
         
            -
                except ValueError:
         
     | 
| 
       60 
     | 
    
         
            -
                    raise ValueError(f"Invalid visibility: {visibility!r} from backend")
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            def registry_visibility_to_gql(
         
     | 
| 
       64 
     | 
    
         
            -
                visibility: Literal["organization", "restricted"],
         
     | 
| 
       65 
     | 
    
         
            -
            ) -> str:
         
     | 
| 
       66 
     | 
    
         
            -
                """Convert the registry visibility to the GQL visibility."""
         
     | 
| 
       67 
     | 
    
         
            -
                try:
         
     | 
| 
       68 
     | 
    
         
            -
                    return Visibility[visibility].value
         
     | 
| 
       69 
     | 
    
         
            -
                except LookupError:
         
     | 
| 
       70 
     | 
    
         
            -
                    allowed_str = ", ".join(map(repr, (e.name for e in Visibility)))
         
     | 
| 
       71 
     | 
    
         
            -
                    raise ValueError(
         
     | 
| 
       72 
     | 
    
         
            -
                        f"Invalid visibility: {visibility!r}. Must be one of: {allowed_str}"
         
     | 
| 
       73 
     | 
    
         
            -
                    )
         
     | 
| 
      
 61 
     | 
    
         
            +
                if artifact_types:
         
     | 
| 
      
 62 
     | 
    
         
            +
                    return [{"name": typ} for typ in validate_artifact_types(artifact_types)]
         
     | 
| 
      
 63 
     | 
    
         
            +
                return None
         
     | 
| 
       74 
64 
     | 
    
         | 
| 
       75 
65 
     | 
    
         | 
| 
       76 
66 
     | 
    
         
             
            def ensure_registry_prefix_on_names(query: Any, in_name: bool = False) -> Any:
         
     | 
| 
         @@ -81,25 +71,21 @@ def ensure_registry_prefix_on_names(query: Any, in_name: bool = False) -> Any: 
     | 
|
| 
       81 
71 
     | 
    
         
             
                EX: {"name": "model"} -> {"name": "wandb-registry-model"}
         
     | 
| 
       82 
72 
     | 
    
         
             
                """
         
     | 
| 
       83 
73 
     | 
    
         
             
                if isinstance((txt := query), str):
         
     | 
| 
       84 
     | 
    
         
            -
                    if in_name 
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                    return txt
         
     | 
| 
       87 
     | 
    
         
            -
                if isinstance((dct := query), Mapping):
         
     | 
| 
      
 74 
     | 
    
         
            +
                    return ensureprefix(txt, REGISTRY_PREFIX) if in_name else txt
         
     | 
| 
      
 75 
     | 
    
         
            +
                if isinstance((dct := query), dict):
         
     | 
| 
       88 
76 
     | 
    
         
             
                    new_dict = {}
         
     | 
| 
       89 
77 
     | 
    
         
             
                    for key, obj in dct.items():
         
     | 
| 
       90 
     | 
    
         
            -
                        if key == " 
     | 
| 
       91 
     | 
    
         
            -
                            new_dict[key] = ensure_registry_prefix_on_names(obj, in_name=True)
         
     | 
| 
       92 
     | 
    
         
            -
                        elif key == "$regex":
         
     | 
| 
      
 78 
     | 
    
         
            +
                        if key == "$regex":
         
     | 
| 
       93 
79 
     | 
    
         
             
                            # For regex operator, we skip transformation of its value.
         
     | 
| 
       94 
80 
     | 
    
         
             
                            new_dict[key] = obj
         
     | 
| 
      
 81 
     | 
    
         
            +
                        elif key == "name":
         
     | 
| 
      
 82 
     | 
    
         
            +
                            new_dict[key] = ensure_registry_prefix_on_names(obj, in_name=True)
         
     | 
| 
       95 
83 
     | 
    
         
             
                        else:
         
     | 
| 
       96 
84 
     | 
    
         
             
                            # For any other key, propagate the in_name and skip_transform flags as-is.
         
     | 
| 
       97 
85 
     | 
    
         
             
                            new_dict[key] = ensure_registry_prefix_on_names(obj, in_name=in_name)
         
     | 
| 
       98 
86 
     | 
    
         
             
                    return new_dict
         
     | 
| 
       99 
     | 
    
         
            -
                if isinstance(( 
     | 
| 
       100 
     | 
    
         
            -
                    return list(
         
     | 
| 
       101 
     | 
    
         
            -
                        map(lambda x: ensure_registry_prefix_on_names(x, in_name=in_name), objs)
         
     | 
| 
       102 
     | 
    
         
            -
                    )
         
     | 
| 
      
 87 
     | 
    
         
            +
                if isinstance((seq := query), (list, tuple)):
         
     | 
| 
      
 88 
     | 
    
         
            +
                    return list(map(partial(ensure_registry_prefix_on_names, in_name=in_name), seq))
         
     | 
| 
       103 
89 
     | 
    
         
             
                return query
         
     | 
| 
       104 
90 
     | 
    
         | 
| 
       105 
91 
     | 
    
         | 
| 
         @@ -5,33 +5,38 @@ from __future__ import annotations 
     | 
|
| 
       5 
5 
     | 
    
         
             
            import json
         
     | 
| 
       6 
6 
     | 
    
         
             
            from typing import TYPE_CHECKING, Any
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            from pydantic import ValidationError
         
     | 
| 
      
 8 
     | 
    
         
            +
            from pydantic import PositiveInt, ValidationError
         
     | 
| 
       9 
9 
     | 
    
         
             
            from typing_extensions import override
         
     | 
| 
       10 
10 
     | 
    
         
             
            from wandb_gql import gql
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            from wandb._analytics import tracked
         
     | 
| 
       13 
13 
     | 
    
         
             
            from wandb.apis.paginator import Paginator
         
     | 
| 
      
 14 
     | 
    
         
            +
            from wandb.apis.public.artifacts import ArtifactCollection
         
     | 
| 
       14 
15 
     | 
    
         
             
            from wandb.apis.public.utils import gql_compat
         
     | 
| 
       15 
16 
     | 
    
         
             
            from wandb.sdk.artifacts._generated import (
         
     | 
| 
       16 
17 
     | 
    
         
             
                FETCH_REGISTRIES_GQL,
         
     | 
| 
       17 
18 
     | 
    
         
             
                REGISTRY_COLLECTIONS_GQL,
         
     | 
| 
       18 
19 
     | 
    
         
             
                REGISTRY_VERSIONS_GQL,
         
     | 
| 
       19 
     | 
    
         
            -
                ArtifactCollectionType,
         
     | 
| 
       20 
20 
     | 
    
         
             
                FetchRegistries,
         
     | 
| 
       21 
     | 
    
         
            -
                RegistriesPage,
         
     | 
| 
       22 
21 
     | 
    
         
             
                RegistryCollections,
         
     | 
| 
       23 
     | 
    
         
            -
                RegistryCollectionsPage,
         
     | 
| 
       24 
22 
     | 
    
         
             
                RegistryVersions,
         
     | 
| 
       25 
     | 
    
         
            -
                RegistryVersionsPage,
         
     | 
| 
       26 
23 
     | 
    
         
             
            )
         
     | 
| 
       27 
24 
     | 
    
         
             
            from wandb.sdk.artifacts._gqlutils import omit_artifact_fields
         
     | 
| 
       28 
     | 
    
         
            -
            from wandb.sdk.artifacts. 
     | 
| 
      
 25 
     | 
    
         
            +
            from wandb.sdk.artifacts._models.pagination import (
         
     | 
| 
      
 26 
     | 
    
         
            +
                ArtifactMembershipConnection,
         
     | 
| 
      
 27 
     | 
    
         
            +
                RegistryCollectionConnection,
         
     | 
| 
      
 28 
     | 
    
         
            +
                RegistryConnection,
         
     | 
| 
      
 29 
     | 
    
         
            +
            )
         
     | 
| 
      
 30 
     | 
    
         
            +
            from wandb.sdk.artifacts._validators import (
         
     | 
| 
      
 31 
     | 
    
         
            +
                SOURCE_COLLECTION_TYPENAME,
         
     | 
| 
      
 32 
     | 
    
         
            +
                FullArtifactPath,
         
     | 
| 
      
 33 
     | 
    
         
            +
                remove_registry_prefix,
         
     | 
| 
      
 34 
     | 
    
         
            +
            )
         
     | 
| 
       29 
35 
     | 
    
         | 
| 
       30 
36 
     | 
    
         
             
            from ._utils import ensure_registry_prefix_on_names
         
     | 
| 
       31 
37 
     | 
    
         | 
| 
       32 
38 
     | 
    
         
             
            if TYPE_CHECKING:
         
     | 
| 
       33 
     | 
    
         
            -
                from  
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                from wandb.apis.public import RetryingClient
         
     | 
| 
       35 
40 
     | 
    
         
             
                from wandb.sdk.artifacts.artifact import Artifact
         
     | 
| 
       36 
41 
     | 
    
         | 
| 
       37 
42 
     | 
    
         | 
| 
         @@ -40,15 +45,14 @@ class Registries(Paginator): 
     | 
|
| 
       40 
45 
     | 
    
         | 
| 
       41 
46 
     | 
    
         
             
                QUERY = gql(FETCH_REGISTRIES_GQL)
         
     | 
| 
       42 
47 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                last_response:  
     | 
| 
       44 
     | 
    
         
            -
                _last_org_entity: str | None
         
     | 
| 
      
 48 
     | 
    
         
            +
                last_response: RegistryConnection | None
         
     | 
| 
       45 
49 
     | 
    
         | 
| 
       46 
50 
     | 
    
         
             
                def __init__(
         
     | 
| 
       47 
51 
     | 
    
         
             
                    self,
         
     | 
| 
       48 
     | 
    
         
            -
                    client:  
     | 
| 
      
 52 
     | 
    
         
            +
                    client: RetryingClient,
         
     | 
| 
       49 
53 
     | 
    
         
             
                    organization: str,
         
     | 
| 
       50 
54 
     | 
    
         
             
                    filter: dict[str, Any] | None = None,
         
     | 
| 
       51 
     | 
    
         
            -
                    per_page:  
     | 
| 
      
 55 
     | 
    
         
            +
                    per_page: PositiveInt = 100,
         
     | 
| 
       52 
56 
     | 
    
         
             
                ):
         
     | 
| 
       53 
57 
     | 
    
         
             
                    self.client = client
         
     | 
| 
       54 
58 
     | 
    
         
             
                    self.organization = organization
         
     | 
| 
         @@ -57,11 +61,8 @@ class Registries(Paginator): 
     | 
|
| 
       57 
61 
     | 
    
         
             
                        "organization": organization,
         
     | 
| 
       58 
62 
     | 
    
         
             
                        "filters": json.dumps(self.filter),
         
     | 
| 
       59 
63 
     | 
    
         
             
                    }
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
64 
     | 
    
         
             
                    super().__init__(client, variables, per_page)
         
     | 
| 
       62 
65 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                    self._last_org_entity = None
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
66 
     | 
    
         
             
                def __next__(self):
         
     | 
| 
       66 
67 
     | 
    
         
             
                    # Implement custom next since its possible to load empty pages because of auth
         
     | 
| 
       67 
68 
     | 
    
         
             
                    self.index += 1
         
     | 
| 
         @@ -71,22 +72,28 @@ class Registries(Paginator): 
     | 
|
| 
       71 
72 
     | 
    
         
             
                    return self.objects[self.index]
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
74 
     | 
    
         
             
                @tracked
         
     | 
| 
       74 
     | 
    
         
            -
                def collections( 
     | 
| 
      
 75 
     | 
    
         
            +
                def collections(
         
     | 
| 
      
 76 
     | 
    
         
            +
                    self, filter: dict[str, Any] | None = None, per_page: PositiveInt = 100
         
     | 
| 
      
 77 
     | 
    
         
            +
                ) -> Collections:
         
     | 
| 
       75 
78 
     | 
    
         
             
                    return Collections(
         
     | 
| 
       76 
79 
     | 
    
         
             
                        client=self.client,
         
     | 
| 
       77 
80 
     | 
    
         
             
                        organization=self.organization,
         
     | 
| 
       78 
81 
     | 
    
         
             
                        registry_filter=self.filter,
         
     | 
| 
       79 
82 
     | 
    
         
             
                        collection_filter=filter,
         
     | 
| 
      
 83 
     | 
    
         
            +
                        per_page=per_page,
         
     | 
| 
       80 
84 
     | 
    
         
             
                    )
         
     | 
| 
       81 
85 
     | 
    
         | 
| 
       82 
86 
     | 
    
         
             
                @tracked
         
     | 
| 
       83 
     | 
    
         
            -
                def versions( 
     | 
| 
      
 87 
     | 
    
         
            +
                def versions(
         
     | 
| 
      
 88 
     | 
    
         
            +
                    self, filter: dict[str, Any] | None = None, per_page: PositiveInt = 100
         
     | 
| 
      
 89 
     | 
    
         
            +
                ) -> Versions:
         
     | 
| 
       84 
90 
     | 
    
         
             
                    return Versions(
         
     | 
| 
       85 
91 
     | 
    
         
             
                        client=self.client,
         
     | 
| 
       86 
92 
     | 
    
         
             
                        organization=self.organization,
         
     | 
| 
       87 
93 
     | 
    
         
             
                        registry_filter=self.filter,
         
     | 
| 
       88 
94 
     | 
    
         
             
                        collection_filter=None,
         
     | 
| 
       89 
95 
     | 
    
         
             
                        artifact_filter=filter,
         
     | 
| 
      
 96 
     | 
    
         
            +
                        per_page=per_page,
         
     | 
| 
       90 
97 
     | 
    
         
             
                    )
         
     | 
| 
       91 
98 
     | 
    
         | 
| 
       92 
99 
     | 
    
         
             
                @property
         
     | 
| 
         @@ -97,15 +104,11 @@ class Registries(Paginator): 
     | 
|
| 
       97 
104 
     | 
    
         | 
| 
       98 
105 
     | 
    
         
             
                @property
         
     | 
| 
       99 
106 
     | 
    
         
             
                def more(self):
         
     | 
| 
       100 
     | 
    
         
            -
                     
     | 
| 
       101 
     | 
    
         
            -
                        return True
         
     | 
| 
       102 
     | 
    
         
            -
                    return self.last_response.page_info.has_next_page
         
     | 
| 
      
 107 
     | 
    
         
            +
                    return (conn := self.last_response) is None or conn.has_next
         
     | 
| 
       103 
108 
     | 
    
         | 
| 
       104 
109 
     | 
    
         
             
                @property
         
     | 
| 
       105 
110 
     | 
    
         
             
                def cursor(self):
         
     | 
| 
       106 
     | 
    
         
            -
                    if self.last_response  
     | 
| 
       107 
     | 
    
         
            -
                        return None
         
     | 
| 
       108 
     | 
    
         
            -
                    return self.last_response.page_info.end_cursor
         
     | 
| 
      
 111 
     | 
    
         
            +
                    return conn.next_cursor if (conn := self.last_response) else None
         
     | 
| 
       109 
112 
     | 
    
         | 
| 
       110 
113 
     | 
    
         
             
                @override
         
     | 
| 
       111 
114 
     | 
    
         
             
                def _update_response(self) -> None:
         
     | 
| 
         @@ -117,45 +120,43 @@ class Registries(Paginator): 
     | 
|
| 
       117 
120 
     | 
    
         
             
                        )
         
     | 
| 
       118 
121 
     | 
    
         | 
| 
       119 
122 
     | 
    
         
             
                    try:
         
     | 
| 
       120 
     | 
    
         
            -
                         
     | 
| 
       121 
     | 
    
         
            -
                        self.last_response =  
     | 
| 
       122 
     | 
    
         
            -
                        self._last_org_entity = org_entity.name
         
     | 
| 
      
 123 
     | 
    
         
            +
                        conn = org_entity.projects
         
     | 
| 
      
 124 
     | 
    
         
            +
                        self.last_response = RegistryConnection.model_validate(conn)
         
     | 
| 
       123 
125 
     | 
    
         
             
                    except (LookupError, AttributeError, ValidationError) as e:
         
     | 
| 
       124 
126 
     | 
    
         
             
                        raise ValueError("Unexpected response data") from e
         
     | 
| 
       125 
127 
     | 
    
         | 
| 
       126 
128 
     | 
    
         
             
                def convert_objects(self):
         
     | 
| 
       127 
129 
     | 
    
         
             
                    from wandb.apis.public.registries.registry import Registry
         
     | 
| 
       128 
130 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
                    if  
     | 
| 
      
 131 
     | 
    
         
            +
                    if self.last_response is None:
         
     | 
| 
       130 
132 
     | 
    
         
             
                        return []
         
     | 
| 
       131 
133 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
                    nodes = (e.node for e in self.last_response.edges)
         
     | 
| 
       133 
134 
     | 
    
         
             
                    return [
         
     | 
| 
       134 
135 
     | 
    
         
             
                        Registry(
         
     | 
| 
       135 
136 
     | 
    
         
             
                            client=self.client,
         
     | 
| 
       136 
137 
     | 
    
         
             
                            organization=self.organization,
         
     | 
| 
       137 
     | 
    
         
            -
                            entity= 
     | 
| 
      
 138 
     | 
    
         
            +
                            entity=node.entity.name,
         
     | 
| 
       138 
139 
     | 
    
         
             
                            name=remove_registry_prefix(node.name),
         
     | 
| 
       139 
     | 
    
         
            -
                            attrs=node 
     | 
| 
      
 140 
     | 
    
         
            +
                            attrs=node,
         
     | 
| 
       140 
141 
     | 
    
         
             
                        )
         
     | 
| 
       141 
     | 
    
         
            -
                        for node in nodes
         
     | 
| 
      
 142 
     | 
    
         
            +
                        for node in self.last_response.nodes()
         
     | 
| 
       142 
143 
     | 
    
         
             
                    ]
         
     | 
| 
       143 
144 
     | 
    
         | 
| 
       144 
145 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
            class Collections(Paginator[ 
     | 
| 
      
 146 
     | 
    
         
            +
            class Collections(Paginator[ArtifactCollection]):
         
     | 
| 
       146 
147 
     | 
    
         
             
                """An lazy iterator of `ArtifactCollection` objects in a Registry."""
         
     | 
| 
       147 
148 
     | 
    
         | 
| 
       148 
149 
     | 
    
         
             
                QUERY = gql(REGISTRY_COLLECTIONS_GQL)
         
     | 
| 
       149 
150 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
                last_response:  
     | 
| 
      
 151 
     | 
    
         
            +
                last_response: RegistryCollectionConnection | None
         
     | 
| 
       151 
152 
     | 
    
         | 
| 
       152 
153 
     | 
    
         
             
                def __init__(
         
     | 
| 
       153 
154 
     | 
    
         
             
                    self,
         
     | 
| 
       154 
     | 
    
         
            -
                    client:  
     | 
| 
      
 155 
     | 
    
         
            +
                    client: RetryingClient,
         
     | 
| 
       155 
156 
     | 
    
         
             
                    organization: str,
         
     | 
| 
       156 
157 
     | 
    
         
             
                    registry_filter: dict[str, Any] | None = None,
         
     | 
| 
       157 
158 
     | 
    
         
             
                    collection_filter: dict[str, Any] | None = None,
         
     | 
| 
       158 
     | 
    
         
            -
                    per_page:  
     | 
| 
      
 159 
     | 
    
         
            +
                    per_page: PositiveInt = 100,
         
     | 
| 
       159 
160 
     | 
    
         
             
                ):
         
     | 
| 
       160 
161 
     | 
    
         
             
                    self.client = client
         
     | 
| 
       161 
162 
     | 
    
         
             
                    self.organization = organization
         
     | 
| 
         @@ -166,7 +167,6 @@ class Collections(Paginator["ArtifactCollection"]): 
     | 
|
| 
       166 
167 
     | 
    
         
             
                        "registryFilter": json.dumps(f) if (f := registry_filter) else None,
         
     | 
| 
       167 
168 
     | 
    
         
             
                        "collectionFilter": json.dumps(f) if (f := collection_filter) else None,
         
     | 
| 
       168 
169 
     | 
    
         
             
                        "organization": organization,
         
     | 
| 
       169 
     | 
    
         
            -
                        "collectionTypes": [ArtifactCollectionType.PORTFOLIO],
         
     | 
| 
       170 
170 
     | 
    
         
             
                        "perPage": per_page,
         
     | 
| 
       171 
171 
     | 
    
         
             
                    }
         
     | 
| 
       172 
172 
     | 
    
         | 
| 
         @@ -181,48 +181,42 @@ class Collections(Paginator["ArtifactCollection"]): 
     | 
|
| 
       181 
181 
     | 
    
         
             
                    return self.objects[self.index]
         
     | 
| 
       182 
182 
     | 
    
         | 
| 
       183 
183 
     | 
    
         
             
                @tracked
         
     | 
| 
       184 
     | 
    
         
            -
                def versions( 
     | 
| 
      
 184 
     | 
    
         
            +
                def versions(
         
     | 
| 
      
 185 
     | 
    
         
            +
                    self, filter: dict[str, Any] | None = None, per_page: PositiveInt = 100
         
     | 
| 
      
 186 
     | 
    
         
            +
                ) -> Versions:
         
     | 
| 
       185 
187 
     | 
    
         
             
                    return Versions(
         
     | 
| 
       186 
188 
     | 
    
         
             
                        client=self.client,
         
     | 
| 
       187 
189 
     | 
    
         
             
                        organization=self.organization,
         
     | 
| 
       188 
190 
     | 
    
         
             
                        registry_filter=self.registry_filter,
         
     | 
| 
       189 
191 
     | 
    
         
             
                        collection_filter=self.collection_filter,
         
     | 
| 
       190 
192 
     | 
    
         
             
                        artifact_filter=filter,
         
     | 
| 
      
 193 
     | 
    
         
            +
                        per_page=per_page,
         
     | 
| 
       191 
194 
     | 
    
         
             
                    )
         
     | 
| 
       192 
195 
     | 
    
         | 
| 
       193 
196 
     | 
    
         
             
                @property
         
     | 
| 
       194 
197 
     | 
    
         
             
                def length(self):
         
     | 
| 
       195 
     | 
    
         
            -
                    if self.last_response  
     | 
| 
       196 
     | 
    
         
            -
                        return None
         
     | 
| 
       197 
     | 
    
         
            -
                    return self.last_response.total_count
         
     | 
| 
      
 198 
     | 
    
         
            +
                    return conn.total_count if (conn := self.last_response) else None
         
     | 
| 
       198 
199 
     | 
    
         | 
| 
       199 
200 
     | 
    
         
             
                @property
         
     | 
| 
       200 
201 
     | 
    
         
             
                def more(self):
         
     | 
| 
       201 
     | 
    
         
            -
                     
     | 
| 
       202 
     | 
    
         
            -
                        return True
         
     | 
| 
       203 
     | 
    
         
            -
                    return self.last_response.page_info.has_next_page
         
     | 
| 
      
 202 
     | 
    
         
            +
                    return (conn := self.last_response) is None or conn.has_next
         
     | 
| 
       204 
203 
     | 
    
         | 
| 
       205 
204 
     | 
    
         
             
                @property
         
     | 
| 
       206 
205 
     | 
    
         
             
                def cursor(self):
         
     | 
| 
       207 
     | 
    
         
            -
                    if self.last_response  
     | 
| 
       208 
     | 
    
         
            -
                        return None
         
     | 
| 
       209 
     | 
    
         
            -
                    return self.last_response.page_info.end_cursor
         
     | 
| 
      
 206 
     | 
    
         
            +
                    return conn.next_cursor if (conn := self.last_response) else None
         
     | 
| 
       210 
207 
     | 
    
         | 
| 
       211 
208 
     | 
    
         
             
                @override
         
     | 
| 
       212 
209 
     | 
    
         
             
                def _update_response(self) -> None:
         
     | 
| 
       213 
210 
     | 
    
         
             
                    data = self.client.execute(self.QUERY, variable_values=self.variables)
         
     | 
| 
       214 
211 
     | 
    
         
             
                    result = RegistryCollections.model_validate(data)
         
     | 
| 
       215 
     | 
    
         
            -
                    if not (
         
     | 
| 
       216 
     | 
    
         
            -
                        (org_data := result.organization)
         
     | 
| 
       217 
     | 
    
         
            -
                        and (org_entity_data := org_data.org_entity)
         
     | 
| 
       218 
     | 
    
         
            -
                    ):
         
     | 
| 
      
 212 
     | 
    
         
            +
                    if not ((org := result.organization) and (org_entity := org.org_entity)):
         
     | 
| 
       219 
213 
     | 
    
         
             
                        raise ValueError(
         
     | 
| 
       220 
214 
     | 
    
         
             
                            f"Organization {self.organization!r} not found. Please verify the organization name is correct."
         
     | 
| 
       221 
215 
     | 
    
         
             
                        )
         
     | 
| 
       222 
216 
     | 
    
         | 
| 
       223 
217 
     | 
    
         
             
                    try:
         
     | 
| 
       224 
     | 
    
         
            -
                         
     | 
| 
       225 
     | 
    
         
            -
                        self.last_response =  
     | 
| 
      
 218 
     | 
    
         
            +
                        conn = org_entity.artifact_collections
         
     | 
| 
      
 219 
     | 
    
         
            +
                        self.last_response = RegistryCollectionConnection.model_validate(conn)
         
     | 
| 
       226 
220 
     | 
    
         
             
                    except (LookupError, AttributeError, ValidationError) as e:
         
     | 
| 
       227 
221 
     | 
    
         
             
                        raise ValueError("Unexpected response data") from e
         
     | 
| 
       228 
222 
     | 
    
         | 
| 
         @@ -232,36 +226,36 @@ class Collections(Paginator["ArtifactCollection"]): 
     | 
|
| 
       232 
226 
     | 
    
         
             
                    if self.last_response is None:
         
     | 
| 
       233 
227 
     | 
    
         
             
                        return []
         
     | 
| 
       234 
228 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
                    nodes = (e.node for e in self.last_response.edges)
         
     | 
| 
       236 
229 
     | 
    
         
             
                    return [
         
     | 
| 
       237 
230 
     | 
    
         
             
                        ArtifactCollection(
         
     | 
| 
       238 
231 
     | 
    
         
             
                            client=self.client,
         
     | 
| 
       239 
     | 
    
         
            -
                            entity=project.entity.name,
         
     | 
| 
       240 
     | 
    
         
            -
                            project=project.name,
         
     | 
| 
      
 232 
     | 
    
         
            +
                            entity=node.project.entity.name,
         
     | 
| 
      
 233 
     | 
    
         
            +
                            project=node.project.name,
         
     | 
| 
       241 
234 
     | 
    
         
             
                            name=node.name,
         
     | 
| 
       242 
     | 
    
         
            -
                            type=node. 
     | 
| 
      
 235 
     | 
    
         
            +
                            type=node.type.name,
         
     | 
| 
       243 
236 
     | 
    
         
             
                            organization=self.organization,
         
     | 
| 
       244 
     | 
    
         
            -
                            attrs=node 
     | 
| 
       245 
     | 
    
         
            -
                            is_sequence=False,
         
     | 
| 
      
 237 
     | 
    
         
            +
                            attrs=node,
         
     | 
| 
       246 
238 
     | 
    
         
             
                        )
         
     | 
| 
       247 
     | 
    
         
            -
                        for node in nodes
         
     | 
| 
       248 
     | 
    
         
            -
                         
     | 
| 
      
 239 
     | 
    
         
            +
                        for node in self.last_response.nodes()
         
     | 
| 
      
 240 
     | 
    
         
            +
                        # We don't _expect_ any registry collections to be
         
     | 
| 
      
 241 
     | 
    
         
            +
                        # ArtifactSequences, but defensively filter them out anyway.
         
     | 
| 
      
 242 
     | 
    
         
            +
                        if node.project and (node.typename__ != SOURCE_COLLECTION_TYPENAME)
         
     | 
| 
       249 
243 
     | 
    
         
             
                    ]
         
     | 
| 
       250 
244 
     | 
    
         | 
| 
       251 
245 
     | 
    
         | 
| 
       252 
246 
     | 
    
         
             
            class Versions(Paginator["Artifact"]):
         
     | 
| 
       253 
247 
     | 
    
         
             
                """An lazy iterator of `Artifact` objects in a Registry."""
         
     | 
| 
       254 
248 
     | 
    
         | 
| 
       255 
     | 
    
         
            -
                last_response:  
     | 
| 
      
 249 
     | 
    
         
            +
                last_response: ArtifactMembershipConnection | None
         
     | 
| 
       256 
250 
     | 
    
         | 
| 
       257 
251 
     | 
    
         
             
                def __init__(
         
     | 
| 
       258 
252 
     | 
    
         
             
                    self,
         
     | 
| 
       259 
     | 
    
         
            -
                    client:  
     | 
| 
      
 253 
     | 
    
         
            +
                    client: RetryingClient,
         
     | 
| 
       260 
254 
     | 
    
         
             
                    organization: str,
         
     | 
| 
       261 
255 
     | 
    
         
             
                    registry_filter: dict[str, Any] | None = None,
         
     | 
| 
       262 
256 
     | 
    
         
             
                    collection_filter: dict[str, Any] | None = None,
         
     | 
| 
       263 
257 
     | 
    
         
             
                    artifact_filter: dict[str, Any] | None = None,
         
     | 
| 
       264 
     | 
    
         
            -
                    per_page:  
     | 
| 
      
 258 
     | 
    
         
            +
                    per_page: PositiveInt = 100,
         
     | 
| 
       265 
259 
     | 
    
         
             
                ):
         
     | 
| 
       266 
260 
     | 
    
         
             
                    self.client = client
         
     | 
| 
       267 
261 
     | 
    
         
             
                    self.organization = organization
         
     | 
| 
         @@ -298,31 +292,24 @@ class Versions(Paginator["Artifact"]): 
     | 
|
| 
       298 
292 
     | 
    
         | 
| 
       299 
293 
     | 
    
         
             
                @property
         
     | 
| 
       300 
294 
     | 
    
         
             
                def more(self) -> bool:
         
     | 
| 
       301 
     | 
    
         
            -
                     
     | 
| 
       302 
     | 
    
         
            -
                        return True
         
     | 
| 
       303 
     | 
    
         
            -
                    return self.last_response.page_info.has_next_page
         
     | 
| 
      
 295 
     | 
    
         
            +
                    return (conn := self.last_response) is None or conn.has_next
         
     | 
| 
       304 
296 
     | 
    
         | 
| 
       305 
297 
     | 
    
         
             
                @property
         
     | 
| 
       306 
298 
     | 
    
         
             
                def cursor(self) -> str | None:
         
     | 
| 
       307 
     | 
    
         
            -
                    if self.last_response  
     | 
| 
       308 
     | 
    
         
            -
                        return None
         
     | 
| 
       309 
     | 
    
         
            -
                    return self.last_response.page_info.end_cursor
         
     | 
| 
      
 299 
     | 
    
         
            +
                    return conn.next_cursor if (conn := self.last_response) else None
         
     | 
| 
       310 
300 
     | 
    
         | 
| 
       311 
301 
     | 
    
         
             
                @override
         
     | 
| 
       312 
302 
     | 
    
         
             
                def _update_response(self) -> None:
         
     | 
| 
       313 
303 
     | 
    
         
             
                    data = self.client.execute(self.QUERY, variable_values=self.variables)
         
     | 
| 
       314 
304 
     | 
    
         
             
                    result = RegistryVersions.model_validate(data)
         
     | 
| 
       315 
     | 
    
         
            -
                    if not (
         
     | 
| 
       316 
     | 
    
         
            -
                        (org_data := result.organization)
         
     | 
| 
       317 
     | 
    
         
            -
                        and (org_entity_data := org_data.org_entity)
         
     | 
| 
       318 
     | 
    
         
            -
                    ):
         
     | 
| 
      
 305 
     | 
    
         
            +
                    if not ((org := result.organization) and (org_entity := org.org_entity)):
         
     | 
| 
       319 
306 
     | 
    
         
             
                        raise ValueError(
         
     | 
| 
       320 
307 
     | 
    
         
             
                            f"Organization {self.organization!r} not found. Please verify the organization name is correct."
         
     | 
| 
       321 
308 
     | 
    
         
             
                        )
         
     | 
| 
       322 
309 
     | 
    
         | 
| 
       323 
310 
     | 
    
         
             
                    try:
         
     | 
| 
       324 
     | 
    
         
            -
                         
     | 
| 
       325 
     | 
    
         
            -
                        self.last_response =  
     | 
| 
      
 311 
     | 
    
         
            +
                        conn = org_entity.artifact_memberships
         
     | 
| 
      
 312 
     | 
    
         
            +
                        self.last_response = ArtifactMembershipConnection.model_validate(conn)
         
     | 
| 
       326 
313 
     | 
    
         
             
                    except (LookupError, AttributeError, ValidationError) as e:
         
     | 
| 
       327 
314 
     | 
    
         
             
                        raise ValueError("Unexpected response data") from e
         
     | 
| 
       328 
315 
     | 
    
         | 
| 
         @@ -331,23 +318,21 @@ class Versions(Paginator["Artifact"]): 
     | 
|
| 
       331 
318 
     | 
    
         | 
| 
       332 
319 
     | 
    
         
             
                    if self.last_response is None:
         
     | 
| 
       333 
320 
     | 
    
         
             
                        return []
         
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
       335 
     | 
    
         
            -
                    nodes = (e.node for e in self.last_response.edges)
         
     | 
| 
       336 
321 
     | 
    
         
             
                    return [
         
     | 
| 
       337 
     | 
    
         
            -
                        Artifact. 
     | 
| 
       338 
     | 
    
         
            -
                             
     | 
| 
      
 322 
     | 
    
         
            +
                        Artifact._from_membership(
         
     | 
| 
      
 323 
     | 
    
         
            +
                            membership=membership,
         
     | 
| 
      
 324 
     | 
    
         
            +
                            target=FullArtifactPath(
         
     | 
| 
       339 
325 
     | 
    
         
             
                                prefix=project.entity.name,
         
     | 
| 
       340 
326 
     | 
    
         
             
                                project=project.name,
         
     | 
| 
       341 
     | 
    
         
            -
                                name=f"{collection.name}:v{ 
     | 
| 
      
 327 
     | 
    
         
            +
                                name=f"{collection.name}:v{version_idx}",
         
     | 
| 
       342 
328 
     | 
    
         
             
                            ),
         
     | 
| 
       343 
     | 
    
         
            -
                            attrs=artifact,
         
     | 
| 
       344 
329 
     | 
    
         
             
                            client=self.client,
         
     | 
| 
       345 
     | 
    
         
            -
                            aliases=[alias.alias for alias in node.aliases],
         
     | 
| 
       346 
330 
     | 
    
         
             
                        )
         
     | 
| 
       347 
     | 
    
         
            -
                        for  
     | 
| 
      
 331 
     | 
    
         
            +
                        for membership in self.last_response.nodes()
         
     | 
| 
       348 
332 
     | 
    
         
             
                        if (
         
     | 
| 
       349 
     | 
    
         
            -
                            (collection :=  
     | 
| 
      
 333 
     | 
    
         
            +
                            (collection := membership.artifact_collection)
         
     | 
| 
       350 
334 
     | 
    
         
             
                            and (project := collection.project)
         
     | 
| 
       351 
     | 
    
         
            -
                            and  
     | 
| 
      
 335 
     | 
    
         
            +
                            and membership.artifact
         
     | 
| 
      
 336 
     | 
    
         
            +
                            and (version_idx := membership.version_index) is not None
         
     | 
| 
       352 
337 
     | 
    
         
             
                        )
         
     | 
| 
       353 
338 
     | 
    
         
             
                    ]
         
     |