"""Wrappers for the backup, restore-job, and backup-schedule listing responses."""
from __future__ import annotations
from collections.abc import Iterator
from typing import TYPE_CHECKING, Any
from pinecone.models.backups.model import BackupModel, RestoreJobModel
from pinecone.models.backups.schedules import BackupScheduleHistoryItem, BackupScheduleModel
if TYPE_CHECKING:
from pinecone.models.vectors.responses import Pagination
[docs]
class BackupList:
"""One page of backups, plus the token for the next page.
Returned by :meth:`~pinecone.client.backups.Backups.list`; not constructed
directly. Iteration, ``len()`` and index access all read the page in hand
only; :meth:`~pinecone.client.indexes.Indexes.list_backups` is the shape
that walks every page for you.
"""
[docs]
def __init__(
self,
backups: list[BackupModel],
*,
pagination: Pagination | None = None,
) -> None:
"""Initialize a BackupList.
Args:
backups: List of :class:`BackupModel` instances representing
index backups.
pagination: Optional :class:`Pagination` token for fetching
additional pages of results.
"""
self._backups = backups
self.pagination = pagination
@property
def data(self) -> list[BackupModel]:
"""Return the list of backups."""
return self._backups
def __getattr__(self, name: str) -> object:
"""Raise AttributeError for unknown attributes (legacy dict-style delegation)."""
raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")
def __iter__(self) -> Iterator[BackupModel]:
return iter(self._backups)
def __len__(self) -> int:
return len(self._backups)
def __getitem__(self, index: int) -> BackupModel:
return self._backups[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
backup dicts, each produced by :meth:`BackupModel.to_dict`. When the
wrapper has a pagination token, the dict also includes a
``"pagination"`` key with the token for fetching the next page.
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> backups = pc.backups.list(index_name="product-search")
>>> [b["backup_id"] for b in backups.to_dict()["data"]]
['bk-abc123']
>>> "pagination" in backups.to_dict()
False
"""
result: dict[str, Any] = {"data": [b.to_dict() for b in self._backups]}
if self.pagination is not None:
result["pagination"] = self.pagination.to_dict()
return result
[docs]
def names(self) -> list[str]:
"""Return a list of backup names, falling back to backup_id.
If a backup has no ``name`` set, its ``backup_id`` is used instead.
Returns:
list[str]: Backup names (or IDs when names are absent).
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> backups = pc.backups.list(index_name="product-search")
>>> backups.names()
['daily-20240115']
"""
return [b.name or b.backup_id for b in self._backups]
def __repr__(self) -> str:
summaries = ", ".join(
f"<name={(b.name or b.backup_id)!r}, status={b.status!r}, "
f"source={b.source_index_name!r}>"
for b in self._backups
)
return f"BackupList([{summaries}])"
[docs]
class RestoreJobList:
"""One page of restore jobs, plus the token for the next page.
Returned by :meth:`~pinecone.client.restore_jobs.RestoreJobs.list`; not
constructed directly. Iteration, ``len()`` and index access all read the
page in hand only, and the listing itself is best-effort; see that
method's warning before treating it as an inventory.
"""
[docs]
def __init__(
self,
restore_jobs: list[RestoreJobModel],
*,
pagination: Pagination | None = None,
) -> None:
"""Initialize a RestoreJobList.
Args:
restore_jobs: List of :class:`RestoreJobModel` instances
representing restore operations.
pagination: Optional :class:`Pagination` token for fetching
additional pages of results.
"""
self._restore_jobs = restore_jobs
self.pagination = pagination
@property
def data(self) -> list[RestoreJobModel]:
"""Return the list of restore jobs."""
return self._restore_jobs
def __getattr__(self, name: str) -> object:
"""Raise AttributeError for unknown attributes (legacy dict-style delegation)."""
raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")
def __iter__(self) -> Iterator[RestoreJobModel]:
return iter(self._restore_jobs)
def __len__(self) -> int:
return len(self._restore_jobs)
def __getitem__(self, index: int) -> RestoreJobModel:
return self._restore_jobs[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
restore job dicts, each produced by :meth:`RestoreJobModel.to_dict`.
When the wrapper has a pagination token, the dict also includes a
``"pagination"`` key with the token for fetching the next page.
Examples:
.. code-block:: python
from pinecone import Pinecone
pc = Pinecone(api_key="your-api-key")
jobs = pc.restore_jobs.list()
print([r["restore_job_id"] for r in jobs.to_dict()["data"]])
"""
result: dict[str, Any] = {"data": [r.to_dict() for r in self._restore_jobs]}
if self.pagination is not None:
result["pagination"] = self.pagination.to_dict()
return result
def __repr__(self) -> str:
summaries = ", ".join(
f"<id={r.restore_job_id!r}, status={r.status!r}, target={r.target_index_name!r}>"
for r in self._restore_jobs
)
return f"RestoreJobList([{summaries}])"
[docs]
class BackupScheduleList:
"""One page of an index's backup schedules, plus its next-page token.
Returned by
:meth:`~pinecone.client.backup_schedules.BackupSchedules.list`; not
constructed directly. Iteration, ``len()``, :meth:`names` and
:meth:`enabled_schedules` all read the page in hand only;
:meth:`~pinecone.client.backup_schedules.BackupSchedules.iter_schedules`
walks every page instead.
"""
[docs]
def __init__(
self,
schedules: list[BackupScheduleModel],
*,
pagination: Pagination | None = None,
) -> None:
"""Initialize a BackupScheduleList.
Args:
schedules: List of :class:`BackupScheduleModel` instances
representing the backup schedules on an index.
pagination: Optional :class:`Pagination` token for fetching
additional pages of results.
"""
self._schedules = schedules
self.pagination = pagination
@property
def data(self) -> list[BackupScheduleModel]:
"""Return the list of backup schedules."""
return self._schedules
def __getattr__(self, name: str) -> object:
"""Raise AttributeError for attributes this wrapper does not define."""
raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")
def __iter__(self) -> Iterator[BackupScheduleModel]:
return iter(self._schedules)
def __len__(self) -> int:
return len(self._schedules)
def __getitem__(self, index: int) -> BackupScheduleModel:
return self._schedules[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 schedule dicts, each produced by
:meth:`BackupScheduleModel.to_dict`. When the wrapper has a
pagination token, the dict also includes a ``"pagination"``
key with the token for fetching the next page.
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedules = pc.backup_schedules.list(index_name="product-search")
>>> schedules.to_dict()["data"][0]["frequency"]
'daily'
"""
result: dict[str, Any] = {"data": [s.to_dict() for s in self._schedules]}
if self.pagination is not None:
result["pagination"] = self.pagination.to_dict()
return result
[docs]
def names(self) -> list[str]:
"""Return the schedule names.
Returns:
list[str]: Schedule names, in the order the API returned them.
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> pc.backup_schedules.list(index_name="product-search").names()
['compliance-snapshots']
"""
return [s.name for s in self._schedules]
[docs]
def enabled_schedules(self) -> list[BackupScheduleModel]:
"""Return only the enabled schedules on this page.
At most one schedule per index can be enabled, so this answers "which
schedule is running", as long as the listing fits one page.
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedules = pc.backup_schedules.list(index_name="product-search")
>>> [s.name for s in schedules.enabled_schedules()]
['compliance-snapshots']
"""
return [s for s in self._schedules if s.enabled]
def __repr__(self) -> str:
summaries = ", ".join(
f"<name={s.name!r}, frequency={s.frequency!r}, enabled={s.enabled!r}>"
for s in self._schedules
)
return f"BackupScheduleList([{summaries}])"
[docs]
class BackupScheduleHistoryList:
"""One page of the backups a schedule has produced, plus its next-page token.
Returned by
:meth:`~pinecone.client.backup_schedules.BackupSchedules.history`; not
constructed directly. Iteration, ``len()`` and :meth:`scheduled` all read
the page in hand only;
:meth:`~pinecone.client.backup_schedules.BackupSchedules.iter_history`
walks every page instead.
"""
[docs]
def __init__(
self,
items: list[BackupScheduleHistoryItem],
*,
pagination: Pagination | None = None,
) -> None:
"""Initialize a BackupScheduleHistoryList.
Args:
items: List of :class:`BackupScheduleHistoryItem` instances
representing backups produced by one schedule.
pagination: Optional :class:`Pagination` token for fetching
additional pages of results.
"""
self._items = items
self.pagination = pagination
@property
def data(self) -> list[BackupScheduleHistoryItem]:
"""Return the list of history rows."""
return self._items
def __getattr__(self, name: str) -> object:
"""Raise AttributeError for attributes this wrapper does not define."""
raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")
def __iter__(self) -> Iterator[BackupScheduleHistoryItem]:
return iter(self._items)
def __len__(self) -> int:
return len(self._items)
def __getitem__(self, index: int) -> BackupScheduleHistoryItem:
return self._items[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 history-row dicts, each produced by
:meth:`BackupScheduleHistoryItem.to_dict`. When the wrapper has
a pagination token, the dict also includes a ``"pagination"``
key with the token for fetching the next page.
Examples:
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> runs = pc.backup_schedules.history(
... schedule_id="e88f7273-42aa-47e9-af73-593827136867"
... )
>>> runs.to_dict()["data"][0]["name"]
'compliance-snapshots-20260403T060000Z'
"""
result: dict[str, Any] = {"data": [item.to_dict() for item in self._items]}
if self.pagination is not None:
result["pagination"] = self.pagination.to_dict()
return result
[docs]
def scheduled(self) -> list[BackupScheduleHistoryItem]:
"""Return the rows on this page whose status is ``"Scheduled"``.
The 2026-07 API reports a planned run as ``"Initializing"``, so this
returns an empty list for its responses. To find finished backups,
filter on ``status == "Ready"``.
"""
return [item for item in self._items if item.is_scheduled]
def __repr__(self) -> str:
summaries = ", ".join(
f"<backup_id={item.backup_id!r}, status={item.status!r}, name={item.name!r}>"
for item in self._items
)
return f"BackupScheduleHistoryList([{summaries}])"