Skip to content

Conversation

@albertsola
Copy link
Contributor

@albertsola albertsola commented Dec 3, 2025

Summary by CodeRabbit

  • New Features

    • Product items service added to the catalog, enabling retrieval and listing of items for individual products via both synchronous and asynchronous interfaces.
  • Tests

    • Added unit tests validating the new product items service, endpoint configuration, and available public methods for sync and async flows.
  • Chores

    • Increased default HTTP and Async HTTP client timeout from 5s to 10s.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Walkthrough

Adds product-item-level services and accessors to the catalog client (sync and async), introduces a new product-items service module with tests, and increases default HTTP client timeouts from 5.0s to 10.0s.

Changes

Cohort / File(s) Summary
Product Service Enhancement
mpt_api_client/resources/catalog/products.py
Imported ProductItemService and AsyncProductItemService. Added items(self, product_id: str) methods to ProductsService and AsyncProductsService returning configured item-level service instances with endpoint_params including product_id.
New Product Items Service
mpt_api_client/resources/catalog/products_items.py
New module defining ProductItemServiceConfig with _endpoint: "/public/v1/catalog/products/{product_id}/items", _model_class: Item, _collection_key: "data". Added ProductItemService and AsyncProductItemService combining get/collection mixins with the config.
Tests — products & product items
tests/unit/resources/catalog/test_products.py, tests/unit/resources/catalog/test_products_items.py
Updated test_products.py to expect items mapping to new services. Added test_products_items.py with fixtures for sync/async services (product_id = PRD-001), asserting endpoint path and presence of get/iterate (and async equivalents).
HTTP client timeout change
mpt_api_client/http/client.py, mpt_api_client/http/async_client.py
Increased default timeout parameter in HTTPClient.__init__ and AsyncHTTPClient.__init__ from 5.0 to 10.0. No other behavioral changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Focus areas:
    • Endpoint template and interpolation for /public/v1/catalog/products/{product_id}/items
    • Correct typing and return value of items() methods for sync and async services
    • Inheritance/composition of mixins in ProductItemService and AsyncProductItemService
    • Test fixtures and assertions for endpoint path and async vs sync method availability
    • Default timeout change impact in client initialization tests

Suggested reviewers

  • jentyk
  • d3rky
  • svazquezco
  • robcsegal
  • alephsur

Poem

🐇 I hopped through code, a curious sight,
Found product items ready to take flight.
Sync or async, both paths now sing,
Timeouts stretched out — joy they bring! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'MPT-15844 Add catalog product items service' accurately reflects the main changes in the pull request, which introduce new product items service classes and integration with the products service.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch MPT-15844-catalog-product-items-service

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0088838 and 9379b07.

