-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathhello_seller_with_webhooks.py
More file actions
58 lines (46 loc) · 2.22 KB
/
hello_seller_with_webhooks.py
File metadata and controls
58 lines (46 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""Hello-seller-with-webhooks — canonical ``WebhookSender`` + supervisor wiring.
Extends ``hello_seller.py`` with a wired :class:`InMemoryWebhookDeliverySupervisor`
so sync-completion webhooks are delivered to buyers who register
``push_notification_config.url``. Uses :meth:`WebhookSender.from_bearer_token`
as the auth mode — no key management, simplest first step.
Run::
WEBHOOK_BEARER_TOKEN=<your-token> uv run python examples/hello_seller_with_webhooks.py
The server boots on http://localhost:3001/mcp. Any buyer that registers
``push_notification_config.url`` on a ``create_media_buy`` request receives a
completion notification POSTed with ``Authorization: Bearer <token>``.
To use RFC 9421 JWK signing instead (AdCP spec baseline, required for buyers
that verify body signatures), swap :meth:`~WebhookSender.from_bearer_token`
for :meth:`~WebhookSender.from_jwk`. See ``docs/handler-authoring.md#webhooks``
for the full constructor comparison.
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
# Allow importing hello_seller as a sibling module when run as a script.
sys.path.insert(0, str(Path(__file__).parent))
from hello_seller import HelloSeller # type: ignore[import] # noqa: E402
from adcp.decisioning import serve
from adcp.webhook_sender import WebhookSender
from adcp.webhook_supervisor import InMemoryWebhookDeliverySupervisor
if __name__ == "__main__":
token = os.environ.get("WEBHOOK_BEARER_TOKEN", "")
if not token:
import warnings
warnings.warn(
"WEBHOOK_BEARER_TOKEN is not set; using 'dev-fixture-token'. "
"Set WEBHOOK_BEARER_TOKEN=<real-token> before connecting real buyers.",
category=UserWarning,
stacklevel=1,
)
token = "dev-fixture-token"
sender = WebhookSender.from_bearer_token(token)
# InMemoryWebhookDeliverySupervisor wraps the sender with retry
# (exponential backoff, 3 attempts) and per-endpoint circuit breakers.
# Pass webhook_supervisor= rather than webhook_sender= in production.
supervisor = InMemoryWebhookDeliverySupervisor(sender=sender)
serve(
HelloSeller(),
name="hello-seller-with-webhooks",
webhook_supervisor=supervisor,
)