diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 93e8660..d52d2b9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.12.2" + ".": "0.13.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index c5955c5..e87950d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/azure/partnermax-fa73d56cb03e02b0bf904b1336512bcdef94150eb14ecd514ef709214608d69f.yml -openapi_spec_hash: 5b05f6d46fc6d51dcd5b9930a6fc29ba -config_hash: 085d04841ad5a779fb40c5000448d9d9 +configured_endpoints: 27 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/azure/partnermax-33c6a68b0b225895b68bd2e9bf19b189b01fa887239b98a5867eb7b1505985ef.yml +openapi_spec_hash: c79381758719d11fc5fb4f1fb1b1d8b2 +config_hash: b71de6785b0e0c91836519dead13f632 diff --git a/CHANGELOG.md b/CHANGELOG.md index 25e3c1a..68c55c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.13.0 (2026-06-29) + +Full Changelog: [v0.12.2...v0.13.0](https://github.com/DealerMax-app/partnermax-python/compare/v0.12.2...v0.13.0) + +### Features + +* regenerate PartnerMAX SDKs for v1.5.13 ([5e87e7f](https://github.com/DealerMax-app/partnermax-python/commit/5e87e7fe81516ea14f146a3096452c95e62816a8)) +* regenerate SDK for vehicle contract 1.5.12 ([0bb2c08](https://github.com/DealerMax-app/partnermax-python/commit/0bb2c082e28eee883c826f124d691b1b08593556)) + ## 0.12.2 (2026-06-28) Full Changelog: [v0.12.1...v0.12.2](https://github.com/DealerMax-app/partnermax-python/compare/v0.12.1...v0.12.2) diff --git a/api.md b/api.md index 3847f23..f744aab 100644 --- a/api.md +++ b/api.md @@ -27,6 +27,9 @@ Methods: - client.dealers.update(dealer_id, \*\*params) -> DealerDetail - client.dealers.list(\*\*params) -> SyncCursorPage[DealerSummary] - client.dealers.delete(dealer_id) -> None +- client.dealers.activate_reference(external_dealer_id) -> PartnerDealerResponse +- client.dealers.revoke_reference(external_dealer_id) -> None +- client.dealers.suspend_reference(external_dealer_id) -> PartnerDealerResponse ## NltSettings @@ -93,3 +96,17 @@ Methods: - client.dealers.vehicles.images.create(vehicle_id, \*, dealer_id, \*\*params) -> VehicleImage - client.dealers.vehicles.images.list(vehicle_id, \*, dealer_id) -> VehicleImageList - client.dealers.vehicles.images.delete(image_id, \*, dealer_id, vehicle_id) -> None + +### Accessories + +Types: + +```python +from partnermax.types.dealers.vehicles import VehicleAccessoriesCatalog, VehicleAccessoryItem +``` + +Methods: + +- client.dealers.vehicles.accessories.update(vehicle_id, \*, dealer_id, \*\*params) -> VehicleAccessoriesCatalog +- client.dealers.vehicles.accessories.refresh_catalog(vehicle_id, \*, dealer_id) -> VehicleAccessoriesCatalog +- client.dealers.vehicles.accessories.retrieve_catalog(vehicle_id, \*, dealer_id) -> VehicleAccessoriesCatalog diff --git a/pyproject.toml b/pyproject.toml index e889b4a..f3e3aaa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "partnermax" -version = "0.12.2" +version = "0.13.0" description = "The official Python library for the partnermax API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/partnermax/_client.py b/src/partnermax/_client.py index b32d2d5..32548c0 100644 --- a/src/partnermax/_client.py +++ b/src/partnermax/_client.py @@ -163,7 +163,9 @@ def keys(self) -> KeysResource: @cached_property def dealers(self) -> DealersResource: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import DealersResource return DealersResource(self) @@ -420,7 +422,9 @@ def keys(self) -> AsyncKeysResource: @cached_property def dealers(self) -> AsyncDealersResource: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import AsyncDealersResource return AsyncDealersResource(self) @@ -591,7 +595,9 @@ def keys(self) -> keys.KeysResourceWithRawResponse: @cached_property def dealers(self) -> dealers.DealersResourceWithRawResponse: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import DealersResourceWithRawResponse return DealersResourceWithRawResponse(self._client.dealers) @@ -615,7 +621,9 @@ def keys(self) -> keys.AsyncKeysResourceWithRawResponse: @cached_property def dealers(self) -> dealers.AsyncDealersResourceWithRawResponse: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import AsyncDealersResourceWithRawResponse return AsyncDealersResourceWithRawResponse(self._client.dealers) @@ -639,7 +647,9 @@ def keys(self) -> keys.KeysResourceWithStreamingResponse: @cached_property def dealers(self) -> dealers.DealersResourceWithStreamingResponse: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import DealersResourceWithStreamingResponse return DealersResourceWithStreamingResponse(self._client.dealers) @@ -663,7 +673,9 @@ def keys(self) -> keys.AsyncKeysResourceWithStreamingResponse: @cached_property def dealers(self) -> dealers.AsyncDealersResourceWithStreamingResponse: - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ from .resources.dealers import AsyncDealersResourceWithStreamingResponse return AsyncDealersResourceWithStreamingResponse(self._client.dealers) diff --git a/src/partnermax/_version.py b/src/partnermax/_version.py index bdd33cc..34d9d84 100644 --- a/src/partnermax/_version.py +++ b/src/partnermax/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "partnermax" -__version__ = "0.12.2" # x-release-please-version +__version__ = "0.13.0" # x-release-please-version diff --git a/src/partnermax/resources/dealers/dealers.py b/src/partnermax/resources/dealers/dealers.py index 20cd859..326c01f 100644 --- a/src/partnermax/resources/dealers/dealers.py +++ b/src/partnermax/resources/dealers/dealers.py @@ -52,7 +52,9 @@ class DealersResource(SyncAPIResource): - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ @cached_property def nlt_settings(self) -> NltSettingsResource: @@ -64,9 +66,9 @@ def nlt(self) -> NltResource: @cached_property def vehicles(self) -> VehiclesResource: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return VehiclesResource(self._client) @@ -103,18 +105,18 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PartnerDealerResponse: - """Create a partner-owned opaque dealer reference. + """Register an opaque dealer reference for this partner. SDK users call - `client.dealers.create(...)`; the generated client sends this request to the - core-owned `/api/partner/dealers` route. + `client.dealers.create(...)`; the generated client sends this request to + `/api/partner/dealers` on the public PartnerMAX API host. Args: - external_dealer_id: Partner-owned opaque dealer id. This becomes the dealer_id used by vehicle and - NLT SDK calls. + external_dealer_id: Partner-supplied opaque dealer id. This becomes the dealer_id used by vehicle + and NLT SDK calls. activate: When true, the dealer can immediately receive vehicle/NLT operations. When - false, create the registry row but keep it suspended until activated. + false, create the registry row but keep it inactive until activated. metadata: Optional scalar partner-side correlation metadata. @@ -241,7 +243,7 @@ def list( *, cursor: Optional[str] | Omit = omit, limit: int | Omit = omit, - status: Literal["active", "inactive", "all"] | Omit = omit, + status: Literal["active", "inactive", "deleted", "all"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -249,7 +251,7 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPage[DealerSummary]: - """List dealers owned by the calling partner. + """List dealer references registered for the calling partner. Cursor-paginated. @@ -317,9 +319,120 @@ def delete( cast_to=NoneType, ) + def activate_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PartnerDealerResponse: + """Reactivate a non-terminal opaque dealer reference. + + SDK users can also call + `PATCH /v1/dealers/{dealer_id}` with `status=active`; this registry endpoint is + exposed for integrations that manage the `/api/partner` lifecycle directly. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + return self._post( + path_template("/api/partner/dealers/{external_dealer_id}/activate", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PartnerDealerResponse, + ) + + def revoke_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """Terminally revoke an opaque dealer reference. + + This is equivalent to deleting the + dealer through `/v1/dealers/{dealer_id}` from the partner's perspective: the + public status becomes `deleted` and reactivation requires DealerMAX support. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._delete( + path_template("/api/partner/dealers/{external_dealer_id}", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def suspend_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PartnerDealerResponse: + """Temporarily deactivate an opaque dealer reference. + + SDK users can also call + `PATCH /v1/dealers/{dealer_id}` with `status=inactive`; both routes map the + public status to `inactive`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + return self._post( + path_template("/api/partner/dealers/{external_dealer_id}/suspend", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PartnerDealerResponse, + ) + class AsyncDealersResource(AsyncAPIResource): - """Provision, update, deactivate, and list dealers owned by the calling partner.""" + """ + Register, update, deactivate, and list dealer references registered for the calling partner. + """ @cached_property def nlt_settings(self) -> AsyncNltSettingsResource: @@ -331,9 +444,9 @@ def nlt(self) -> AsyncNltResource: @cached_property def vehicles(self) -> AsyncVehiclesResource: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncVehiclesResource(self._client) @@ -370,18 +483,18 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PartnerDealerResponse: - """Create a partner-owned opaque dealer reference. + """Register an opaque dealer reference for this partner. SDK users call - `client.dealers.create(...)`; the generated client sends this request to the - core-owned `/api/partner/dealers` route. + `client.dealers.create(...)`; the generated client sends this request to + `/api/partner/dealers` on the public PartnerMAX API host. Args: - external_dealer_id: Partner-owned opaque dealer id. This becomes the dealer_id used by vehicle and - NLT SDK calls. + external_dealer_id: Partner-supplied opaque dealer id. This becomes the dealer_id used by vehicle + and NLT SDK calls. activate: When true, the dealer can immediately receive vehicle/NLT operations. When - false, create the registry row but keep it suspended until activated. + false, create the registry row but keep it inactive until activated. metadata: Optional scalar partner-side correlation metadata. @@ -508,7 +621,7 @@ def list( *, cursor: Optional[str] | Omit = omit, limit: int | Omit = omit, - status: Literal["active", "inactive", "all"] | Omit = omit, + status: Literal["active", "inactive", "deleted", "all"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -516,7 +629,7 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[DealerSummary, AsyncCursorPage[DealerSummary]]: - """List dealers owned by the calling partner. + """List dealer references registered for the calling partner. Cursor-paginated. @@ -584,6 +697,115 @@ async def delete( cast_to=NoneType, ) + async def activate_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PartnerDealerResponse: + """Reactivate a non-terminal opaque dealer reference. + + SDK users can also call + `PATCH /v1/dealers/{dealer_id}` with `status=active`; this registry endpoint is + exposed for integrations that manage the `/api/partner` lifecycle directly. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + return await self._post( + path_template("/api/partner/dealers/{external_dealer_id}/activate", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PartnerDealerResponse, + ) + + async def revoke_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """Terminally revoke an opaque dealer reference. + + This is equivalent to deleting the + dealer through `/v1/dealers/{dealer_id}` from the partner's perspective: the + public status becomes `deleted` and reactivation requires DealerMAX support. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template("/api/partner/dealers/{external_dealer_id}", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def suspend_reference( + self, + external_dealer_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PartnerDealerResponse: + """Temporarily deactivate an opaque dealer reference. + + SDK users can also call + `PATCH /v1/dealers/{dealer_id}` with `status=inactive`; both routes map the + public status to `inactive`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not external_dealer_id: + raise ValueError(f"Expected a non-empty value for `external_dealer_id` but received {external_dealer_id!r}") + return await self._post( + path_template("/api/partner/dealers/{external_dealer_id}/suspend", external_dealer_id=external_dealer_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PartnerDealerResponse, + ) + class DealersResourceWithRawResponse: def __init__(self, dealers: DealersResource) -> None: @@ -604,6 +826,15 @@ def __init__(self, dealers: DealersResource) -> None: self.delete = to_raw_response_wrapper( dealers.delete, ) + self.activate_reference = to_raw_response_wrapper( + dealers.activate_reference, + ) + self.revoke_reference = to_raw_response_wrapper( + dealers.revoke_reference, + ) + self.suspend_reference = to_raw_response_wrapper( + dealers.suspend_reference, + ) @cached_property def nlt_settings(self) -> NltSettingsResourceWithRawResponse: @@ -615,9 +846,9 @@ def nlt(self) -> NltResourceWithRawResponse: @cached_property def vehicles(self) -> VehiclesResourceWithRawResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return VehiclesResourceWithRawResponse(self._dealers.vehicles) @@ -641,6 +872,15 @@ def __init__(self, dealers: AsyncDealersResource) -> None: self.delete = async_to_raw_response_wrapper( dealers.delete, ) + self.activate_reference = async_to_raw_response_wrapper( + dealers.activate_reference, + ) + self.revoke_reference = async_to_raw_response_wrapper( + dealers.revoke_reference, + ) + self.suspend_reference = async_to_raw_response_wrapper( + dealers.suspend_reference, + ) @cached_property def nlt_settings(self) -> AsyncNltSettingsResourceWithRawResponse: @@ -652,9 +892,9 @@ def nlt(self) -> AsyncNltResourceWithRawResponse: @cached_property def vehicles(self) -> AsyncVehiclesResourceWithRawResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncVehiclesResourceWithRawResponse(self._dealers.vehicles) @@ -678,6 +918,15 @@ def __init__(self, dealers: DealersResource) -> None: self.delete = to_streamed_response_wrapper( dealers.delete, ) + self.activate_reference = to_streamed_response_wrapper( + dealers.activate_reference, + ) + self.revoke_reference = to_streamed_response_wrapper( + dealers.revoke_reference, + ) + self.suspend_reference = to_streamed_response_wrapper( + dealers.suspend_reference, + ) @cached_property def nlt_settings(self) -> NltSettingsResourceWithStreamingResponse: @@ -689,9 +938,9 @@ def nlt(self) -> NltResourceWithStreamingResponse: @cached_property def vehicles(self) -> VehiclesResourceWithStreamingResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return VehiclesResourceWithStreamingResponse(self._dealers.vehicles) @@ -715,6 +964,15 @@ def __init__(self, dealers: AsyncDealersResource) -> None: self.delete = async_to_streamed_response_wrapper( dealers.delete, ) + self.activate_reference = async_to_streamed_response_wrapper( + dealers.activate_reference, + ) + self.revoke_reference = async_to_streamed_response_wrapper( + dealers.revoke_reference, + ) + self.suspend_reference = async_to_streamed_response_wrapper( + dealers.suspend_reference, + ) @cached_property def nlt_settings(self) -> AsyncNltSettingsResourceWithStreamingResponse: @@ -726,8 +984,8 @@ def nlt(self) -> AsyncNltResourceWithStreamingResponse: @cached_property def vehicles(self) -> AsyncVehiclesResourceWithStreamingResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncVehiclesResourceWithStreamingResponse(self._dealers.vehicles) diff --git a/src/partnermax/resources/dealers/vehicles/__init__.py b/src/partnermax/resources/dealers/vehicles/__init__.py index d80c5c5..780231a 100644 --- a/src/partnermax/resources/dealers/vehicles/__init__.py +++ b/src/partnermax/resources/dealers/vehicles/__init__.py @@ -16,6 +16,14 @@ VehiclesResourceWithStreamingResponse, AsyncVehiclesResourceWithStreamingResponse, ) +from .accessories import ( + AccessoriesResource, + AsyncAccessoriesResource, + AccessoriesResourceWithRawResponse, + AsyncAccessoriesResourceWithRawResponse, + AccessoriesResourceWithStreamingResponse, + AsyncAccessoriesResourceWithStreamingResponse, +) __all__ = [ "ImagesResource", @@ -24,6 +32,12 @@ "AsyncImagesResourceWithRawResponse", "ImagesResourceWithStreamingResponse", "AsyncImagesResourceWithStreamingResponse", + "AccessoriesResource", + "AsyncAccessoriesResource", + "AccessoriesResourceWithRawResponse", + "AsyncAccessoriesResourceWithRawResponse", + "AccessoriesResourceWithStreamingResponse", + "AsyncAccessoriesResourceWithStreamingResponse", "VehiclesResource", "AsyncVehiclesResource", "VehiclesResourceWithRawResponse", diff --git a/src/partnermax/resources/dealers/vehicles/accessories.py b/src/partnermax/resources/dealers/vehicles/accessories.py new file mode 100644 index 0000000..67f50d9 --- /dev/null +++ b/src/partnermax/resources/dealers/vehicles/accessories.py @@ -0,0 +1,397 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.dealers.vehicles import accessory_update_params +from ....types.dealers.vehicles.vehicle_accessories_catalog import VehicleAccessoriesCatalog + +__all__ = ["AccessoriesResource", "AsyncAccessoriesResource"] + + +class AccessoriesResource(SyncAPIResource): + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + + @cached_property + def with_raw_response(self) -> AccessoriesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/DealerMax-app/partnermax-python#accessing-raw-response-data-eg-headers + """ + return AccessoriesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccessoriesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/DealerMax-app/partnermax-python#with_streaming_response + """ + return AccessoriesResourceWithStreamingResponse(self) + + def update( + self, + vehicle_id: str, + *, + dealer_id: str, + alloy_wheel_size: Optional[int] | Omit = omit, + equipment_ids: SequenceNotStr[str] | Omit = omit, + optional_ids: SequenceNotStr[str] | Omit = omit, + package_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Set Vehicle Accessories + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return self._put( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories", dealer_id=dealer_id, vehicle_id=vehicle_id + ), + body=maybe_transform( + { + "alloy_wheel_size": alloy_wheel_size, + "equipment_ids": equipment_ids, + "optional_ids": optional_ids, + "package_ids": package_ids, + }, + accessory_update_params.AccessoryUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + def refresh_catalog( + self, + vehicle_id: str, + *, + dealer_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Refresh Vehicle Accessories Catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return self._post( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories/catalog/refresh", + dealer_id=dealer_id, + vehicle_id=vehicle_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + def retrieve_catalog( + self, + vehicle_id: str, + *, + dealer_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Get Vehicle Accessories Catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return self._get( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories/catalog", + dealer_id=dealer_id, + vehicle_id=vehicle_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + +class AsyncAccessoriesResource(AsyncAPIResource): + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + + @cached_property + def with_raw_response(self) -> AsyncAccessoriesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/DealerMax-app/partnermax-python#accessing-raw-response-data-eg-headers + """ + return AsyncAccessoriesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccessoriesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/DealerMax-app/partnermax-python#with_streaming_response + """ + return AsyncAccessoriesResourceWithStreamingResponse(self) + + async def update( + self, + vehicle_id: str, + *, + dealer_id: str, + alloy_wheel_size: Optional[int] | Omit = omit, + equipment_ids: SequenceNotStr[str] | Omit = omit, + optional_ids: SequenceNotStr[str] | Omit = omit, + package_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Set Vehicle Accessories + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return await self._put( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories", dealer_id=dealer_id, vehicle_id=vehicle_id + ), + body=await async_maybe_transform( + { + "alloy_wheel_size": alloy_wheel_size, + "equipment_ids": equipment_ids, + "optional_ids": optional_ids, + "package_ids": package_ids, + }, + accessory_update_params.AccessoryUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + async def refresh_catalog( + self, + vehicle_id: str, + *, + dealer_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Refresh Vehicle Accessories Catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return await self._post( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories/catalog/refresh", + dealer_id=dealer_id, + vehicle_id=vehicle_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + async def retrieve_catalog( + self, + vehicle_id: str, + *, + dealer_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VehicleAccessoriesCatalog: + """ + Get Vehicle Accessories Catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not dealer_id: + raise ValueError(f"Expected a non-empty value for `dealer_id` but received {dealer_id!r}") + if not vehicle_id: + raise ValueError(f"Expected a non-empty value for `vehicle_id` but received {vehicle_id!r}") + return await self._get( + path_template( + "/v1/dealers/{dealer_id}/vehicles/{vehicle_id}/accessories/catalog", + dealer_id=dealer_id, + vehicle_id=vehicle_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VehicleAccessoriesCatalog, + ) + + +class AccessoriesResourceWithRawResponse: + def __init__(self, accessories: AccessoriesResource) -> None: + self._accessories = accessories + + self.update = to_raw_response_wrapper( + accessories.update, + ) + self.refresh_catalog = to_raw_response_wrapper( + accessories.refresh_catalog, + ) + self.retrieve_catalog = to_raw_response_wrapper( + accessories.retrieve_catalog, + ) + + +class AsyncAccessoriesResourceWithRawResponse: + def __init__(self, accessories: AsyncAccessoriesResource) -> None: + self._accessories = accessories + + self.update = async_to_raw_response_wrapper( + accessories.update, + ) + self.refresh_catalog = async_to_raw_response_wrapper( + accessories.refresh_catalog, + ) + self.retrieve_catalog = async_to_raw_response_wrapper( + accessories.retrieve_catalog, + ) + + +class AccessoriesResourceWithStreamingResponse: + def __init__(self, accessories: AccessoriesResource) -> None: + self._accessories = accessories + + self.update = to_streamed_response_wrapper( + accessories.update, + ) + self.refresh_catalog = to_streamed_response_wrapper( + accessories.refresh_catalog, + ) + self.retrieve_catalog = to_streamed_response_wrapper( + accessories.retrieve_catalog, + ) + + +class AsyncAccessoriesResourceWithStreamingResponse: + def __init__(self, accessories: AsyncAccessoriesResource) -> None: + self._accessories = accessories + + self.update = async_to_streamed_response_wrapper( + accessories.update, + ) + self.refresh_catalog = async_to_streamed_response_wrapper( + accessories.refresh_catalog, + ) + self.retrieve_catalog = async_to_streamed_response_wrapper( + accessories.retrieve_catalog, + ) diff --git a/src/partnermax/resources/dealers/vehicles/images.py b/src/partnermax/resources/dealers/vehicles/images.py index b2aa56b..a43af16 100644 --- a/src/partnermax/resources/dealers/vehicles/images.py +++ b/src/partnermax/resources/dealers/vehicles/images.py @@ -26,9 +26,9 @@ class ImagesResource(SyncAPIResource): - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ @cached_property @@ -211,9 +211,9 @@ def delete( class AsyncImagesResource(AsyncAPIResource): - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ @cached_property diff --git a/src/partnermax/resources/dealers/vehicles/vehicles.py b/src/partnermax/resources/dealers/vehicles/vehicles.py index 91219e2..84f036e 100644 --- a/src/partnermax/resources/dealers/vehicles/vehicles.py +++ b/src/partnermax/resources/dealers/vehicles/vehicles.py @@ -2,7 +2,9 @@ from __future__ import annotations -from typing import Iterable, Optional +from typing import List, Union, Iterable, Optional +from datetime import date +from typing_extensions import Literal import httpx @@ -17,6 +19,14 @@ from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform from ...._compat import cached_property +from .accessories import ( + AccessoriesResource, + AsyncAccessoriesResource, + AccessoriesResourceWithRawResponse, + AsyncAccessoriesResourceWithRawResponse, + AccessoriesResourceWithStreamingResponse, + AsyncAccessoriesResourceWithStreamingResponse, +) from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( to_raw_response_wrapper, @@ -41,19 +51,27 @@ class VehiclesResource(SyncAPIResource): - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ @cached_property def images(self) -> ImagesResource: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return ImagesResource(self._client) + @cached_property + def accessories(self) -> AccessoriesResource: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AccessoriesResource(self._client) + @cached_property def with_raw_response(self) -> VehiclesResourceWithRawResponse: """ @@ -81,19 +99,40 @@ def create( motornet_code: str, plate: str, registration_year: int, - sale_price_eur: float, alloy_wheel_size: Optional[int] | Omit = omit, + base_color: Optional[str] | Omit = omit, + co2_emissions_g_km_override: Optional[float] | Omit = omit, color: Optional[str] | Omit = omit, + cost_price_eur: Optional[float] | Omit = omit, + damage_repaired: Optional[bool] | Omit = omit, description: str | Omit = omit, + double_keys_available: bool | Omit = omit, + enabled_channels: List[Literal["rewind", "nos"]] | Omit = omit, extended_warranty_enabled: bool | Omit = omit, extended_warranty_months: Optional[int] | Omit = omit, - is_for_sale: bool | Omit = omit, + fuel_type_override: Optional[str] | Omit = omit, + inspection_due_date: Union[str, date, None] | Omit = omit, is_visible: bool | Omit = omit, + last_inspection_date: Union[str, date, None] | Omit = omit, + last_inspection_km: Optional[int] | Omit = omit, + last_service_date: Union[str, date, None] | Omit = omit, + last_service_km: Optional[int] | Omit = omit, + last_service_notes: Optional[str] | Omit = omit, notes: Optional[str] | Omit = omit, + ownership_transfer_date: Union[str, date, None] | Omit = omit, + power_kw_override: Optional[int] | Omit = omit, + previous_owner_count: Optional[int] | Omit = omit, + property_tax_due_date: Union[str, date, None] | Omit = omit, registration_month: Optional[int] | Omit = omit, + sale_price_eur: Optional[float] | Omit = omit, + service_history_available: bool | Omit = omit, + trim_alias: Optional[str] | Omit = omit, vat_displayed: bool | Omit = omit, - vehicle_damaged: bool | Omit = omit, + vehicle_damaged: Optional[bool] | Omit = omit, vin: Optional[str] | Omit = omit, + wltp_consumption_combined_l_100km: Optional[float] | Omit = omit, + wltp_consumption_extraurban_l_100km: Optional[float] | Omit = omit, + wltp_consumption_urban_l_100km: Optional[float] | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -118,8 +157,8 @@ def create( motornet_code: Motornet UNI code identifying the exact vehicle configuration. Must exist in the DealerMAX auto/VCOM catalogue at submission time; otherwise the call returns 422 `motornet_code_not_in_catalogue`. Partners may send a code from their own - Motornet agreement or use the paid control-plane targa/VIN resolver before - creating the vehicle. + Motornet agreement or use the paid targa/VIN resolver on api.dealermax.app + before creating the vehicle. plate: Italian licence plate. Uppercased server-side. UNIQUE across the network for active vehicles; reusable once the previous holder withdraws the vehicle from @@ -127,12 +166,11 @@ def create( registration_year: Year of first registration. Upper bound is current year + 1. - sale_price_eur: Public sale price in EUR. Surfaced on MCP / Custom GPT / NLWeb and on the - dealer's site JSON-LD `Offer.price`. + damage_repaired: Tri-state repaired-damage declaration: true=yes, false=no, null=unknown. description: Partner-supplied long description. Surfaced on the dealer site detail page. - is_for_sale: When false the vehicle remains in stock but is not offered for sale. + enabled_channels: Publication channels enabled for this vehicle. Default is ['rewind']. is_visible: Soft-publish flag. When false the row exists in stock but is excluded from consumer-facing AI surfaces. @@ -141,9 +179,16 @@ def create( registration_month: Month of registration (1–12). + sale_price_eur: Public REWIND sale price in EUR. Required when enabled_channels contains + 'rewind'; optional/0 for NOS-only vehicles. + + service_history_available: Dealer-declared certified service-history availability. + vat_displayed: If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive (B2C). + vehicle_damaged: Tri-state damage declaration: true=yes, false=no, null=unknown. + vin: ISO 3779 vehicle identification number. Optional but strongly recommended. extra_headers: Send extra headers @@ -165,19 +210,40 @@ def create( "motornet_code": motornet_code, "plate": plate, "registration_year": registration_year, - "sale_price_eur": sale_price_eur, "alloy_wheel_size": alloy_wheel_size, + "base_color": base_color, + "co2_emissions_g_km_override": co2_emissions_g_km_override, "color": color, + "cost_price_eur": cost_price_eur, + "damage_repaired": damage_repaired, "description": description, + "double_keys_available": double_keys_available, + "enabled_channels": enabled_channels, "extended_warranty_enabled": extended_warranty_enabled, "extended_warranty_months": extended_warranty_months, - "is_for_sale": is_for_sale, + "fuel_type_override": fuel_type_override, + "inspection_due_date": inspection_due_date, "is_visible": is_visible, + "last_inspection_date": last_inspection_date, + "last_inspection_km": last_inspection_km, + "last_service_date": last_service_date, + "last_service_km": last_service_km, + "last_service_notes": last_service_notes, "notes": notes, + "ownership_transfer_date": ownership_transfer_date, + "power_kw_override": power_kw_override, + "previous_owner_count": previous_owner_count, + "property_tax_due_date": property_tax_due_date, "registration_month": registration_month, + "sale_price_eur": sale_price_eur, + "service_history_available": service_history_available, + "trim_alias": trim_alias, "vat_displayed": vat_displayed, "vehicle_damaged": vehicle_damaged, "vin": vin, + "wltp_consumption_combined_l_100km": wltp_consumption_combined_l_100km, + "wltp_consumption_extraurban_l_100km": wltp_consumption_extraurban_l_100km, + "wltp_consumption_urban_l_100km": wltp_consumption_urban_l_100km, }, vehicle_create_params.VehicleCreateParams, ), @@ -240,18 +306,41 @@ def update( *, dealer_id: str, alloy_wheel_size: Optional[int] | Omit = omit, + base_color: Optional[str] | Omit = omit, certified_km: Optional[int] | Omit = omit, + co2_emissions_g_km_override: Optional[float] | Omit = omit, color: Optional[str] | Omit = omit, + cost_price_eur: Optional[float] | Omit = omit, + damage_repaired: Optional[bool] | Omit = omit, description: Optional[str] | Omit = omit, + double_keys_available: Optional[bool] | Omit = omit, + enabled_channels: Optional[List[Literal["rewind", "nos"]]] | Omit = omit, extended_warranty_enabled: Optional[bool] | Omit = omit, extended_warranty_months: Optional[int] | Omit = omit, - is_for_sale: Optional[bool] | Omit = omit, + fuel_type_override: Optional[str] | Omit = omit, + inspection_due_date: Union[str, date, None] | Omit = omit, is_visible: Optional[bool] | Omit = omit, + last_inspection_date: Union[str, date, None] | Omit = omit, + last_inspection_km: Optional[int] | Omit = omit, + last_service_date: Union[str, date, None] | Omit = omit, + last_service_km: Optional[int] | Omit = omit, + last_service_notes: Optional[str] | Omit = omit, notes: Optional[str] | Omit = omit, + ownership_transfer_date: Union[str, date, None] | Omit = omit, + power_kw_override: Optional[int] | Omit = omit, + previous_owner_count: Optional[int] | Omit = omit, + property_tax_due_date: Union[str, date, None] | Omit = omit, registration_month: Optional[int] | Omit = omit, + registration_year: Optional[int] | Omit = omit, sale_price_eur: Optional[float] | Omit = omit, + service_history_available: Optional[bool] | Omit = omit, + trim_alias: Optional[str] | Omit = omit, vat_displayed: Optional[bool] | Omit = omit, vehicle_damaged: Optional[bool] | Omit = omit, + vin: Optional[str] | Omit = omit, + wltp_consumption_combined_l_100km: Optional[float] | Omit = omit, + wltp_consumption_extraurban_l_100km: Optional[float] | Omit = omit, + wltp_consumption_urban_l_100km: Optional[float] | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -286,18 +375,41 @@ def update( body=maybe_transform( { "alloy_wheel_size": alloy_wheel_size, + "base_color": base_color, "certified_km": certified_km, + "co2_emissions_g_km_override": co2_emissions_g_km_override, "color": color, + "cost_price_eur": cost_price_eur, + "damage_repaired": damage_repaired, "description": description, + "double_keys_available": double_keys_available, + "enabled_channels": enabled_channels, "extended_warranty_enabled": extended_warranty_enabled, "extended_warranty_months": extended_warranty_months, - "is_for_sale": is_for_sale, + "fuel_type_override": fuel_type_override, + "inspection_due_date": inspection_due_date, "is_visible": is_visible, + "last_inspection_date": last_inspection_date, + "last_inspection_km": last_inspection_km, + "last_service_date": last_service_date, + "last_service_km": last_service_km, + "last_service_notes": last_service_notes, "notes": notes, + "ownership_transfer_date": ownership_transfer_date, + "power_kw_override": power_kw_override, + "previous_owner_count": previous_owner_count, + "property_tax_due_date": property_tax_due_date, "registration_month": registration_month, + "registration_year": registration_year, "sale_price_eur": sale_price_eur, + "service_history_available": service_history_available, + "trim_alias": trim_alias, "vat_displayed": vat_displayed, "vehicle_damaged": vehicle_damaged, + "vin": vin, + "wltp_consumption_combined_l_100km": wltp_consumption_combined_l_100km, + "wltp_consumption_extraurban_l_100km": wltp_consumption_extraurban_l_100km, + "wltp_consumption_urban_l_100km": wltp_consumption_urban_l_100km, }, vehicle_update_params.VehicleUpdateParams, ), @@ -312,8 +424,8 @@ def list( dealer_id: str, *, cursor: Optional[str] | Omit = omit, + enabled_channel: Optional[Literal["rewind", "nos"]] | Omit = omit, include_deleted: bool | Omit = omit, - is_for_sale: Optional[bool] | Omit = omit, is_visible: Optional[bool] | Omit = omit, limit: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -324,7 +436,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPage[VehicleSummary]: """ - List vehicles in a dealer's stock owned by the calling partner. + List vehicles in the resolved dealer's stock for the calling partner. Cursor pagination is opaque base64url over the last vehicle UUID. Default sort is `i.data_inserimento ASC` so freshly provisioned vehicles surface at the tail. @@ -332,11 +444,11 @@ def list( this preserves the soft-delete semantic across the API contract. Args: + enabled_channel: Filter vehicles enabled on one publication channel: rewind or nos. + include_deleted: If true, soft-deleted rows (`venduto_il` populated) are also returned. Default false — listings hide soft-deleted vehicles. - is_for_sale: Filter on the sale flag. - is_visible: Filter on the visibility flag. extra_headers: Send extra headers @@ -360,8 +472,8 @@ def list( query=maybe_transform( { "cursor": cursor, + "enabled_channel": enabled_channel, "include_deleted": include_deleted, - "is_for_sale": is_for_sale, "is_visible": is_visible, "limit": limit, }, @@ -485,19 +597,27 @@ def bulk( class AsyncVehiclesResource(AsyncAPIResource): - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ @cached_property def images(self) -> AsyncImagesResource: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncImagesResource(self._client) + @cached_property + def accessories(self) -> AsyncAccessoriesResource: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AsyncAccessoriesResource(self._client) + @cached_property def with_raw_response(self) -> AsyncVehiclesResourceWithRawResponse: """ @@ -525,19 +645,40 @@ async def create( motornet_code: str, plate: str, registration_year: int, - sale_price_eur: float, alloy_wheel_size: Optional[int] | Omit = omit, + base_color: Optional[str] | Omit = omit, + co2_emissions_g_km_override: Optional[float] | Omit = omit, color: Optional[str] | Omit = omit, + cost_price_eur: Optional[float] | Omit = omit, + damage_repaired: Optional[bool] | Omit = omit, description: str | Omit = omit, + double_keys_available: bool | Omit = omit, + enabled_channels: List[Literal["rewind", "nos"]] | Omit = omit, extended_warranty_enabled: bool | Omit = omit, extended_warranty_months: Optional[int] | Omit = omit, - is_for_sale: bool | Omit = omit, + fuel_type_override: Optional[str] | Omit = omit, + inspection_due_date: Union[str, date, None] | Omit = omit, is_visible: bool | Omit = omit, + last_inspection_date: Union[str, date, None] | Omit = omit, + last_inspection_km: Optional[int] | Omit = omit, + last_service_date: Union[str, date, None] | Omit = omit, + last_service_km: Optional[int] | Omit = omit, + last_service_notes: Optional[str] | Omit = omit, notes: Optional[str] | Omit = omit, + ownership_transfer_date: Union[str, date, None] | Omit = omit, + power_kw_override: Optional[int] | Omit = omit, + previous_owner_count: Optional[int] | Omit = omit, + property_tax_due_date: Union[str, date, None] | Omit = omit, registration_month: Optional[int] | Omit = omit, + sale_price_eur: Optional[float] | Omit = omit, + service_history_available: bool | Omit = omit, + trim_alias: Optional[str] | Omit = omit, vat_displayed: bool | Omit = omit, - vehicle_damaged: bool | Omit = omit, + vehicle_damaged: Optional[bool] | Omit = omit, vin: Optional[str] | Omit = omit, + wltp_consumption_combined_l_100km: Optional[float] | Omit = omit, + wltp_consumption_extraurban_l_100km: Optional[float] | Omit = omit, + wltp_consumption_urban_l_100km: Optional[float] | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -562,8 +703,8 @@ async def create( motornet_code: Motornet UNI code identifying the exact vehicle configuration. Must exist in the DealerMAX auto/VCOM catalogue at submission time; otherwise the call returns 422 `motornet_code_not_in_catalogue`. Partners may send a code from their own - Motornet agreement or use the paid control-plane targa/VIN resolver before - creating the vehicle. + Motornet agreement or use the paid targa/VIN resolver on api.dealermax.app + before creating the vehicle. plate: Italian licence plate. Uppercased server-side. UNIQUE across the network for active vehicles; reusable once the previous holder withdraws the vehicle from @@ -571,12 +712,11 @@ async def create( registration_year: Year of first registration. Upper bound is current year + 1. - sale_price_eur: Public sale price in EUR. Surfaced on MCP / Custom GPT / NLWeb and on the - dealer's site JSON-LD `Offer.price`. + damage_repaired: Tri-state repaired-damage declaration: true=yes, false=no, null=unknown. description: Partner-supplied long description. Surfaced on the dealer site detail page. - is_for_sale: When false the vehicle remains in stock but is not offered for sale. + enabled_channels: Publication channels enabled for this vehicle. Default is ['rewind']. is_visible: Soft-publish flag. When false the row exists in stock but is excluded from consumer-facing AI surfaces. @@ -585,9 +725,16 @@ async def create( registration_month: Month of registration (1–12). + sale_price_eur: Public REWIND sale price in EUR. Required when enabled_channels contains + 'rewind'; optional/0 for NOS-only vehicles. + + service_history_available: Dealer-declared certified service-history availability. + vat_displayed: If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive (B2C). + vehicle_damaged: Tri-state damage declaration: true=yes, false=no, null=unknown. + vin: ISO 3779 vehicle identification number. Optional but strongly recommended. extra_headers: Send extra headers @@ -609,19 +756,40 @@ async def create( "motornet_code": motornet_code, "plate": plate, "registration_year": registration_year, - "sale_price_eur": sale_price_eur, "alloy_wheel_size": alloy_wheel_size, + "base_color": base_color, + "co2_emissions_g_km_override": co2_emissions_g_km_override, "color": color, + "cost_price_eur": cost_price_eur, + "damage_repaired": damage_repaired, "description": description, + "double_keys_available": double_keys_available, + "enabled_channels": enabled_channels, "extended_warranty_enabled": extended_warranty_enabled, "extended_warranty_months": extended_warranty_months, - "is_for_sale": is_for_sale, + "fuel_type_override": fuel_type_override, + "inspection_due_date": inspection_due_date, "is_visible": is_visible, + "last_inspection_date": last_inspection_date, + "last_inspection_km": last_inspection_km, + "last_service_date": last_service_date, + "last_service_km": last_service_km, + "last_service_notes": last_service_notes, "notes": notes, + "ownership_transfer_date": ownership_transfer_date, + "power_kw_override": power_kw_override, + "previous_owner_count": previous_owner_count, + "property_tax_due_date": property_tax_due_date, "registration_month": registration_month, + "sale_price_eur": sale_price_eur, + "service_history_available": service_history_available, + "trim_alias": trim_alias, "vat_displayed": vat_displayed, "vehicle_damaged": vehicle_damaged, "vin": vin, + "wltp_consumption_combined_l_100km": wltp_consumption_combined_l_100km, + "wltp_consumption_extraurban_l_100km": wltp_consumption_extraurban_l_100km, + "wltp_consumption_urban_l_100km": wltp_consumption_urban_l_100km, }, vehicle_create_params.VehicleCreateParams, ), @@ -684,18 +852,41 @@ async def update( *, dealer_id: str, alloy_wheel_size: Optional[int] | Omit = omit, + base_color: Optional[str] | Omit = omit, certified_km: Optional[int] | Omit = omit, + co2_emissions_g_km_override: Optional[float] | Omit = omit, color: Optional[str] | Omit = omit, + cost_price_eur: Optional[float] | Omit = omit, + damage_repaired: Optional[bool] | Omit = omit, description: Optional[str] | Omit = omit, + double_keys_available: Optional[bool] | Omit = omit, + enabled_channels: Optional[List[Literal["rewind", "nos"]]] | Omit = omit, extended_warranty_enabled: Optional[bool] | Omit = omit, extended_warranty_months: Optional[int] | Omit = omit, - is_for_sale: Optional[bool] | Omit = omit, + fuel_type_override: Optional[str] | Omit = omit, + inspection_due_date: Union[str, date, None] | Omit = omit, is_visible: Optional[bool] | Omit = omit, + last_inspection_date: Union[str, date, None] | Omit = omit, + last_inspection_km: Optional[int] | Omit = omit, + last_service_date: Union[str, date, None] | Omit = omit, + last_service_km: Optional[int] | Omit = omit, + last_service_notes: Optional[str] | Omit = omit, notes: Optional[str] | Omit = omit, + ownership_transfer_date: Union[str, date, None] | Omit = omit, + power_kw_override: Optional[int] | Omit = omit, + previous_owner_count: Optional[int] | Omit = omit, + property_tax_due_date: Union[str, date, None] | Omit = omit, registration_month: Optional[int] | Omit = omit, + registration_year: Optional[int] | Omit = omit, sale_price_eur: Optional[float] | Omit = omit, + service_history_available: Optional[bool] | Omit = omit, + trim_alias: Optional[str] | Omit = omit, vat_displayed: Optional[bool] | Omit = omit, vehicle_damaged: Optional[bool] | Omit = omit, + vin: Optional[str] | Omit = omit, + wltp_consumption_combined_l_100km: Optional[float] | Omit = omit, + wltp_consumption_extraurban_l_100km: Optional[float] | Omit = omit, + wltp_consumption_urban_l_100km: Optional[float] | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -730,18 +921,41 @@ async def update( body=await async_maybe_transform( { "alloy_wheel_size": alloy_wheel_size, + "base_color": base_color, "certified_km": certified_km, + "co2_emissions_g_km_override": co2_emissions_g_km_override, "color": color, + "cost_price_eur": cost_price_eur, + "damage_repaired": damage_repaired, "description": description, + "double_keys_available": double_keys_available, + "enabled_channels": enabled_channels, "extended_warranty_enabled": extended_warranty_enabled, "extended_warranty_months": extended_warranty_months, - "is_for_sale": is_for_sale, + "fuel_type_override": fuel_type_override, + "inspection_due_date": inspection_due_date, "is_visible": is_visible, + "last_inspection_date": last_inspection_date, + "last_inspection_km": last_inspection_km, + "last_service_date": last_service_date, + "last_service_km": last_service_km, + "last_service_notes": last_service_notes, "notes": notes, + "ownership_transfer_date": ownership_transfer_date, + "power_kw_override": power_kw_override, + "previous_owner_count": previous_owner_count, + "property_tax_due_date": property_tax_due_date, "registration_month": registration_month, + "registration_year": registration_year, "sale_price_eur": sale_price_eur, + "service_history_available": service_history_available, + "trim_alias": trim_alias, "vat_displayed": vat_displayed, "vehicle_damaged": vehicle_damaged, + "vin": vin, + "wltp_consumption_combined_l_100km": wltp_consumption_combined_l_100km, + "wltp_consumption_extraurban_l_100km": wltp_consumption_extraurban_l_100km, + "wltp_consumption_urban_l_100km": wltp_consumption_urban_l_100km, }, vehicle_update_params.VehicleUpdateParams, ), @@ -756,8 +970,8 @@ def list( dealer_id: str, *, cursor: Optional[str] | Omit = omit, + enabled_channel: Optional[Literal["rewind", "nos"]] | Omit = omit, include_deleted: bool | Omit = omit, - is_for_sale: Optional[bool] | Omit = omit, is_visible: Optional[bool] | Omit = omit, limit: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -768,7 +982,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[VehicleSummary, AsyncCursorPage[VehicleSummary]]: """ - List vehicles in a dealer's stock owned by the calling partner. + List vehicles in the resolved dealer's stock for the calling partner. Cursor pagination is opaque base64url over the last vehicle UUID. Default sort is `i.data_inserimento ASC` so freshly provisioned vehicles surface at the tail. @@ -776,11 +990,11 @@ def list( this preserves the soft-delete semantic across the API contract. Args: + enabled_channel: Filter vehicles enabled on one publication channel: rewind or nos. + include_deleted: If true, soft-deleted rows (`venduto_il` populated) are also returned. Default false — listings hide soft-deleted vehicles. - is_for_sale: Filter on the sale flag. - is_visible: Filter on the visibility flag. extra_headers: Send extra headers @@ -804,8 +1018,8 @@ def list( query=maybe_transform( { "cursor": cursor, + "enabled_channel": enabled_channel, "include_deleted": include_deleted, - "is_for_sale": is_for_sale, "is_visible": is_visible, "limit": limit, }, @@ -953,12 +1167,20 @@ def __init__(self, vehicles: VehiclesResource) -> None: @cached_property def images(self) -> ImagesResourceWithRawResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return ImagesResourceWithRawResponse(self._vehicles.images) + @cached_property + def accessories(self) -> AccessoriesResourceWithRawResponse: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AccessoriesResourceWithRawResponse(self._vehicles.accessories) + class AsyncVehiclesResourceWithRawResponse: def __init__(self, vehicles: AsyncVehiclesResource) -> None: @@ -985,12 +1207,20 @@ def __init__(self, vehicles: AsyncVehiclesResource) -> None: @cached_property def images(self) -> AsyncImagesResourceWithRawResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncImagesResourceWithRawResponse(self._vehicles.images) + @cached_property + def accessories(self) -> AsyncAccessoriesResourceWithRawResponse: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AsyncAccessoriesResourceWithRawResponse(self._vehicles.accessories) + class VehiclesResourceWithStreamingResponse: def __init__(self, vehicles: VehiclesResource) -> None: @@ -1017,12 +1247,20 @@ def __init__(self, vehicles: VehiclesResource) -> None: @cached_property def images(self) -> ImagesResourceWithStreamingResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return ImagesResourceWithStreamingResponse(self._vehicles.images) + @cached_property + def accessories(self) -> AccessoriesResourceWithStreamingResponse: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AccessoriesResourceWithStreamingResponse(self._vehicles.accessories) + class AsyncVehiclesResourceWithStreamingResponse: def __init__(self, vehicles: AsyncVehiclesResource) -> None: @@ -1049,8 +1287,16 @@ def __init__(self, vehicles: AsyncVehiclesResource) -> None: @cached_property def images(self) -> AsyncImagesResourceWithStreamingResponse: - """Used-vehicle stock management for partner-owned dealers. + """Used-vehicle stock management for dealers registered under a partner. - The partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). """ return AsyncImagesResourceWithStreamingResponse(self._vehicles.images) + + @cached_property + def accessories(self) -> AsyncAccessoriesResourceWithStreamingResponse: + """Used-vehicle stock management for dealers registered under a partner. + + Every vehicle request is scoped by dealer_id; the partner uploads each used vehicle by its canonical Motornet UNI code; DealerMAX joins the partner-provided pricing and stock metadata with the catalog master so the resulting listing is immediately indexed by the AI surfaces (MCP server, ChatGPT Custom GPT, NLWeb /ask, and the SEO/JSON-LD layer). + """ + return AsyncAccessoriesResourceWithStreamingResponse(self._vehicles.accessories) diff --git a/src/partnermax/types/dealer_create_params.py b/src/partnermax/types/dealer_create_params.py index 1be5175..bb0a072 100644 --- a/src/partnermax/types/dealer_create_params.py +++ b/src/partnermax/types/dealer_create_params.py @@ -12,7 +12,7 @@ class DealerCreateParams(TypedDict, total=False): external_dealer_id: Required[str] - """Partner-owned opaque dealer id. + """Partner-supplied opaque dealer id. This becomes the dealer_id used by vehicle and NLT SDK calls. """ @@ -20,7 +20,7 @@ class DealerCreateParams(TypedDict, total=False): activate: bool """When true, the dealer can immediately receive vehicle/NLT operations. - When false, create the registry row but keep it suspended until activated. + When false, create the registry row but keep it inactive until activated. """ metadata: Dict[str, Union[str, float, bool, None]] diff --git a/src/partnermax/types/dealer_list_params.py b/src/partnermax/types/dealer_list_params.py index f54d641..959f0a9 100644 --- a/src/partnermax/types/dealer_list_params.py +++ b/src/partnermax/types/dealer_list_params.py @@ -13,4 +13,4 @@ class DealerListParams(TypedDict, total=False): limit: int - status: Literal["active", "inactive", "all"] + status: Literal["active", "inactive", "deleted", "all"] diff --git a/src/partnermax/types/dealers/bulk_row_outcome.py b/src/partnermax/types/dealers/bulk_row_outcome.py index e04e7f9..8c6dcff 100644 --- a/src/partnermax/types/dealers/bulk_row_outcome.py +++ b/src/partnermax/types/dealers/bulk_row_outcome.py @@ -50,7 +50,7 @@ class BulkRowOutcome(BaseModel): consumers display (descriptions, highlights, FAQ, SEO meta). `null` until the worker has processed the vehicle. - Dealer-internal margin and operations data remains outside this SDK surface; - partners receive only the inventory, commercial, catalogue, media, and - AI-derived fields needed to publish the vehicle. + Dealer-entered inventory, commercial, condition, service-history, catalogue, + media, and AI-derived fields are available through the SDK so partners can keep + the same stock record DealerMax shows. """ diff --git a/src/partnermax/types/dealers/nlt/offer_retrieve_response.py b/src/partnermax/types/dealers/nlt/offer_retrieve_response.py index e93444a..9d1f293 100644 --- a/src/partnermax/types/dealers/nlt/offer_retrieve_response.py +++ b/src/partnermax/types/dealers/nlt/offer_retrieve_response.py @@ -147,9 +147,8 @@ class NetworkOffer(BaseModel): """One network dealer's quote for this offer. Sorted by `min_monthly_canon_eur ASC`. In PartnerMAX this list is scoped - to the calling partner's `partner_dealers` rows and returns the - partner-owned `external_dealer_id`. Legacy `dlr_` values remain only - for compatibility callers. + to the calling partner's dealer references and returns the partner-supplied + external dealer id. """ dealer_id: str diff --git a/src/partnermax/types/dealers/vehicle_bulk_params.py b/src/partnermax/types/dealers/vehicle_bulk_params.py index 943ec6a..4fb4ce6 100644 --- a/src/partnermax/types/dealers/vehicle_bulk_params.py +++ b/src/partnermax/types/dealers/vehicle_bulk_params.py @@ -2,8 +2,9 @@ from __future__ import annotations -from typing import Iterable, Optional -from typing_extensions import Required, Annotated, TypedDict +from typing import List, Union, Iterable, Optional +from datetime import date +from typing_extensions import Literal, Required, Annotated, TypedDict from ..._utils import PropertyInfo @@ -30,8 +31,8 @@ class Vehicle(TypedDict, total=False): derived server-side from DealerMAX's licensed Motornet-backed catalogue — the partner never types them. - Fields immutable after creation: `motornet_code`, `plate`, `vin`. Other - fields may be updated via PATCH. + Fields immutable after creation: `motornet_code`, `plate`. The VIN and + other dealer-entered fields may be corrected via PATCH. """ certified_km: Required[int] @@ -42,8 +43,8 @@ class Vehicle(TypedDict, total=False): Must exist in the DealerMAX auto/VCOM catalogue at submission time; otherwise the call returns 422 `motornet_code_not_in_catalogue`. Partners may send a code - from their own Motornet agreement or use the paid control-plane targa/VIN - resolver before creating the vehicle. + from their own Motornet agreement or use the paid targa/VIN resolver on + api.dealermax.app before creating the vehicle. """ plate: Required[str] @@ -56,26 +57,34 @@ class Vehicle(TypedDict, total=False): registration_year: Required[int] """Year of first registration. Upper bound is current year + 1.""" - sale_price_eur: Required[float] - """Public sale price in EUR. + alloy_wheel_size: Optional[int] - Surfaced on MCP / Custom GPT / NLWeb and on the dealer's site JSON-LD - `Offer.price`. - """ + base_color: Optional[str] - alloy_wheel_size: Optional[int] + co2_emissions_g_km_override: Optional[float] color: Optional[str] + cost_price_eur: Optional[float] + + damage_repaired: Optional[bool] + """Tri-state repaired-damage declaration: true=yes, false=no, null=unknown.""" + description: str """Partner-supplied long description. Surfaced on the dealer site detail page.""" + double_keys_available: bool + + enabled_channels: List[Literal["rewind", "nos"]] + """Publication channels enabled for this vehicle. Default is ['rewind'].""" + extended_warranty_enabled: bool extended_warranty_months: Optional[int] - is_for_sale: bool - """When false the vehicle remains in stock but is not offered for sale.""" + fuel_type_override: Optional[str] + + inspection_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] is_visible: bool """Soft-publish flag. @@ -84,19 +93,56 @@ class Vehicle(TypedDict, total=False): surfaces. """ + last_inspection_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_inspection_km: Optional[int] + + last_service_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_service_km: Optional[int] + + last_service_notes: Optional[str] + notes: Optional[str] """Free-form short notes for partner-facing vehicle detail views.""" + ownership_transfer_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + power_kw_override: Optional[int] + + previous_owner_count: Optional[int] + + property_tax_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + registration_month: Optional[int] """Month of registration (1–12).""" + sale_price_eur: Optional[float] + """Public REWIND sale price in EUR. + + Required when enabled_channels contains 'rewind'; optional/0 for NOS-only + vehicles. + """ + + service_history_available: bool + """Dealer-declared certified service-history availability.""" + + trim_alias: Optional[str] + vat_displayed: bool """ If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive (B2C). """ - vehicle_damaged: bool + vehicle_damaged: Optional[bool] + """Tri-state damage declaration: true=yes, false=no, null=unknown.""" vin: Optional[str] """ISO 3779 vehicle identification number. Optional but strongly recommended.""" + + wltp_consumption_combined_l_100km: Optional[float] + + wltp_consumption_extraurban_l_100km: Optional[float] + + wltp_consumption_urban_l_100km: Optional[float] diff --git a/src/partnermax/types/dealers/vehicle_create_params.py b/src/partnermax/types/dealers/vehicle_create_params.py index 30d3887..0303312 100644 --- a/src/partnermax/types/dealers/vehicle_create_params.py +++ b/src/partnermax/types/dealers/vehicle_create_params.py @@ -2,8 +2,9 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Required, Annotated, TypedDict +from typing import List, Union, Optional +from datetime import date +from typing_extensions import Literal, Required, Annotated, TypedDict from ..._utils import PropertyInfo @@ -19,8 +20,8 @@ class VehicleCreateParams(TypedDict, total=False): Must exist in the DealerMAX auto/VCOM catalogue at submission time; otherwise the call returns 422 `motornet_code_not_in_catalogue`. Partners may send a code - from their own Motornet agreement or use the paid control-plane targa/VIN - resolver before creating the vehicle. + from their own Motornet agreement or use the paid targa/VIN resolver on + api.dealermax.app before creating the vehicle. """ plate: Required[str] @@ -33,26 +34,34 @@ class VehicleCreateParams(TypedDict, total=False): registration_year: Required[int] """Year of first registration. Upper bound is current year + 1.""" - sale_price_eur: Required[float] - """Public sale price in EUR. + alloy_wheel_size: Optional[int] - Surfaced on MCP / Custom GPT / NLWeb and on the dealer's site JSON-LD - `Offer.price`. - """ + base_color: Optional[str] - alloy_wheel_size: Optional[int] + co2_emissions_g_km_override: Optional[float] color: Optional[str] + cost_price_eur: Optional[float] + + damage_repaired: Optional[bool] + """Tri-state repaired-damage declaration: true=yes, false=no, null=unknown.""" + description: str """Partner-supplied long description. Surfaced on the dealer site detail page.""" + double_keys_available: bool + + enabled_channels: List[Literal["rewind", "nos"]] + """Publication channels enabled for this vehicle. Default is ['rewind'].""" + extended_warranty_enabled: bool extended_warranty_months: Optional[int] - is_for_sale: bool - """When false the vehicle remains in stock but is not offered for sale.""" + fuel_type_override: Optional[str] + + inspection_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] is_visible: bool """Soft-publish flag. @@ -61,21 +70,58 @@ class VehicleCreateParams(TypedDict, total=False): surfaces. """ + last_inspection_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_inspection_km: Optional[int] + + last_service_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_service_km: Optional[int] + + last_service_notes: Optional[str] + notes: Optional[str] """Free-form short notes for partner-facing vehicle detail views.""" + ownership_transfer_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + power_kw_override: Optional[int] + + previous_owner_count: Optional[int] + + property_tax_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + registration_month: Optional[int] """Month of registration (1–12).""" + sale_price_eur: Optional[float] + """Public REWIND sale price in EUR. + + Required when enabled_channels contains 'rewind'; optional/0 for NOS-only + vehicles. + """ + + service_history_available: bool + """Dealer-declared certified service-history availability.""" + + trim_alias: Optional[str] + vat_displayed: bool """ If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive (B2C). """ - vehicle_damaged: bool + vehicle_damaged: Optional[bool] + """Tri-state damage declaration: true=yes, false=no, null=unknown.""" vin: Optional[str] """ISO 3779 vehicle identification number. Optional but strongly recommended.""" + wltp_consumption_combined_l_100km: Optional[float] + + wltp_consumption_extraurban_l_100km: Optional[float] + + wltp_consumption_urban_l_100km: Optional[float] + idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] diff --git a/src/partnermax/types/dealers/vehicle_detail.py b/src/partnermax/types/dealers/vehicle_detail.py index afff02b..1d2ea0c 100644 --- a/src/partnermax/types/dealers/vehicle_detail.py +++ b/src/partnermax/types/dealers/vehicle_detail.py @@ -1,7 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Dict, List, Optional -from datetime import datetime +from datetime import date, datetime +from typing_extensions import Literal from ..._models import BaseModel from .ai_content import AIContent @@ -27,9 +28,9 @@ class VehicleDetail(BaseModel): cross-network consumers display (descriptions, highlights, FAQ, SEO meta). ``null`` until the worker has processed the vehicle. - Dealer-internal margin and operations data remains outside this SDK - surface; partners receive only the inventory, commercial, catalogue, media, - and AI-derived fields needed to publish the vehicle. + Dealer-entered inventory, commercial, condition, service-history, catalogue, + media, and AI-derived fields are available through the SDK so partners can + keep the same stock record DealerMax shows. """ certified_km: int @@ -40,9 +41,9 @@ class VehicleDetail(BaseModel): description: str - extended_warranty_enabled: bool + enabled_channels: List[Literal["rewind", "nos"]] - is_for_sale: bool + extended_warranty_enabled: bool is_visible: bool @@ -60,8 +61,6 @@ class VehicleDetail(BaseModel): vat_displayed: bool - vehicle_damaged: bool - vehicle_id: str ai_content: Optional[AIContent] = None @@ -71,16 +70,38 @@ class VehicleDetail(BaseModel): seconds). Populated for the same consumer-AI surfaces (MCP, Custom GPT, NLWeb). """ + ai_short: Optional[str] = None + + ai_tagline: Optional[str] = None + alloy_wheel_size: Optional[int] = None + base_color: Optional[str] = None + brand: Optional[str] = None + co2_emissions_g_km_override: Optional[float] = None + color: Optional[str] = None + cost_price_eur: Optional[float] = None + + cover_image_url: Optional[str] = None + + damage_repaired: Optional[bool] = None + + deleted_at: Optional[datetime] = None + + double_keys_available: Optional[bool] = None + extended_warranty_months: Optional[int] = None fuel_type: Optional[str] = None + fuel_type_override: Optional[str] = None + + image_count: Optional[int] = None + image_urls: Optional[List[str]] = None """Vehicle photos in display order. @@ -88,12 +109,34 @@ class VehicleDetail(BaseModel): endpoint). """ + inspection_due_date: Optional[date] = None + + last_inspection_date: Optional[date] = None + + last_inspection_km: Optional[int] = None + + last_service_date: Optional[date] = None + + last_service_km: Optional[int] = None + + last_service_notes: Optional[str] = None + model: Optional[str] = None notes: Optional[str] = None + ownership_transfer_date: Optional[date] = None + + power_kw_override: Optional[int] = None + + previous_owner_count: Optional[int] = None + + property_tax_due_date: Optional[date] = None + registration_month: Optional[int] = None + service_history_available: Optional[bool] = None + technical_details: Optional[Dict[str, object]] = None """Flat dictionary of Motornet-backed technical attributes for this `motornet_code`. @@ -104,4 +147,14 @@ class VehicleDetail(BaseModel): trim: Optional[str] = None + trim_alias: Optional[str] = None + + vehicle_damaged: Optional[bool] = None + vin: Optional[str] = None + + wltp_consumption_combined_l_100km: Optional[float] = None + + wltp_consumption_extraurban_l_100km: Optional[float] = None + + wltp_consumption_urban_l_100km: Optional[float] = None diff --git a/src/partnermax/types/dealers/vehicle_list_params.py b/src/partnermax/types/dealers/vehicle_list_params.py index 3380df1..c1270aa 100644 --- a/src/partnermax/types/dealers/vehicle_list_params.py +++ b/src/partnermax/types/dealers/vehicle_list_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Optional -from typing_extensions import TypedDict +from typing_extensions import Literal, TypedDict __all__ = ["VehicleListParams"] @@ -11,15 +11,15 @@ class VehicleListParams(TypedDict, total=False): cursor: Optional[str] + enabled_channel: Optional[Literal["rewind", "nos"]] + """Filter vehicles enabled on one publication channel: rewind or nos.""" + include_deleted: bool """If true, soft-deleted rows (`venduto_il` populated) are also returned. Default false — listings hide soft-deleted vehicles. """ - is_for_sale: Optional[bool] - """Filter on the sale flag.""" - is_visible: Optional[bool] """Filter on the visibility flag.""" diff --git a/src/partnermax/types/dealers/vehicle_summary.py b/src/partnermax/types/dealers/vehicle_summary.py index 81fb90d..4eebeff 100644 --- a/src/partnermax/types/dealers/vehicle_summary.py +++ b/src/partnermax/types/dealers/vehicle_summary.py @@ -1,7 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel @@ -23,10 +24,12 @@ class VehicleSummary(BaseModel): dealer_id: str - is_for_sale: bool + enabled_channels: List[Literal["rewind", "nos"]] is_visible: bool + last_modified_at: datetime + motornet_code: str plate: str @@ -35,14 +38,36 @@ class VehicleSummary(BaseModel): sale_price_eur: float + vat_displayed: bool + vehicle_id: str + ai_short: Optional[str] = None + + ai_tagline: Optional[str] = None + brand: Optional[str] = None color: Optional[str] = None + cost_price_eur: Optional[float] = None + + cover_image_url: Optional[str] = None + + damage_repaired: Optional[bool] = None + + deleted_at: Optional[datetime] = None + fuel_type: Optional[str] = None + image_count: Optional[int] = None + model: Optional[str] = None + registration_month: Optional[int] = None + trim: Optional[str] = None + + trim_alias: Optional[str] = None + + vehicle_damaged: Optional[bool] = None diff --git a/src/partnermax/types/dealers/vehicle_update_params.py b/src/partnermax/types/dealers/vehicle_update_params.py index eaa57da..4208d3d 100644 --- a/src/partnermax/types/dealers/vehicle_update_params.py +++ b/src/partnermax/types/dealers/vehicle_update_params.py @@ -2,8 +2,9 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Required, Annotated, TypedDict +from typing import List, Union, Optional +from datetime import date +from typing_extensions import Literal, Required, Annotated, TypedDict from ..._utils import PropertyInfo @@ -15,28 +16,74 @@ class VehicleUpdateParams(TypedDict, total=False): alloy_wheel_size: Optional[int] + base_color: Optional[str] + certified_km: Optional[int] + co2_emissions_g_km_override: Optional[float] + color: Optional[str] + cost_price_eur: Optional[float] + + damage_repaired: Optional[bool] + description: Optional[str] + double_keys_available: Optional[bool] + + enabled_channels: Optional[List[Literal["rewind", "nos"]]] + extended_warranty_enabled: Optional[bool] extended_warranty_months: Optional[int] - is_for_sale: Optional[bool] + fuel_type_override: Optional[str] + + inspection_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] is_visible: Optional[bool] + last_inspection_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_inspection_km: Optional[int] + + last_service_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + last_service_km: Optional[int] + + last_service_notes: Optional[str] + notes: Optional[str] + ownership_transfer_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + + power_kw_override: Optional[int] + + previous_owner_count: Optional[int] + + property_tax_due_date: Annotated[Union[str, date, None], PropertyInfo(format="iso8601")] + registration_month: Optional[int] + registration_year: Optional[int] + sale_price_eur: Optional[float] + service_history_available: Optional[bool] + + trim_alias: Optional[str] + vat_displayed: Optional[bool] vehicle_damaged: Optional[bool] + vin: Optional[str] + + wltp_consumption_combined_l_100km: Optional[float] + + wltp_consumption_extraurban_l_100km: Optional[float] + + wltp_consumption_urban_l_100km: Optional[float] + idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] diff --git a/src/partnermax/types/dealers/vehicles/__init__.py b/src/partnermax/types/dealers/vehicles/__init__.py index 7eafcde..bc7f842 100644 --- a/src/partnermax/types/dealers/vehicles/__init__.py +++ b/src/partnermax/types/dealers/vehicles/__init__.py @@ -5,3 +5,6 @@ from .vehicle_image import VehicleImage as VehicleImage from .vehicle_image_list import VehicleImageList as VehicleImageList from .image_create_params import ImageCreateParams as ImageCreateParams +from .vehicle_accessory_item import VehicleAccessoryItem as VehicleAccessoryItem +from .accessory_update_params import AccessoryUpdateParams as AccessoryUpdateParams +from .vehicle_accessories_catalog import VehicleAccessoriesCatalog as VehicleAccessoriesCatalog diff --git a/src/partnermax/types/dealers/vehicles/accessory_update_params.py b/src/partnermax/types/dealers/vehicles/accessory_update_params.py new file mode 100644 index 0000000..8bf5079 --- /dev/null +++ b/src/partnermax/types/dealers/vehicles/accessory_update_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["AccessoryUpdateParams"] + + +class AccessoryUpdateParams(TypedDict, total=False): + dealer_id: Required[str] + + alloy_wheel_size: Optional[int] + + equipment_ids: SequenceNotStr[str] + + optional_ids: SequenceNotStr[str] + + package_ids: SequenceNotStr[str] diff --git a/src/partnermax/types/dealers/vehicles/vehicle_accessories_catalog.py b/src/partnermax/types/dealers/vehicles/vehicle_accessories_catalog.py new file mode 100644 index 0000000..94ce637 --- /dev/null +++ b/src/partnermax/types/dealers/vehicles/vehicle_accessories_catalog.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel +from .vehicle_accessory_item import VehicleAccessoryItem + +__all__ = ["VehicleAccessoriesCatalog"] + + +class VehicleAccessoriesCatalog(BaseModel): + """Per-vehicle accessories catalog plus current selections.""" + + alloy_wheel_size: Optional[int] = None + + equipment: Optional[List[VehicleAccessoryItem]] = None + + optionals: Optional[List[VehicleAccessoryItem]] = None + + packages: Optional[List[VehicleAccessoryItem]] = None + + series: Optional[List[VehicleAccessoryItem]] = None diff --git a/src/partnermax/types/dealers/vehicles/vehicle_accessory_item.py b/src/partnermax/types/dealers/vehicles/vehicle_accessory_item.py new file mode 100644 index 0000000..58141a4 --- /dev/null +++ b/src/partnermax/types/dealers/vehicles/vehicle_accessory_item.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["VehicleAccessoryItem"] + + +class VehicleAccessoryItem(BaseModel): + """Single accessory/equipment row available for a used vehicle.""" + + id: str + + description: str + + category: Optional[str] = None + + code: Optional[str] = None + + group: Optional[str] = None + + price_eur: Optional[float] = None + + selected: Optional[bool] = None diff --git a/src/partnermax/types/partner_dealer_response.py b/src/partnermax/types/partner_dealer_response.py index c43ac8d..0f9247d 100644 --- a/src/partnermax/types/partner_dealer_response.py +++ b/src/partnermax/types/partner_dealer_response.py @@ -18,13 +18,18 @@ class PartnerDealerResponse(BaseModel): created_at: datetime dealer_id: str - """The partner-owned external dealer id.""" + """The partner-supplied external dealer id.""" partner_id: str public_surfaces_enabled: bool - status: Literal["active", "suspended", "revoked"] + status: Literal["active", "inactive", "deleted"] + """Public API status. + + The backing registry may store internal states such as suspended/revoked, but + SDK responses expose inactive/deleted. + """ updated_at: datetime diff --git a/tests/api_resources/dealers/test_vehicles.py b/tests/api_resources/dealers/test_vehicles.py index 265a4e0..bfeaa9f 100644 --- a/tests/api_resources/dealers/test_vehicles.py +++ b/tests/api_resources/dealers/test_vehicles.py @@ -9,6 +9,7 @@ from partnermax import Partnermax, AsyncPartnermax from tests.utils import assert_matches_type +from partnermax._utils import parse_date from partnermax.pagination import SyncCursorPage, AsyncCursorPage from partnermax.types.dealers import ( VehicleDetail, @@ -31,7 +32,6 @@ def test_method_create(self, client: Partnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -44,19 +44,40 @@ def test_method_create_with_all_params(self, client: Partnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, alloy_wheel_size=13, + base_color="base_color", + co2_emissions_g_km_override=0, color="color", + cost_price_eur=0, + damage_repaired=True, description="description", + double_keys_available=True, + enabled_channels=["rewind"], extended_warranty_enabled=True, extended_warranty_months=1, - is_for_sale=True, + fuel_type_override="fuel_type_override", + inspection_due_date=parse_date("2019-12-27"), is_visible=True, + last_inspection_date=parse_date("2019-12-27"), + last_inspection_km=0, + last_service_date=parse_date("2019-12-27"), + last_service_km=0, + last_service_notes="last_service_notes", notes="notes", + ownership_transfer_date=parse_date("2019-12-27"), + power_kw_override=1, + previous_owner_count=0, + property_tax_due_date=parse_date("2019-12-27"), registration_month=1, + sale_price_eur=0, + service_history_available=True, + trim_alias="trim_alias", vat_displayed=True, vehicle_damaged=True, vin="PTNLCJPPNYGP316PJ", + wltp_consumption_combined_l_100km=0, + wltp_consumption_extraurban_l_100km=0, + wltp_consumption_urban_l_100km=0, idempotency_key="Idempotency-Key", ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -70,7 +91,6 @@ def test_raw_response_create(self, client: Partnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) assert response.is_closed is True @@ -87,7 +107,6 @@ def test_streaming_response_create(self, client: Partnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -107,7 +126,6 @@ def test_path_params_create(self, client: Partnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -188,18 +206,41 @@ def test_method_update_with_all_params(self, client: Partnermax) -> None: vehicle_id="vehicle_id", dealer_id="dealer_id", alloy_wheel_size=13, + base_color="base_color", certified_km=0, + co2_emissions_g_km_override=0, color="color", + cost_price_eur=0, + damage_repaired=True, description="description", + double_keys_available=True, + enabled_channels=["rewind"], extended_warranty_enabled=True, extended_warranty_months=1, - is_for_sale=True, + fuel_type_override="fuel_type_override", + inspection_due_date=parse_date("2019-12-27"), is_visible=True, + last_inspection_date=parse_date("2019-12-27"), + last_inspection_km=0, + last_service_date=parse_date("2019-12-27"), + last_service_km=0, + last_service_notes="last_service_notes", notes="notes", + ownership_transfer_date=parse_date("2019-12-27"), + power_kw_override=1, + previous_owner_count=0, + property_tax_due_date=parse_date("2019-12-27"), registration_month=1, - sale_price_eur=100, + registration_year=1960, + sale_price_eur=0, + service_history_available=True, + trim_alias="trim_alias", vat_displayed=True, vehicle_damaged=True, + vin="PTNLCJPPNYGP316PJ", + wltp_consumption_combined_l_100km=0, + wltp_consumption_extraurban_l_100km=0, + wltp_consumption_urban_l_100km=0, idempotency_key="Idempotency-Key", ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -261,8 +302,8 @@ def test_method_list_with_all_params(self, client: Partnermax) -> None: vehicle = client.dealers.vehicles.list( dealer_id="dealer_id", cursor="cursor", + enabled_channel="rewind", include_deleted=True, - is_for_sale=True, is_visible=True, limit=1, ) @@ -365,7 +406,6 @@ def test_method_bulk(self, client: Partnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) @@ -382,19 +422,40 @@ def test_method_bulk_with_all_params(self, client: Partnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, "alloy_wheel_size": 13, + "base_color": "base_color", + "co2_emissions_g_km_override": 0, "color": "color", + "cost_price_eur": 0, + "damage_repaired": True, "description": "description", + "double_keys_available": True, + "enabled_channels": ["rewind"], "extended_warranty_enabled": True, "extended_warranty_months": 1, - "is_for_sale": True, + "fuel_type_override": "fuel_type_override", + "inspection_due_date": parse_date("2019-12-27"), "is_visible": True, + "last_inspection_date": parse_date("2019-12-27"), + "last_inspection_km": 0, + "last_service_date": parse_date("2019-12-27"), + "last_service_km": 0, + "last_service_notes": "last_service_notes", "notes": "notes", + "ownership_transfer_date": parse_date("2019-12-27"), + "power_kw_override": 1, + "previous_owner_count": 0, + "property_tax_due_date": parse_date("2019-12-27"), "registration_month": 1, + "sale_price_eur": 0, + "service_history_available": True, + "trim_alias": "trim_alias", "vat_displayed": True, "vehicle_damaged": True, "vin": "PTNLCJPPNYGP316PJ", + "wltp_consumption_combined_l_100km": 0, + "wltp_consumption_extraurban_l_100km": 0, + "wltp_consumption_urban_l_100km": 0, } ], idempotency_key="Idempotency-Key", @@ -412,7 +473,6 @@ def test_raw_response_bulk(self, client: Partnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) @@ -433,7 +493,6 @@ def test_streaming_response_bulk(self, client: Partnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) as response: @@ -457,7 +516,6 @@ def test_path_params_bulk(self, client: Partnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) @@ -477,7 +535,6 @@ async def test_method_create(self, async_client: AsyncPartnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -490,19 +547,40 @@ async def test_method_create_with_all_params(self, async_client: AsyncPartnermax motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, alloy_wheel_size=13, + base_color="base_color", + co2_emissions_g_km_override=0, color="color", + cost_price_eur=0, + damage_repaired=True, description="description", + double_keys_available=True, + enabled_channels=["rewind"], extended_warranty_enabled=True, extended_warranty_months=1, - is_for_sale=True, + fuel_type_override="fuel_type_override", + inspection_due_date=parse_date("2019-12-27"), is_visible=True, + last_inspection_date=parse_date("2019-12-27"), + last_inspection_km=0, + last_service_date=parse_date("2019-12-27"), + last_service_km=0, + last_service_notes="last_service_notes", notes="notes", + ownership_transfer_date=parse_date("2019-12-27"), + power_kw_override=1, + previous_owner_count=0, + property_tax_due_date=parse_date("2019-12-27"), registration_month=1, + sale_price_eur=0, + service_history_available=True, + trim_alias="trim_alias", vat_displayed=True, vehicle_damaged=True, vin="PTNLCJPPNYGP316PJ", + wltp_consumption_combined_l_100km=0, + wltp_consumption_extraurban_l_100km=0, + wltp_consumption_urban_l_100km=0, idempotency_key="Idempotency-Key", ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -516,7 +594,6 @@ async def test_raw_response_create(self, async_client: AsyncPartnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) assert response.is_closed is True @@ -533,7 +610,6 @@ async def test_streaming_response_create(self, async_client: AsyncPartnermax) -> motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -553,7 +629,6 @@ async def test_path_params_create(self, async_client: AsyncPartnermax) -> None: motornet_code="xxxx", plate="26F1KLZN", registration_year=1960, - sale_price_eur=100, ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -634,18 +709,41 @@ async def test_method_update_with_all_params(self, async_client: AsyncPartnermax vehicle_id="vehicle_id", dealer_id="dealer_id", alloy_wheel_size=13, + base_color="base_color", certified_km=0, + co2_emissions_g_km_override=0, color="color", + cost_price_eur=0, + damage_repaired=True, description="description", + double_keys_available=True, + enabled_channels=["rewind"], extended_warranty_enabled=True, extended_warranty_months=1, - is_for_sale=True, + fuel_type_override="fuel_type_override", + inspection_due_date=parse_date("2019-12-27"), is_visible=True, + last_inspection_date=parse_date("2019-12-27"), + last_inspection_km=0, + last_service_date=parse_date("2019-12-27"), + last_service_km=0, + last_service_notes="last_service_notes", notes="notes", + ownership_transfer_date=parse_date("2019-12-27"), + power_kw_override=1, + previous_owner_count=0, + property_tax_due_date=parse_date("2019-12-27"), registration_month=1, - sale_price_eur=100, + registration_year=1960, + sale_price_eur=0, + service_history_available=True, + trim_alias="trim_alias", vat_displayed=True, vehicle_damaged=True, + vin="PTNLCJPPNYGP316PJ", + wltp_consumption_combined_l_100km=0, + wltp_consumption_extraurban_l_100km=0, + wltp_consumption_urban_l_100km=0, idempotency_key="Idempotency-Key", ) assert_matches_type(VehicleDetail, vehicle, path=["response"]) @@ -707,8 +805,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncPartnermax) vehicle = await async_client.dealers.vehicles.list( dealer_id="dealer_id", cursor="cursor", + enabled_channel="rewind", include_deleted=True, - is_for_sale=True, is_visible=True, limit=1, ) @@ -811,7 +909,6 @@ async def test_method_bulk(self, async_client: AsyncPartnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) @@ -828,19 +925,40 @@ async def test_method_bulk_with_all_params(self, async_client: AsyncPartnermax) "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, "alloy_wheel_size": 13, + "base_color": "base_color", + "co2_emissions_g_km_override": 0, "color": "color", + "cost_price_eur": 0, + "damage_repaired": True, "description": "description", + "double_keys_available": True, + "enabled_channels": ["rewind"], "extended_warranty_enabled": True, "extended_warranty_months": 1, - "is_for_sale": True, + "fuel_type_override": "fuel_type_override", + "inspection_due_date": parse_date("2019-12-27"), "is_visible": True, + "last_inspection_date": parse_date("2019-12-27"), + "last_inspection_km": 0, + "last_service_date": parse_date("2019-12-27"), + "last_service_km": 0, + "last_service_notes": "last_service_notes", "notes": "notes", + "ownership_transfer_date": parse_date("2019-12-27"), + "power_kw_override": 1, + "previous_owner_count": 0, + "property_tax_due_date": parse_date("2019-12-27"), "registration_month": 1, + "sale_price_eur": 0, + "service_history_available": True, + "trim_alias": "trim_alias", "vat_displayed": True, "vehicle_damaged": True, "vin": "PTNLCJPPNYGP316PJ", + "wltp_consumption_combined_l_100km": 0, + "wltp_consumption_extraurban_l_100km": 0, + "wltp_consumption_urban_l_100km": 0, } ], idempotency_key="Idempotency-Key", @@ -858,7 +976,6 @@ async def test_raw_response_bulk(self, async_client: AsyncPartnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) @@ -879,7 +996,6 @@ async def test_streaming_response_bulk(self, async_client: AsyncPartnermax) -> N "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) as response: @@ -903,7 +1019,6 @@ async def test_path_params_bulk(self, async_client: AsyncPartnermax) -> None: "motornet_code": "xxxx", "plate": "26F1KLZN", "registration_year": 1960, - "sale_price_eur": 100, } ], ) diff --git a/tests/api_resources/dealers/vehicles/test_accessories.py b/tests/api_resources/dealers/vehicles/test_accessories.py new file mode 100644 index 0000000..559fbb7 --- /dev/null +++ b/tests/api_resources/dealers/vehicles/test_accessories.py @@ -0,0 +1,362 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from partnermax import Partnermax, AsyncPartnermax +from tests.utils import assert_matches_type +from partnermax.types.dealers.vehicles import VehicleAccessoriesCatalog + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAccessories: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Partnermax) -> None: + accessory = client.dealers.vehicles.accessories.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Partnermax) -> None: + accessory = client.dealers.vehicles.accessories.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + alloy_wheel_size=13, + equipment_ids=["string"], + optional_ids=["string"], + package_ids=["string"], + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Partnermax) -> None: + response = client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Partnermax) -> None: + with client.dealers.vehicles.accessories.with_streaming_response.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="", + dealer_id="dealer_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_refresh_catalog(self, client: Partnermax) -> None: + accessory = client.dealers.vehicles.accessories.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_refresh_catalog(self, client: Partnermax) -> None: + response = client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_refresh_catalog(self, client: Partnermax) -> None: + with client.dealers.vehicles.accessories.with_streaming_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_refresh_catalog(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="", + dealer_id="dealer_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve_catalog(self, client: Partnermax) -> None: + accessory = client.dealers.vehicles.accessories.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve_catalog(self, client: Partnermax) -> None: + response = client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve_catalog(self, client: Partnermax) -> None: + with client.dealers.vehicles.accessories.with_streaming_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve_catalog(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="", + dealer_id="dealer_id", + ) + + +class TestAsyncAccessories: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncPartnermax) -> None: + accessory = await async_client.dealers.vehicles.accessories.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncPartnermax) -> None: + accessory = await async_client.dealers.vehicles.accessories.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + alloy_wheel_size=13, + equipment_ids=["string"], + optional_ids=["string"], + package_ids=["string"], + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.vehicles.accessories.with_streaming_response.update( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.update( + vehicle_id="", + dealer_id="dealer_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_refresh_catalog(self, async_client: AsyncPartnermax) -> None: + accessory = await async_client.dealers.vehicles.accessories.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_refresh_catalog(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_refresh_catalog(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.vehicles.accessories.with_streaming_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_refresh_catalog(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.refresh_catalog( + vehicle_id="", + dealer_id="dealer_id", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve_catalog(self, async_client: AsyncPartnermax) -> None: + accessory = await async_client.dealers.vehicles.accessories.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve_catalog(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve_catalog(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.vehicles.accessories.with_streaming_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="dealer_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + accessory = await response.parse() + assert_matches_type(VehicleAccessoriesCatalog, accessory, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve_catalog(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `dealer_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="vehicle_id", + dealer_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `vehicle_id` but received ''"): + await async_client.dealers.vehicles.accessories.with_raw_response.retrieve_catalog( + vehicle_id="", + dealer_id="dealer_id", + ) diff --git a/tests/api_resources/test_dealers.py b/tests/api_resources/test_dealers.py index 2cb8dbb..0efa3af 100644 --- a/tests/api_resources/test_dealers.py +++ b/tests/api_resources/test_dealers.py @@ -249,6 +249,132 @@ def test_path_params_delete(self, client: Partnermax) -> None: "", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_activate_reference(self, client: Partnermax) -> None: + dealer = client.dealers.activate_reference( + "x", + ) + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_activate_reference(self, client: Partnermax) -> None: + response = client.dealers.with_raw_response.activate_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_activate_reference(self, client: Partnermax) -> None: + with client.dealers.with_streaming_response.activate_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_activate_reference(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + client.dealers.with_raw_response.activate_reference( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_revoke_reference(self, client: Partnermax) -> None: + dealer = client.dealers.revoke_reference( + "x", + ) + assert dealer is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_revoke_reference(self, client: Partnermax) -> None: + response = client.dealers.with_raw_response.revoke_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = response.parse() + assert dealer is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_revoke_reference(self, client: Partnermax) -> None: + with client.dealers.with_streaming_response.revoke_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = response.parse() + assert dealer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_revoke_reference(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + client.dealers.with_raw_response.revoke_reference( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_suspend_reference(self, client: Partnermax) -> None: + dealer = client.dealers.suspend_reference( + "x", + ) + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_suspend_reference(self, client: Partnermax) -> None: + response = client.dealers.with_raw_response.suspend_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_suspend_reference(self, client: Partnermax) -> None: + with client.dealers.with_streaming_response.suspend_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_suspend_reference(self, client: Partnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + client.dealers.with_raw_response.suspend_reference( + "", + ) + class TestAsyncDealers: parametrize = pytest.mark.parametrize( @@ -481,3 +607,129 @@ async def test_path_params_delete(self, async_client: AsyncPartnermax) -> None: await async_client.dealers.with_raw_response.delete( "", ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_activate_reference(self, async_client: AsyncPartnermax) -> None: + dealer = await async_client.dealers.activate_reference( + "x", + ) + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_activate_reference(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.with_raw_response.activate_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = await response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_activate_reference(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.with_streaming_response.activate_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = await response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_activate_reference(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + await async_client.dealers.with_raw_response.activate_reference( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_revoke_reference(self, async_client: AsyncPartnermax) -> None: + dealer = await async_client.dealers.revoke_reference( + "x", + ) + assert dealer is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_revoke_reference(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.with_raw_response.revoke_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = await response.parse() + assert dealer is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_revoke_reference(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.with_streaming_response.revoke_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = await response.parse() + assert dealer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_revoke_reference(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + await async_client.dealers.with_raw_response.revoke_reference( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_suspend_reference(self, async_client: AsyncPartnermax) -> None: + dealer = await async_client.dealers.suspend_reference( + "x", + ) + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_suspend_reference(self, async_client: AsyncPartnermax) -> None: + response = await async_client.dealers.with_raw_response.suspend_reference( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dealer = await response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_suspend_reference(self, async_client: AsyncPartnermax) -> None: + async with async_client.dealers.with_streaming_response.suspend_reference( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dealer = await response.parse() + assert_matches_type(PartnerDealerResponse, dealer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_suspend_reference(self, async_client: AsyncPartnermax) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `external_dealer_id` but received ''"): + await async_client.dealers.with_raw_response.suspend_reference( + "", + )