Metadata-Version: 2.4
Name: ledgix-python
Version: 0.1.8
Summary: Agent-agnostic compliance shim for SOX 404 policy enforcement via the ALCV Vault
Project-URL: Homepage, https://github.com/ledgix-dev/python-sdk
Project-URL: Documentation, https://docs.ledgix.dev
Project-URL: Repository, https://github.com/ledgix-dev/python-sdk
Author-email: Ledgix <team@ledgix.dev>
License: MIT
Keywords: agents,ai,compliance,security,sox404,vault
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjwt[crypto]>=2.8.0
Provides-Extra: crewai
Requires-Dist: crewai>=0.1.0; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
Provides-Extra: llamaindex
Requires-Dist: llama-index-core>=0.10.0; extra == 'llamaindex'
Description-Content-Type: text/markdown

# Ledgix Python SDK

[![PyPI](https://img.shields.io/badge/pypi-v0.1.8-blue)](https://pypi.org/project/ledgix-python/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)

Python SDK for customer integrations with Ledgix. Use it to request clearance before a payment, refund, or other sensitive tool runs.

## What to do first

1. Create a tenant API key in the Ledgix customer dashboard.
2. Upload or import the policy content for the first action you want to guard.
3. Set the review threshold and reviewer notifications.
4. Wrap one real tool call with the SDK.

## Install

```bash
python3 -m pip install ledgix-python
```

Optional adapters:

```bash
pip install ledgix-python[langchain]
pip install ledgix-python[llamaindex]
pip install ledgix-python[crewai]
```

## Create the client

```python
from ledgix_python import LedgixClient

client = LedgixClient()  # Reads LEDGIX_* environment variables
```

Or configure explicitly:

```python
from ledgix_python import LedgixClient, VaultConfig

client = LedgixClient(
    config=VaultConfig(
        vault_url="https://vault.example.com",
        vault_api_key="sk_prod_example",
        agent_id="payments-agent",
        session_id="checkout-42",
    )
)
```

## Quick start: guard a refund

```python
from ledgix_python import vault_enforce

@vault_enforce(client, tool_name="stripe_refund", policy_id="payments-prod")
def process_refund(amount: int, reason: str, order_event_id: str, **kwargs):
    clearance = kwargs["_clearance"]
    return stripe.Refund.create(
        amount=amount,
        reason=reason,
        metadata={
            "order_event_id": order_event_id,
            "ledgix_request_id": clearance.request_id,
            "ledgix_token": clearance.token,
        },
    )
```

## Direct clearance example

```python
from ledgix_python import ClearanceRequest

clearance = client.request_clearance(
    ClearanceRequest(
        tool_name="create_stripe_payment",
        tool_args={
            "amount": 249.99,
            "currency": "USD",
            "customer_id": "cus_123",
            "payment_method_id": "pm_123",
            "order_event_id": "ord_evt_2048",
            "reasoning": "Charge matches a completed order event.",
        },
        agent_id="payments-agent",
        session_id="checkout-42",
        context={"policy_id": "payments-prod"},
    )
)

if clearance.approved and clearance.token:
    print("Approved token:", clearance.token)
else:
    print(clearance.status, clearance.reason)
```

## Framework adapters

### LangChain

```python
from langchain_core.tools import StructuredTool
from ledgix_python.adapters.langchain import LedgixTool

refund_tool = StructuredTool.from_function(
    func=refund_customer,
    name="stripe_refund",
    description="Refund a customer payment",
)

guarded_tool = LedgixTool.wrap(
    client,
    refund_tool,
    policy_id="payments-prod",
)
```

### LlamaIndex

```python
from llama_index.core.tools import FunctionTool
from ledgix_python.adapters.llamaindex import wrap_tool

refund_tool = FunctionTool.from_defaults(
    fn=refund_customer,
    name="stripe_refund",
    description="Refund a customer payment",
)

guarded_tool = wrap_tool(
    client,
    refund_tool,
    policy_id="payments-prod",
)
```

### CrewAI

```python
from crewai.tools import BaseTool
from ledgix_python.adapters.crewai import LedgixCrewAITool

class StripeRefundTool(BaseTool):
    name = "stripe_refund"
    description = "Refund a customer payment"

    def _run(self, amount: int, reason: str, order_event_id: str):
        return refund_customer(
            amount=amount,
            reason=reason,
            order_event_id=order_event_id,
        )

guarded_tool = LedgixCrewAITool.wrap(
    client,
    StripeRefundTool(),
    policy_id="payments-prod",
)
```

## Async example

```python
result = await client.arequest_clearance(
    ClearanceRequest(
        tool_name="create_stripe_payment",
        tool_args={"amount": 249.99, "currency": "USD"},
        agent_id="payments-agent",
        session_id="checkout-42",
        context={"policy_id": "payments-prod"},
    )
)
```

## Configuration

| Variable | Default | Description |
|---|---|---|
| `LEDGIX_VAULT_URL` | `http://localhost:8000` | Vault URL |
| `LEDGIX_VAULT_API_KEY` | `""` | Tenant API key |
| `LEDGIX_VAULT_TIMEOUT` | `30.0` | Timeout in seconds |
| `LEDGIX_VERIFY_JWT` | `true` | Verify approval tokens automatically |
| `LEDGIX_JWT_ISSUER` | `alcv-vault` | Expected token issuer |
| `LEDGIX_JWT_AUDIENCE` | `ledgix-sdk` | Expected token audience |
| `LEDGIX_AGENT_ID` | `default-agent` | Calling agent or service ID |
| `LEDGIX_SESSION_ID` | `""` | Workflow or session ID |

## Available helpers

- `request_clearance()` and `arequest_clearance()`
- `register_policy()`
- `fetch_jwks()` and `verify_token()`
- `fetch_ledger()`, `fetch_ledger_checkpoints()`, and `fetch_ledger_proof_bundle()`
- `verify_ledger_proof_bundle()`
- `VaultContext` for explicit context-manager style flows

## Errors to handle separately

```python
from ledgix_python import (
    ClearanceDeniedError,
    ManualReviewTimeoutError,
    VaultConnectionError,
    TokenVerificationError,
)
```

Treat denied or review-paused requests differently from connectivity failures.

## More documentation

- Customer quickstart: `/getting-started`
- Policy management: `/guides/policy-ingestion-and-rag`
- Manual review: `/guides/manual-review-and-thresholds`
- Full Python guide: `/sdk/python`

## License

MIT
