xlambda-core
Shared HTTP client, error handling, and webhook verification/parsing for
xlambda's service SDKs. A dependency of the other four — install
xlambda-media, xlambda-postgres,
xlambda-redis, or xlambda-email instead, unless
you're building a generic multi-event-family webhook receiver.
pip install xlambda-core
This is the Python port of @xlambda-tech/core and
wraps the same /v1/* API. Same wire format, same error envelope, same
webhook signature scheme — a receiver can be moved between the two without
touching the dashboard's webhook config.
Two clients
Every package here ships a blocking client and an awaitable one, sharing one definition of retry policy and error mapping:
from xlambda.core import XlambdaClient, AsyncXlambdaClient
with XlambdaClient(api_key=..., base_url="https://api.xlambda.tech") as client:
project = client.request("/v1/things", query={"projectId": "p1"})
async with AsyncXlambdaClient(api_key=...) as client:
project = await client.request("/v1/things", query={"projectId": "p1"})
Retries 429 (honoring X-RateLimit-Reset when present) and 5xx with
exponential backoff and jitter, up to max_retries (default 3). Never
retries a 4xx — that's the caller's own mistake and retrying won't change
the outcome. Every non-2xx raises XlambdaError with .code, .status,
.message, .details read from the platform's documented error envelope.
Unlike the npm SDK (where fetch has no default timeout), these default to
a 30s per-request timeout — httpx's own 5s default is too tight for
uploads. Pass your own http_client to control proxies, TLS, or transports.
Webhooks
handle(raw_body, signature_header) is the framework-agnostic core; every
adapter is a thin wrapper around it.
from xlambda.core import create_webhook_handler
handler = create_webhook_handler(
secret=os.environ["XLAMBDA_WEBHOOK_SECRET"],
on_event=lambda event: print(event["event"], event["data"]),
)
result = handler.handle(raw_bytes, signature_header) # -> .status, .body
Ready-made servers, no framework needed:
handler.to_wsgi_app() # sync
create_async_webhook_handler(...).to_asgi_app() # async
Framework adapters live behind their own imports, so installing this package never pulls in a web framework you don't use:
# pip install "xlambda-core[flask]"
from xlambda.core.webhooks.adapters.flask import create_flask_blueprint
app.register_blueprint(create_flask_blueprint(handler), url_prefix="/webhooks")
# pip install "xlambda-core[fastapi]"
from xlambda.core.webhooks.adapters.fastapi import create_fastapi_router
app.include_router(create_fastapi_router(async_handler), prefix="/webhooks")
Always verify the raw request bytes. Both adapters read the body before
anything parses it (request.get_data() / await request.body()). A
receiver that verifies a re-serialized body will fail every signature, since
the bytes no longer match what was signed.
An event that doesn't match your filter still gets a 200 with
{"received": true, "handled": false} — the platform treats anything but a
2xx as a delivery failure and retries three times, so "not interested in this
event" has to look like success on the wire. An exception raised inside
on_event deliberately propagates, so your framework turns it into a 5xx and
the delivery is retried.
Conventions
- Inputs are snake_case, outputs are the API's own camelCase. Method
arguments read as Python (
project_id=...); responses are returned as the raw decoded JSON (domain["dkimRecords"]), typed byTypedDict. That keeps responses 1:1 withdocs/API.mdand means a field the server adds tomorrow arrives intact instead of being dropped by a rename table this version has never heard of. fromis spelledfrom_as an argument, since it's a Python keyword — but staysfromin responses and webhook payloads, where it's just a dict key.- Responses are plain dicts at runtime.
TypedDictis a type-checker construct only; nothing is validated or coerced.
Development
pip install -e ".[flask,fastapi]" pytest
pytest
The test suite includes a cross-language golden vector — a signature
generated by Node's own crypto against webhookWorker.ts's exact
construction — so a pass proves this verifier accepts what the live platform
actually sends, not just what this package signs.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xlambda_core-0.2.0.tar.gz.
File metadata
- Download URL: xlambda_core-0.2.0.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
910773136a02f27db8aa77b17e4267f6f9677c09d67c329ab617fbeaa66cdf5b
|
|
| MD5 |
7c23ce97f09124a614d403a4b28f942b
|
|
| BLAKE2b-256 |
f1c3ef45eddc5c5ddc06b68cc1039ba44bea9397e16d1be9f36efbba05f8bf19
|
Provenance
The following attestation bundles were made for xlambda_core-0.2.0.tar.gz:
Publisher:
sdk-release-python.yml on randyryan177-cloud/media-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xlambda_core-0.2.0.tar.gz -
Subject digest:
910773136a02f27db8aa77b17e4267f6f9677c09d67c329ab617fbeaa66cdf5b - Sigstore transparency entry: 2743354176
- Sigstore integration time:
-
Permalink:
randyryan177-cloud/media-server@52f9f31ba1bd54d30231faecd72325166d087444 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/randyryan177-cloud
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-release-python.yml@52f9f31ba1bd54d30231faecd72325166d087444 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file xlambda_core-0.2.0-py3-none-any.whl.
File metadata
- Download URL: xlambda_core-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7656e2b8abc53889878fdcf05c1eacba57821f805989cf3cc48a0832cef4cc05
|
|
| MD5 |
78b6d2da2645fa01a54a20c8d314949d
|
|
| BLAKE2b-256 |
736c74497da2028f6adc188b9d5d2c161a888acd0ef854a2cc229541bdb0cd18
|
Provenance
The following attestation bundles were made for xlambda_core-0.2.0-py3-none-any.whl:
Publisher:
sdk-release-python.yml on randyryan177-cloud/media-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xlambda_core-0.2.0-py3-none-any.whl -
Subject digest:
7656e2b8abc53889878fdcf05c1eacba57821f805989cf3cc48a0832cef4cc05 - Sigstore transparency entry: 2743354194
- Sigstore integration time:
-
Permalink:
randyryan177-cloud/media-server@52f9f31ba1bd54d30231faecd72325166d087444 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/randyryan177-cloud
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-release-python.yml@52f9f31ba1bd54d30231faecd72325166d087444 -
Trigger Event:
workflow_dispatch
-
Statement type: