Source code for pinecone.models.admin.api_key

"""API key response models for the Admin API."""

from __future__ import annotations

from collections.abc import Iterator
from enum import Enum
from typing import Any

from msgspec import Struct

from pinecone.models._mixin import StructDictMixin


[docs] class APIKeyRole(str, Enum): """Roles that can be assigned to a Pinecone API key. Possible values: ``PROJECT_EDITOR``, ``PROJECT_VIEWER``, ``CONTROL_PLANE_EDITOR``, ``CONTROL_PLANE_VIEWER``, ``DATA_PLANE_EDITOR``, ``DATA_PLANE_VIEWER``. Examples: >>> from pinecone import Admin >>> from pinecone.models.admin.api_key import APIKeyRole >>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret") >>> result = admin.api_keys.create( ... project_id="proj-abc123", ... name="read-only-key", ... roles=[APIKeyRole.DATA_PLANE_VIEWER], ... ) >>> result.key.roles # doctest: +SKIP [<APIKeyRole.DATA_PLANE_VIEWER: 'DataPlaneViewer'>] Update a key to use control-plane access: >>> key = admin.api_keys.update( ... api_key_id="key-abc123", ... roles=[APIKeyRole.CONTROL_PLANE_EDITOR], ... ) >>> key.role # doctest: +SKIP <APIKeyRole.CONTROL_PLANE_EDITOR: 'ControlPlaneEditor'> """ PROJECT_EDITOR = "ProjectEditor" PROJECT_VIEWER = "ProjectViewer" CONTROL_PLANE_EDITOR = "ControlPlaneEditor" CONTROL_PLANE_VIEWER = "ControlPlaneViewer" DATA_PLANE_EDITOR = "DataPlaneEditor" DATA_PLANE_VIEWER = "DataPlaneViewer"
[docs] class APIKeyModel(StructDictMixin, Struct, kw_only=True): """Response model for a Pinecone API key. Attributes: id (str): Unique identifier for the API key. name (str): Name of the API key. project_id (str): Identifier of the project the key belongs to. roles (list[APIKeyRole]): List of roles assigned to the key (see :class:`APIKeyRole`). description (str | None): Optional description for the API key. ``None`` if no description was set. Examples: >>> from pinecone import Admin >>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret") >>> key = admin.api_keys.describe(api_key_id="key-abc123") >>> key.id 'key-abc123' >>> key.name 'prod-search-key' >>> key.roles [<APIKeyRole.DATA_PLANE_EDITOR: 'DataPlaneEditor'>] >>> key.description 'Used by the search service' """ id: str name: str project_id: str roles: list[APIKeyRole] description: str | None = None @property def role(self) -> APIKeyRole: """Singular alias for ``roles`` when the key has exactly one role. Returns: :class:`APIKeyRole`: The single role assigned to this key. Raises: :exc:`ValueError`: If the key has no roles or more than one role. Examples: >>> key = admin.api_keys.describe(api_key_id="key-abc123") >>> key.role <APIKeyRole.DATA_PLANE_EDITOR: 'DataPlaneEditor'> Keys with multiple roles raise :exc:`ValueError`; use :attr:`roles` instead: .. code-block:: python multi_role_key = APIKeyModel( id="k2", name="k2", project_id="p1", roles=[APIKeyRole.PROJECT_EDITOR, APIKeyRole.DATA_PLANE_EDITOR] ) try: multi_role_key.role except ValueError as exc: print(exc) # API key has 2 roles; use .roles to access all """ if len(self.roles) == 0: raise ValueError("API key has no roles") if len(self.roles) > 1: raise ValueError(f"API key has {len(self.roles)} roles; use .roles to access all") return self.roles[0] def __getitem__(self, key: str) -> Any: """Support bracket access (e.g. api_key['name']).""" if key not in self.__struct_fields__: raise KeyError(key) return getattr(self, key) def __contains__(self, key: object) -> bool: """Support ``in`` operator (e.g. ``'name' in api_key``).""" return key in self.__struct_fields__
[docs] class APIKeyWithSecret(StructDictMixin, Struct, kw_only=True): """Response model for an API key with its secret value. The secret value is only available at creation time. Attributes: key: The API key metadata. value: The secret API key string. """ key: APIKeyModel value: str def __repr__(self) -> str: masked = f"...{self.value[-4:]}" if len(self.value) >= 4 else "***" return f"APIKeyWithSecret(key={self.key!r}, value='{masked}')" def __str__(self) -> str: return repr(self) def __getitem__(self, key: str) -> Any: """Support bracket access (e.g. response['value']).""" if key not in self.__struct_fields__: raise KeyError(key) return getattr(self, key) def __contains__(self, key: object) -> bool: """Support ``in`` operator (e.g. ``'value' in response``).""" return key in self.__struct_fields__
[docs] class APIKeyList: """Wrapper around a list of APIKeyModel with convenience methods."""
[docs] def __init__(self, api_keys: list[APIKeyModel]) -> None: """Initialize an APIKeyList. Args: api_keys: List of :class:`APIKeyModel` instances representing Pinecone API keys. """ self._api_keys = api_keys
def __iter__(self) -> Iterator[APIKeyModel]: return iter(self._api_keys) def __len__(self) -> int: return len(self._api_keys) def __getitem__(self, index: int) -> APIKeyModel: return self._api_keys[index]
[docs] def to_dict(self) -> dict[str, Any]: """Return the list as a serializable dict. Returns: dict[str, Any]: A dict with a ``"data"`` key containing a list of API key dicts, each produced by :meth:`APIKeyModel.to_dict`. Examples: >>> from pinecone import Admin >>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret") >>> keys = admin.api_keys.list(project_id="proj-abc123") >>> keys.to_dict() # doctest: +SKIP {'data': [{'name': 'prod-search-key', ...}, {'name': 'ci-pipeline-key', ...}]} """ return {"data": [k.to_dict() for k in self._api_keys]}
[docs] def names(self) -> list[str]: """Return a list of API key names. Returns: list[str]: API key names in the same order as the list. Examples: >>> from pinecone import Admin >>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret") >>> keys = admin.api_keys.list(project_id="proj-abc123") >>> keys.names() # doctest: +SKIP ['prod-search-key', 'ci-pipeline-key'] """ return [api_key.name for api_key in self._api_keys]
def __repr__(self) -> str: summaries = ", ".join( f"<name={k.name!r}, project_id={k.project_id!r}>" for k in self._api_keys ) return f"APIKeyList([{summaries}])"