Skip to content

Commit 024e095

Browse files
committed
docs(examples): expand hello_seller.py to full 9-method sales-non-guaranteed surface
The canonical example tripped validate_platform soft-warns for four SalesPlatform Protocol methods required in v6.0 rc.1+: get_media_buys, list_creative_formats, list_creatives, provide_performance_feedback. A "hello world" example that emits warnings at boot teaches adopters to ignore validator signal — the opposite of the fail-fast contract. Add minimal stub implementations for all four methods, each clearly annotated to wire to the adopter's inventory/analytics system in production. Update module and class docstrings to correctly state the 9-method required surface rather than the stale "five required methods" count. validate_platform now passes clean with zero soft-warns. Closes #515 https://claude.ai/code/session_01SQEG3PCARK4eKHBbqu4fTS
1 parent 863bb93 commit 024e095

1 file changed

Lines changed: 82 additions & 14 deletions

File tree

examples/hello_seller.py

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
"""Hello-seller — the smallest possible v6.0 DecisioningPlatform.
1+
"""Hello-seller — the canonical v6.0 DecisioningPlatform starting point.
22
3-
A minimal :class:`SalesPlatform` adopter showing the canonical surface:
3+
A minimal :class:`SalesPlatform` adopter showing the full required surface:
44
55
* :class:`DecisioningCapabilities` declared on the class body
66
* :class:`SingletonAccounts` for the dev/single-tenant case
7-
* Five required ``sales-non-guaranteed`` methods (``get_products``,
8-
``create_media_buy``, ``update_media_buy``, ``sync_creatives``,
9-
``get_media_buy_delivery``) — all sync, sync return path. The full
10-
required set is enforced at server boot by ``validate_platform``
11-
via :data:`REQUIRED_METHODS_PER_SPECIALISM` — omitting any of the
12-
five fails fast with INVALID_REQUEST.
7+
* Nine required ``sales-non-guaranteed`` methods — five hard-required
8+
(``get_products``, ``create_media_buy``, ``update_media_buy``,
9+
``sync_creatives``, ``get_media_buy_delivery``) plus four required by the
10+
SalesPlatform Protocol for any ``sales-*`` specialism in v6.0 rc.1+
11+
(``get_media_buys``, ``list_creative_formats``, ``list_creatives``,
12+
``provide_performance_feedback``). The authoritative source is the
13+
:data:`~adcp.decisioning.dispatch.REQUIRED_METHODS_PER_SPECIALISM` and
14+
:data:`~adcp.decisioning.dispatch.RECOMMENDED_METHODS_PER_SPECIALISM`
15+
maps; ``validate_platform`` checks both at server boot.
1316
1417
Run::
1518
@@ -77,13 +80,18 @@
7780

7881

7982
class HelloSeller(DecisioningPlatform):
80-
"""The canonical minimal v6.0 sales-non-guaranteed adopter.
83+
"""The canonical v6.0 sales-non-guaranteed adopter.
8184
82-
Implements all five required methods of ``sales-non-guaranteed``
83-
(the full contract per :data:`REQUIRED_METHODS_PER_SPECIALISM`):
84-
``get_products``, ``create_media_buy``, ``update_media_buy``,
85-
``sync_creatives``, ``get_media_buy_delivery``. ``validate_platform``
86-
runs at boot and fails fast on any missing method.
85+
Implements all nine required methods of ``sales-non-guaranteed``: the
86+
five hard-required (``get_products``, ``create_media_buy``,
87+
``update_media_buy``, ``sync_creatives``, ``get_media_buy_delivery``)
88+
and the four required by the SalesPlatform Protocol in v6.0 rc.1+
89+
(``get_media_buys``, ``list_creative_formats``, ``list_creatives``,
90+
``provide_performance_feedback``).
91+
92+
``validate_platform`` runs at boot and fails fast on any missing
93+
hard-required method; it soft-warns (or hard-fails in strict mode) for
94+
the four rc.1+ methods. This example passes all checks cleanly.
8795
"""
8896

8997
capabilities = DecisioningCapabilities(
@@ -234,6 +242,66 @@ def get_media_buy_delivery(
234242
],
235243
}
236244

245+
# ---- v6.0 rc.1 required methods ----------------------------------------
246+
# These four methods are required by the SalesPlatform Protocol for any
247+
# sales-* specialism in v6.0 rc.1+. The stubs below return the minimal
248+
# valid wire shape (empty collections / acknowledged). Wire them to your
249+
# inventory system / analytics pipeline in production.
250+
251+
def get_media_buys(
252+
self,
253+
req: Any,
254+
ctx: RequestContext[Any],
255+
) -> dict[str, Any]:
256+
"""List media buys for the resolved account.
257+
258+
Return all active media buys here. Wire to your order-management
259+
system in production; buyers use this for status polling and
260+
reconciliation.
261+
"""
262+
return {"media_buys": []}
263+
264+
def list_creative_formats(
265+
self,
266+
req: Any,
267+
ctx: RequestContext[Any],
268+
) -> dict[str, Any]:
269+
"""Catalog of accepted creative formats.
270+
271+
Return the full list of format definitions this seller accepts.
272+
Wire to your creative-spec registry in production; buyers use this
273+
to validate creatives before submission.
274+
"""
275+
return {"formats": []}
276+
277+
def list_creatives(
278+
self,
279+
req: Any,
280+
ctx: RequestContext[Any],
281+
) -> dict[str, Any]:
282+
"""List the seller's view of buyer-uploaded creatives.
283+
284+
Return all creatives the buyer has synced. Wire to your creative
285+
asset store in production; buyers use this to check approval
286+
statuses and discover available creatives.
287+
"""
288+
return {"creatives": []}
289+
290+
def provide_performance_feedback(
291+
self,
292+
req: Any,
293+
ctx: RequestContext[Any],
294+
) -> dict[str, Any]:
295+
"""Buyer-supplied performance signal back to the seller.
296+
297+
Acknowledge receipt and log to your analytics pipeline in
298+
production. Buyers send conversion events (clicks, installs,
299+
purchases) here so the seller can optimize pacing and targeting.
300+
"""
301+
return {"success": True}
302+
303+
# -------------------------------------------------------------------------
304+
237305
@staticmethod
238306
def _get_packages(req: Any) -> list[dict[str, Any]]:
239307
"""Pull the wire ``packages`` array from the request, tolerating

0 commit comments

Comments
 (0)