Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.9.0"
".": "0.10.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 21
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/azure/partnermax-5a0409bb0fddcda8df26a189afdb3328c0402ce1385e56c4793e2969efd2b290.yml
openapi_spec_hash: fa78b80fb8127ab4e7761cbf9ccbbdd2
config_hash: 84dd1a86856c12a806c07e9e23badbfd
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/azure/partnermax-aee817a9450d1094d357a560cebc1c876863fb7d1c712efaf2509a567cd55954.yml
openapi_spec_hash: 6f576691201740bbee9e1f7f97bdd9b0
config_hash: 18c6c7df17bad3320b9f2c126947f00a
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.10.0 (2026-05-18)

Full Changelog: [v0.9.0...v0.10.0](https://github.com/DealerMax-app/partnermax-python/compare/v0.9.0...v0.10.0)

### Features

* **vehicles:** used-vehicle CRUD + bulk insert for v1.1.0 ([85e4b4f](https://github.com/DealerMax-app/partnermax-python/commit/85e4b4fb69db79b37dbb528c403763138d147ce4))

## 0.9.0 (2026-05-18)

Full Changelog: [v0.8.0...v0.9.0](https://github.com/DealerMax-app/partnermax-python/compare/v0.8.0...v0.9.0)
Expand Down
1 change: 1 addition & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Types:

```python
from partnermax.types.dealers import (
AIContent,
BulkCreateVehiclesResponse,
BulkRowOutcome,
VehicleDetail,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "partnermax"
version = "0.9.0"
version = "0.10.0"
description = "The official Python library for the partnermax API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/partnermax/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "partnermax"
__version__ = "0.9.0" # x-release-please-version
__version__ = "0.10.0" # x-release-please-version
77 changes: 1 addition & 76 deletions src/partnermax/resources/dealers/vehicles/vehicles.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from __future__ import annotations

from typing import Union, Iterable, Optional
from datetime import date
from typing import Iterable, Optional

import httpx

Expand Down Expand Up @@ -78,7 +77,6 @@ def create(
dealer_id: str,
*,
certified_km: int,
cost_price_eur: float,
motornet_code: str,
plate: str,
registration_year: int,
Expand All @@ -88,17 +86,10 @@ def create(
description: str | Omit = omit,
extended_warranty_enabled: bool | Omit = omit,
extended_warranty_months: Optional[int] | Omit = omit,
inspection_expiry_date: Union[str, date, None] | Omit = omit,
is_for_sale: bool | Omit = omit,
is_visible: bool | 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,
previous_owner_count: Optional[int] | Omit = omit,
previous_ownership_transfer_date: Union[str, date, None] | Omit = omit,
registration_month: Optional[int] | Omit = omit,
road_tax_expiry_date: Union[str, date, None] | Omit = omit,
vat_displayed: bool | Omit = omit,
vehicle_damaged: bool | Omit = omit,
vin: Optional[str] | Omit = omit,
Expand All @@ -124,9 +115,6 @@ def create(
Args:
certified_km: Certified odometer reading at intake, in kilometres.

cost_price_eur: Cost basis to the dealer in EUR (partner/dealer internal). Not surfaced on
consumer-facing AI surfaces; used by dealer reporting and margin analytics only.

motornet_code: Motornet UNI code identifying the exact vehicle configuration. Must exist in
`mnet_dettagli_usato` at submission time; otherwise the call returns 422
`motornet_code_not_in_catalogue`. The partner is expected to source this from
Expand All @@ -151,8 +139,6 @@ def create(

notes: Free-form short notes; surfaced as `mnet_dettagli.precisazioni`-style.

previous_ownership_transfer_date: Date of the most recent ownership transfer, if known.

registration_month: Month of registration (1–12).

vat_displayed: If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive
Expand All @@ -176,7 +162,6 @@ def create(
body=maybe_transform(
{
"certified_km": certified_km,
"cost_price_eur": cost_price_eur,
"motornet_code": motornet_code,
"plate": plate,
"registration_year": registration_year,
Expand All @@ -186,17 +171,10 @@ def create(
"description": description,
"extended_warranty_enabled": extended_warranty_enabled,
"extended_warranty_months": extended_warranty_months,
"inspection_expiry_date": inspection_expiry_date,
"is_for_sale": is_for_sale,
"is_visible": is_visible,
"last_service_date": last_service_date,
"last_service_km": last_service_km,
"last_service_notes": last_service_notes,
"notes": notes,
"previous_owner_count": previous_owner_count,
"previous_ownership_transfer_date": previous_ownership_transfer_date,
"registration_month": registration_month,
"road_tax_expiry_date": road_tax_expiry_date,
"vat_displayed": vat_displayed,
"vehicle_damaged": vehicle_damaged,
"vin": vin,
Expand Down Expand Up @@ -264,21 +242,13 @@ def update(
alloy_wheel_size: Optional[int] | Omit = omit,
certified_km: Optional[int] | Omit = omit,
color: Optional[str] | Omit = omit,
cost_price_eur: Optional[float] | Omit = omit,
description: Optional[str] | Omit = omit,
extended_warranty_enabled: Optional[bool] | Omit = omit,
extended_warranty_months: Optional[int] | Omit = omit,
inspection_expiry_date: Union[str, date, None] | Omit = omit,
is_for_sale: Optional[bool] | Omit = omit,
is_visible: Optional[bool] | 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,
previous_owner_count: Optional[int] | Omit = omit,
previous_ownership_transfer_date: Union[str, date, None] | Omit = omit,
registration_month: Optional[int] | Omit = omit,
road_tax_expiry_date: Union[str, date, None] | Omit = omit,
sale_price_eur: Optional[float] | Omit = omit,
vat_displayed: Optional[bool] | Omit = omit,
vehicle_damaged: Optional[bool] | Omit = omit,
Expand Down Expand Up @@ -318,21 +288,13 @@ def update(
"alloy_wheel_size": alloy_wheel_size,
"certified_km": certified_km,
"color": color,
"cost_price_eur": cost_price_eur,
"description": description,
"extended_warranty_enabled": extended_warranty_enabled,
"extended_warranty_months": extended_warranty_months,
"inspection_expiry_date": inspection_expiry_date,
"is_for_sale": is_for_sale,
"is_visible": is_visible,
"last_service_date": last_service_date,
"last_service_km": last_service_km,
"last_service_notes": last_service_notes,
"notes": notes,
"previous_owner_count": previous_owner_count,
"previous_ownership_transfer_date": previous_ownership_transfer_date,
"registration_month": registration_month,
"road_tax_expiry_date": road_tax_expiry_date,
"sale_price_eur": sale_price_eur,
"vat_displayed": vat_displayed,
"vehicle_damaged": vehicle_damaged,
Expand Down Expand Up @@ -562,7 +524,6 @@ async def create(
dealer_id: str,
*,
certified_km: int,
cost_price_eur: float,
motornet_code: str,
plate: str,
registration_year: int,
Expand All @@ -572,17 +533,10 @@ async def create(
description: str | Omit = omit,
extended_warranty_enabled: bool | Omit = omit,
extended_warranty_months: Optional[int] | Omit = omit,
inspection_expiry_date: Union[str, date, None] | Omit = omit,
is_for_sale: bool | Omit = omit,
is_visible: bool | 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,
previous_owner_count: Optional[int] | Omit = omit,
previous_ownership_transfer_date: Union[str, date, None] | Omit = omit,
registration_month: Optional[int] | Omit = omit,
road_tax_expiry_date: Union[str, date, None] | Omit = omit,
vat_displayed: bool | Omit = omit,
vehicle_damaged: bool | Omit = omit,
vin: Optional[str] | Omit = omit,
Expand All @@ -608,9 +562,6 @@ async def create(
Args:
certified_km: Certified odometer reading at intake, in kilometres.

cost_price_eur: Cost basis to the dealer in EUR (partner/dealer internal). Not surfaced on
consumer-facing AI surfaces; used by dealer reporting and margin analytics only.

motornet_code: Motornet UNI code identifying the exact vehicle configuration. Must exist in
`mnet_dettagli_usato` at submission time; otherwise the call returns 422
`motornet_code_not_in_catalogue`. The partner is expected to source this from
Expand All @@ -635,8 +586,6 @@ async def create(

notes: Free-form short notes; surfaced as `mnet_dettagli.precisazioni`-style.

previous_ownership_transfer_date: Date of the most recent ownership transfer, if known.

registration_month: Month of registration (1–12).

vat_displayed: If true the public price is displayed VAT-exposed (B2B); otherwise VAT-inclusive
Expand All @@ -660,7 +609,6 @@ async def create(
body=await async_maybe_transform(
{
"certified_km": certified_km,
"cost_price_eur": cost_price_eur,
"motornet_code": motornet_code,
"plate": plate,
"registration_year": registration_year,
Expand All @@ -670,17 +618,10 @@ async def create(
"description": description,
"extended_warranty_enabled": extended_warranty_enabled,
"extended_warranty_months": extended_warranty_months,
"inspection_expiry_date": inspection_expiry_date,
"is_for_sale": is_for_sale,
"is_visible": is_visible,
"last_service_date": last_service_date,
"last_service_km": last_service_km,
"last_service_notes": last_service_notes,
"notes": notes,
"previous_owner_count": previous_owner_count,
"previous_ownership_transfer_date": previous_ownership_transfer_date,
"registration_month": registration_month,
"road_tax_expiry_date": road_tax_expiry_date,
"vat_displayed": vat_displayed,
"vehicle_damaged": vehicle_damaged,
"vin": vin,
Expand Down Expand Up @@ -748,21 +689,13 @@ async def update(
alloy_wheel_size: Optional[int] | Omit = omit,
certified_km: Optional[int] | Omit = omit,
color: Optional[str] | Omit = omit,
cost_price_eur: Optional[float] | Omit = omit,
description: Optional[str] | Omit = omit,
extended_warranty_enabled: Optional[bool] | Omit = omit,
extended_warranty_months: Optional[int] | Omit = omit,
inspection_expiry_date: Union[str, date, None] | Omit = omit,
is_for_sale: Optional[bool] | Omit = omit,
is_visible: Optional[bool] | 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,
previous_owner_count: Optional[int] | Omit = omit,
previous_ownership_transfer_date: Union[str, date, None] | Omit = omit,
registration_month: Optional[int] | Omit = omit,
road_tax_expiry_date: Union[str, date, None] | Omit = omit,
sale_price_eur: Optional[float] | Omit = omit,
vat_displayed: Optional[bool] | Omit = omit,
vehicle_damaged: Optional[bool] | Omit = omit,
Expand Down Expand Up @@ -802,21 +735,13 @@ async def update(
"alloy_wheel_size": alloy_wheel_size,
"certified_km": certified_km,
"color": color,
"cost_price_eur": cost_price_eur,
"description": description,
"extended_warranty_enabled": extended_warranty_enabled,
"extended_warranty_months": extended_warranty_months,
"inspection_expiry_date": inspection_expiry_date,
"is_for_sale": is_for_sale,
"is_visible": is_visible,
"last_service_date": last_service_date,
"last_service_km": last_service_km,
"last_service_notes": last_service_notes,
"notes": notes,
"previous_owner_count": previous_owner_count,
"previous_ownership_transfer_date": previous_ownership_transfer_date,
"registration_month": registration_month,
"road_tax_expiry_date": road_tax_expiry_date,
"sale_price_eur": sale_price_eur,
"vat_displayed": vat_displayed,
"vehicle_damaged": vehicle_damaged,
Expand Down
1 change: 1 addition & 0 deletions src/partnermax/types/dealers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from .ai_content import AIContent as AIContent
from .nlt_settings import NltSettings as NltSettings
from .vehicle_list import VehicleList as VehicleList
from .vehicle_detail import VehicleDetail as VehicleDetail
Expand Down
65 changes: 65 additions & 0 deletions src/partnermax/types/dealers/ai_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Dict, List, Optional
from datetime import datetime

from ..._models import BaseModel

__all__ = ["AIContent"]


class AIContent(BaseModel):
"""AI-generated editorial content for a single vehicle.

Produced asynchronously by the ``usato_ai_content_worker`` in
``azurenet-engine`` within ~60 seconds of vehicle creation. While the
worker is still pending, every field is ``null``; once the worker
completes the row this object carries the full editorial set the
cross-network AI consumers (MCP, ChatGPT Custom GPT, NLWeb) display.

Layered descriptions:

* ``tagline`` — 8–12 word headline. Use on listing cards / push notifications.
* ``short`` — 1–2 sentence summary (≤ 220 chars). Use as the meta description fallback.
* ``medium`` — paragraph (~400 chars). Use on vehicle-detail SEO blurbs.
* ``long`` — full marketing description (1500–3000 chars). Use on detail pages.
* ``highlights`` — array of 3–7 selling points. Render as a bullet list above the description.
* ``faq`` — array of ``{question, answer}`` objects. Render as accordion / JSON-LD ``FAQPage``.
* ``seo_title`` — ≤ 60 chars, ``<title>``-ready.
* ``seo_description`` — ≤ 160 chars, meta description-ready.
* ``slug`` — URL-safe slug used in the canonical URL on the dealer site.

The Italian language is canonical (``lang='it'``). Multi-language is
on the roadmap; until then the partner gets exactly what the
consumer AI surfaces get.
"""

faq: Optional[List[Dict[str, str]]] = None
"""Array of `{question, answer}` objects.

Each entry has two string keys; render with the partner's own FAQ UI or feed
into a `FAQPage` JSON-LD block.
"""

generated_at: Optional[datetime] = None
"""UTC timestamp of the most recent AI generation.

`null` until the worker first processes the vehicle (≤ 60 seconds after vehicle
creation).
"""

highlights: Optional[List[str]] = None

long: Optional[str] = None

medium: Optional[str] = None

seo_description: Optional[str] = None

seo_title: Optional[str] = None

short: Optional[str] = None

slug: Optional[str] = None

tagline: Optional[str] = None
23 changes: 18 additions & 5 deletions src/partnermax/types/dealers/bulk_row_outcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,22 @@ class BulkRowOutcome(BaseModel):
Returned by `GET /v1/dealers/{id}/vehicles/{id}`,
`POST /v1/dealers/{id}/vehicles`, and `PATCH /v1/dealers/{id}/vehicles/{id}`.

`technical_details` carries the flat Motornet specs dict (Italian column names
as keys: `cilindrata`, `kw`, `hp`, `lunghezza`, `consumo_medio`,
`emissioni_co2`, etc.). Same shape conventions as `NltOfferDetail`
(`feedback_partnermax_field_naming_us_english`: field names are English
snake_case, raw catalogue values stay verbatim).
Carries three layers of information:

- **Partner-supplied** — what the partner posted (`plate`, `description`,
`sale_price_eur`, etc.).
- **Catalogue-derived** — `technical_details` is the flat `mnet_dettagli_usato`
dict (Italian column keys: `cilindrata`, `kw`, `hp`, `lunghezza`,
`consumo_medio`, `emissioni_co2`, etc.). Same shape conventions as
`NltOfferDetail` per `feedback_partnermax_field_naming_us_english`.
- **AI-derived** — `ai_content` carries the editorial output the cross-network
consumers display (descriptions, highlights, FAQ, SEO meta). `null` until the
worker has processed the vehicle.

Fields the partner does NOT see through this surface (because they are
dealer-internal margin/operations data the partner does not own):
`cost_price_eur`, `inspection_expiry_date`, `road_tax_expiry_date`,
`previous_owner_count`, `previous_ownership_transfer_date`, `last_service_*`.
These exist in the underlying DB tables for the DealerMAX dashboard but are
intentionally not exposed via the SDK.
"""
Loading
Loading