diff --git a/mpt_api_client/http/async_service.py b/mpt_api_client/http/async_service.py index 77d4cd1e..5749b81e 100644 --- a/mpt_api_client/http/async_service.py +++ b/mpt_api_client/http/async_service.py @@ -1,11 +1,10 @@ -from collections.abc import AsyncIterator from urllib.parse import urljoin from mpt_api_client.http.async_client import AsyncHTTPClient from mpt_api_client.http.base_service import ServiceBase from mpt_api_client.http.types import QueryParam, Response -from mpt_api_client.models import Collection, ResourceData from mpt_api_client.models import Model as BaseModel +from mpt_api_client.models import ResourceData from mpt_api_client.models.collection import ResourceList @@ -21,72 +20,6 @@ class AsyncService[Model: BaseModel](ServiceBase[AsyncHTTPClient, Model]): # no """ - async def fetch_page(self, limit: int = 100, offset: int = 0) -> Collection[Model]: - """Fetch one page of resources. - - Returns: - Collection of resources. - """ - response = await self._fetch_page_as_response(limit=limit, offset=offset) - return self._create_collection(response) - - async def fetch_one(self) -> Model: - """Fetch one resource, expect exactly one result. - - Returns: - One resource. - - Raises: - ValueError: If the total matching records are not exactly one. - """ - response = await self._fetch_page_as_response(limit=1, offset=0) - resource_list = self._create_collection(response) - total_records = len(resource_list) - if resource_list.meta: - total_records = resource_list.meta.pagination.total - if total_records == 0: - raise ValueError("Expected one result, but got zero results") - if total_records > 1: - raise ValueError(f"Expected one result, but got {total_records} results") - - return resource_list[0] - - async def iterate(self, batch_size: int = 100) -> AsyncIterator[Model]: - """Iterate over all resources, yielding GenericResource objects. - - Args: - batch_size: Number of resources to fetch per request - - Returns: - Iterator of resources. - """ - offset = 0 - limit = batch_size # Default page size - - while True: - response = await self._fetch_page_as_response(limit=limit, offset=offset) - items_collection = self._create_collection(response) - for resource in items_collection: - yield resource - - if not items_collection.meta: - break - if not items_collection.meta.pagination.has_next(): - break - offset = items_collection.meta.pagination.next_offset() - - async def _fetch_page_as_response(self, limit: int = 100, offset: int = 0) -> Response: - """Fetch one page of resources. - - Returns: - Response object. - - Raises: - HTTPStatusError: if the response status code is not 200. - """ - pagination_params: dict[str, int] = {"limit": limit, "offset": offset} - return await self.http_client.request("get", self.build_path(pagination_params)) - async def _resource_do_request( # noqa: WPS211 self, resource_id: str, diff --git a/mpt_api_client/http/base_service.py b/mpt_api_client/http/base_service.py index 8d456175..b1d55563 100644 --- a/mpt_api_client/http/base_service.py +++ b/mpt_api_client/http/base_service.py @@ -1,13 +1,12 @@ from typing import Any -from mpt_api_client.http.mixins import QueryableMixin from mpt_api_client.http.query_state import QueryState from mpt_api_client.http.types import Response from mpt_api_client.models import Collection, Meta from mpt_api_client.models import Model as BaseModel -class ServiceBase[Client, Model: BaseModel](QueryableMixin): # noqa: WPS214 +class ServiceBase[Client, Model: BaseModel]: # noqa: WPS214 """Service base with agnostic HTTP client.""" _endpoint: str @@ -43,7 +42,12 @@ def build_path( return f"{self.path}?{query}" if query else self.path @classmethod - def _create_collection(cls, response: Response) -> Collection[Model]: + def make_collection(cls, response: Response) -> Collection[Model]: + """Builds a collection from a response. + + Args: + response: The response object. + """ meta = Meta.from_response(response) return Collection( resources=[ diff --git a/mpt_api_client/http/mixins.py b/mpt_api_client/http/mixins.py index 75aaaf25..fb09a6be 100644 --- a/mpt_api_client/http/mixins.py +++ b/mpt_api_client/http/mixins.py @@ -1,10 +1,12 @@ import json +from collections.abc import AsyncIterator, Iterator from typing import Self from urllib.parse import urljoin from mpt_api_client.http.query_state import QueryState from mpt_api_client.http.types import FileTypes, Response -from mpt_api_client.models import FileModel, ResourceData +from mpt_api_client.models import Collection, FileModel, ResourceData +from mpt_api_client.models import Model as BaseModel from mpt_api_client.rql import RQLQuery @@ -301,3 +303,162 @@ def _create_new_instance( query_state=query_state, endpoint_params=self.endpoint_params, # type: ignore[attr-defined] ) + + +class CollectionMixin[Model: BaseModel](QueryableMixin): + """Mixin providing collection functionality.""" + + def fetch_page(self, limit: int = 100, offset: int = 0) -> Collection[Model]: + """Fetch one page of resources. + + Returns: + Collection of resources. + """ + response = self._fetch_page_as_response(limit=limit, offset=offset) + return self.make_collection(response) # type: ignore[attr-defined, no-any-return] + + def fetch_one(self) -> Model: + """Fetch one resource, expect exactly one result. + + Returns: + One resource. + + Raises: + ValueError: If the total matching records are not exactly one. + """ + response = self._fetch_page_as_response(limit=1, offset=0) + resource_list = self.make_collection(response) # type: ignore[attr-defined] + total_records = len(resource_list) + if resource_list.meta: + total_records = resource_list.meta.pagination.total + if total_records == 0: + raise ValueError("Expected one result, but got zero results") + if total_records > 1: + raise ValueError(f"Expected one result, but got {total_records} results") + + return resource_list[0] # type: ignore[no-any-return] + + def iterate(self, batch_size: int = 100) -> Iterator[Model]: + """Iterate over all resources, yielding GenericResource objects. + + Args: + batch_size: Number of resources to fetch per request + + Returns: + Iterator of resources. + """ + offset = 0 + limit = batch_size # Default page size + + while True: + response = self._fetch_page_as_response(limit=limit, offset=offset) + items_collection = self.make_collection(response) # type: ignore[attr-defined] + yield from items_collection + + if not items_collection.meta: + break + if not items_collection.meta.pagination.has_next(): + break + offset = items_collection.meta.pagination.next_offset() + + def _fetch_page_as_response(self, limit: int = 100, offset: int = 0) -> Response: + """Fetch one page of resources. + + Returns: + Response object. + + Raises: + HTTPStatusError: if the response status code is not 200. + """ + pagination_params: dict[str, int] = {"limit": limit, "offset": offset} + return self.http_client.request("get", self.build_path(pagination_params)) # type: ignore[attr-defined, no-any-return] + + +class AsyncCollectionMixin[Model: BaseModel](QueryableMixin): + """Async mixin providing collection functionality.""" + + async def fetch_page(self, limit: int = 100, offset: int = 0) -> Collection[Model]: + """Fetch one page of resources. + + Returns: + Collection of resources. + """ + response = await self._fetch_page_as_response(limit=limit, offset=offset) + return self.make_collection(response) # type: ignore[no-any-return,attr-defined] + + async def fetch_one(self) -> Model: + """Fetch one resource, expect exactly one result. + + Returns: + One resource. + + Raises: + ValueError: If the total matching records are not exactly one. + """ + response = await self._fetch_page_as_response(limit=1, offset=0) + resource_list = self.make_collection(response) # type: ignore[attr-defined] + total_records = len(resource_list) + if resource_list.meta: + total_records = resource_list.meta.pagination.total + if total_records == 0: + raise ValueError("Expected one result, but got zero results") + if total_records > 1: + raise ValueError(f"Expected one result, but got {total_records} results") + + return resource_list[0] # type: ignore[no-any-return] + + async def iterate(self, batch_size: int = 100) -> AsyncIterator[Model]: + """Iterate over all resources, yielding GenericResource objects. + + Args: + batch_size: Number of resources to fetch per request + + Returns: + Iterator of resources. + """ + offset = 0 + limit = batch_size # Default page size + + while True: + response = await self._fetch_page_as_response(limit=limit, offset=offset) + items_collection = self.make_collection(response) # type: ignore[attr-defined] + for resource in items_collection: + yield resource + + if not items_collection.meta: + break + if not items_collection.meta.pagination.has_next(): + break + offset = items_collection.meta.pagination.next_offset() + + async def _fetch_page_as_response(self, limit: int = 100, offset: int = 0) -> Response: + """Fetch one page of resources. + + Returns: + Response object. + + Raises: + HTTPStatusError: if the response status code is not 200. + """ + pagination_params: dict[str, int] = {"limit": limit, "offset": offset} + return await self.http_client.request("get", self.build_path(pagination_params)) # type: ignore[attr-defined,no-any-return] + + +class ModifiableResourceMixin[Model](GetMixin[Model], UpdateMixin[Model], DeleteMixin): + """Editable resource mixin allows to read and update a resource resources.""" + + +class AsyncModifiableResourceMixin[Model]( + AsyncGetMixin[Model], AsyncUpdateMixin[Model], AsyncDeleteMixin +): + """Editable resource mixin allows to read and update a resource resources.""" + + +class ManagedResourceMixin[Model](CreateMixin[Model], ModifiableResourceMixin[Model]): + """Managed resource mixin allows to read, create, update and delete a resource resources.""" + + +class AsyncManagedResourceMixin[Model]( + AsyncCreateMixin[Model], AsyncModifiableResourceMixin[Model] +): + """Managed resource mixin allows to read, create, update and delete a resource resources.""" diff --git a/mpt_api_client/http/service.py b/mpt_api_client/http/service.py index 999edc93..00162823 100644 --- a/mpt_api_client/http/service.py +++ b/mpt_api_client/http/service.py @@ -1,11 +1,10 @@ -from collections.abc import Iterator from urllib.parse import urljoin from mpt_api_client.http.base_service import ServiceBase from mpt_api_client.http.client import HTTPClient from mpt_api_client.http.types import QueryParam, Response -from mpt_api_client.models import Collection, ResourceData from mpt_api_client.models import Model as BaseModel +from mpt_api_client.models import ResourceData from mpt_api_client.models.collection import ResourceList @@ -21,71 +20,6 @@ class Service[Model: BaseModel](ServiceBase[HTTPClient, Model]): # noqa: WPS214 """ - def fetch_page(self, limit: int = 100, offset: int = 0) -> Collection[Model]: - """Fetch one page of resources. - - Returns: - Collection of resources. - """ - response = self._fetch_page_as_response(limit=limit, offset=offset) - return self._create_collection(response) - - def fetch_one(self) -> Model: - """Fetch one resource, expect exactly one result. - - Returns: - One resource. - - Raises: - ValueError: If the total matching records are not exactly one. - """ - response = self._fetch_page_as_response(limit=1, offset=0) - resource_list = self._create_collection(response) - total_records = len(resource_list) - if resource_list.meta: - total_records = resource_list.meta.pagination.total - if total_records == 0: - raise ValueError("Expected one result, but got zero results") - if total_records > 1: - raise ValueError(f"Expected one result, but got {total_records} results") - - return resource_list[0] - - def iterate(self, batch_size: int = 100) -> Iterator[Model]: - """Iterate over all resources, yielding GenericResource objects. - - Args: - batch_size: Number of resources to fetch per request - - Returns: - Iterator of resources. - """ - offset = 0 - limit = batch_size # Default page size - - while True: - response = self._fetch_page_as_response(limit=limit, offset=offset) - items_collection = self._create_collection(response) - yield from items_collection - - if not items_collection.meta: - break - if not items_collection.meta.pagination.has_next(): - break - offset = items_collection.meta.pagination.next_offset() - - def _fetch_page_as_response(self, limit: int = 100, offset: int = 0) -> Response: - """Fetch one page of resources. - - Returns: - Response object. - - Raises: - HTTPStatusError: if the response status code is not 200. - """ - pagination_params: dict[str, int] = {"limit": limit, "offset": offset} - return self.http_client.request("get", self.build_path(pagination_params)) - def _resource_do_request( # noqa: WPS211 self, resource_id: str, diff --git a/mpt_api_client/resources/accounts/account.py b/mpt_api_client/resources/accounts/account.py index 83c74a70..f0aff6c1 100644 --- a/mpt_api_client/resources/accounts/account.py +++ b/mpt_api_client/resources/accounts/account.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, CreateMixin, GetMixin, UpdateMixin, @@ -41,6 +43,7 @@ class AccountsService( EnablableMixin[Account], ValidateMixin[Account], GetMixin[Account], + CollectionMixin[Account], Service[Account], AccountsServiceConfig, ): @@ -60,6 +63,7 @@ class AsyncAccountsService( AsyncEnablableMixin[Account], AsyncValidateMixin[Account], AsyncGetMixin[Account], + AsyncCollectionMixin[Account], AsyncService[Account], AccountsServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/account_user_groups.py b/mpt_api_client/resources/accounts/account_user_groups.py index 1d43005a..d1980489 100644 --- a/mpt_api_client/resources/accounts/account_user_groups.py +++ b/mpt_api_client/resources/accounts/account_user_groups.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class AccountUserGroupsServiceConfig: class AccountUserGroupsService( - CreateMixin[AccountUserGroup], - DeleteMixin, - UpdateMixin[AccountUserGroup], - GetMixin[AccountUserGroup], + ManagedResourceMixin[AccountUserGroup], + CollectionMixin[AccountUserGroup], Service[AccountUserGroup], AccountUserGroupsServiceConfig, ): @@ -36,10 +30,8 @@ class AccountUserGroupsService( class AsyncAccountUserGroupsService( - AsyncCreateMixin[AccountUserGroup], - AsyncDeleteMixin, - AsyncUpdateMixin[AccountUserGroup], - AsyncGetMixin[AccountUserGroup], + AsyncManagedResourceMixin[AccountUserGroup], + AsyncCollectionMixin[AccountUserGroup], AsyncService[AccountUserGroup], AccountUserGroupsServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/account_users.py b/mpt_api_client/resources/accounts/account_users.py index 5791dcb7..fa9f88d6 100644 --- a/mpt_api_client/resources/accounts/account_users.py +++ b/mpt_api_client/resources/accounts/account_users.py @@ -1,7 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, + CollectionMixin, CreateMixin, GetMixin, ) @@ -32,6 +34,7 @@ class AccountUsersService( CreateMixin[AccountUser], InvitableMixin[AccountUser], GetMixin[AccountUser], + CollectionMixin[AccountUser], Service[AccountUser], AccountUsersServiceConfig, ): @@ -49,6 +52,7 @@ class AsyncAccountUsersService( AsyncCreateMixin[AccountUser], AsyncInvitableMixin[AccountUser], AsyncGetMixin[AccountUser], + AsyncCollectionMixin[AccountUser], AsyncService[AccountUser], AccountUsersServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/accounts_user_groups.py b/mpt_api_client/resources/accounts/accounts_user_groups.py index 99544435..2b17c6c2 100644 --- a/mpt_api_client/resources/accounts/accounts_user_groups.py +++ b/mpt_api_client/resources/accounts/accounts_user_groups.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class AccountsUserGroupsServiceConfig: class AccountsUserGroupsService( - UpdateMixin[AccountsUserGroup], - DeleteMixin, - GetMixin[AccountsUserGroup], - CreateMixin[AccountsUserGroup], + ManagedResourceMixin[AccountsUserGroup], + CollectionMixin[AccountsUserGroup], Service[AccountsUserGroup], AccountsUserGroupsServiceConfig, ): @@ -36,10 +30,8 @@ class AccountsUserGroupsService( class AsyncAccountsUserGroupsService( - AsyncUpdateMixin[AccountsUserGroup], - AsyncDeleteMixin, - AsyncGetMixin[AccountsUserGroup], - AsyncCreateMixin[AccountsUserGroup], + AsyncManagedResourceMixin[AccountsUserGroup], + AsyncCollectionMixin[AccountsUserGroup], AsyncService[AccountsUserGroup], AccountsUserGroupsServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/accounts_users.py b/mpt_api_client/resources/accounts/accounts_users.py index d950cc9a..8f5f3bc4 100644 --- a/mpt_api_client/resources/accounts/accounts_users.py +++ b/mpt_api_client/resources/accounts/accounts_users.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.accounts.accounts_user_groups import ( @@ -33,11 +29,9 @@ class AccountsUsersServiceConfig: class AccountsUsersService( - UpdateMixin[AccountsUser], - DeleteMixin, - CreateMixin[AccountsUser], + ManagedResourceMixin[AccountsUser], InvitableMixin[AccountsUser], - GetMixin[AccountsUser], + CollectionMixin[AccountsUser], Service[AccountsUser], AccountsUsersServiceConfig, ): @@ -55,11 +49,9 @@ def groups(self, user_id: str) -> AccountsUserGroupsService: class AsyncAccountsUsersService( - AsyncUpdateMixin[AccountsUser], - AsyncDeleteMixin, - AsyncCreateMixin[AccountsUser], + AsyncManagedResourceMixin[AccountsUser], AsyncInvitableMixin[AccountsUser], - AsyncGetMixin[AccountsUser], + AsyncCollectionMixin[AccountsUser], AsyncService[AccountsUser], AccountsUsersServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/api_tokens.py b/mpt_api_client/resources/accounts/api_tokens.py index 3234ba10..efceeb67 100644 --- a/mpt_api_client/resources/accounts/api_tokens.py +++ b/mpt_api_client/resources/accounts/api_tokens.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.accounts.mixins import AsyncEnablableMixin, EnablableMixin @@ -26,11 +22,9 @@ class ApiTokensServiceConfig: class ApiTokensService( - CreateMixin[ApiToken], - DeleteMixin, - UpdateMixin[ApiToken], + ManagedResourceMixin[ApiToken], EnablableMixin[ApiToken], - GetMixin[ApiToken], + CollectionMixin[ApiToken], Service[ApiToken], ApiTokensServiceConfig, ): @@ -38,11 +32,9 @@ class ApiTokensService( class AsyncApiTokensService( - AsyncCreateMixin[ApiToken], - AsyncDeleteMixin, - AsyncUpdateMixin[ApiToken], + AsyncManagedResourceMixin[ApiToken], AsyncEnablableMixin[ApiToken], - AsyncGetMixin[ApiToken], + AsyncCollectionMixin[ApiToken], AsyncService[ApiToken], ApiTokensServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/buyers.py b/mpt_api_client/resources/accounts/buyers.py index 088212d9..0e40c142 100644 --- a/mpt_api_client/resources/accounts/buyers.py +++ b/mpt_api_client/resources/accounts/buyers.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.models.model import ResourceData @@ -34,13 +30,11 @@ class BuyersServiceConfig: class BuyersService( - CreateMixin[Buyer], - DeleteMixin, - UpdateMixin[Buyer], ActivatableMixin[Buyer], EnablableMixin[Buyer], ValidateMixin[Buyer], - GetMixin[Buyer], + ManagedResourceMixin[Buyer], + CollectionMixin[Buyer], Service[Buyer], BuyersServiceConfig, ): @@ -66,13 +60,11 @@ def transfer(self, resource_id: str, resource_data: ResourceData | None = None) class AsyncBuyersService( - AsyncCreateMixin[Buyer], - AsyncDeleteMixin, - AsyncUpdateMixin[Buyer], AsyncActivatableMixin[Buyer], AsyncEnablableMixin[Buyer], AsyncValidateMixin[Buyer], - AsyncGetMixin[Buyer], + AsyncManagedResourceMixin[Buyer], + AsyncCollectionMixin[Buyer], AsyncService[Buyer], BuyersServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/cloud_tenants.py b/mpt_api_client/resources/accounts/cloud_tenants.py index efb096b9..6850ed3a 100644 --- a/mpt_api_client/resources/accounts/cloud_tenants.py +++ b/mpt_api_client/resources/accounts/cloud_tenants.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class CloudTenantsServiceConfig: class CloudTenantsService( - CreateMixin[CloudTenant], - DeleteMixin, - UpdateMixin[CloudTenant], - GetMixin[CloudTenant], + ManagedResourceMixin[CloudTenant], + CollectionMixin[CloudTenant], Service[CloudTenant], CloudTenantsServiceConfig, ): @@ -36,10 +30,8 @@ class CloudTenantsService( class AsyncCloudTenantsService( - AsyncCreateMixin[CloudTenant], - AsyncDeleteMixin, - AsyncUpdateMixin[CloudTenant], - AsyncGetMixin[CloudTenant], + AsyncManagedResourceMixin[CloudTenant], + AsyncCollectionMixin[CloudTenant], AsyncService[CloudTenant], CloudTenantsServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/erp_links.py b/mpt_api_client/resources/accounts/erp_links.py index afb4c59d..5da21dc7 100644 --- a/mpt_api_client/resources/accounts/erp_links.py +++ b/mpt_api_client/resources/accounts/erp_links.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, CreateMixin, GetMixin, UpdateMixin, @@ -28,6 +30,7 @@ class ErpLinksService( UpdateMixin[ErpLink], BlockableMixin[ErpLink], GetMixin[ErpLink], + CollectionMixin[ErpLink], Service[ErpLink], ErpLinksServiceConfig, ): @@ -39,6 +42,7 @@ class AsyncErpLinksService( AsyncUpdateMixin[ErpLink], AsyncBlockableMixin[ErpLink], AsyncGetMixin[ErpLink], + AsyncCollectionMixin[ErpLink], AsyncService[ErpLink], ErpLinksServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/licensees.py b/mpt_api_client/resources/accounts/licensees.py index e29c3ef7..cabecde8 100644 --- a/mpt_api_client/resources/accounts/licensees.py +++ b/mpt_api_client/resources/accounts/licensees.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.accounts.mixins import AsyncEnablableMixin, EnablableMixin @@ -26,11 +22,9 @@ class LicenseesServiceConfig: class LicenseesService( - CreateMixin[Licensee], - DeleteMixin, - UpdateMixin[Licensee], EnablableMixin[Licensee], - GetMixin[Licensee], + ManagedResourceMixin[Licensee], + CollectionMixin[Licensee], Service[Licensee], LicenseesServiceConfig, ): @@ -38,11 +32,9 @@ class LicenseesService( class AsyncLicenseesService( - AsyncCreateMixin[Licensee], - AsyncDeleteMixin, - AsyncUpdateMixin[Licensee], AsyncEnablableMixin[Licensee], - AsyncGetMixin[Licensee], + AsyncManagedResourceMixin[Licensee], + AsyncCollectionMixin[Licensee], AsyncService[Licensee], LicenseesServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/modules.py b/mpt_api_client/resources/accounts/modules.py index f78daa45..5c761415 100644 --- a/mpt_api_client/resources/accounts/modules.py +++ b/mpt_api_client/resources/accounts/modules.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -15,9 +20,13 @@ class ModulesServiceConfig: _collection_key = "data" -class ModulesService(GetMixin[Module], Service[Module], ModulesServiceConfig): +class ModulesService( + GetMixin[Module], CollectionMixin[Module], Service[Module], ModulesServiceConfig +): """Modules Service.""" -class AsyncModulesService(AsyncGetMixin[Module], AsyncService[Module], ModulesServiceConfig): +class AsyncModulesService( + AsyncGetMixin[Module], AsyncCollectionMixin[Model], AsyncService[Module], ModulesServiceConfig +): """Asynchronous Modules Service.""" diff --git a/mpt_api_client/resources/accounts/sellers.py b/mpt_api_client/resources/accounts/sellers.py index 57b4d31f..7677bff3 100644 --- a/mpt_api_client/resources/accounts/sellers.py +++ b/mpt_api_client/resources/accounts/sellers.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.models.model import ResourceData @@ -27,11 +23,9 @@ class SellersServiceConfig: class SellersService( - CreateMixin[Seller], - DeleteMixin, - GetMixin[Seller], - UpdateMixin[Seller], ActivatableMixin[Seller], + ManagedResourceMixin[Seller], + CollectionMixin[Seller], Service[Seller], SellersServiceConfig, ): @@ -48,11 +42,9 @@ def disable(self, resource_id: str, resource_data: ResourceData | None = None) - class AsyncSellersService( - AsyncCreateMixin[Seller], - AsyncDeleteMixin, - AsyncGetMixin[Seller], - AsyncUpdateMixin[Seller], AsyncActivatableMixin[Seller], + AsyncManagedResourceMixin[Seller], + AsyncCollectionMixin[Seller], AsyncService[Seller], SellersServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/user_groups.py b/mpt_api_client/resources/accounts/user_groups.py index e7ee7f82..c34d9cbe 100644 --- a/mpt_api_client/resources/accounts/user_groups.py +++ b/mpt_api_client/resources/accounts/user_groups.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class UserGroupsServiceConfig: class UserGroupsService( - CreateMixin[UserGroup], - UpdateMixin[UserGroup], - DeleteMixin, - GetMixin[UserGroup], + ManagedResourceMixin[UserGroup], + CollectionMixin[UserGroup], Service[UserGroup], UserGroupsServiceConfig, ): @@ -36,10 +30,8 @@ class UserGroupsService( class AsyncUserGroupsService( - AsyncCreateMixin[UserGroup], - AsyncUpdateMixin[UserGroup], - AsyncDeleteMixin, - AsyncGetMixin[UserGroup], + AsyncManagedResourceMixin[UserGroup], + AsyncCollectionMixin[UserGroup], AsyncService[UserGroup], UserGroupsServiceConfig, ): diff --git a/mpt_api_client/resources/accounts/users.py b/mpt_api_client/resources/accounts/users.py index eef09226..fd1c6753 100644 --- a/mpt_api_client/resources/accounts/users.py +++ b/mpt_api_client/resources/accounts/users.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncDeleteMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, DeleteMixin, GetMixin, UpdateMixin, @@ -32,6 +34,7 @@ class UsersService( DeleteMixin, BlockableMixin[User], GetMixin[User], + CollectionMixin[User], Service[User], UsersServiceConfig, ): @@ -72,6 +75,7 @@ class AsyncUsersService( AsyncDeleteMixin, AsyncBlockableMixin[User], AsyncGetMixin[User], + AsyncCollectionMixin[User], AsyncService[User], UsersServiceConfig, ): diff --git a/mpt_api_client/resources/audit/event_types.py b/mpt_api_client/resources/audit/event_types.py index 955f41d4..677b9c12 100644 --- a/mpt_api_client/resources/audit/event_types.py +++ b/mpt_api_client/resources/audit/event_types.py @@ -1,7 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, GetMixin, UpdateMixin, ) @@ -21,7 +23,11 @@ class EventTypesServiceConfig: class EventTypesService( - UpdateMixin[EventType], GetMixin[EventType], Service[EventType], EventTypesServiceConfig + UpdateMixin[EventType], + GetMixin[EventType], + CollectionMixin[EventType], + Service[EventType], + EventTypesServiceConfig, ): """Event Types service.""" @@ -29,6 +35,7 @@ class EventTypesService( class AsyncEventTypesService( AsyncUpdateMixin[EventType], AsyncGetMixin[EventType], + AsyncCollectionMixin[EventType], AsyncService[EventType], EventTypesServiceConfig, ): diff --git a/mpt_api_client/resources/audit/records.py b/mpt_api_client/resources/audit/records.py index 881f4c09..0b9e7e45 100644 --- a/mpt_api_client/resources/audit/records.py +++ b/mpt_api_client/resources/audit/records.py @@ -1,7 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, + CollectionMixin, CreateMixin, GetMixin, ) @@ -20,11 +22,21 @@ class RecordsServiceConfig: _collection_key = "data" -class RecordsService(CreateMixin[Record], GetMixin[Record], Service[Record], RecordsServiceConfig): +class RecordsService( + CreateMixin[Record], + GetMixin[Record], + CollectionMixin[Record], + Service[Record], + RecordsServiceConfig, +): """Records service.""" class AsyncRecordsService( - AsyncCreateMixin[Record], AsyncGetMixin[Record], AsyncService[Record], RecordsServiceConfig + AsyncCreateMixin[Record], + AsyncGetMixin[Record], + AsyncCollectionMixin[Record], + AsyncService[Record], + RecordsServiceConfig, ): """Async records service.""" diff --git a/mpt_api_client/resources/billing/credit_memo_attachments.py b/mpt_api_client/resources/billing/credit_memo_attachments.py index 7061b7f4..65e020fa 100644 --- a/mpt_api_client/resources/billing/credit_memo_attachments.py +++ b/mpt_api_client/resources/billing/credit_memo_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model @@ -26,9 +24,8 @@ class CreditMemoAttachmentsServiceConfig: class CreditMemoAttachmentsService( FileOperationsMixin[CreditMemoAttachment], - DeleteMixin, - GetMixin[CreditMemoAttachment], - UpdateMixin[CreditMemoAttachment], + ModifiableResourceMixin[CreditMemoAttachment], + CollectionMixin[CreditMemoAttachment], Service[CreditMemoAttachment], CreditMemoAttachmentsServiceConfig, ): @@ -37,9 +34,8 @@ class CreditMemoAttachmentsService( class AsyncCreditMemoAttachmentsService( AsyncFileOperationsMixin[CreditMemoAttachment], - AsyncDeleteMixin, - AsyncGetMixin[CreditMemoAttachment], - AsyncUpdateMixin[CreditMemoAttachment], + AsyncModifiableResourceMixin[CreditMemoAttachment], + AsyncCollectionMixin[CreditMemoAttachment], AsyncService[CreditMemoAttachment], CreditMemoAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/credit_memos.py b/mpt_api_client/resources/billing/credit_memos.py index 569f8eb9..ea779134 100644 --- a/mpt_api_client/resources/billing/credit_memos.py +++ b/mpt_api_client/resources/billing/credit_memos.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, CreateMixin, GetMixin, UpdateMixin, @@ -30,6 +32,7 @@ class CreditMemosService( CreateMixin[CreditMemo], UpdateMixin[CreditMemo], GetMixin[CreditMemo], + CollectionMixin[CreditMemo], Service[CreditMemo], CreditMemosServiceConfig, ): @@ -47,6 +50,7 @@ class AsyncCreditMemosService( AsyncCreateMixin[CreditMemo], AsyncUpdateMixin[CreditMemo], AsyncGetMixin[CreditMemo], + AsyncCollectionMixin[CreditMemo], AsyncService[CreditMemo], CreditMemosServiceConfig, ): diff --git a/mpt_api_client/resources/billing/custom_ledger_attachments.py b/mpt_api_client/resources/billing/custom_ledger_attachments.py index 0ec22be5..5fda68da 100644 --- a/mpt_api_client/resources/billing/custom_ledger_attachments.py +++ b/mpt_api_client/resources/billing/custom_ledger_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model @@ -26,9 +24,8 @@ class CustomLedgerAttachmentsServiceConfig: class CustomLedgerAttachmentsService( FileOperationsMixin[CustomLedgerAttachment], - DeleteMixin, - GetMixin[CustomLedgerAttachment], - UpdateMixin[CustomLedgerAttachment], + ModifiableResourceMixin[CustomLedgerAttachment], + CollectionMixin[CustomLedgerAttachment], Service[CustomLedgerAttachment], CustomLedgerAttachmentsServiceConfig, ): @@ -37,9 +34,8 @@ class CustomLedgerAttachmentsService( class AsyncCustomLedgerAttachmentsService( AsyncFileOperationsMixin[CustomLedgerAttachment], - AsyncDeleteMixin, - AsyncGetMixin[CustomLedgerAttachment], - AsyncUpdateMixin[CustomLedgerAttachment], + AsyncModifiableResourceMixin[CustomLedgerAttachment], + AsyncCollectionMixin[CustomLedgerAttachment], AsyncService[CustomLedgerAttachment], CustomLedgerAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/custom_ledger_charges.py b/mpt_api_client/resources/billing/custom_ledger_charges.py index 9ce830b0..2673d103 100644 --- a/mpt_api_client/resources/billing/custom_ledger_charges.py +++ b/mpt_api_client/resources/billing/custom_ledger_charges.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -17,6 +22,7 @@ class CustomLedgerChargesServiceConfig: class CustomLedgerChargesService( GetMixin[CustomLedgerCharge], + CollectionMixin[CustomLedgerCharge], Service[CustomLedgerCharge], CustomLedgerChargesServiceConfig, ): @@ -25,6 +31,7 @@ class CustomLedgerChargesService( class AsyncCustomLedgerChargesService( AsyncGetMixin[CustomLedgerCharge], + AsyncCollectionMixin[CustomLedgerCharge], AsyncService[CustomLedgerCharge], CustomLedgerChargesServiceConfig, ): diff --git a/mpt_api_client/resources/billing/custom_ledgers.py b/mpt_api_client/resources/billing/custom_ledgers.py index 18da5f43..e5253f2f 100644 --- a/mpt_api_client/resources/billing/custom_ledgers.py +++ b/mpt_api_client/resources/billing/custom_ledgers.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.billing.custom_ledger_attachments import ( @@ -38,10 +34,8 @@ class CustomLedgersServiceConfig: class CustomLedgersService( - CreateMixin[CustomLedger], - DeleteMixin, - GetMixin[CustomLedger], - UpdateMixin[CustomLedger], + ManagedResourceMixin[CustomLedger], + CollectionMixin[CustomLedger], AcceptableMixin[CustomLedger], Service[CustomLedger], CustomLedgersServiceConfig, @@ -71,10 +65,8 @@ def attachments(self, custom_ledger_id: str) -> CustomLedgerAttachmentsService: class AsyncCustomLedgersService( - AsyncCreateMixin[CustomLedger], - AsyncDeleteMixin, - AsyncGetMixin[CustomLedger], - AsyncUpdateMixin[CustomLedger], + AsyncManagedResourceMixin[CustomLedger], + AsyncCollectionMixin[CustomLedger], AsyncAcceptableMixin[CustomLedger], AsyncService[CustomLedger], CustomLedgersServiceConfig, diff --git a/mpt_api_client/resources/billing/invoice_attachments.py b/mpt_api_client/resources/billing/invoice_attachments.py index 4e2fa366..ba9cd800 100644 --- a/mpt_api_client/resources/billing/invoice_attachments.py +++ b/mpt_api_client/resources/billing/invoice_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model @@ -26,9 +24,8 @@ class InvoiceAttachmentsServiceConfig: class InvoiceAttachmentsService( FileOperationsMixin[InvoiceAttachment], - DeleteMixin, - GetMixin[InvoiceAttachment], - UpdateMixin[InvoiceAttachment], + ModifiableResourceMixin[InvoiceAttachment], + CollectionMixin[InvoiceAttachment], Service[InvoiceAttachment], InvoiceAttachmentsServiceConfig, ): @@ -37,9 +34,8 @@ class InvoiceAttachmentsService( class AsyncInvoiceAttachmentsService( AsyncFileOperationsMixin[InvoiceAttachment], - AsyncDeleteMixin, - AsyncGetMixin[InvoiceAttachment], - AsyncUpdateMixin[InvoiceAttachment], + AsyncModifiableResourceMixin[InvoiceAttachment], + AsyncCollectionMixin[InvoiceAttachment], AsyncService[InvoiceAttachment], InvoiceAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/invoices.py b/mpt_api_client/resources/billing/invoices.py index fbf14bdc..44175ea2 100644 --- a/mpt_api_client/resources/billing/invoices.py +++ b/mpt_api_client/resources/billing/invoices.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, CreateMixin, GetMixin, UpdateMixin, @@ -30,6 +32,7 @@ class InvoicesService( CreateMixin[Invoice], UpdateMixin[Invoice], GetMixin[Invoice], + CollectionMixin[Invoice], Service[Invoice], InvoicesServiceConfig, ): @@ -47,6 +50,7 @@ class AsyncInvoicesService( AsyncCreateMixin[Invoice], AsyncUpdateMixin[Invoice], AsyncGetMixin[Invoice], + AsyncCollectionMixin[Invoice], AsyncService[Invoice], InvoicesServiceConfig, ): diff --git a/mpt_api_client/resources/billing/journal_attachments.py b/mpt_api_client/resources/billing/journal_attachments.py index fd010195..6fc50ba3 100644 --- a/mpt_api_client/resources/billing/journal_attachments.py +++ b/mpt_api_client/resources/billing/journal_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model @@ -26,9 +24,8 @@ class JournalAttachmentsServiceConfig: class JournalAttachmentsService( FileOperationsMixin[JournalAttachment], - DeleteMixin, - GetMixin[JournalAttachment], - UpdateMixin[JournalAttachment], + ModifiableResourceMixin[JournalAttachment], + CollectionMixin[JournalAttachment], Service[JournalAttachment], JournalAttachmentsServiceConfig, ): @@ -37,9 +34,8 @@ class JournalAttachmentsService( class AsyncJournalAttachmentsService( AsyncFileOperationsMixin[JournalAttachment], - AsyncDeleteMixin, - AsyncGetMixin[JournalAttachment], - AsyncUpdateMixin[JournalAttachment], + AsyncModifiableResourceMixin[JournalAttachment], + AsyncCollectionMixin[JournalAttachment], AsyncService[JournalAttachment], JournalAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/journal_charges.py b/mpt_api_client/resources/billing/journal_charges.py index 2289eb17..57773a96 100644 --- a/mpt_api_client/resources/billing/journal_charges.py +++ b/mpt_api_client/resources/billing/journal_charges.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -16,8 +21,9 @@ class JournalChargesServiceConfig: class JournalChargesService( - Service[JournalCharge], GetMixin[JournalCharge], + CollectionMixin[JournalCharge], + Service[JournalCharge], JournalChargesServiceConfig, ): """Journal Charges service.""" @@ -25,6 +31,7 @@ class JournalChargesService( class AsyncJournalChargesService( AsyncGetMixin[JournalCharge], + AsyncCollectionMixin[JournalCharge], AsyncService[JournalCharge], JournalChargesServiceConfig, ): diff --git a/mpt_api_client/resources/billing/journal_sellers.py b/mpt_api_client/resources/billing/journal_sellers.py index f91f990a..86135f95 100644 --- a/mpt_api_client/resources/billing/journal_sellers.py +++ b/mpt_api_client/resources/billing/journal_sellers.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -17,6 +22,7 @@ class JournalSellersServiceConfig: class JournalSellersService( GetMixin[JournalSeller], + CollectionMixin[JournalSeller], Service[JournalSeller], JournalSellersServiceConfig, ): @@ -25,6 +31,7 @@ class JournalSellersService( class AsyncJournalSellersService( AsyncGetMixin[JournalSeller], + AsyncCollectionMixin[JournalSeller], AsyncService[JournalSeller], JournalSellersServiceConfig, ): diff --git a/mpt_api_client/resources/billing/journal_upload.py b/mpt_api_client/resources/billing/journal_upload.py index 3ca82890..da661985 100644 --- a/mpt_api_client/resources/billing/journal_upload.py +++ b/mpt_api_client/resources/billing/journal_upload.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncFileOperationsMixin, FileOperationsMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncFileOperationsMixin, + CollectionMixin, + FileOperationsMixin, +) from mpt_api_client.models import Model @@ -17,6 +22,7 @@ class JournalUploadServiceConfig: class JournalUploadService( FileOperationsMixin[JournalUpload], + CollectionMixin[JournalUpload], Service[JournalUpload], JournalUploadServiceConfig, ): @@ -25,6 +31,7 @@ class JournalUploadService( class AsyncJournalUploadService( AsyncFileOperationsMixin[JournalUpload], + AsyncCollectionMixin[JournalUpload], AsyncService[JournalUpload], JournalUploadServiceConfig, ): diff --git a/mpt_api_client/resources/billing/journals.py b/mpt_api_client/resources/billing/journals.py index 6989fe20..208b5a49 100644 --- a/mpt_api_client/resources/billing/journals.py +++ b/mpt_api_client/resources/billing/journals.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.billing.journal_attachments import ( @@ -42,11 +38,9 @@ class JournalsServiceConfig: class JournalsService( - CreateMixin[Journal], - DeleteMixin, - GetMixin[Journal], - UpdateMixin[Journal], RegeneratableMixin[Journal], + ManagedResourceMixin[Journal], + CollectionMixin[Journal], Service[Journal], JournalsServiceConfig, ): @@ -79,11 +73,9 @@ def upload(self, journal_id: str) -> JournalUploadService: class AsyncJournalsService( - AsyncCreateMixin[Journal], - AsyncDeleteMixin, - AsyncGetMixin[Journal], - AsyncUpdateMixin[Journal], AsyncRegeneratableMixin[Journal], + AsyncManagedResourceMixin[Journal], + AsyncCollectionMixin[Journal], AsyncService[Journal], JournalsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/ledger_attachments.py b/mpt_api_client/resources/billing/ledger_attachments.py index 70242b63..6f195868 100644 --- a/mpt_api_client/resources/billing/ledger_attachments.py +++ b/mpt_api_client/resources/billing/ledger_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model @@ -26,9 +24,8 @@ class LedgerAttachmentsServiceConfig: class LedgerAttachmentsService( FileOperationsMixin[LedgerAttachment], - DeleteMixin, - GetMixin[LedgerAttachment], - UpdateMixin[LedgerAttachment], + ModifiableResourceMixin[LedgerAttachment], + CollectionMixin[LedgerAttachment], Service[LedgerAttachment], LedgerAttachmentsServiceConfig, ): @@ -37,9 +34,8 @@ class LedgerAttachmentsService( class AsyncLedgerAttachmentsService( AsyncFileOperationsMixin[LedgerAttachment], - AsyncDeleteMixin, - AsyncGetMixin[LedgerAttachment], - AsyncUpdateMixin[LedgerAttachment], + AsyncModifiableResourceMixin[LedgerAttachment], + AsyncCollectionMixin[LedgerAttachment], AsyncService[LedgerAttachment], LedgerAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/billing/ledger_charges.py b/mpt_api_client/resources/billing/ledger_charges.py index 56779e80..73021c6b 100644 --- a/mpt_api_client/resources/billing/ledger_charges.py +++ b/mpt_api_client/resources/billing/ledger_charges.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -18,6 +23,7 @@ class LedgerChargesServiceConfig: class LedgerChargesService( GetMixin[LedgerCharge], Service[LedgerCharge], + CollectionMixin[LedgerCharge], LedgerChargesServiceConfig, ): """Ledger Charges service.""" @@ -26,6 +32,7 @@ class LedgerChargesService( class AsyncLedgerChargesService( AsyncGetMixin[LedgerCharge], AsyncService[LedgerCharge], + AsyncCollectionMixin[LedgerCharge], LedgerChargesServiceConfig, ): """Async Ledger Charges service.""" diff --git a/mpt_api_client/resources/billing/ledgers.py b/mpt_api_client/resources/billing/ledgers.py index 06a8497c..b3a908ad 100644 --- a/mpt_api_client/resources/billing/ledgers.py +++ b/mpt_api_client/resources/billing/ledgers.py @@ -1,7 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, + CollectionMixin, CreateMixin, GetMixin, ) @@ -31,6 +33,7 @@ class LedgersServiceConfig: class LedgersService( CreateMixin[Ledger], GetMixin[Ledger], + CollectionMixin[Ledger], Service[Ledger], LedgersServiceConfig, ): @@ -54,6 +57,7 @@ def attachments(self, ledger_id: str) -> LedgerAttachmentsService: class AsyncLedgersService( AsyncCreateMixin[Ledger], AsyncGetMixin[Ledger], + AsyncCollectionMixin[Ledger], AsyncService[Ledger], LedgersServiceConfig, ): diff --git a/mpt_api_client/resources/billing/manual_overrides.py b/mpt_api_client/resources/billing/manual_overrides.py index a8f0aff4..432323e0 100644 --- a/mpt_api_client/resources/billing/manual_overrides.py +++ b/mpt_api_client/resources/billing/manual_overrides.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncGetMixin, AsyncUpdateMixin, + CollectionMixin, CreateMixin, GetMixin, UpdateMixin, @@ -26,6 +28,7 @@ class ManualOverridesService( CreateMixin[ManualOverride], UpdateMixin[ManualOverride], GetMixin[ManualOverride], + CollectionMixin[ManualOverride], Service[ManualOverride], ManualOverridesServiceConfig, ): @@ -36,6 +39,7 @@ class AsyncManualOverridesService( AsyncCreateMixin[ManualOverride], AsyncUpdateMixin[ManualOverride], AsyncGetMixin[ManualOverride], + AsyncCollectionMixin[ManualOverride], AsyncService[ManualOverride], ManualOverridesServiceConfig, ): diff --git a/mpt_api_client/resources/billing/statement_charges.py b/mpt_api_client/resources/billing/statement_charges.py index 5ef289d5..61fe1bd2 100644 --- a/mpt_api_client/resources/billing/statement_charges.py +++ b/mpt_api_client/resources/billing/statement_charges.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -17,6 +22,7 @@ class StatementChargesServiceConfig: class StatementChargesService( GetMixin[StatementCharge], + CollectionMixin[StatementCharge], Service[StatementCharge], StatementChargesServiceConfig, ): @@ -25,6 +31,7 @@ class StatementChargesService( class AsyncStatementChargesService( AsyncGetMixin[StatementCharge], + AsyncCollectionMixin[StatementCharge], AsyncService[StatementCharge], StatementChargesServiceConfig, ): diff --git a/mpt_api_client/resources/billing/statements.py b/mpt_api_client/resources/billing/statements.py index c0fa7729..5125b5a6 100644 --- a/mpt_api_client/resources/billing/statements.py +++ b/mpt_api_client/resources/billing/statements.py @@ -1,5 +1,12 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, AsyncUpdateMixin, GetMixin, UpdateMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + AsyncUpdateMixin, + CollectionMixin, + GetMixin, + UpdateMixin, +) from mpt_api_client.models import Model from mpt_api_client.resources.billing.mixins import AsyncIssuableMixin, IssuableMixin from mpt_api_client.resources.billing.statement_charges import ( @@ -24,6 +31,7 @@ class StatementsService( UpdateMixin[Statement], IssuableMixin[Statement], GetMixin[Statement], + CollectionMixin[Statement], Service[Statement], StatementsServiceConfig, ): @@ -41,6 +49,7 @@ class AsyncStatementsService( AsyncUpdateMixin[Statement], AsyncIssuableMixin[Statement], AsyncGetMixin[Statement], + AsyncCollectionMixin[Statement], AsyncService[Statement], StatementsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/authorizations.py b/mpt_api_client/resources/catalog/authorizations.py index d078a224..e49513be 100644 --- a/mpt_api_client/resources/catalog/authorizations.py +++ b/mpt_api_client/resources/catalog/authorizations.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class AuthorizationsServiceConfig: class AuthorizationsService( - CreateMixin[Authorization], - DeleteMixin, - GetMixin[Authorization], - UpdateMixin[Authorization], + ManagedResourceMixin[Authorization], + CollectionMixin[Authorization], Service[Authorization], AuthorizationsServiceConfig, ): @@ -36,10 +30,8 @@ class AuthorizationsService( class AsyncAuthorizationsService( - AsyncCreateMixin[Authorization], - AsyncDeleteMixin, - AsyncGetMixin[Authorization], - AsyncUpdateMixin[Authorization], + AsyncManagedResourceMixin[Authorization], + AsyncCollectionMixin[Authorization], AsyncService[Authorization], AuthorizationsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/items.py b/mpt_api_client/resources/catalog/items.py index 5161a602..0fb88e41 100644 --- a/mpt_api_client/resources/catalog/items.py +++ b/mpt_api_client/resources/catalog/items.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.mixins import ( @@ -29,11 +25,9 @@ class ItemsServiceConfig: class ItemsService( - CreateMixin[Item], - DeleteMixin, - GetMixin[Item], - UpdateMixin[Item], PublishableMixin[Item], + ManagedResourceMixin[Item], + CollectionMixin[Item], Service[Item], ItemsServiceConfig, ): @@ -41,11 +35,9 @@ class ItemsService( class AsyncItemsService( - AsyncCreateMixin[Item], - AsyncDeleteMixin, - AsyncGetMixin[Item], - AsyncUpdateMixin[Item], AsyncPublishableMixin[Item], + AsyncManagedResourceMixin[Item], + AsyncCollectionMixin[Item], AsyncService[Item], ItemsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/listings.py b/mpt_api_client/resources/catalog/listings.py index 170bc604..1780a474 100644 --- a/mpt_api_client/resources/catalog/listings.py +++ b/mpt_api_client/resources/catalog/listings.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class ListingsServiceConfig: class ListingsService( - CreateMixin[Listing], - DeleteMixin, - GetMixin[Listing], - UpdateMixin[Listing], + ManagedResourceMixin[Listing], + CollectionMixin[Listing], Service[Listing], ListingsServiceConfig, ): @@ -36,10 +30,8 @@ class ListingsService( class AsyncListingsService( - AsyncCreateMixin[Listing], - AsyncDeleteMixin, - AsyncGetMixin[Listing], - AsyncUpdateMixin[Listing], + AsyncManagedResourceMixin[Listing], + AsyncCollectionMixin[Listing], AsyncService[Listing], ListingsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/price_list_items.py b/mpt_api_client/resources/catalog/price_list_items.py index b2a34d1e..496f0794 100644 --- a/mpt_api_client/resources/catalog/price_list_items.py +++ b/mpt_api_client/resources/catalog/price_list_items.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class PriceListItemsServiceConfig: class PriceListItemsService( - CreateMixin[PriceListItem], - DeleteMixin, - GetMixin[PriceListItem], - UpdateMixin[PriceListItem], + ManagedResourceMixin[PriceListItem], + CollectionMixin[PriceListItem], Service[PriceListItem], PriceListItemsServiceConfig, ): @@ -36,10 +30,8 @@ class PriceListItemsService( class AsyncPriceListItemsService( - AsyncCreateMixin[PriceListItem], - AsyncDeleteMixin, - AsyncGetMixin[PriceListItem], - AsyncUpdateMixin[PriceListItem], + AsyncManagedResourceMixin[PriceListItem], + AsyncCollectionMixin[PriceListItem], AsyncService[PriceListItem], PriceListItemsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/price_lists.py b/mpt_api_client/resources/catalog/price_lists.py index 2d2afd47..9c5eaad1 100644 --- a/mpt_api_client/resources/catalog/price_lists.py +++ b/mpt_api_client/resources/catalog/price_lists.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.price_list_items import ( @@ -29,10 +25,8 @@ class PriceListsServiceConfig: class PriceListsService( - CreateMixin[PriceList], - DeleteMixin, - GetMixin[PriceList], - UpdateMixin[PriceList], + ManagedResourceMixin[PriceList], + CollectionMixin[PriceList], Service[PriceList], PriceListsServiceConfig, ): @@ -46,10 +40,8 @@ def items(self, price_list_id: str) -> PriceListItemsService: class AsyncPriceListsService( - AsyncCreateMixin[PriceList], - AsyncDeleteMixin, - AsyncGetMixin[PriceList], - AsyncUpdateMixin[PriceList], + AsyncManagedResourceMixin[PriceList], + AsyncCollectionMixin[PriceList], AsyncService[PriceList], PriceListsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/pricing_policies.py b/mpt_api_client/resources/catalog/pricing_policies.py index f726bc82..e8ee5502 100644 --- a/mpt_api_client/resources/catalog/pricing_policies.py +++ b/mpt_api_client/resources/catalog/pricing_policies.py @@ -2,7 +2,14 @@ AsyncService, Service, ) -from mpt_api_client.http.mixins import AsyncCreateMixin, AsyncDeleteMixin, CreateMixin, DeleteMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncCreateMixin, + AsyncDeleteMixin, + CollectionMixin, + CreateMixin, + DeleteMixin, +) from mpt_api_client.models import Model, ResourceData from mpt_api_client.resources.catalog.pricing_policy_attachments import ( AsyncPricingPolicyAttachmentsService, @@ -25,6 +32,7 @@ class PricingPoliciesServiceConfig: class PricingPoliciesService( # noqa: WPS215 CreateMixin[PricingPolicy], DeleteMixin, + CollectionMixin[PricingPolicy], Service[PricingPolicy], PricingPoliciesServiceConfig, ): @@ -65,6 +73,7 @@ def disable(self, resource_id: str, resource_data: ResourceData) -> PricingPolic class AsyncPricingPoliciesService( AsyncCreateMixin[PricingPolicy], AsyncDeleteMixin, + AsyncCollectionMixin[PricingPolicy], AsyncService[PricingPolicy], PricingPoliciesServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/pricing_policy_attachments.py b/mpt_api_client/resources/catalog/pricing_policy_attachments.py index 53fd9483..72042bea 100644 --- a/mpt_api_client/resources/catalog/pricing_policy_attachments.py +++ b/mpt_api_client/resources/catalog/pricing_policy_attachments.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.mixins import ActivatableMixin, AsyncActivatableMixin @@ -27,10 +25,9 @@ class PricingPolicyAttachmentsServiceConfig: class PricingPolicyAttachmentsService( FileOperationsMixin[PricingPolicyAttachment], - DeleteMixin, - GetMixin[PricingPolicyAttachment], - UpdateMixin[PricingPolicyAttachment], ActivatableMixin[PricingPolicyAttachment], + ModifiableResourceMixin[PricingPolicyAttachment], + CollectionMixin[PricingPolicyAttachment], Service[PricingPolicyAttachment], PricingPolicyAttachmentsServiceConfig, ): @@ -39,10 +36,9 @@ class PricingPolicyAttachmentsService( class AsyncPricingPolicyAttachmentsService( AsyncFileOperationsMixin[PricingPolicyAttachment], - AsyncDeleteMixin, - AsyncGetMixin[PricingPolicyAttachment], - AsyncUpdateMixin[PricingPolicyAttachment], AsyncActivatableMixin[PricingPolicyAttachment], + AsyncModifiableResourceMixin[PricingPolicyAttachment], + AsyncCollectionMixin[PricingPolicyAttachment], AsyncService[PricingPolicyAttachment], PricingPolicyAttachmentsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/product_term_variants.py b/mpt_api_client/resources/catalog/product_term_variants.py index 125681e3..12ef4e5f 100644 --- a/mpt_api_client/resources/catalog/product_term_variants.py +++ b/mpt_api_client/resources/catalog/product_term_variants.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.mixins import ( @@ -30,10 +28,9 @@ class TermVariantServiceConfig: class TermVariantService( FileOperationsMixin[TermVariant], - DeleteMixin, - GetMixin[TermVariant], - UpdateMixin[TermVariant], + ModifiableResourceMixin[TermVariant], PublishableMixin[TermVariant], + CollectionMixin[TermVariant], Service[TermVariant], TermVariantServiceConfig, ): @@ -42,10 +39,9 @@ class TermVariantService( class AsyncTermVariantService( AsyncFileOperationsMixin[TermVariant], - AsyncDeleteMixin, - AsyncGetMixin[TermVariant], - AsyncUpdateMixin[TermVariant], + AsyncModifiableResourceMixin[TermVariant], AsyncPublishableMixin[TermVariant], + AsyncCollectionMixin[TermVariant], AsyncService[TermVariant], TermVariantServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/product_terms.py b/mpt_api_client/resources/catalog/product_terms.py index 11ec391a..a443885a 100644 --- a/mpt_api_client/resources/catalog/product_terms.py +++ b/mpt_api_client/resources/catalog/product_terms.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.mixins import AsyncPublishableMixin, PublishableMixin @@ -30,11 +26,9 @@ class TermServiceConfig: class TermService( - CreateMixin[Term], - DeleteMixin, - GetMixin[Term], - UpdateMixin[Term], PublishableMixin[Term], + ManagedResourceMixin[Term], + CollectionMixin[Term], Service[Term], TermServiceConfig, ): @@ -49,11 +43,9 @@ def variants(self, term_id: str) -> TermVariantService: class AsyncTermService( - AsyncCreateMixin[Term], - AsyncDeleteMixin, - AsyncGetMixin[Term], - AsyncUpdateMixin[Term], AsyncPublishableMixin[Term], + AsyncManagedResourceMixin[Term], + AsyncCollectionMixin[Term], AsyncService[Term], TermServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products.py b/mpt_api_client/resources/catalog/products.py index c3f15643..f6ef8791 100644 --- a/mpt_api_client/resources/catalog/products.py +++ b/mpt_api_client/resources/catalog/products.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model, ResourceData from mpt_api_client.resources.catalog.mixins import ( @@ -57,11 +53,9 @@ class ProductsServiceConfig: class ProductsService( - CreateMixin[Product], - DeleteMixin, - GetMixin[Product], - UpdateMixin[Product], PublishableMixin[Product], + ManagedResourceMixin[Product], + CollectionMixin[Product], Service[Product], ProductsServiceConfig, ): @@ -113,11 +107,9 @@ def update_settings(self, product_id: str, settings: ResourceData) -> Product: class AsyncProductsService( - AsyncCreateMixin[Product], - AsyncDeleteMixin, - AsyncGetMixin[Product], - AsyncUpdateMixin[Product], AsyncPublishableMixin[Product], + AsyncManagedResourceMixin[Product], + AsyncCollectionMixin[Product], AsyncService[Product], ProductsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_documents.py b/mpt_api_client/resources/catalog/products_documents.py index 9734b312..f903fc8f 100644 --- a/mpt_api_client/resources/catalog/products_documents.py +++ b/mpt_api_client/resources/catalog/products_documents.py @@ -1,13 +1,11 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.catalog.mixins import AsyncPublishableMixin, PublishableMixin @@ -27,10 +25,9 @@ class DocumentServiceConfig: class DocumentService( FileOperationsMixin[Document], - DeleteMixin, - GetMixin[Document], - UpdateMixin[Document], PublishableMixin[Document], + ModifiableResourceMixin[Document], + CollectionMixin[Document], Service[Document], DocumentServiceConfig, ): @@ -39,10 +36,9 @@ class DocumentService( class AsyncDocumentService( AsyncFileOperationsMixin[Document], - AsyncDeleteMixin, - AsyncGetMixin[Document], - AsyncUpdateMixin[Document], AsyncPublishableMixin[Document], + AsyncModifiableResourceMixin[Document], + AsyncCollectionMixin[Document], AsyncService[Document], DocumentServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_item_groups.py b/mpt_api_client/resources/catalog/products_item_groups.py index 7fb6798d..29cfdaa7 100644 --- a/mpt_api_client/resources/catalog/products_item_groups.py +++ b/mpt_api_client/resources/catalog/products_item_groups.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class ItemGroupsServiceConfig: class ItemGroupsService( - CreateMixin[ItemGroup], - DeleteMixin, - GetMixin[ItemGroup], - UpdateMixin[ItemGroup], + ManagedResourceMixin[ItemGroup], + CollectionMixin[ItemGroup], Service[ItemGroup], ItemGroupsServiceConfig, ): @@ -36,10 +30,8 @@ class ItemGroupsService( class AsyncItemGroupsService( - AsyncCreateMixin[ItemGroup], - AsyncDeleteMixin, - AsyncGetMixin[ItemGroup], - AsyncUpdateMixin[ItemGroup], + AsyncManagedResourceMixin[ItemGroup], + AsyncCollectionMixin[ItemGroup], AsyncService[ItemGroup], ItemGroupsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_media.py b/mpt_api_client/resources/catalog/products_media.py index 68fc59f0..21ddf5f0 100644 --- a/mpt_api_client/resources/catalog/products_media.py +++ b/mpt_api_client/resources/catalog/products_media.py @@ -4,14 +4,12 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncDeleteMixin, + AsyncCollectionMixin, AsyncFileOperationsMixin, - AsyncGetMixin, - AsyncUpdateMixin, - DeleteMixin, + AsyncModifiableResourceMixin, + CollectionMixin, FileOperationsMixin, - GetMixin, - UpdateMixin, + ModifiableResourceMixin, ) from mpt_api_client.models import Model, ResourceData from mpt_api_client.resources.catalog.mixins import ( @@ -34,10 +32,9 @@ class MediaServiceConfig: class MediaService( FileOperationsMixin[Media], - DeleteMixin, - GetMixin[Media], - UpdateMixin[Media], PublishableMixin[Media], + ModifiableResourceMixin[Media], + CollectionMixin[Media], Service[Media], MediaServiceConfig, ): @@ -88,10 +85,9 @@ def create( class AsyncMediaService( AsyncFileOperationsMixin[Media], - AsyncDeleteMixin, - AsyncGetMixin[Media], - AsyncUpdateMixin[Media], AsyncPublishableMixin[Media], + AsyncModifiableResourceMixin[Media], + AsyncCollectionMixin[Media], AsyncService[Media], MediaServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_parameter_groups.py b/mpt_api_client/resources/catalog/products_parameter_groups.py index 414985a7..605fca01 100644 --- a/mpt_api_client/resources/catalog/products_parameter_groups.py +++ b/mpt_api_client/resources/catalog/products_parameter_groups.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class ParameterGroupsServiceConfig: class ParameterGroupsService( - CreateMixin[ParameterGroup], - DeleteMixin, - GetMixin[ParameterGroup], - UpdateMixin[ParameterGroup], + ManagedResourceMixin[ParameterGroup], + CollectionMixin[ParameterGroup], Service[ParameterGroup], ParameterGroupsServiceConfig, ): @@ -36,10 +30,8 @@ class ParameterGroupsService( class AsyncParameterGroupsService( - AsyncCreateMixin[ParameterGroup], - AsyncDeleteMixin, - AsyncGetMixin[ParameterGroup], - AsyncUpdateMixin[ParameterGroup], + AsyncManagedResourceMixin[ParameterGroup], + AsyncCollectionMixin[ParameterGroup], AsyncService[ParameterGroup], ParameterGroupsServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_parameters.py b/mpt_api_client/resources/catalog/products_parameters.py index ec243d51..6205801e 100644 --- a/mpt_api_client/resources/catalog/products_parameters.py +++ b/mpt_api_client/resources/catalog/products_parameters.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class ParametersServiceConfig: class ParametersService( - CreateMixin[Parameter], - DeleteMixin, - GetMixin[Parameter], - UpdateMixin[Parameter], + ManagedResourceMixin[Parameter], + CollectionMixin[Parameter], Service[Parameter], ParametersServiceConfig, ): @@ -36,10 +30,8 @@ class ParametersService( class AsyncParametersService( - AsyncCreateMixin[Parameter], - AsyncDeleteMixin, - AsyncGetMixin[Parameter], - AsyncUpdateMixin[Parameter], + AsyncManagedResourceMixin[Parameter], + AsyncCollectionMixin[Parameter], AsyncService[Parameter], ParametersServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/products_templates.py b/mpt_api_client/resources/catalog/products_templates.py index 5dc323a0..963bc1b7 100644 --- a/mpt_api_client/resources/catalog/products_templates.py +++ b/mpt_api_client/resources/catalog/products_templates.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class TemplatesServiceConfig: class TemplatesService( - CreateMixin[Template], - DeleteMixin, - GetMixin[Template], - UpdateMixin[Template], + ManagedResourceMixin[Template], + CollectionMixin[Template], Service[Template], TemplatesServiceConfig, ): @@ -36,10 +30,8 @@ class TemplatesService( class AsyncTemplatesService( - AsyncCreateMixin[Template], - AsyncDeleteMixin, - AsyncGetMixin[Template], - AsyncUpdateMixin[Template], + AsyncManagedResourceMixin[Template], + AsyncCollectionMixin[Template], AsyncService[Template], TemplatesServiceConfig, ): diff --git a/mpt_api_client/resources/catalog/units_of_measure.py b/mpt_api_client/resources/catalog/units_of_measure.py index af7574b4..151e5de1 100644 --- a/mpt_api_client/resources/catalog/units_of_measure.py +++ b/mpt_api_client/resources/catalog/units_of_measure.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class UnitsOfMeasureServiceConfig: class UnitsOfMeasureService( - CreateMixin[UnitOfMeasure], - DeleteMixin, - GetMixin[UnitOfMeasure], - UpdateMixin[UnitOfMeasure], + ManagedResourceMixin[UnitOfMeasure], + CollectionMixin[UnitOfMeasure], Service[UnitOfMeasure], UnitsOfMeasureServiceConfig, ): @@ -36,10 +30,8 @@ class UnitsOfMeasureService( class AsyncUnitsOfMeasureService( - AsyncCreateMixin[UnitOfMeasure], - AsyncDeleteMixin, - AsyncGetMixin[UnitOfMeasure], - AsyncUpdateMixin[UnitOfMeasure], + AsyncManagedResourceMixin[UnitOfMeasure], + AsyncCollectionMixin[UnitOfMeasure], AsyncService[UnitOfMeasure], UnitsOfMeasureServiceConfig, ): diff --git a/mpt_api_client/resources/commerce/agreements.py b/mpt_api_client/resources/commerce/agreements.py index 1efb8b5d..b1fe0ea9 100644 --- a/mpt_api_client/resources/commerce/agreements.py +++ b/mpt_api_client/resources/commerce/agreements.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model from mpt_api_client.resources.commerce.agreements_attachments import ( @@ -28,11 +24,9 @@ class AgreementsServiceConfig: _collection_key = "data" -class AgreementsService( # noqa: WPS215 - CreateMixin[Agreement], - UpdateMixin[Agreement], - GetMixin[Agreement], - DeleteMixin, +class AgreementsService( + ManagedResourceMixin[Agreement], + CollectionMixin[Agreement], Service[Agreement], AgreementsServiceConfig, ): @@ -65,11 +59,9 @@ def attachments(self, agreement_id: str) -> AgreementsAttachmentService: ) -class AsyncAgreementsService( # noqa: WPS215 - AsyncCreateMixin[Agreement], - AsyncUpdateMixin[Agreement], - AsyncGetMixin[Agreement], - AsyncDeleteMixin, +class AsyncAgreementsService( + AsyncManagedResourceMixin[Agreement], + AsyncCollectionMixin[Agreement], AsyncService[Agreement], AgreementsServiceConfig, ): diff --git a/mpt_api_client/resources/commerce/agreements_attachments.py b/mpt_api_client/resources/commerce/agreements_attachments.py index e0ba98ab..5042b88d 100644 --- a/mpt_api_client/resources/commerce/agreements_attachments.py +++ b/mpt_api_client/resources/commerce/agreements_attachments.py @@ -1,8 +1,10 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncDeleteMixin, AsyncFileOperationsMixin, AsyncGetMixin, + CollectionMixin, DeleteMixin, FileOperationsMixin, GetMixin, @@ -26,6 +28,7 @@ class AgreementsAttachmentService( FileOperationsMixin[AgreementAttachment], DeleteMixin, GetMixin[AgreementAttachment], + CollectionMixin[AgreementAttachment], Service[AgreementAttachment], AgreementsAttachmentServiceConfig, ): @@ -36,6 +39,7 @@ class AsyncAgreementsAttachmentService( AsyncFileOperationsMixin[AgreementAttachment], AsyncDeleteMixin, AsyncGetMixin[AgreementAttachment], + AsyncCollectionMixin[AgreementAttachment], AsyncService[AgreementAttachment], AgreementsAttachmentServiceConfig, ): diff --git a/mpt_api_client/resources/commerce/orders.py b/mpt_api_client/resources/commerce/orders.py index 972a5c63..29935acc 100644 --- a/mpt_api_client/resources/commerce/orders.py +++ b/mpt_api_client/resources/commerce/orders.py @@ -3,14 +3,10 @@ Service, ) from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model, ResourceData from mpt_api_client.resources.commerce.orders_subscription import ( @@ -32,10 +28,8 @@ class OrdersServiceConfig: class OrdersService( # noqa: WPS215 WPS214 - CreateMixin[Order], - DeleteMixin, - GetMixin[Order], - UpdateMixin[Order], + ManagedResourceMixin[Order], + CollectionMixin[Order], Service[Order], OrdersServiceConfig, ): @@ -123,10 +117,8 @@ def subscriptions(self, order_id: str) -> OrderSubscriptionsService: class AsyncOrdersService( # noqa: WPS215 WPS214 - AsyncCreateMixin[Order], - AsyncDeleteMixin, - AsyncGetMixin[Order], - AsyncUpdateMixin[Order], + AsyncManagedResourceMixin[Order], + AsyncCollectionMixin[Order], AsyncService[Order], OrdersServiceConfig, ): diff --git a/mpt_api_client/resources/commerce/orders_subscription.py b/mpt_api_client/resources/commerce/orders_subscription.py index a49d3c7e..f7e7ea14 100644 --- a/mpt_api_client/resources/commerce/orders_subscription.py +++ b/mpt_api_client/resources/commerce/orders_subscription.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -25,10 +21,8 @@ class OrderSubscriptionsServiceConfig: class OrderSubscriptionsService( # noqa: WPS215 - CreateMixin[OrderSubscription], - DeleteMixin, - GetMixin[OrderSubscription], - UpdateMixin[OrderSubscription], + ManagedResourceMixin[OrderSubscription], + CollectionMixin[OrderSubscription], Service[OrderSubscription], OrderSubscriptionsServiceConfig, ): @@ -36,10 +30,8 @@ class OrderSubscriptionsService( # noqa: WPS215 class AsyncOrderSubscriptionsService( # noqa: WPS215 - AsyncCreateMixin[OrderSubscription], - AsyncDeleteMixin, - AsyncGetMixin[OrderSubscription], - AsyncUpdateMixin[OrderSubscription], + AsyncManagedResourceMixin[OrderSubscription], + AsyncCollectionMixin[OrderSubscription], AsyncService[OrderSubscription], OrderSubscriptionsServiceConfig, ): diff --git a/mpt_api_client/resources/commerce/subscriptions.py b/mpt_api_client/resources/commerce/subscriptions.py index e411b6e6..ca5e46e3 100644 --- a/mpt_api_client/resources/commerce/subscriptions.py +++ b/mpt_api_client/resources/commerce/subscriptions.py @@ -3,9 +3,11 @@ Service, ) from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, AsyncCreateMixin, AsyncDeleteMixin, AsyncGetMixin, + CollectionMixin, CreateMixin, DeleteMixin, GetMixin, @@ -29,6 +31,7 @@ class SubscriptionsService( # noqa: WPS215 CreateMixin[Subscription], DeleteMixin, GetMixin[Subscription], + CollectionMixin[Subscription], Service[Subscription], SubscriptionsServiceConfig, ): @@ -63,6 +66,7 @@ class AsyncSubscriptionsService( # noqa: WPS215 AsyncCreateMixin[Subscription], AsyncDeleteMixin, AsyncGetMixin[Subscription], + AsyncCollectionMixin[Subscription], AsyncService[Subscription], SubscriptionsServiceConfig, ): diff --git a/mpt_api_client/resources/notifications/batches.py b/mpt_api_client/resources/notifications/batches.py index 5c89ff54..4c3ec1ab 100644 --- a/mpt_api_client/resources/notifications/batches.py +++ b/mpt_api_client/resources/notifications/batches.py @@ -1,7 +1,13 @@ from httpx._types import FileTypes from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin, _json_to_file_payload +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, + _json_to_file_payload, +) from mpt_api_client.models import FileModel, Model, ResourceData @@ -19,6 +25,7 @@ class BatchesServiceConfig: class BatchesService( GetMixin[Batch], + CollectionMixin[Batch], Service[Batch], BatchesServiceConfig, ): @@ -71,6 +78,7 @@ def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel: class AsyncBatchesService( AsyncGetMixin[Batch], + AsyncCollectionMixin[Batch], AsyncService[Batch], BatchesServiceConfig, ): diff --git a/mpt_api_client/resources/notifications/categories.py b/mpt_api_client/resources/notifications/categories.py index f781e3f7..3d9f1482 100644 --- a/mpt_api_client/resources/notifications/categories.py +++ b/mpt_api_client/resources/notifications/categories.py @@ -1,11 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model, ResourceData @@ -23,9 +21,8 @@ class CategoriesServiceConfig: class CategoriesService( - CreateMixin[Category], - UpdateMixin[Category], - DeleteMixin, + ManagedResourceMixin[Category], + CollectionMixin[Category], Service[Category], CategoriesServiceConfig, ): @@ -51,9 +48,8 @@ def unpublish(self, resource_id: str, resource_data: ResourceData | None = None) class AsyncCategoriesService( - AsyncCreateMixin[Category], - AsyncUpdateMixin[Category], - AsyncDeleteMixin, + AsyncManagedResourceMixin[Category], + AsyncCollectionMixin[Category], AsyncService[Category], CategoriesServiceConfig, ): diff --git a/mpt_api_client/resources/notifications/contacts.py b/mpt_api_client/resources/notifications/contacts.py index dc3557a4..7a4a8d9f 100644 --- a/mpt_api_client/resources/notifications/contacts.py +++ b/mpt_api_client/resources/notifications/contacts.py @@ -1,12 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model, ResourceData @@ -24,10 +21,8 @@ class ContactsServiceConfig: class ContactsService( - CreateMixin[Contact], - UpdateMixin[Contact], - DeleteMixin, - GetMixin[Contact], + ManagedResourceMixin[Contact], + CollectionMixin[Contact], Service[Contact], ContactsServiceConfig, ): @@ -43,10 +38,8 @@ def unblock(self, resource_id: str, resource_data: ResourceData | None = None) - class AsyncContactsService( - AsyncCreateMixin[Contact], - AsyncUpdateMixin[Contact], - AsyncDeleteMixin, - GetMixin[Contact], + AsyncManagedResourceMixin[Contact], + AsyncCollectionMixin[Contact], AsyncService[Contact], ContactsServiceConfig, ): diff --git a/mpt_api_client/resources/notifications/messages.py b/mpt_api_client/resources/notifications/messages.py index d8727d28..ad426efc 100644 --- a/mpt_api_client/resources/notifications/messages.py +++ b/mpt_api_client/resources/notifications/messages.py @@ -1,5 +1,10 @@ from mpt_api_client.http import AsyncService, Service -from mpt_api_client.http.mixins import AsyncGetMixin, GetMixin +from mpt_api_client.http.mixins import ( + AsyncCollectionMixin, + AsyncGetMixin, + CollectionMixin, + GetMixin, +) from mpt_api_client.models import Model @@ -17,6 +22,7 @@ class MessagesServiceConfig: class MessagesService( GetMixin[Message], + CollectionMixin[Message], Service[Message], MessagesServiceConfig, ): @@ -25,6 +31,7 @@ class MessagesService( class AsyncMessagesService( AsyncGetMixin[Message], + AsyncCollectionMixin[Message], AsyncService[Message], MessagesServiceConfig, ): diff --git a/mpt_api_client/resources/notifications/subscribers.py b/mpt_api_client/resources/notifications/subscribers.py index ddc8b599..47ee4594 100644 --- a/mpt_api_client/resources/notifications/subscribers.py +++ b/mpt_api_client/resources/notifications/subscribers.py @@ -1,13 +1,9 @@ from mpt_api_client.http import AsyncService, Service from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from mpt_api_client.models import Model @@ -24,22 +20,18 @@ class SubscribersServiceConfig: _collection_key = "data" -class SubscribersService( # noqa: WPS215 - CreateMixin[Subscriber], - UpdateMixin[Subscriber], - GetMixin[Subscriber], - DeleteMixin, +class SubscribersService( + ManagedResourceMixin[Subscriber], + CollectionMixin[Subscriber], Service[Subscriber], SubscribersServiceConfig, ): """Subscribers service.""" -class AsyncSubscribersService( # noqa: WPS215 - AsyncCreateMixin[Subscriber], - AsyncUpdateMixin[Subscriber], - AsyncGetMixin[Subscriber], - AsyncDeleteMixin, +class AsyncSubscribersService( + AsyncManagedResourceMixin[Subscriber], + AsyncCollectionMixin[Subscriber], AsyncService[Subscriber], SubscribersServiceConfig, ): diff --git a/tests/http/conftest.py b/tests/http/conftest.py index 1ed1aa62..892ffce8 100644 --- a/tests/http/conftest.py +++ b/tests/http/conftest.py @@ -7,23 +7,17 @@ Service, ) from mpt_api_client.http.mixins import ( - AsyncCreateMixin, - AsyncDeleteMixin, - AsyncGetMixin, - AsyncUpdateMixin, - CreateMixin, - DeleteMixin, - GetMixin, - UpdateMixin, + AsyncCollectionMixin, + AsyncManagedResourceMixin, + CollectionMixin, + ManagedResourceMixin, ) from tests.conftest import DummyModel class DummyService( # noqa: WPS215 - CreateMixin[DummyModel], - DeleteMixin, - UpdateMixin[DummyModel], - GetMixin[DummyModel], + ManagedResourceMixin[DummyModel], + CollectionMixin[DummyModel], Service[DummyModel], ): _endpoint = "/api/v1/test" @@ -31,10 +25,8 @@ class DummyService( # noqa: WPS215 class AsyncDummyService( # noqa: WPS215 - AsyncCreateMixin[DummyModel], - AsyncDeleteMixin, - AsyncUpdateMixin[DummyModel], - AsyncGetMixin[DummyModel], + AsyncManagedResourceMixin[DummyModel], + AsyncCollectionMixin[DummyModel], AsyncService[DummyModel], ): _endpoint = "/api/v1/test" diff --git a/tests/http/test_async_service.py b/tests/http/test_async_service.py deleted file mode 100644 index f8fa36d2..00000000 --- a/tests/http/test_async_service.py +++ /dev/null @@ -1,255 +0,0 @@ -import httpx -import pytest -import respx - -from mpt_api_client.exceptions import MPTAPIError -from mpt_api_client.http.query_state import QueryState -from tests.http.conftest import AsyncDummyService - - -async def test_async_fetch_one_success(async_dummy_service, single_result_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_result_response - ) - - resource = await async_dummy_service.fetch_one() - - assert resource.id == "ID-1" - assert resource.name == "Test Resource" - assert mock_route.called - - first_request = mock_route.calls[0].request - assert "limit=1" in str(first_request.url) - assert "offset=0" in str(first_request.url) - - -async def test_async_fetch_one_no_results(async_dummy_service, no_results_response): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock(return_value=no_results_response) - - with pytest.raises(ValueError, match="Expected one result, but got zero results"): - await async_dummy_service.fetch_one() - - -async def test_async_fetch_one_multiple_results(async_dummy_service, multiple_results_response): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock( - return_value=multiple_results_response - ) - - with pytest.raises(ValueError, match=r"Expected one result, but got 2 results"): - await async_dummy_service.fetch_one() - - -async def test_async_fetch_one_with_filters( - async_dummy_service, single_result_response, filter_status_active -): - filtered_collection = ( - async_dummy_service.filter(filter_status_active).select("id", "name").order_by("created") - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_result_response - ) - resource = await filtered_collection.fetch_one() - - assert resource.id == "ID-1" - assert mock_route.called - - first_request = mock_route.calls[0].request - assert first_request.method == "GET" - assert first_request.url == ( - "https://api.example.com/api/v1/test" - "?limit=1&offset=0&order=created" - "&select=id,name&eq(status,active)" - ) - - -async def test_async_fetch_page_with_filter( - async_dummy_service, list_response, filter_status_active -) -> None: - custom_collection = ( - async_dummy_service.filter(filter_status_active) - .select("-audit", "product.agreements", "-product.agreements.product") - .order_by("-created", "name") - ) - - expected_url = ( - "https://api.example.com/api/v1/test?limit=10&offset=5" - "&order=-created,name" - "&select=-audit,product.agreements,-product.agreements.product" - "&eq(status,active)" - ) - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=list_response - ) - collection_results = await custom_collection.fetch_page(limit=10, offset=5) - - assert collection_results.to_list() == [{"id": "ID-1"}] - assert mock_route.called - assert mock_route.call_count == 1 - request = mock_route.calls[0].request - assert request.method == "GET" - assert request.url == expected_url - - -def test_async_init_defaults(async_dummy_service): - assert async_dummy_service.query_state.filter is None - assert async_dummy_service.query_state.order_by is None - assert async_dummy_service.query_state.select is None - assert async_dummy_service.build_path() == "/api/v1/test" - - -def test_async_init_with_filter(async_http_client, filter_status_active): - collection_client = AsyncDummyService( - http_client=async_http_client, - query_state=QueryState(rql=filter_status_active), - ) - - assert collection_client.query_state.filter == filter_status_active - assert collection_client.query_state.order_by is None - assert collection_client.query_state.select is None - assert collection_client.build_path() == "/api/v1/test?eq(status,active)" - - -async def test_async_iterate_single_page(async_dummy_service, single_page_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_page_response - ) - - resources = [resource async for resource in async_dummy_service.iterate()] - - request = mock_route.calls[0].request - - assert len(resources) == 2 - assert resources[0].to_dict() == {"id": "ID-1", "name": "Resource 1"} - assert resources[1].to_dict() == {"id": "ID-2", "name": "Resource 2"} - assert mock_route.call_count == 1 - assert request.url == "https://api.example.com/api/v1/test?limit=100&offset=0" - - -async def test_async_iterate_multiple_pages( - async_dummy_service, multi_page_response_page1, multi_page_response_page2 -): - with respx.mock: - respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 0}).mock( - return_value=multi_page_response_page1 - ) - respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 2}).mock( - return_value=multi_page_response_page2 - ) - - resources = [resource async for resource in async_dummy_service.iterate(2)] - - assert len(resources) == 4 - assert resources[0].id == "ID-1" - assert resources[1].id == "ID-2" - assert resources[2].id == "ID-3" - assert resources[3].id == "ID-4" - - -async def test_async_iterate_empty_results(async_dummy_service, empty_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=empty_response - ) - - resources = [resource async for resource in async_dummy_service.iterate()] - - assert len(resources) == 0 - assert mock_route.call_count == 1 - - -async def test_async_iterate_no_meta(async_dummy_service, no_meta_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=no_meta_response - ) - - resources = [resource async for resource in async_dummy_service.iterate()] - - assert len(resources) == 2 - assert resources[0].id == "ID-1" - assert resources[1].id == "ID-2" - assert mock_route.call_count == 1 - - -async def test_async_iterate_with_filters(async_dummy_service, filter_status_active): - filtered_collection = ( - async_dummy_service.filter(filter_status_active).select("id", "name").order_by("created") - ) - - response = httpx.Response( - httpx.codes.OK, - json={ - "data": [{"id": "ID-1", "name": "Active Resource"}], - "$meta": { - "pagination": { - "total": 1, - "offset": 0, - "limit": 100, - } - }, - }, - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) - - resources = [resource async for resource in filtered_collection.iterate()] - - assert len(resources) == 1 - assert resources[0].id == "ID-1" - assert resources[0].name == "Active Resource" - - request = mock_route.calls[0].request - assert ( - str(request.url) == "https://api.example.com/api/v1/test" - "?limit=100&offset=0&order=created&select=id,name&eq(status,active)" - ) - - -async def test_async_iterate_lazy_evaluation(async_dummy_service): - response = httpx.Response( - httpx.codes.OK, - json={ - "data": [{"id": "ID-1", "name": "Resource 1"}], - "$meta": { - "pagination": { - "total": 1, - "offset": 0, - "limit": 100, - } - }, - }, - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) - - iterator = async_dummy_service.iterate() - - # No requests should be made until we start iterating - assert mock_route.call_count == 0 - - # Get first item to trigger the first request - first_resource = await anext(iterator) - - assert first_resource.id == "ID-1" - assert mock_route.call_count == 1 - - -async def test_sync_iterate_handles_api_errors(async_dummy_service): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock( - return_value=httpx.Response( - httpx.codes.INTERNAL_SERVER_ERROR, json={"error": "Internal Server Error"} - ) - ) - - with pytest.raises(MPTAPIError): - [resource async for resource in async_dummy_service.iterate()] diff --git a/tests/http/test_mixins.py b/tests/http/test_mixins.py index 091a2002..7dcce28e 100644 --- a/tests/http/test_mixins.py +++ b/tests/http/test_mixins.py @@ -6,10 +6,18 @@ import respx from mpt_api_client import RQLQuery +from mpt_api_client.exceptions import MPTAPIError +from mpt_api_client.http.mixins import ( + AsyncManagedResourceMixin, + AsyncModifiableResourceMixin, + ManagedResourceMixin, + ModifiableResourceMixin, +) from mpt_api_client.resources.catalog.products_media import ( AsyncMediaService, MediaService, ) +from tests.conftest import DummyModel @pytest.fixture @@ -399,3 +407,536 @@ def test_queryable_mixin_method_chaining(dummy_service, filter_status_active): assert chained_service.query_state.filter == filter_status_active assert chained_service.query_state.order_by == ["created", "-name"] assert chained_service.query_state.select == ["id", "name"] + + +def test_col_mx_fetch_one_success(dummy_service, single_result_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_result_response + ) + + resource = dummy_service.fetch_one() + + assert resource.id == "ID-1" + assert resource.name == "Test Resource" + assert mock_route.called + + first_request = mock_route.calls[0].request + assert "limit=1" in str(first_request.url) + assert "offset=0" in str(first_request.url) + + +def test_col_mx_fetch_one_no_results(dummy_service, no_results_response): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock(return_value=no_results_response) + + with pytest.raises(ValueError, match="Expected one result, but got zero results"): + dummy_service.fetch_one() + + +def test_col_mx_fetch_one_multiple_results(dummy_service, multiple_results_response): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock( + return_value=multiple_results_response + ) + + with pytest.raises(ValueError, match=r"Expected one result, but got 2 results"): + dummy_service.fetch_one() + + +def test_col_mx_fetch_one_with_filters(dummy_service, single_result_response, filter_status_active): + filtered_collection = ( + dummy_service.filter(filter_status_active).select("id", "name").order_by("created") + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_result_response + ) + resource = filtered_collection.fetch_one() + + assert resource.id == "ID-1" + assert mock_route.called + + first_request = mock_route.calls[0].request + assert first_request.method == "GET" + assert first_request.url == ( + "https://api.example.com/api/v1/test" + "?limit=1&offset=0&order=created" + "&select=id,name&eq(status,active)" + ) + + +def test_col_mx_fetch_page_with_filter(dummy_service, list_response, filter_status_active): + custom_collection = ( + dummy_service.filter(filter_status_active) + .select("-audit", "product.agreements", "-product.agreements.product") + .order_by("-created", "name") + ) + + expected_url = ( + "https://api.example.com/api/v1/test?limit=10&offset=5" + "&order=-created,name" + "&select=-audit,product.agreements,-product.agreements.product" + "&eq(status,active)" + ) + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=list_response + ) + collection_results = custom_collection.fetch_page(limit=10, offset=5) + + assert collection_results.to_list() == [{"id": "ID-1"}] + assert mock_route.called + assert mock_route.call_count == 1 + request = mock_route.calls[0].request + assert request.method == "GET" + assert request.url == expected_url + + +def test_col_mx_iterate_single_page(dummy_service, single_page_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_page_response + ) + + resources = list(dummy_service.iterate()) + request = mock_route.calls[0].request + + assert len(resources) == 2 + assert resources[0].to_dict() == {"id": "ID-1", "name": "Resource 1"} + assert resources[1].to_dict() == {"id": "ID-2", "name": "Resource 2"} + assert mock_route.call_count == 1 + assert request.url == "https://api.example.com/api/v1/test?limit=100&offset=0" + + +def test_col_mx_iterate_multiple_pages( + dummy_service, multi_page_response_page1, multi_page_response_page2 +): + with respx.mock: + respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 0}).mock( + return_value=multi_page_response_page1 + ) + respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 2}).mock( + return_value=multi_page_response_page2 + ) + + resources = list(dummy_service.iterate(2)) + + assert len(resources) == 4 + assert resources[0].id == "ID-1" + assert resources[1].id == "ID-2" + assert resources[2].id == "ID-3" + assert resources[3].id == "ID-4" + + +def test_col_mx_iterate_empty_results(dummy_service, empty_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=empty_response + ) + + resources = list(dummy_service.iterate(2)) + + assert len(resources) == 0 + assert mock_route.call_count == 1 + + +def test_col_mx_iterate_no_meta(dummy_service, no_meta_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=no_meta_response + ) + + resources = list(dummy_service.iterate()) + + assert len(resources) == 2 + assert resources[0].id == "ID-1" + assert resources[1].id == "ID-2" + assert mock_route.call_count == 1 + + +def test_col_mx_iterate_with_filters(dummy_service, filter_status_active): + filtered_collection = ( + dummy_service.filter(filter_status_active).select("id", "name").order_by("created") + ) + + response = httpx.Response( + httpx.codes.OK, + json={ + "data": [{"id": "ID-1", "name": "Active Resource"}], + "$meta": { + "pagination": { + "total": 1, + "offset": 0, + "limit": 100, + } + }, + }, + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) + + resources = list(filtered_collection.iterate()) + + assert len(resources) == 1 + assert resources[0].id == "ID-1" + assert resources[0].name == "Active Resource" + + request = mock_route.calls[0].request + assert ( + str(request.url) == "https://api.example.com/api/v1/test" + "?limit=100&offset=0&order=created&select=id,name&eq(status,active)" + ) + + +def test_col_mx_iterate_lazy_evaluation(dummy_service): + response = httpx.Response( + httpx.codes.OK, + json={ + "data": [{"id": "ID-1", "name": "Resource 1"}], + "$meta": { + "pagination": { + "total": 1, + "offset": 0, + "limit": 100, + } + }, + }, + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) + + iterator = dummy_service.iterate() + + assert mock_route.call_count == 0 + + first_resource = next(iterator) + + assert mock_route.call_count == 1 + assert first_resource.id == "ID-1" + + +def test_col_mx_iterate_handles_api_errors(dummy_service): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock( + return_value=httpx.Response( + httpx.codes.INTERNAL_SERVER_ERROR, json={"error": "Internal Server Error"} + ) + ) + + iterator = dummy_service.iterate() + + with pytest.raises(MPTAPIError): + list(iterator) + + +async def test_async_col_mx_fetch_one_success(async_dummy_service, single_result_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_result_response + ) + + resource = await async_dummy_service.fetch_one() + + assert resource.id == "ID-1" + assert resource.name == "Test Resource" + assert mock_route.called + + first_request = mock_route.calls[0].request + assert "limit=1" in str(first_request.url) + assert "offset=0" in str(first_request.url) + + +async def test_async_col_mx_fetch_one_no_results(async_dummy_service, no_results_response): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock(return_value=no_results_response) + + with pytest.raises(ValueError, match="Expected one result, but got zero results"): + await async_dummy_service.fetch_one() + + +async def test_async_col_mx_fetch_one_multiple_results( + async_dummy_service, multiple_results_response +): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock( + return_value=multiple_results_response + ) + + with pytest.raises(ValueError, match=r"Expected one result, but got 2 results"): + await async_dummy_service.fetch_one() + + +async def test_async_col_mx_fetch_one_with_filters( + async_dummy_service, single_result_response, filter_status_active +): + filtered_collection = ( + async_dummy_service.filter(filter_status_active).select("id", "name").order_by("created") + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_result_response + ) + resource = await filtered_collection.fetch_one() + + assert resource.id == "ID-1" + assert mock_route.called + + first_request = mock_route.calls[0].request + assert first_request.method == "GET" + assert first_request.url == ( + "https://api.example.com/api/v1/test" + "?limit=1&offset=0&order=created" + "&select=id,name&eq(status,active)" + ) + + +async def test_async_col_mx_fetch_page_with_filter( + async_dummy_service, list_response, filter_status_active +) -> None: + custom_collection = ( + async_dummy_service.filter(filter_status_active) + .select("-audit", "product.agreements", "-product.agreements.product") + .order_by("-created", "name") + ) + + expected_url = ( + "https://api.example.com/api/v1/test?limit=10&offset=5" + "&order=-created,name" + "&select=-audit,product.agreements,-product.agreements.product" + "&eq(status,active)" + ) + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=list_response + ) + collection_results = await custom_collection.fetch_page(limit=10, offset=5) + + assert collection_results.to_list() == [{"id": "ID-1"}] + assert mock_route.called + assert mock_route.call_count == 1 + request = mock_route.calls[0].request + assert request.method == "GET" + assert request.url == expected_url + + +async def test_async_col_mx_iterate_single_page(async_dummy_service, single_page_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=single_page_response + ) + + resources = [resource async for resource in async_dummy_service.iterate()] + + request = mock_route.calls[0].request + + assert len(resources) == 2 + assert resources[0].to_dict() == {"id": "ID-1", "name": "Resource 1"} + assert resources[1].to_dict() == {"id": "ID-2", "name": "Resource 2"} + assert mock_route.call_count == 1 + assert request.url == "https://api.example.com/api/v1/test?limit=100&offset=0" + + +async def test_async_col_mx_iterate_multiple_pages( + async_dummy_service, multi_page_response_page1, multi_page_response_page2 +): + with respx.mock: + respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 0}).mock( + return_value=multi_page_response_page1 + ) + respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 2}).mock( + return_value=multi_page_response_page2 + ) + + resources = [resource async for resource in async_dummy_service.iterate(2)] + + assert len(resources) == 4 + assert resources[0].id == "ID-1" + assert resources[1].id == "ID-2" + assert resources[2].id == "ID-3" + assert resources[3].id == "ID-4" + + +async def test_async_col_mx_iterate_empty_results(async_dummy_service, empty_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=empty_response + ) + + resources = [resource async for resource in async_dummy_service.iterate()] + + assert len(resources) == 0 + assert mock_route.call_count == 1 + + +async def test_async_col_mx_iterate_no_meta(async_dummy_service, no_meta_response): + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock( + return_value=no_meta_response + ) + + resources = [resource async for resource in async_dummy_service.iterate()] + + assert len(resources) == 2 + assert resources[0].id == "ID-1" + assert resources[1].id == "ID-2" + assert mock_route.call_count == 1 + + +async def test_async_col_mx_iterate_with_filters(async_dummy_service, filter_status_active): + filtered_collection = ( + async_dummy_service.filter(filter_status_active).select("id", "name").order_by("created") + ) + + response = httpx.Response( + httpx.codes.OK, + json={ + "data": [{"id": "ID-1", "name": "Active Resource"}], + "$meta": { + "pagination": { + "total": 1, + "offset": 0, + "limit": 100, + } + }, + }, + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) + + resources = [resource async for resource in filtered_collection.iterate()] + + assert len(resources) == 1 + assert resources[0].id == "ID-1" + assert resources[0].name == "Active Resource" + + request = mock_route.calls[0].request + assert ( + str(request.url) == "https://api.example.com/api/v1/test" + "?limit=100&offset=0&order=created&select=id,name&eq(status,active)" + ) + + +async def test_async_col_mx_iterate_lazy_evaluation(async_dummy_service): + response = httpx.Response( + httpx.codes.OK, + json={ + "data": [{"id": "ID-1", "name": "Resource 1"}], + "$meta": { + "pagination": { + "total": 1, + "offset": 0, + "limit": 100, + } + }, + }, + ) + + with respx.mock: + mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) + + iterator = async_dummy_service.iterate() + + # No requests should be made until we start iterating + assert mock_route.call_count == 0 + + # Get first item to trigger the first request + first_resource = await anext(iterator) + + assert first_resource.id == "ID-1" + assert mock_route.call_count == 1 + + +async def test_async_col_mx_iterate_handles_api_errors(async_dummy_service): + with respx.mock: + respx.get("https://api.example.com/api/v1/test").mock( + return_value=httpx.Response( + httpx.codes.INTERNAL_SERVER_ERROR, json={"error": "Internal Server Error"} + ) + ) + + with pytest.raises(MPTAPIError): + [resource async for resource in async_dummy_service.iterate()] + + +@pytest.mark.parametrize( + "method_name", + [ + "update", + "delete", + "get", + ], +) +def test_modifieable_resource_mixin(method_name): + class Service(ModifiableResourceMixin[DummyModel]): # noqa: WPS431 + """Dummy service class for testing required methods.""" + + service = Service() + + assert hasattr(service, method_name), f"ManagedResourceMixin should have {method_name} method" + assert callable(getattr(service, method_name)), f"{method_name} should be callable" + + +@pytest.mark.parametrize( + "method_name", + [ + "update", + "delete", + "get", + ], +) +def test_async_modifiable_resource_mixin(async_dummy_service, method_name): + class Service(AsyncModifiableResourceMixin[DummyModel]): # noqa: WPS431 + """Dummy service class for testing required methods.""" + + service = Service() + + assert hasattr(service, method_name), ( + f"AsyncManagedResourceMixin should have {method_name} method" + ) + assert callable(getattr(service, method_name)), f"{method_name} should be callable" + + +@pytest.mark.parametrize( + "method_name", + [ + "create", + "update", + "delete", + "get", + ], +) +def test_managed_resource_mixin(method_name): + class ManagedService(ManagedResourceMixin[DummyModel]): # noqa: WPS431 + """Dummy service class for testing required methods.""" + + service = ManagedService() + + assert hasattr(service, method_name), f"ManagedResourceMixin should have {method_name} method" + assert callable(getattr(service, method_name)), f"{method_name} should be callable" + + +@pytest.mark.parametrize( + "method_name", + [ + "create", + "update", + "delete", + "get", + ], +) +def test_async_managed_resource_mixin(async_dummy_service, method_name): + class AsyncManagedService(AsyncManagedResourceMixin[DummyModel]): # noqa: WPS431 + """Dummy service class for testing required methods.""" + + async_service = AsyncManagedService() + + assert hasattr(async_service, method_name), ( + f"AsyncManagedResourceMixin should have {method_name} method" + ) + assert callable(getattr(async_service, method_name)), f"{method_name} should be callable" diff --git a/tests/http/test_service.py b/tests/http/test_service.py deleted file mode 100644 index b6b02a3a..00000000 --- a/tests/http/test_service.py +++ /dev/null @@ -1,254 +0,0 @@ -import httpx -import pytest -import respx - -from mpt_api_client.exceptions import MPTAPIError -from tests.conftest import DummyModel -from tests.http.conftest import DummyService - - -def test_sync_fetch_one_success(dummy_service, single_result_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_result_response - ) - - resource = dummy_service.fetch_one() - - assert resource.id == "ID-1" - assert resource.name == "Test Resource" - assert mock_route.called - - first_request = mock_route.calls[0].request - assert "limit=1" in str(first_request.url) - assert "offset=0" in str(first_request.url) - - -def test_sync_fetch_one_no_results(dummy_service, no_results_response): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock(return_value=no_results_response) - - with pytest.raises(ValueError, match="Expected one result, but got zero results"): - dummy_service.fetch_one() - - -def test_sync_fetch_one_multiple_results(dummy_service, multiple_results_response): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock( - return_value=multiple_results_response - ) - - with pytest.raises(ValueError, match=r"Expected one result, but got 2 results"): - dummy_service.fetch_one() - - -def test_sync_fetch_one_with_filters(dummy_service, single_result_response, filter_status_active): - filtered_collection = ( - dummy_service.filter(filter_status_active).select("id", "name").order_by("created") - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_result_response - ) - resource = filtered_collection.fetch_one() - - assert resource.id == "ID-1" - assert mock_route.called - - first_request = mock_route.calls[0].request - assert first_request.method == "GET" - assert first_request.url == ( - "https://api.example.com/api/v1/test" - "?limit=1&offset=0&order=created" - "&select=id,name&eq(status,active)" - ) - - -def test_sync_fetch_page_with_filter(dummy_service, list_response, filter_status_active): - custom_collection = ( - dummy_service.filter(filter_status_active) - .select("-audit", "product.agreements", "-product.agreements.product") - .order_by("-created", "name") - ) - - expected_url = ( - "https://api.example.com/api/v1/test?limit=10&offset=5" - "&order=-created,name" - "&select=-audit,product.agreements,-product.agreements.product" - "&eq(status,active)" - ) - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=list_response - ) - collection_results = custom_collection.fetch_page(limit=10, offset=5) - - assert collection_results.to_list() == [{"id": "ID-1"}] - assert mock_route.called - assert mock_route.call_count == 1 - request = mock_route.calls[0].request - assert request.method == "GET" - assert request.url == expected_url - - -def test_sync_get(dummy_service): - resource_data = {"id": "RES-123", "name": "Test Resource"} - with respx.mock: - mock_route = respx.get( - "https://api.example.com/api/v1/test/RES-123", params={"select": "id,name"} - ).mock(return_value=httpx.Response(httpx.codes.OK, json=resource_data)) - - resource = dummy_service.get("RES-123", select=["id", "name"]) - - request = mock_route.calls[0].request - accept_header = (b"Accept", b"application/json") - assert accept_header in request.headers.raw - assert isinstance(resource, DummyModel) - assert resource.to_dict() == resource_data - - -def test_sync_init_defaults(http_client): - collection_client = DummyService(http_client=http_client) - - assert collection_client.endpoint_params == {} - assert collection_client.build_path() == "/api/v1/test" - - -def test_sync_iterate_single_page(dummy_service, single_page_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=single_page_response - ) - - resources = list(dummy_service.iterate()) - request = mock_route.calls[0].request - - assert len(resources) == 2 - assert resources[0].to_dict() == {"id": "ID-1", "name": "Resource 1"} - assert resources[1].to_dict() == {"id": "ID-2", "name": "Resource 2"} - assert mock_route.call_count == 1 - assert request.url == "https://api.example.com/api/v1/test?limit=100&offset=0" - - -def test_sync_iterate_multiple_pages( - dummy_service, multi_page_response_page1, multi_page_response_page2 -): - with respx.mock: - respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 0}).mock( - return_value=multi_page_response_page1 - ) - respx.get("https://api.example.com/api/v1/test", params={"limit": 2, "offset": 2}).mock( - return_value=multi_page_response_page2 - ) - - resources = list(dummy_service.iterate(2)) - - assert len(resources) == 4 - assert resources[0].id == "ID-1" - assert resources[1].id == "ID-2" - assert resources[2].id == "ID-3" - assert resources[3].id == "ID-4" - - -def test_sync_iterate_empty_results(dummy_service, empty_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=empty_response - ) - - resources = list(dummy_service.iterate(2)) - - assert len(resources) == 0 - assert mock_route.call_count == 1 - - -def test_sync_iterate_no_meta(dummy_service, no_meta_response): - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock( - return_value=no_meta_response - ) - - resources = list(dummy_service.iterate()) - - assert len(resources) == 2 - assert resources[0].id == "ID-1" - assert resources[1].id == "ID-2" - assert mock_route.call_count == 1 - - -def test_sync_iterate_with_filters(dummy_service, filter_status_active): - filtered_collection = ( - dummy_service.filter(filter_status_active).select("id", "name").order_by("created") - ) - - response = httpx.Response( - httpx.codes.OK, - json={ - "data": [{"id": "ID-1", "name": "Active Resource"}], - "$meta": { - "pagination": { - "total": 1, - "offset": 0, - "limit": 100, - } - }, - }, - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) - - resources = list(filtered_collection.iterate()) - - assert len(resources) == 1 - assert resources[0].id == "ID-1" - assert resources[0].name == "Active Resource" - - request = mock_route.calls[0].request - assert ( - str(request.url) == "https://api.example.com/api/v1/test" - "?limit=100&offset=0&order=created&select=id,name&eq(status,active)" - ) - - -def test_sync_iterate_lazy_evaluation(dummy_service): - response = httpx.Response( - httpx.codes.OK, - json={ - "data": [{"id": "ID-1", "name": "Resource 1"}], - "$meta": { - "pagination": { - "total": 1, - "offset": 0, - "limit": 100, - } - }, - }, - ) - - with respx.mock: - mock_route = respx.get("https://api.example.com/api/v1/test").mock(return_value=response) - - iterator = dummy_service.iterate() - - assert mock_route.call_count == 0 - - first_resource = next(iterator) - - assert mock_route.call_count == 1 - assert first_resource.id == "ID-1" - - -def test_sync_iterate_handles_api_errors(dummy_service): - with respx.mock: - respx.get("https://api.example.com/api/v1/test").mock( - return_value=httpx.Response( - httpx.codes.INTERNAL_SERVER_ERROR, json={"error": "Internal Server Error"} - ) - ) - - iterator = dummy_service.iterate() - - with pytest.raises(MPTAPIError): - list(iterator)