📒 Files selected for processing (4)
  • mpt_api_client/http/async_client.py (1 hunks)
  • mpt_api_client/http/client.py (1 hunks)
  • tests/unit/http/test_async_client.py (2 hunks)
  • tests/unit/http/test_client.py (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/unit/http/test_async_client.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • mpt_api_client/http/client.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
mpt_api_client/http/async_client.py (1)

30-30: LGTM! Timeout increase is reasonable.

The default timeout increase from 5.0s to 10.0s provides better tolerance for slower network conditions while remaining reasonable for API operations. This aligns with the parallel change in the synchronous HTTPClient.

tests/unit/http/test_client.py (1)

25-25: LGTM! Test expectations correctly updated.

The timeout assertions properly reflect the new 10.0s default value in both initialization test cases.

Also applies to: 44-44


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

Warnings
⚠️

This PR contains 2 commits.

Please squash them into a single commit to keep the git history clean and easy to follow.

Multiple commits are acceptable only in the following cases:

  1. One commit is a technical refactoring, and another introduces business logic changes.
  2. You are doing a complex multi-step refactoring (although in this case we still recommend splitting it into separate PRs).
⚠️

Some newly added source files do not have corresponding tests in the tests/ folder with matching structure and the test_ prefix.

✅ Found Jira issue key in the title: MPT-15844

Tests mirroring check (created files only)

Added source file Expected test (added in this PR)
mpt_api_client/resources/catalog/products_items.py tests/resources/catalog/test_products_items.py

Generated by 🚫 dangerJS against 9379b07

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/unit/resources/catalog/test_products_items.py (1)

21-30: Consider simplifying the assertions.

The tests correctly verify the endpoint paths, but the assertion pattern is verbose.

Apply this diff to simplify:

 def test_endpoint(product_items_service):
-    result = product_items_service.path == "/public/v1/catalog/products/PRD-001/items"
-
-    assert result is True
+    assert product_items_service.path == "/public/v1/catalog/products/PRD-001/items"


 def test_async_endpoint(async_product_items_service):
-    result = async_product_items_service.path == "/public/v1/catalog/products/PRD-001/items"
-
-    assert result is True
+    assert async_product_items_service.path == "/public/v1/catalog/products/PRD-001/items"
mpt_api_client/resources/catalog/products.py (2)

79-83: Remove unused noqa directive.

The implementation correctly follows the established pattern for sub-service accessors. However, the noqa: WPS110 directive is flagged as unused by Ruff.

Based on static analysis hints, apply this diff:

-    def items(self, product_id: str) -> ProductItemService:  # noqa: WPS110
+    def items(self, product_id: str) -> ProductItemService:
         """Return product items service."""
         return ProductItemService(
             http_client=self.http_client, endpoint_params={"product_id": product_id}
         )

If the WPS110 suppression is still needed for wemake-python-styleguide, consider configuring Ruff to recognize it or adjusting your linter setup.


142-146: Remove unused noqa directive.

The async implementation correctly mirrors the synchronous version. However, the noqa: WPS110 directive is flagged as unused by Ruff.

Based on static analysis hints, apply this diff:

-    def items(self, product_id: str) -> AsyncProductItemService:  # noqa: WPS110
+    def items(self, product_id: str) -> AsyncProductItemService:
         """Return product items service."""
         return AsyncProductItemService(
             http_client=self.http_client, endpoint_params={"product_id": product_id}
         )

If the WPS110 suppression is still needed for wemake-python-styleguide, consider configuring Ruff to recognize it or adjusting your linter setup.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c24cde9 and 93bf42f.

📒 Files selected for processing (4)
  • mpt_api_client/resources/catalog/products.py (3 hunks)
  • mpt_api_client/resources/catalog/products_items.py (1 hunks)
  • tests/unit/resources/catalog/test_products.py (3 hunks)
  • tests/unit/resources/catalog/test_products_items.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
tests/unit/resources/catalog/test_products.py (2)
tests/unit/resources/catalog/test_catalog.py (1)
  • catalog (26-27)
mpt_api_client/resources/catalog/products_items.py (2)
  • AsyncProductItemService (28-34)
  • ProductItemService (19-25)
tests/unit/resources/catalog/test_products_items.py (3)
mpt_api_client/resources/catalog/products_items.py (2)
  • AsyncProductItemService (28-34)
  • ProductItemService (19-25)
tests/unit/conftest.py (2)
  • http_client (17-18)
  • async_http_client (22-23)
mpt_api_client/http/base_service.py (1)
  • path (28-30)
mpt_api_client/resources/catalog/products.py (3)
mpt_api_client/resources/catalog/products_items.py (2)
  • AsyncProductItemService (28-34)
  • ProductItemService (19-25)
mpt_api_client/resources/catalog/price_lists.py (2)
  • items (35-39)
  • items (50-54)
mpt_api_client/resources/catalog/catalog.py (2)
  • items (60-62)
  • items (102-104)
mpt_api_client/resources/catalog/products_items.py (5)
mpt_api_client/http/async_service.py (1)
  • AsyncService (12-80)
mpt_api_client/http/service.py (1)
  • Service (12-80)
mpt_api_client/http/mixins.py (4)
  • AsyncCollectionMixin (538-605)
  • AsyncGetMixin (380-395)
  • CollectionMixin (469-535)
  • GetMixin (361-377)
mpt_api_client/resources/catalog/products.py (2)
  • items (79-83)
  • items (142-146)
mpt_api_client/resources/catalog/items.py (1)
  • Item (15-16)
🪛 Ruff (0.14.7)
mpt_api_client/resources/catalog/products.py

79-79: Unused noqa directive (unknown: WPS110)

Remove unused noqa directive

(RUF100)


142-142: Unused noqa directive (unknown: WPS110)

Remove unused noqa directive

(RUF100)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (10)
tests/unit/resources/catalog/test_products.py (2)

18-21: LGTM!

The imports are correctly added and follow the established import structure in the test file.


73-73: LGTM!

The test cases correctly verify that the new items accessor returns the appropriate service classes and passes the product_id parameter correctly.

Also applies to: 93-93

tests/unit/resources/catalog/test_products_items.py (3)

1-6: LGTM!

The imports are clean and include only what's necessary for testing the product items services.


9-18: LGTM!

The fixtures correctly instantiate the services with the required endpoint_params for testing.


33-44: LGTM!

The parameterized tests correctly verify that both sync and async services expose the expected methods from their mixins.

mpt_api_client/resources/catalog/products.py (1)

31-34: LGTM!

The imports are correctly added and follow the alphabetical ordering of the products_* modules.

mpt_api_client/resources/catalog/products_items.py (4)

1-8: LGTM!

The imports are clean and include all necessary components: service base classes, mixins for retrieval and iteration, and the Item model.


11-16: LGTM!

The service configuration correctly defines the endpoint template with the product_id parameter, uses the Item model class, and follows the standard "data" collection key convention.


19-25: LGTM!

The ProductItemService class correctly combines the necessary mixins (GetMixin for individual retrieval, CollectionMixin for iteration) with the Service base class and configuration.


28-34: LGTM!

The AsyncProductItemService class correctly mirrors the synchronous version using async mixins and base classes, maintaining consistency with the async service patterns in the codebase.

@albertsola albertsola force-pushed the MPT-15844-catalog-product-items-service branch from 0088838 to 9379b07 Compare December 3, 2025 10:38
*,
base_url: str | None = None,
api_token: str | None = None,
timeout: float = 5.0,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a ticket to revert this back here:

https://softwareone.atlassian.net/browse/MPT-16150

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 3, 2025

@albertsola albertsola merged commit 2a5e136 into main Dec 3, 2025
6 checks passed
@albertsola albertsola deleted the MPT-15844-catalog-product-items-service branch December 3, 2025 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants