Skip to main content

Python client for the Inhibitor policy compliance inference API

Project description

Inhibitor Python SDK

Official Python client for the Inhibitor policy compliance API. Evaluate natural-language content against your policies and get ALLOW, MODIFY, or BLOCK decisions with explanations.


Features

  • Simple API — Send only query, metadata, and additional_metadata; no extra parameters.
  • Structured metadata — Use the {"key": {"value": "val", "description": "des"}} shape for clear, documented context.
  • Sync and asyncInhibitorClient and AsyncInhibitorClient with the same interface.
  • Typed models — Pydantic request/response models for IDE support and validation.

Installation

pip install inhibitor

Requirements: Python 3.9+, httpx, pydantic.


Quick start

from inhibitor import InhibitorClient

client = InhibitorClient(api_key="your-api-key")

response = client.inference.query(
    "Can I share this document with external partners?",
    metadata={
        "consent": {"value": "yes", "description": "User gave consent"},
        "data_type": {"value": "PHI", "description": "Contains protected health info"},
    },
)

print(response)   # Complete Response
print(response.final_decision)   # ALLOW | MODIFY | BLOCK
print(response.explanation)      # Human-readable explanation
print(response.processing_time_seconds)
client = InhibitorClient(api_key="your-api-key", base_url="https://your-custom-api.com")

API overview

What you send (request)

Only four fields are accepted:

Field Type Required Description
query str Yes Natural language content to evaluate against your policies.
metadata dict No Context for compliance. Shape: {"key": {"value": "val", "description": "des"}}. Used by the engine for the decision.
additional_metadata dict No Stores optional user information (e.g., name, email) as key-value pairs, saved along with the inference log for auditing purposes. Example: {"user_name": "John Doe", "email": "john.doe@example.com"}
explanation bool No If True, wait for explanation generation and include in response. Defaults to False.

Metadata shape — Each key maps to an object with:

  • value (str): The actual value (e.g. "yes", "PHI").
  • description (str): Optional short description of the field.

Example:

metadata = {
    "consent": {"value": "yes", "description": "User consent obtained"},
    "classification": {"value": "internal", "description": "Document classification"},
}

What you get (response)

InferenceResponse includes:

Field Type Description
log_id str | None ID of the inference log for fetching details later.
query str Echo of the query.
final_decision str ALLOW, MODIFY, or BLOCK.
final_score float Aggregate score (0–1).
matched_policies list[str] Policies that were evaluated.
model_results list[RuleResult] Per-rule decision, confidence, and probabilities.
explanation str | None Human-readable explanation.
make_it_compliant str | None Suggested changes to make the query compliant.

Usage

Sync client

from inhibitor import InhibitorClient, InferenceRequest

client = InhibitorClient(api_key="your-api-key")

# Simple query
response = client.inference.query("Should I send this email to a competitor?")

# With metadata (authoritative context for the engine)
response = client.inference.query(
    "Share the report with the client.",
    metadata={
        "consent": {"value": "yes", "description": "Client consent on file"},
        "channel": {"value": "email", "description": "Delivery channel"},
    },
)

# With additional_metadata (stored with log only)
response = client.inference.query(
    "Upload to cloud storage.",
    additional_metadata={"user_name": "John Doe", "email": "john.doe@example.com"},
)

# Using the request model
req = InferenceRequest(
    query="Can I export this data?",
    metadata={"data_type": {"value": "PII", "description": "Personal data"}},
)
response = client.inference.run(req)

# Fetching full inference log details
if response.log_id:
    log_details = client.inference.get_log(response.log_id)
    print(log_details)

Async client

from inhibitor import AsyncInhibitorClient

async with AsyncInhibitorClient(api_key="your-api-key") as client:
    response = await client.inference.query_async(
        "Can I share this document?",
        metadata={"consent": {"value": "yes", "description": "Consent given"}},
    )
    print(response.final_decision)

# Or with run_async
req = InferenceRequest(query="...", metadata={...})
response = await client.inference.run_async(req)

# Fetching full inference log details (async)
if response.log_id:
    log_details = await client.inference.get_log_async(response.log_id)

Configuration

