You already have a service that posts webhooks to your customers with requests or httpx and a hand-built JSON body. This guide replaces one of those calls with a generated, typed sender: no rewrite, no big bang. Set aside about 15 minutes.
You start from something like this, scattered wherever an event happens:
# The ad-hoc send you have today.
requests.post(
customer.webhook_url,
json={"type": "user.created", "data": {"id": user.id, "email": user.email}},
)Python 3.10 or later is required. The client is for trusted server-side code: it holds a publish credential.
Add the CLI and the repost-client runtime to your existing project.
curl -fsSL https://repost.sh/install | shFrom the repository root:
repost schema init --language python --output ./repost_sdkThis creates a repost/ workspace, a .env file for your key, and a starter schema. Python requires an explicit output; its final directory name becomes the importable package, repost_sdk here.
Edit repost/schema.repost so the model and event match the payload your ad-hoc call sends today. For the user.created example above:
generator sdk {
language = "python"
output = "../repost_sdk"
}
model User {
id String
email String
}
type User {
created
}
event UserCreated {
type @type(User.created)
data User
timestamp DateTime
}Add one field per key you send today. Schema covers enums, nested models, and more.
repost schema migrate dev --name initThis records the first migration and generates the Python package. Commit both the repost/ and repost_sdk/ directories. Code generation explains the CI drift check.
Create an environment in the dashboard, copy its publish API key into .env, then sign in and deploy the migration:
repost auth login
repost schema migrate deployLoad .env through your framework or process manager. The runtime reads REPOST_SEND_API_KEY, then REPOST_TOKEN.
Replace the ad-hoc call#
Swap the raw requests.post for the generated sender. Repost fans the event out to the customer's registered endpoints, so you no longer track webhook_url yourself:
from repost_sdk import RepostClient, User
with RepostClient() as repost:
result = repost.webhooks.user.created(
customer_id="customer_123",
data=User(id="user_123", email="[email protected]"),
idempotency_key="user_123:created",
)
print(result.id) # msg_...Generated methods and models catch unknown members, missing fields, and incompatible values in your editor and type checker, and the runtime validates again before opening a connection. The idempotency key is optional; pass a business-stable key when your queue or process may repeat the logical send.
Create one client for a process and close it during shutdown. A context manager is convenient for scripts; long-running apps should use their framework lifecycle.
Verify delivery#
Trigger the code path that fires the event, then open the dashboard. The send appears in the event stream with its msg_... id and per-endpoint delivery status. Once you trust it, delete the old requests.post call and repeat for the next event type.