Skip to main content

ConsentGuard Python SDK

Project description

ConsentGuard Python SDK

Govern AI tool execution with the stable ConsentGuard SDK entry points:

  • ConsentGuardClient
  • wrap()

Install

python -m pip install consentguard

For local repo testing on Windows PowerShell:

python -m pip install -e .\sdk\python

Editable installs link to the source package. Fix package issues in sdk/python, not in a copied site-packages directory.

Minimal Usage

import os

from consentguard import ConsentGuardClient, wrap

client = ConsentGuardClient(
    api_key=os.environ["CONSENTGUARD_API_KEY"],
    base_url="https://your-project.supabase.co/functions/v1",
)


@wrap(client=client, tool_name="transfer_money", timeout=90)
async def send_payment(amount: int) -> dict:
    return {"id": "payment_123", "amount": amount}


result = await send_payment(250)

print(result.data)
print(result.action_id)
print(result.risk_score)
print(result.risk_level)
print(result.decision)
print(result.reasons)

wrap() returns ConsentGuard metadata around the tool result, not the raw tool result directly. Read the original tool value from result.data.

Client Options

Minimal production config:

client = ConsentGuardClient(
    api_key=os.environ["CONSENTGUARD_API_KEY"],
    base_url="https://your-project.supabase.co/functions/v1",
)

Advanced config:

client = ConsentGuardClient(
    api_key=os.environ["CONSENTGUARD_API_KEY"],
    base_url=os.environ["CONSENTGUARD_BASE_URL"],
    poll_interval_seconds=2.0,
    retry={
        "max_retries": 2,
        "initial_delay_seconds": 0.2,
        "max_delay_seconds": 2.0,
        "backoff_multiplier": 2.0,
        "retryable_status_codes": {429, 500, 502, 503, 504},
    },
)
  • api_key: required production API key, usually cg_live_*.
  • base_url: Supabase Edge Functions base URL ending in /functions/v1. The default is a placeholder and should be set before production use.
  • poll_interval_seconds: consent status polling interval in seconds. Defaults to 2.0.
  • retry: backend/network retry policy. Retries apply to retryable infrastructure failures, not governance block or denied consent decisions.

Timeout Units

  • timeout in wrap() config is the consent approval timeout in seconds. Example: timeout=90.
  • poll_interval_seconds in ConsentGuardClient is the consent status polling interval in seconds.
  • Backend and network failures are surfaced through ConsentGuardNetworkError subclasses, not as consent approval timeouts.

Wrapper Result Shape

result = await guarded_tool(250)

print(result.data)
print(result.action_id)
print(result.risk_score)
print(result.risk_level)
print(result.decision)
print(result.reasons)

Tool Name Resolution

ConsentGuard sends a tool_name to the governance backend. Name-based rules only match if this name is stable and meaningful.

Precedence:

  1. tool_name
  2. the wrapped function's inferred __name__
  3. "anonymous_tool" with a warning

Named function:

@wrap(client=client)
async def transfer_money(amount: int) -> dict:
    return {"status": "sent", "amount": amount}

Direct wrap form:

async def transfer_money(amount: int) -> dict:
    return {"status": "sent", "amount": amount}

guarded = wrap(transfer_money, client=client)

Anonymous function with explicit override:

guarded = wrap(lambda amount: {"status": "sent", "amount": amount}, client=client, tool_name="transfer_money")

If an anonymous function has no tool_name, ConsentGuard uses "anonymous_tool" and warns that name-based governance rules will not match.

Error Handling

from consentguard import (
    ConsentGuardAuthError,
    ConsentGuardBlockedError,
    ConsentGuardConsentTimeoutError,
    ConsentGuardDeniedError,
    ConsentGuardNetworkError,
    ConsentGuardRateLimitedError,
    ConsentGuardServiceUnavailableError,
)

try:
    result = await send_payment(12500)
    print(result.data, result.decision, result.reasons)
except ConsentGuardBlockedError as error:
    print("Blocked by policy", error.action_id)
except ConsentGuardDeniedError as error:
    print("Consent denied", error.action_id)
except ConsentGuardConsentTimeoutError as error:
    print("Consent approval timed out", error.action_id)
except ConsentGuardAuthError as error:
    print("Invalid API key or base URL", error.code)
except ConsentGuardRateLimitedError as error:
    print("Rate limited", error.retry_after_seconds)
except ConsentGuardServiceUnavailableError:
    print("ConsentGuard service unavailable")
except ConsentGuardNetworkError as error:
    print("Network/backend failure", error.code, error.retryable)

Hierarchy:

ConsentGuardError
  ConsentGuardBlockedError
  ConsentGuardDeniedError
  ConsentGuardTimeoutError
    ConsentGuardConsentTimeoutError
  ConsentGuardNetworkError
    ConsentGuardAuthError
    ConsentGuardRateLimitedError
    ConsentGuardServiceUnavailableError
    ConsentGuardInvalidResponseError

Retryable errors expose retryable = True. Auth and invalid response errors are not retryable.

Synchronous Frameworks

The Python SDK is async-first. In plain scripts, call governed tools from an async main:

import asyncio

asyncio.run(send_payment(250))

Framework guidance:

  • Streamlit: use a small bridge that calls asyncio.run() when no loop is active, or runs the coroutine in a worker thread when a loop is already active.
  • Flask and Django sync views: prefer moving governed tool execution into an async view/task where possible. If you must bridge, do it at the view boundary and avoid nested asyncio.run() inside an already running loop.
  • CLI scripts: asyncio.run() is usually enough.

See the Streamlit example for a concrete bridge:

cd .\sdk\python\examples\streamlit-basic
python -m pip install -r requirements.txt
python -m pip install -e ..\..
streamlit run app.py

Stability

For v0.1.0, wrap(), ConsentGuardClient, the decision vocabulary, and the exported error classes are the stable public entry points. Additive config fields and result metadata may expand during the Phase 4 readiness pass, but internal governance contracts are not yet a public extension API. Do not depend on private module internals.

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

consentguard-0.1.1.tar.gz (10.8 kB view details)

Uploaded Source

Built Distribution

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

consentguard-0.1.1-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file consentguard-0.1.1.tar.gz.

File metadata

  • Download URL: consentguard-0.1.1.tar.gz
  • Upload date:
  • Size: 10.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for consentguard-0.1.1.tar.gz
Algorithm Hash digest
SHA256 49a963e2214d9b318858da724e0e55f924d181932ea37aa05b489f3831ee422e
MD5 4df13b8f2afb90eb109275f71ddd4a15
BLAKE2b-256 83fe10bcb5b314018bf67d0f1e91c4671101e309ddb263458d751a9117545a47

See more details on using hashes here.

File details

Details for the file consentguard-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: consentguard-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for consentguard-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7dfb5b99b1289c7c644fcc746156e0602e06b7105bea2d90048d5dfa4c00d4c3
MD5 74fd4a87cbf55bbfa76fb089220080ad
BLAKE2b-256 2e351f7170e4a25c2af2abe860cad4871cd989810670906c238aaef11a7a252d

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