Skip to main content

Official Python SDK for Notiformer — human-in-the-loop approval gates and push notifications for AI agents.

Project description

notiformer (Python)

Official Python SDK for Notiformer — approval gates, multi-option decisions, real-time push notifications, and feature gates for AI agents. Mirrors the Node.js SDK 1:1: same methods, same config, same REST API underneath.

Install

pip install notiformer

Requires Python 3.8+.

Get started

1. Create a free account at app.notiformer.com — no credit card required for the Dev plan. Verify your email before creating a project or using the API.

2. Create a project and copy your API key (ntf_live_...).

3. Quick start:

from notiformer import Notiformer

n = Notiformer("ntf_live_...")

# 🛑 Pause and wait for Approve / Deny — always set fallback or handle the raise
try:
    result = n.ask(
        "Deploy v2 to production?",
        context="Build #442 · 3 services affected",
        timeout=300,
        fallback="deny",  # omit and a timeout raises NotiformerError
    )
    if result["approved"]:
        deploy()
    else:
        print("Timed out — auto-denied" if result["timed_out"] else "Denied")
except NotiformerError as err:
    if err.code == "timeout":
        print("No response. Respond via the app, Telegram, or Slack.")

# 🔔 Fire-and-forget alert
n.event("agents", "task_complete")

Use n = Notiformer("ntf_live_test") to try the SDK without a real key — calls are skipped locally and safe defaults are returned (a one-time setup notice is printed).

Config

Notiformer(
    api_key,
    *,
    silent=False,          # skip all calls locally, return safe defaults — good for local/dev/test
    throw_on_error=True,   # False: event()/gate() failures return a default instead of raising
    on_error=None,         # callback: fn(NotiformerError) -> None, called on every failure
)

ask()/select() always raise NotiformerError(code="timeout") when nobody responds and no fallback was set — this is unconditional and ignores throw_on_error=False. Set a fallback, or wrap the call in try/except and handle it explicitly.

API

n.event(channel, event, *, description=None, icon=None, tags=None, value=None, notify=True, recipients=None)

Fire-and-forget. Returns {"id", "createdAt", "rateLimited"?, "usageMicroUsd"?}, or None if the placeholder key or silent is used, or the call failed and throw_on_error=False.

n.ask(message, *, timeout=300, fallback=None, context=None, details=None)

Approval gate. Posts the request, then polls every 2s until it resolves. Returns {"approved", "timed_out", "responded_at"}.

n.select(message, options, *, timeout=300, fallback=None, context=None, details=None)

Like ask(), but the user picks one of 2–6 custom options instead of Approve/Deny. Each option: {"value", "label", "isDestructive"?} — use the select_option() helper:

from notiformer import select_option
select_option("stop", "🛑 Stop the pipeline", is_destructive=True)

Returns {"selected", "timed_out", "responded_at"}.

n.gate(key, *, fallback=False, cache_ttl=0)

Boolean feature-gate check. Never raises — always falls back on any error. cache_ttl (seconds) enables a local in-memory cache on this client instance only; there's no server-side caching.

n.gate_details(key, *, fallback=False, cache_ttl=0)

Same as gate(), returns {"key", "enabled", "cached"}.

n.clear_gate_cache(key=None)

Clears the local gate cache for one key, or all of them if omitted.

Errors

API and timeout failures raise notiformer.NotiformerError:

from notiformer import NotiformerError

try:
    n.ask("Deploy?", timeout=60)  # no fallback → raises on timeout
except NotiformerError as e:
    print(e.code)  # "timeout", "invalid_api_key", "rate_limited", "cap_reached", ...
    raise

.code is one of: invalid_api_key, card_required, card_locked, cap_reached, feature_not_available, validation, rate_limited, network, internal, timeout. On cap_reached, .cycle_resets_at, .manage_url, and .upgrade_url may also be set.

Request-shape mistakes (missing message, wrong number of options, a fallback that doesn't match any option, etc.) raise a plain ValueError instead — these are always raised, regardless of throw_on_error.

Links

License

MIT

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

notiformer-1.0.0.tar.gz (15.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

notiformer-1.0.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file notiformer-1.0.0.tar.gz.

File metadata

  • Download URL: notiformer-1.0.0.tar.gz
  • Upload date:
  • Size: 15.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.2

File hashes

Hashes for notiformer-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f012fed823dd71e0c22c4155a9c20929047a28be756b91478d8053e83c5218a5
MD5 57ff2c694b2c5e5714ac2899ead0af69
BLAKE2b-256 4be09e343caea06ad9cbd7854f5312122ac8c40b66039fb427457ffffe819005

See more details on using hashes here.

File details

Details for the file notiformer-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: notiformer-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.2

File hashes

Hashes for notiformer-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a9f96f678244cd6b3698fc06010ba436a4211b1ae73c206ef803127251d6ad7
MD5 077931bd89a72399aa5fe5fa0c26883d
BLAKE2b-256 85a903a6e6e3f2fc0663195368b99438bb1f2a2717b316914ee454751de11afe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page