sigtake
English · Español
Official Python SDK for Sigtake. Sends alerts and signal readings. Sync and async, one dependency, typed.
pip install sigtake
Requires Python 3.10 or newer.
Quickstart
from sigtake import Sigtake
with Sigtake(api_key="sk_...") as sigtake:
sigtake.alerts.ingest(
title="Checkout latency above threshold",
severity="high",
source="checkout-api",
team_code="OPS",
payload={"p95_ms": 2400, "region": "eu-west-1"},
)
Without api_key, the client reads SIGTAKE_API_KEY from the environment.
Getting an API key
In the app: API Keys → New Key (requires admin or super_admin). The key is shown once —
copy it then.
The key resolves both your tenant and your project. There is no project id to pass: one key per project, and staging and production keys are different keys.
The team_code comes from Teams, printed on each team card. It decides who gets notified.
Async
Same surface, with await. Use it in FastAPI or any asyncio app: the sync client would block the
event loop on every alert.
from sigtake import AsyncSigtake
async with AsyncSigtake() as sigtake:
await sigtake.alerts.ingest(title="Payment declined", source="checkout", team_code="PAY")
Create one client per process and reuse it — that is what makes the connection pool worth having.
Alerts
result = sigtake.alerts.ingest(
title="Payment webhook failing",
source="payments-worker",
team_code="PAY",
severity="critical", # 'critical' | 'high' | 'medium' | 'low' | 'info', defaults to 'info'
payload={"attempt": 3}, # optional, must serialize to 8 KB or less
)
result.data.id # alert id
result.meta.is_duplicate # True when it folded into an open incident
result.meta.occurrence_count # how many times this incident has fired
Alerts are deduplicated on source | title | severity per project. An open alert with the same
fingerprint gets its occurrence count bumped instead of opening a second incident, and notifications
go out at occurrences 1, 10, 25, 50, 100, then every 100.
team_code must exist in your tenant and the team must be assigned to the project this API key
belongs to. If it isn't, the call fails with code == "TEAM_NOT_IN_PROJECT" — assign the team to
the project in the app.
Signals
# Flat dict — the common case
sigtake.signals.send("billing-service", {"emails_sent": 42, "queue_depth": 3})
# Explicit readings
sigtake.signals.ingest(
source="billing-service",
readings=[{"metric": "emails_sent", "value": 42}],
)
source is the monitor's source key, which must already exist in the project. Up to 100 readings
per call, 50 distinct metric names per monitor.
Hitting the metric cap answers with a partial delivery rather than an error — the readings that fit were stored:
result = sigtake.signals.send("billing-service", metrics)
if result.rejected:
logger.warning("metric cap reached, dropped: %s", result.rejected)
A total rejection (nothing stored) raises SigtakeValidationError.
Errors
Every failure is a SigtakeError subclass carrying status, code and the raw body.
from sigtake import SigtakeRateLimitError, SigtakeValidationError
try:
sigtake.alerts.ingest(title=..., source=..., team_code=...)
except SigtakeValidationError as err:
print(err.field_errors)
except SigtakeRateLimitError:
print("retries exhausted")
| Class | When |
|---|---|
SigtakeValidationError |
400, the total-rejection 422, and local input checks (status == 0) |
SigtakeAuthError |
401 / 403 — missing, invalid or disabled key |
SigtakeNotFoundError |
404 — no monitor with that source in this project |
SigtakeConflictError |
409 — monitor is paused |
SigtakeRateLimitError |
429, after retries are exhausted |
SigtakeServerError |
5xx, after retries are exhausted |
SigtakeNetworkError |
DNS, connection, or timeout (status == 0) |
408, 429, 5xx and network failures are retried with exponential backoff and jitter. Validation errors never are.
No idempotency. The API does not accept an idempotency key yet, and timeouts are retried. If a request times out after reaching the server, the retry bumps
occurrence_counton the existing alert. Nothing is lost or duplicated as an incident, but a notification threshold may fire slightly early.
Configuration
Sigtake(
api_key="sk_...", # or SIGTAKE_API_KEY
base_url="https://api.sigtake.com", # default; or SIGTAKE_BASE_URL
timeout=10.0, # seconds, per attempt
max_retries=3, # 0 disables retries
headers={}, # merged into every request
http_client=None, # bring your own httpx.Client; if you pass it, you close it
)
Per call:
sigtake.alerts.ingest(title=..., source=..., team_code=..., timeout=2.0)
Alert ingestion is best treated as fire-and-forget — never let it break the code path that produced the alert:
try:
sigtake.alerts.ingest(title=..., source=..., team_code=...)
except SigtakeError:
logger.warning("sigtake ingest failed", exc_info=True)
Development
uv sync --all-groups
uv run ruff check . && uv run mypy
uv run pytest tests/unit --cov=sigtake
Contract tests need a mock served from the spec:
docker run --rm -p 4010:4010 -v "$PWD/spec:/spec" stoplight/prism:5 \
mock -h 0.0.0.0 --errors -m false /spec/openapi.yaml
uv run pytest tests/contract
More detail in
docs/ARCHITECTURE.md.
Releasing
git tag sdk-python-v0.1.0 && git push --tags
The tag triggers the publish workflow, which refuses to publish if the tag and pyproject.toml
disagree.
License
MIT
Release files for sigtake 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sigtake-0.1.1.tar.gz | 116.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sigtake-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 133.6 kB
Release files / sigtake-0.1.1.tar.gz
| Download URL | sigtake-0.1.1.tar.gz |
|---|---|
| Size | 116.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5ac003169be564a7562aa4a3a82173b9b89df493c0ccab2bf2a774b9eec2c7c
|
|
BLAKE2b-256 checksum How to use checksums |
a1944f8e0ab36f29ce21fc343edad3c82d4015db10e95038915884808cb7ea64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency logRelease files / sigtake-0.1.1-py3-none-any.whl
| Download URL | sigtake-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df7fb6bdbe6fbb71c44a1ae7c8c4bc5ef244ac1d5c776c045d11220040636107
|
|
BLAKE2b-256 checksum How to use checksums |
b407b2e04236945eedfa059c6b144fe33a2310eec41f4ad1308b427eda83f297
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency log