Skip to content

Commit 2a5e136

Browse files
authored
MPT-15844 Add catalog product items service (#145)
2 parents c24cde9 + 9379b07 commit 2a5e136

8 files changed

Lines changed: 106 additions & 6 deletions

File tree

mpt_api_client/http/async_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(
2727
*,
2828
base_url: str | None = None,
2929
api_token: str | None = None,
30-
timeout: float = 5.0,
30+
timeout: float = 10.0,
3131
retries: int = 5,
3232
):
3333
api_token = api_token or os.getenv("MPT_TOKEN")

mpt_api_client/http/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def __init__(
4040
*,
4141
base_url: str | None = None,
4242
api_token: str | None = None,
43-
timeout: float = 5.0,
43+
timeout: float = 10.0,
4444
retries: int = 5,
4545
):
4646
api_token = api_token or os.getenv("MPT_TOKEN")

mpt_api_client/resources/catalog/products.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
AsyncItemGroupsService,
2929
ItemGroupsService,
3030
)
31+
from mpt_api_client.resources.catalog.products_items import (
32+
AsyncProductItemService,
33+
ProductItemService,
34+
)
3135
from mpt_api_client.resources.catalog.products_media import (
3236
AsyncMediaService,
3337
MediaService,
@@ -72,6 +76,12 @@ class ProductsService(
7276
):
7377
"""Products service."""
7478

79+
def items(self, product_id: str) -> ProductItemService: # noqa: WPS110
80+
"""Return product items service."""
81+
return ProductItemService(
82+
http_client=self.http_client, endpoint_params={"product_id": product_id}
83+
)
84+
7585
def item_groups(self, product_id: str) -> ItemGroupsService:
7686
"""Return item_groups service."""
7787
return ItemGroupsService(
@@ -129,6 +139,12 @@ class AsyncProductsService(
129139
):
130140
"""Products service."""
131141

142+
def items(self, product_id: str) -> AsyncProductItemService: # noqa: WPS110
143+
"""Return product items service."""
144+
return AsyncProductItemService(
145+
http_client=self.http_client, endpoint_params={"product_id": product_id}
146+
)
147+
132148
def item_groups(self, product_id: str) -> AsyncItemGroupsService:
133149
"""Return item_groups service."""
134150
return AsyncItemGroupsService(
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from mpt_api_client.http import AsyncService, Service
2+
from mpt_api_client.http.mixins import (
3+
AsyncCollectionMixin,
4+
AsyncGetMixin,
5+
CollectionMixin,
6+
GetMixin,
7+
)
8+
from mpt_api_client.resources.catalog.items import Item
9+
10+
11+
class ProductItemServiceConfig:
12+
"""Product Item service configuration."""
13+
14+
_endpoint = "/public/v1/catalog/products/{product_id}/items"
15+
_model_class = Item
16+
_collection_key = "data"
17+
18+
19+
class ProductItemService(
20+
GetMixin[Item],
21+
CollectionMixin[Item],
22+
Service[Item],
23+
ProductItemServiceConfig,
24+
):
25+
"""Product Item service."""
26+
27+
28+
class AsyncProductItemService(
29+
AsyncGetMixin[Item],
30+
AsyncCollectionMixin[Item],
31+
AsyncService[Item],
32+
ProductItemServiceConfig,
33+
):
34+
"""Product Item service."""

tests/unit/http/test_async_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_async_http_initialization(mocker):
3333
"Authorization": "Bearer test-token",
3434
"Accept": "application/json",
3535
},
36-
timeout=5.0,
36+
timeout=10.0,
3737
transport=mocker.ANY,
3838
)
3939

@@ -53,7 +53,7 @@ def test_async_env_initialization(monkeypatch, mocker):
5353
"Authorization": f"Bearer {API_TOKEN}",
5454
"Accept": "application/json",
5555
},
56-
timeout=5.0,
56+
timeout=10.0,
5757
transport=mocker.ANY,
5858
)
5959

tests/unit/http/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def test_http_initialization(mocker):
2222
"User-Agent": "swo-marketplace-client/1.0",
2323
"Authorization": "Bearer test-token",
2424
},
25-
timeout=5.0,
25+
timeout=10.0,
2626
transport=mocker.ANY,
2727
)
2828

@@ -41,7 +41,7 @@ def test_env_initialization(monkeypatch, mocker):
4141
"User-Agent": "swo-marketplace-client/1.0",
4242
"Authorization": f"Bearer {API_TOKEN}",
4343
},
44-
timeout=5.0,
44+
timeout=10.0,
4545
transport=mocker.ANY,
4646
)
4747

tests/unit/resources/catalog/test_products.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
AsyncItemGroupsService,
1616
ItemGroupsService,
1717
)
18+
from mpt_api_client.resources.catalog.products_items import (
19+
AsyncProductItemService,
20+
ProductItemService,
21+
)
1822
from mpt_api_client.resources.catalog.products_media import (
1923
AsyncMediaService,
2024
MediaService,
@@ -66,6 +70,7 @@ def test_async_mixins_present(async_products_service, method):
6670
@pytest.mark.parametrize(
6771
("service_method", "expected_service_class"),
6872
[
73+
("items", ProductItemService),
6974
("item_groups", ItemGroupsService),
7075
("parameter_groups", ParameterGroupsService),
7176
("media", MediaService),
@@ -85,6 +90,7 @@ def test_property_services(products_service, service_method, expected_service_cl
8590
@pytest.mark.parametrize(
8691
("service_method", "expected_service_class"),
8792
[
93+
("items", AsyncProductItemService),
8894
("item_groups", AsyncItemGroupsService),
8995
("parameter_groups", AsyncParameterGroupsService),
9096
("media", AsyncMediaService),
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import pytest
2+
3+
from mpt_api_client.resources.catalog.products_items import (
4+
AsyncProductItemService,
5+
ProductItemService,
6+
)
7+
8+
9+
@pytest.fixture
10+
def product_items_service(http_client):
11+
return ProductItemService(http_client=http_client, endpoint_params={"product_id": "PRD-001"})
12+
13+
14+
@pytest.fixture
15+
def async_product_items_service(async_http_client):
16+
return AsyncProductItemService(
17+
http_client=async_http_client, endpoint_params={"product_id": "PRD-001"}
18+
)
19+
20+
21+
def test_endpoint(product_items_service):
22+
result = product_items_service.path == "/public/v1/catalog/products/PRD-001/items"
23+
24+
assert result is True
25+
26+
27+
def test_async_endpoint(async_product_items_service):
28+
result = async_product_items_service.path == "/public/v1/catalog/products/PRD-001/items"
29+
30+
assert result is True
31+
32+
33+
@pytest.mark.parametrize("method", ["get", "iterate"])
34+
def test_methods_present(product_items_service, method):
35+
result = hasattr(product_items_service, method)
36+
37+
assert result is True
38+
39+
40+
@pytest.mark.parametrize("method", ["get", "iterate"])
41+
def test_async_methods_present(async_product_items_service, method):
42+
result = hasattr(async_product_items_service, method)
43+
44+
assert result is True

0 commit comments

Comments
 (0)