from __future__ import annotations from typing import TYPE_CHECKING, Any, Optional from pydantic import Field from typing_extensions import Self from wandb._pydantic import GQLId, field_validator from wandb._strutils import nameof from wandb.apis.public.registries._freezable_list import AddOnlyArtifactTypesList from wandb.apis.public.registries._utils import Visibility from .base_model import ArtifactsBase if TYPE_CHECKING: from wandb.sdk.artifacts._generated import RegistryFragment class RegistryData(ArtifactsBase): """Transport-free model for local `Registry` data. For now, this is separated from the public `Registry` class to more easily ensure continuity in the public `Registry` API. """ id: GQLId = Field(frozen=True) """The unique, encoded ID for this registry.""" created_at: str = Field(frozen=True) """When this registry was created.""" updated_at: Optional[str] = Field(frozen=True) """When this registry was last updated.""" organization: str = Field(frozen=True) """The organization of the registry.""" entity: str = Field(frozen=True) """The organization entity of the registry.""" name: str = Field(min_length=1) # Disallow empty strings """The name of the registry without the `wandb-registry-` project prefix.""" description: Optional[str] = None """The description, if any, of the registry.""" allow_all_artifact_types: bool """Whether all artifact types are allowed in the registry.""" artifact_types: AddOnlyArtifactTypesList = Field( default_factory=AddOnlyArtifactTypesList ) """The artifact types allowed in the registry. The meaning of this list depends on `allow_all_artifact_types`: - If True: `artifact_types` are the previously saved or currently used types in the registry. - If False: `artifact_types` are the only allowed artifact types in the registry. """ visibility: Visibility = Field(alias="access") """The visibility of the registry.""" @property def full_name(self) -> str: """The project name with the expected `wandb-registry-` prefix.""" from wandb.sdk.artifacts._validators import REGISTRY_PREFIX return f"{REGISTRY_PREFIX}{self.name}" @field_validator("artifact_types", mode="plain") def _validate_artifact_types(cls, v: Any) -> AddOnlyArtifactTypesList: """Coerce `artifact_types` to an AddOnlyArtifactTypesList.""" from wandb.sdk.artifacts._generated.fragments import ( RegistryFragmentArtifactTypes, ) if isinstance(v, RegistryFragmentArtifactTypes): # This is a GQL connection object, so we need to extract the node names return AddOnlyArtifactTypesList(e.node.name for e in v.edges if e.node) # By default, assume we were passed an iterable of strings return AddOnlyArtifactTypesList(v) @classmethod def from_fragment(cls, obj: RegistryFragment) -> Self: from wandb.sdk.artifacts._validators import remove_registry_prefix if not obj.entity.organization: raise ValueError( f"Unable to parse registry organization from {nameof(type(obj))!r} object" ) return cls( id=obj.id, created_at=obj.created_at, updated_at=obj.updated_at, organization=obj.entity.organization.name, entity=obj.entity.name, name=remove_registry_prefix(obj.name), description=obj.description, allow_all_artifact_types=obj.allow_all_artifact_types, artifact_types=obj.artifact_types, visibility=obj.access, )