SignalGate antifraud backend SDK for Python — thin HTTP forwarder to api.signalgate.ai
Project description
signalgate — Python backend SDK
Thin HTTP forwarder for SignalGate antifraud.
Tenants embed this in their backend to call /v0/check (synchronous verdict)
and /v0/log (async analytics). The SDK does no crypto — the opaque
encrypted payload comes from @signalgate/frontend-js-sdk.
Install
pip install signalgate
For local development against an unpublished checkout:
pip install -e /path/to/backend-python-sdk
Quickstart
check() and log() are two calls at two points in your funnel, not two
ways to send one event:
check()— before the action you're gating. Synchronous; returns a verdict so you can block or allow. The server records the check for analytics.log()— after the action completes. Fire-and-forget telemetry; no verdict.
A typical flow calls both:
from signalgate import Client, Event, EncryptedPayload
client = Client(api_key="pk_live_...") # API key minted by the SignalGate dashboard
# 1. BEFORE the gated action — get a verdict and gate on it.
gate_event = Event(
user_id="u_123",
ip=request.headers.get("X-Forwarded-For", request.remote_addr),
method="checkout",
timestamp="2026-04-01T13:08:50+00:00",
payload=EncryptedPayload(**frontend_payload_dict), # verbatim from the browser (incl. v=2)
custom={"plan": "pro"},
)
verdict = client.check(gate_event)
if verdict.action == "block":
raise PermissionError("blocked by SignalGate")
charge_the_customer() # your paid action
# 2. AFTER the action completes — log it (fire-and-forget analytics).
client.log(done_event) # a fresh event captured at this funnel point
You can also call log() on its own for actions you aren't gating — background
jobs, downstream clientPaidAction completions, page-view telemetry, etc.
Distinct events per call.
checkandlogfire at different moments, so each carries its own event with its own fingerprint payload (its ownnonce). Don't forward the byte-identical payload to both back-to-back — the server's nonce-freshness guard would replay-reject the second.
At process shutdown:
client.close() # drains the log queue within 5 × log_timeout_ms
Or use it as a context manager:
with Client(api_key="...") as client:
client.check(event)
Configuration
Override the defaults selectively:
Client(
api_key="...",
check_timeout_ms=3000,
log_timeout_ms=1000,
log_queue_capacity=10000,
log_max_retries=3,
fail_open=True, # default: on timeout/5xx, check() returns allow
)
Error handling
check() raises on 4xx (tenant bug — bad/revoked pk_* API key, malformed
event). With
fail_open=True (default), timeouts / network errors / 5xx return a
synthesized CheckResult(action="allow", failed_open=True).
from signalgate import ServerError, TimeoutError, NetworkError
try:
result = client.check(event)
except ServerError as e:
# e.status_code, e.code, e.message, e.request_id, e.details
...
log() never raises. Failures are counted in client.metrics.
Metrics
client.metrics.get("check_total")
client.metrics.get("check_failed_open_total")
client.metrics.get("log_dropped_total", reason="queue_full")
client.metrics.snapshot() # all counters
Full counter list:
| Counter | Labels | Incremented when |
|---|---|---|
check_total |
— | check() called |
check_success_total |
— | check() returned a real verdict |
check_failed_open_total |
— | check() returned a synthesized allow |
check_error_total |
type |
check() raised |
log_enqueued_total |
— | log() accepted into queue |
log_sent_total |
— | server acknowledged a log event |
log_http_error_total |
status |
a log retry was triggered |
log_dropped_total |
reason |
queue_full / closed / retry_exhausted |
Development
pip install -e ".[dev]" # install with dev extras
pytest -q # run the test suite
CI runs pytest -q on every push and PR to main via .github/workflows/test.yml (Python 3.12, pip cache keyed on pyproject.toml).
License
Licensed under the Apache License, Version 2.0.
Links
- Homepage: https://signalgate.ai
- Documentation: https://signalgate.ai/docs/python
Project details
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 signalgate-0.3.2.tar.gz.
File metadata
- Download URL: signalgate-0.3.2.tar.gz
- Upload date:
- Size: 42.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cae0585a4e2003ae4d2fcdfcbd30df4311e85597c3946502c9138a381cdbc19
|
|
| MD5 |
a2d0fbc3141ec4ad4d4f506ce5062f3c
|
|
| BLAKE2b-256 |
de38a32e6a416c19fd0be3e82add89acaec67538e277cd2ce20ad6bf6fe217bf
|
File details
Details for the file signalgate-0.3.2-py3-none-any.whl.
File metadata
- Download URL: signalgate-0.3.2-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d8f06a164285ce8636c9c8ed9b432e0710e127ae385803d79bc04a446f28455
|
|
| MD5 |
eb27eb9a9da90429fe727b543e2f91d3
|
|
| BLAKE2b-256 |
2ec06bfaef4f46b2e4708c066f3efb4d796f8b8524b3f42194e5cf5291ebdba5
|