Skip to content

Commit cc4a68e

Browse files
committed
MPT-14767 E2E seeding proof of concept
- Added seeding proof of concept - Fix create product request Run: docker compose run --rm bash python seed/main.py
1 parent 419d0d5 commit cc4a68e

37 files changed

+1506
-22
lines changed

mpt_api_client/http/async_service.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,20 @@ async def _resource_do_request( # noqa: WPS211
3131
) -> Response:
3232
"""Perform an action on a specific resource using.
3333
34-
Request with action: `HTTP_METHOD /endpoint/{resource_id}/{action}`.
35-
Request without action: `HTTP_METHOD /endpoint/{resource_id}`.
34+
:Loading parameter group
35+
Request with action: `HTTP_METHOD /endpoint/{resource_id}/{action}`.
36+
Request without action: `HTTP_METHOD /endpoint/{resource_id}`.
3637
3738
Args:
38-
resource_id: The resource ID to operate on.
39-
method: The HTTP method to use.
40-
action: The action name to use.
41-
json: The updated resource data.
42-
query_params: Additional query parameters.
43-
headers: Additional headers.
39+
resource_id: The resource ID to operate on.
40+
method: The HTTP method to use.
41+
action: The action name to use.
42+
json: The updated resource data.
43+
query_params: Additional query parameters.
44+
headers: Additional headers.
4445
4546
Raises:
46-
HTTPError: If the action fails.
47+
HTTPError: If the action fails.
4748
"""
4849
resource_url = urljoin(f"{self.path}/", resource_id)
4950
url = urljoin(f"{resource_url}/", action) if action else resource_url

mpt_api_client/http/client.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ def __init__(
4949
base_headers = {
5050
"User-Agent": "swo-marketplace-client/1.0",
5151
"Authorization": f"Bearer {api_token}",
52-
"content-type": "application/json",
5352
}
5453
self.httpx_client = Client(
5554
base_url=base_url,

mpt_api_client/http/mixins.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ def create(
8686
_json_to_file_payload(resource_data),
8787
"application/json",
8888
)
89-
9089
response = self.http_client.request("post", self.path, files=files) # type: ignore[attr-defined]
9190

9291
return self._model_class.from_response(response) # type: ignore[attr-defined, no-any-return]

mpt_api_client/models/model.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ def from_response(cls, response: Response) -> Self:
5252
meta = Meta.from_response(response)
5353
return cls.new(response_data, meta)
5454

55+
@property
56+
def id(self) -> str:
57+
"""Returns the resource ID."""
58+
return str(self._resource_data.get("id", "")) # type: ignore[no-untyped-call]
59+
5560
def to_dict(self) -> dict[str, Any]:
5661
"""Returns the resource as a dictionary."""
5762
return self._resource_data.to_dict()

mpt_api_client/resources/catalog/products.py

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import json
2+
13
from mpt_api_client.http import AsyncService, Service
24
from mpt_api_client.http.mixins import (
35
AsyncCollectionMixin,
4-
AsyncManagedResourceMixin,
6+
AsyncModifiableResourceMixin,
57
CollectionMixin,
6-
ManagedResourceMixin,
8+
ModifiableResourceMixin,
79
)
10+
from mpt_api_client.http.types import FileTypes
811
from mpt_api_client.models import Model, ResourceData
912
from mpt_api_client.resources.catalog.mixins import (
1013
AsyncPublishableMixin,
@@ -54,13 +57,38 @@ class ProductsServiceConfig:
5457

5558
class ProductsService(
5659
PublishableMixin[Product],
57-
ManagedResourceMixin[Product],
60+
ModifiableResourceMixin[Product],
5861
CollectionMixin[Product],
5962
Service[Product],
6063
ProductsServiceConfig,
6164
):
6265
"""Products service."""
6366

67+
def create(
68+
self,
69+
resource_data: ResourceData,
70+
icon: FileTypes,
71+
) -> Product:
72+
"""Create product with icon.
73+
74+
Args:
75+
resource_data: Product data.
76+
icon: Icon image in jpg, png, GIF, etc.
77+
78+
Returns:
79+
Created resource.
80+
"""
81+
files: dict[str, FileTypes] = {}
82+
files["product"] = (
83+
None,
84+
json.dumps(resource_data),
85+
"application/json",
86+
)
87+
files["icon"] = icon
88+
response = self.http_client.request("post", self.path, files=files)
89+
90+
return self._model_class.from_response(response)
91+
6492
def item_groups(self, product_id: str) -> ItemGroupsService:
6593
"""Return item_groups service."""
6694
return ItemGroupsService(
@@ -108,13 +136,37 @@ def update_settings(self, product_id: str, settings: ResourceData) -> Product:
108136

109137
class AsyncProductsService(
110138
AsyncPublishableMixin[Product],
111-
AsyncManagedResourceMixin[Product],
139+
AsyncModifiableResourceMixin[Product],
112140
AsyncCollectionMixin[Product],
113141
AsyncService[Product],
114142
ProductsServiceConfig,
115143
):
116144
"""Products service."""
117145

146+
async def create(
147+
self,
148+
resource_data: ResourceData,
149+
icon: FileTypes,
150+
) -> Product:
151+
"""Create product with icon.
152+
153+
Args:
154+
resource_data: Product data.
155+
icon: Icon image in jpg, png, GIF, etc.
156+
157+
Returns:
158+
Created resource.
159+
"""
160+
files: dict[str, FileTypes] = {}
161+
files["product"] = (
162+
None,
163+
json.dumps(resource_data),
164+
"application/json",
165+
)
166+
files["icon"] = icon
167+
response = await self.http_client.request("post", self.path, files=files)
168+
return self._model_class.from_response(response)
169+
118170
def item_groups(self, product_id: str) -> AsyncItemGroupsService:
119171
"""Return item_groups service."""
120172
return AsyncItemGroupsService(

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dependencies = [
2626

2727
[dependency-groups]
2828
dev = [
29+
"dependency-injector>=4.48.2",
2930
"freezegun==1.5.*",
3031
"ipdb==0.13.*",
3132
"ipython==9.*",

seed/__init__.py

Whitespace-only changes.
84 KB
Loading

seed/catalog/__init__.py

Whitespace-only changes.

seed/catalog/catalog.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import asyncio
2+
import logging
3+
from typing import Any
4+
5+
from seed.catalog.item import seed_items
6+
from seed.catalog.item_group import seed_item_group
7+
from seed.catalog.product import seed_product
8+
from seed.catalog.product_parameters import seed_parameters
9+
from seed.catalog.product_parameters_group import seed_parameter_group
10+
11+
logger = logging.getLogger(__name__)
12+
13+
14+
async def seed_catalog_stage1() -> None:
15+
"""Seed parallel tasks for item groups and parameter groups."""
16+
tasks: list[asyncio.Task[Any]] = [
17+
asyncio.create_task(seed_item_group()),
18+
asyncio.create_task(seed_parameter_group()),
19+
]
20+
await asyncio.gather(*tasks)
21+
22+
23+
async def seed_catalog_stage2() -> None:
24+
"""Seed final tasks for items and parameters."""
25+
tasks: list[asyncio.Task[Any]] = [
26+
asyncio.create_task(seed_items()),
27+
asyncio.create_task(seed_parameters()),
28+
]
29+
await asyncio.gather(*tasks)
30+
31+
32+
async def seed_catalog() -> None:
33+
"""Seed catalog data including products, item groups, and parameters."""
34+
logger.debug("Seeding catalog ...")
35+
await seed_product()
36+
await seed_catalog_stage1()
37+
await seed_catalog_stage2()
38+
39+
logger.debug("Seeded catalog completed.")

0 commit comments

Comments
 (0)