Skip to content

Commit 4fa739c

Browse files
author
Robert Segal
committed
Adding accounts endpoints
1 parent 7ecc4f0 commit 4fa739c

File tree

11 files changed

+643
-23
lines changed

11 files changed

+643
-23
lines changed

mpt_api_client/mpt_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
44
from mpt_api_client.resources import (
5+
Accounts,
6+
AsyncAccounts,
57
AsyncAudit,
68
AsyncBilling,
79
AsyncCatalog,
@@ -56,6 +58,11 @@ def billing(self) -> AsyncBilling:
5658
"""Billing MPT API Client."""
5759
return AsyncBilling(http_client=self.http_client)
5860

61+
@property
62+
def accounts(self) -> AsyncAccounts:
63+
"""Accounts MPT API Client."""
64+
return AsyncAccounts(http_client=self.http_client)
65+
5966

6067
class MPTClient:
6168
"""MPT API Client."""
@@ -104,3 +111,8 @@ def audit(self) -> Audit:
104111
def billing(self) -> Billing:
105112
"""Billing MPT API Client."""
106113
return Billing(http_client=self.http_client)
114+
115+
@property
116+
def accounts(self) -> Accounts:
117+
"""Accounts MPT API Client."""
118+
return Accounts(http_client=self.http_client)

mpt_api_client/resources/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
from mpt_api_client.resources.accounts import Accounts, AsyncAccounts
12
from mpt_api_client.resources.audit import AsyncAudit, Audit
23
from mpt_api_client.resources.billing import AsyncBilling, Billing
34
from mpt_api_client.resources.catalog import AsyncCatalog, Catalog
45
from mpt_api_client.resources.commerce import AsyncCommerce, Commerce
56

67
__all__ = [ # noqa: WPS410
8+
"Accounts",
9+
"AsyncAccounts",
710
"AsyncAudit",
811
"AsyncBilling",
912
"AsyncCatalog",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from mpt_api_client.resources.accounts.accounts import Accounts, AsyncAccounts
2+
3+
__all__ = ["Accounts", "AsyncAccounts"] # noqa: WPS410
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from mpt_api_client.http import AsyncService, Service
2+
from mpt_api_client.http.mixins import (
3+
AsyncCreateMixin,
4+
AsyncUpdateMixin,
5+
CreateMixin,
6+
UpdateMixin,
7+
)
8+
from mpt_api_client.models import Model
9+
from mpt_api_client.resources.accounts.mixins import (
10+
ActivatableMixin,
11+
AsyncActivatableMixin,
12+
AsyncValidateMixin,
13+
ValidateMixin,
14+
)
15+
16+
17+
class Account(Model):
18+
"""Account resource."""
19+
20+
21+
class AccountsServiceConfig:
22+
"""Accounts service configuration."""
23+
24+
_endpoint = "/public/v1/accounts"
25+
_model_class = Account
26+
_collection_key = "data"
27+
28+
29+
class AccountsService(
30+
CreateMixin[Account],
31+
UpdateMixin[Account],
32+
ActivatableMixin[Account],
33+
ValidateMixin[Account],
34+
Service[Account],
35+
AccountsServiceConfig,
36+
):
37+
"""Accounts service."""
38+
39+
40+
class AsyncAccountsService(
41+
AsyncCreateMixin[Account],
42+
AsyncUpdateMixin[Account],
43+
AsyncActivatableMixin[Account],
44+
AsyncValidateMixin[Account],
45+
AsyncService[Account],
46+
AccountsServiceConfig,
47+
):
48+
"""Async Accounts service."""
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
2+
from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService
3+
4+
5+
class Accounts:
6+
"""Accounts MPT API Module."""
7+
8+
def __init__(self, *, http_client: HTTPClient):
9+
self.http_client = http_client
10+
11+
@property
12+
def accounts(self) -> AccountsService:
13+
"""Accounts service."""
14+
return AccountsService(http_client=self.http_client)
15+
16+
17+
class AsyncAccounts:
18+
"""Async Accounts MPT API Module."""
19+
20+
def __init__(self, *, http_client: AsyncHTTPClient):
21+
self.http_client = http_client
22+
23+
@property
24+
def accounts(self) -> AsyncAccountsService:
25+
"""Accounts service."""
26+
return AsyncAccountsService(http_client=self.http_client)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from mpt_api_client.models import ResourceData
2+
3+
# TODO: Consider reorganizing functions in mixins to reduce duplication and differences amongst
4+
# different domains
5+
6+
7+
class ActivatableMixin[Model]:
8+
"""Activatable mixin for activating, enabling, disabling and deactivating resources."""
9+
10+
def activate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
11+
"""Activate a resource.
12+
13+
Args:
14+
resource_id: Resource ID
15+
resource_data: Resource data will be updated
16+
"""
17+
return self._resource_action( # type: ignore[attr-defined, no-any-return]
18+
resource_id, "POST", "activate", json=resource_data
19+
)
20+
21+
def deactivate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
22+
"""Deactivate a resource.
23+
24+
Args:
25+
resource_id: Resource ID
26+
resource_data: Resource data will be updated
27+
"""
28+
return self._resource_action( # type: ignore[attr-defined, no-any-return]
29+
resource_id, "POST", "deactivate", json=resource_data
30+
)
31+
32+
def enable(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
33+
"""Enable a resource.
34+
35+
Args:
36+
resource_id: Resource ID
37+
resource_data: Resource data will be updated
38+
"""
39+
return self._resource_action( # type: ignore[attr-defined, no-any-return]
40+
resource_id, "POST", "enable", json=resource_data
41+
)
42+
43+
def disable(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
44+
"""Disable a resource.
45+
46+
Args:
47+
resource_id: Resource ID
48+
resource_data: Resource data will be updated
49+
"""
50+
return self._resource_action( # type: ignore[attr-defined, no-any-return]
51+
resource_id, "POST", "disable", json=resource_data
52+
)
53+
54+
55+
class ValidateMixin[Model]:
56+
"""Validate mixin adds the ability to validate a resource."""
57+
58+
def validate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
59+
"""Validate a resource.
60+
61+
Args:
62+
resource_id: Resource ID
63+
resource_data: Resource data will be validated
64+
"""
65+
return self._resource_action( # type: ignore[attr-defined, no-any-return]
66+
resource_id, "POST", "validate", json=resource_data
67+
)
68+
69+
70+
class AsyncActivatableMixin[Model]:
71+
"""Async activatable mixin for activating, enabling, disabling and deactivating resources."""
72+
73+
async def activate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
74+
"""Activate a resource.
75+
76+
Args:
77+
resource_id: Resource ID
78+
resource_data: Resource data will be updated
79+
"""
80+
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
81+
resource_id, "POST", "activate", json=resource_data
82+
)
83+
84+
async def deactivate(
85+
self, resource_id: str, resource_data: ResourceData | None = None
86+
) -> Model:
87+
"""Deactivate a resource.
88+
89+
Args:
90+
resource_id: Resource ID
91+
resource_data: Resource data will be updated
92+
"""
93+
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
94+
resource_id, "POST", "deactivate", json=resource_data
95+
)
96+
97+
async def enable(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
98+
"""Enable a resource.
99+
100+
Args:
101+
resource_id: Resource ID
102+
resource_data: Resource data will be updated
103+
"""
104+
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
105+
resource_id, "POST", "enable", json=resource_data
106+
)
107+
108+
async def disable(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
109+
"""Disable a resource.
110+
111+
Args:
112+
resource_id: Resource ID
113+
resource_data: Resource data will be updated
114+
"""
115+
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
116+
resource_id, "POST", "disable", json=resource_data
117+
)
118+
119+
120+
class AsyncValidateMixin[Model]:
121+
"""Asynchronous Validate mixin adds the ability to validate a resource."""
122+
123+
async def validate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model:
124+
"""Validate a resource.
125+
126+
Args:
127+
resource_id: Resource ID
128+
resource_data: Resource data will be validated
129+
"""
130+
return await self._resource_action( # type: ignore[attr-defined, no-any-return]
131+
resource_id, "POST", "validate", json=resource_data
132+
)

setup.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,21 @@ extend-ignore =
3232

3333

3434
per-file-ignores =
35+
mpt_api_client/resources/accounts/*.py: WPS215
3536
mpt_api_client/resources/audit/*.py: WPS215
3637
mpt_api_client/resources/billing/*.py: WPS215 WPS202 WPS214 WPS204
3738
mpt_api_client/resources/catalog/*.py: WPS110 WPS215 WPS214
3839
mpt_api_client/resources/commerce/*.py: WPS215
3940
mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214
4041
mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215
4142
mpt_api_client/http/mixins.py: WPS202
43+
mpt_api_client/mpt_client.py: WPS235
4244
tests/http/test_async_service.py: WPS204 WPS202
4345
tests/http/test_service.py: WPS204 WPS202
4446
tests/http/test_mixins.py: WPS204 WPS202
4547
tests/resources/catalog/test_products.py: WPS202 WPS210
4648
tests/resources/*/test_mixins.py: WPS118 WPS202 WPS204
49+
tests/test_mpt.py: WPS210 WPS218 WPS235
4750

4851
tests/*:
4952
# Allow magic strings.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
3+
from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService
4+
5+
6+
@pytest.fixture
7+
def account_service(http_client):
8+
return AccountsService(http_client=http_client)
9+
10+
11+
@pytest.fixture
12+
def async_account_service(async_http_client):
13+
return AsyncAccountsService(http_client=async_http_client)
14+
15+
16+
@pytest.mark.parametrize(
17+
"method", ["get", "create", "update", "enable", "disable", "activate", "deactivate", "validate"]
18+
)
19+
def test_mixins_present(account_service, method):
20+
assert hasattr(account_service, method)
21+
22+
23+
@pytest.mark.parametrize(
24+
"method", ["get", "create", "update", "enable", "disable", "activate", "deactivate", "validate"]
25+
)
26+
def test_async_mixins_present(async_account_service, method):
27+
assert hasattr(async_account_service, method)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import pytest
2+
3+
from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService
4+
from mpt_api_client.resources.accounts.accounts import Accounts, AsyncAccounts
5+
6+
7+
@pytest.fixture
8+
def accounts(http_client):
9+
return Accounts(http_client=http_client)
10+
11+
12+
@pytest.fixture
13+
def async_accounts(async_http_client):
14+
return AsyncAccounts(http_client=async_http_client)
15+
16+
17+
@pytest.mark.parametrize(
18+
("property_name", "expected_service_class"), [("accounts", AccountsService)]
19+
)
20+
def test_accounts_properties(accounts, property_name, expected_service_class):
21+
"""Test that Accounts properties return correct instances."""
22+
service = getattr(accounts, property_name)
23+
24+
assert isinstance(service, expected_service_class)
25+
assert service.http_client is accounts.http_client
26+
27+
28+
@pytest.mark.parametrize(
29+
("property_name", "expected_service_class"), [("accounts", AsyncAccountsService)]
30+
)
31+
def test_async_accounts_properties(async_accounts, property_name, expected_service_class):
32+
"""Test that AsyncAccounts properties return correct instances."""
33+
service = getattr(async_accounts, property_name)
34+
35+
assert isinstance(service, expected_service_class)
36+
assert service.http_client is async_accounts.http_client
37+
38+
39+
def test_accounts_initialization(http_client):
40+
accounts = Accounts(http_client=http_client)
41+
42+
assert accounts.http_client is http_client
43+
assert isinstance(accounts, Accounts)
44+
45+
46+
def test_async_accounts_initialization(async_http_client):
47+
accounts = AsyncAccounts(http_client=async_http_client)
48+
49+
assert accounts.http_client is async_http_client
50+
assert isinstance(accounts, AsyncAccounts)

0 commit comments

Comments
 (0)