Исходный код amocrm.resources._base

from __future__ import annotations

import builtins
from collections.abc import Iterator
from typing import TYPE_CHECKING, Any, Generic, Protocol, TypeVar

from ..exceptions import AmoCRMError
from ._utils import _build_params, _iter_all_pages

if TYPE_CHECKING:
    from ..client import AmoCRM


class _DTOProtocol(Protocol):
    """Структурный интерфейс DTO-моделей, используемых в BaseResource."""

    id: int | None

    def to_dict(self) -> dict[str, Any]: ...

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Any: ...


_T = TypeVar("_T", bound=_DTOProtocol)


[документация] class BaseResource(Generic[_T]): """Базовый класс ресурсов AmoCRM API. Предоставляет стандартные CRUD-операции: ``list``, ``get``, ``create``, ``update``, ``update_one``. Конкретные ресурсы наследуют этот класс, задавая ``_path``, ``_embedded_key`` и ``_dto_class``. """ _path: str _embedded_key: str _dto_class: type[_T] _max_per_request: int = 50
[документация] def __init__(self, client: AmoCRM, dto_class: type[_T] | None = None) -> None: self._client = client if dto_class is not None: self._dto_class = dto_class
def _parse(self, data: dict[str, Any]) -> _T: return self._dto_class.from_dict(data) # type: ignore[no-any-return] def _parse_list(self, raw: dict[str, Any]) -> builtins.list[_T]: return [ self._parse(d) for d in raw.get("_embedded", {}).get(self._embedded_key, []) ]
[документация] def list( self, *, page: int | None = None, limit: int | None = None, query: str | None = None, filter: dict[str, Any] | None = None, order: dict[str, str] | None = None, with_: builtins.list[str] | None = None, ) -> builtins.list[_T] | Iterator[_T]: """Получить список сущностей с пагинацией и фильтрами. Args: page: Номер страницы (начиная с 1). Если не передан — автоматически обходит все страницы и возвращает ``Iterator[T]``. limit: Количество сущностей на странице (максимум 250). По умолчанию 50 при авто-пагинации. query: Строка полнотекстового поиска. filter: Словарь фильтров ``{"field": "value"}``. order: Словарь сортировки ``{"field": "asc"|"desc"}``. with_: Список дополнительных данных для подгрузки. Returns: Если ``page`` передан — ``list[T]``. Иначе — ``Iterator[T]``. """ params = _build_params( limit=limit, query=query, filter=filter, order=order, with_=with_, ) if page is not None: params["page"] = page raw = self._client._request("GET", self._path, params=params) return self._parse_list(raw) return ( self._parse(d) for d in _iter_all_pages( self._client, self._path, self._embedded_key, params ) )
[документация] def get(self, entity_id: int, *, with_: builtins.list[str] | None = None) -> _T: """Получить сущность по идентификатору. Args: entity_id: Идентификатор сущности. with_: Список дополнительных данных для подгрузки. """ params: dict[str, Any] = {} if with_: params["with"] = ",".join(with_) raw = self._client._request( "GET", f"{self._path}/{entity_id}", params=params, ) return self._parse(raw)
[документация] def create(self, items: builtins.list[_T]) -> builtins.list[_T]: """Создать одну или несколько сущностей. Raises: AmoCRMError: Если передано более ``_max_per_request`` элементов. """ if len(items) > self._max_per_request: raise AmoCRMError( f"create allows at most {self._max_per_request} items per request" ) raw = self._client._request( "POST", self._path, json=[item.to_dict() for item in items], ) return self._parse_list(raw)
[документация] def update(self, items: builtins.list[_T]) -> builtins.list[_T]: """Обновить одну или несколько сущностей (каждая должна содержать ``id``). Raises: AmoCRMError: Если передано более ``_max_per_request`` элементов. """ if len(items) > self._max_per_request: raise AmoCRMError( f"update allows at most {self._max_per_request} items per request" ) raw = self._client._request( "PATCH", self._path, json=[item.to_dict() for item in items], ) return self._parse_list(raw)
[документация] def update_one(self, data: _T) -> _T: """Обновить одну сущность по идентификатору. Raises: AmoCRMError: Если ``data.id`` не задан. """ if data.id is None: raise AmoCRMError( f"{self._dto_class.__name__}.id must be set for update_one" ) raw = self._client._request( "PATCH", f"{self._path}/{data.id}", json=data.to_dict(), ) return self._parse(raw)