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.0.tar.gz (10.6 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.0-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: consentguard-0.1.0.tar.gz
  • Upload date:
  • Size: 10.6 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.0.tar.gz
Algorithm Hash digest
SHA256 39a04e13cc1d57f7d9cd32887bd10d3c7d8dcaa3ea26d5d9db546f3eae4376f9
MD5 13eec6143442e0da0a98cb431171f198
BLAKE2b-256 bf43263bdcf42f476a5de09c0c8c885626a5355866bae5c30f730a5ec175039c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: consentguard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.9 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e8b09c7f8b04bbb27a271dbbb88ceec569fc5156ce7b650147e42db4adf316ba
MD5 049a13cf70a1e6eecedf505458368d92
BLAKE2b-256 e1a8aa0db0e2dcbe5caabfc3d5a168e17ad2db6d7a27d5a1e2caed7efba8fa54

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