Parameter Description
api_key Required. Your Inhibitor API key (from the dashboard).
base_url Override API base URL. Default: https://inhibitor-be.envistudios.com.
timeout Request timeout in seconds (default: 60.0).
headers Optional extra HTTP headers.

The client sends the API key in the X-API-Key header. No other auth is required.


Exceptions

Exception When
InhibitorAuthError Invalid or expired API key (401).
InhibitorValidationError Bad request or invalid parameters (400).
InhibitorAPIError Other API errors (4xx/5xx). Has status_code, detail, response_body.
ComplianceBlockedError Raised by :func:check_compliance when the decision is BLOCK. Has response (full :class:InferenceResponse).

All extend InhibitorError (with message and optional status_code).

from inhibitor import InhibitorClient
from inhibitor.exceptions import InhibitorAuthError, InhibitorAPIError

client = InhibitorClient(api_key="your-api-key")
try:
    r = client.inference.query("Some query")
except InhibitorAuthError as e:
    print("Auth failed:", e.message)
except InhibitorAPIError as e:
    print("API error:", e.status_code, e.detail)

Integration checklist

  1. Get an API key from your Inhibitor dashboard.
  2. Installpip install inhibitor.
  3. Create clientInhibitorClient(api_key="...").
  4. Callclient.inference.query(query, metadata=..., additional_metadata=...).
  5. Handle — Use response.final_decision, response.explanation, and catch InhibitorAuthError / InhibitorAPIError as needed.

Decorator: check compliance before calling your function

Use :func:check_compliance to run the inference API on a chosen argument before your function runs. If the decision is BLOCK, the decorator raises :exc:ComplianceBlockedError (or returns None); otherwise it calls your function.

from inhibitor import InhibitorClient, check_compliance

client = InhibitorClient(api_key="your-api-key")

@check_compliance(client, query_arg="message")
def handle_user_message(message: str, user_id: str):
    # Only runs if compliance allows (ALLOW or MODIFY)
    return process(message, user_id)

# BLOCK → ComplianceBlockedError (with response.explanation, response.make_it_compliant)
# ALLOW / MODIFY → your function runs
handle_user_message("Can I share this file?", "u-123")

Options: query_arg (param name to check, default "query"), on_block ("raise" or "return_none"), metadata, pass_response (inject _inhibitor_response into kwargs). Use :class:AsyncInhibitorClient with async functions.

from inhibitor import AsyncInhibitorClient, check_compliance

client = AsyncInhibitorClient(api_key="your-api-key")

@check_compliance(client, query_arg="prompt")
async def run_llm(prompt: str):
    return await model.generate(prompt)

Catch blocks with :exc:ComplianceBlockedError and use e.response.explanation or e.response.make_it_compliant to show the user why it was blocked or how to fix it.


Package structure

Each module has a single responsibility:

Module Purpose
inhibitor.constants Default base URL and API path.
inhibitor._http HTTP response helpers (e.g. error detail extraction).
inhibitor.models Request/response Pydantic models and metadata shape.
inhibitor.inference Inference API (sync/async): query, run, query_async, run_async.
inhibitor.client Sync and async HTTP clients.
inhibitor.exceptions Auth, validation, and API exceptions.

Import the public API from inhibitor; use submodules only if you need constants or helpers.


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

inhibitor-0.1.3.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

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

inhibitor-0.1.3-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file inhibitor-0.1.3.tar.gz.

File metadata

  • Download URL: inhibitor-0.1.3.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for inhibitor-0.1.3.tar.gz
Algorithm Hash digest
SHA256 d81c61ef3d8953ac86b907f0228b12c1a4b7f90736a3b0be9fe5effeaca5849b
MD5 cd959fcec1077106e51ca8e272364431
BLAKE2b-256 4c8ae7d5a1056636b65d3ea77b4fef42fd2eaad495f9d528348849cc487231cc

See more details on using hashes here.

File details

Details for the file inhibitor-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: inhibitor-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for inhibitor-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ac3130764aea04e02353062ca36821e5fff07a5eb95b601cc4df497a177de9e1
MD5 cf4fa001b17e02829a12e5700c1cddcf
BLAKE2b-256 b480b0dbb0e0745237eacfe3a2e17c644e5866d676f13709456078033945a07a

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