Skip to content

Python SDK

kestrel-sdk on PyPI — stdlib only, no transitive dependencies.

Install

bash
pip install kestrel-sdk
# or: uv add kestrel-sdk / poetry add kestrel-sdk

Initialize

python
import os
import kestrel_sdk

kestrel_sdk.init(
    endpoint="https://kestrel.example.com/api/v1/ingest",
    token=os.environ["KESTREL_TOKEN"],
    release=os.environ.get("GIT_COMMIT"),
)

init() installs sys.excepthook so any uncaught exception in the main thread is reported. For asyncio:

python
import asyncio
import kestrel_sdk

async def main():
    # ...

loop = asyncio.new_event_loop()
kestrel_sdk.install_asyncio_handler(loop)
loop.run_until_complete(main())

That covers the two paths uncaught exceptions actually escape on. Threading-pool exceptions are not auto-captured (Python doesn't expose a hook for them); use kestrel_sdk.capture() from your worker's exception handler if you need them.

Manual capture

python
try:
    do_thing()
except Exception as exc:
    kestrel_sdk.capture(exc, context={"user_id": user_id})
    raise  # or swallow, your call

What it doesn't do

The SDK does not patch requests, httpx, logging, Django middleware, Flask error handlers, FastAPI exception hooks, or any other framework internal. If you want errors from a web framework, the framework's own exception handler can call kestrel_sdk.capture() directly — that's typically a 5-line addition.

This is on purpose. Patching framework internals is what causes the "we upgraded the SDK and now the request middleware double-runs" class of bug; we don't want to be that SDK.

Type hints

Fully typed — pip install kestrel-sdk ships a py.typed marker, so mypy --strict and pyright pick it up directly.

Releases

The Python SDK versions independently from the server. Track CHANGELOG.md for SDK-specific entries (each is tagged with (Python SDK)).

Released under the MIT License.