Metadata-Version: 2.4
Name: decionis
Version: 0.1.0
Summary: Official Decionis Python SDK for execution interception.
Project-URL: Homepage, https://decionis.ai
Project-URL: Documentation, https://decionis.ai/docs
Project-URL: Repository, https://github.com/decionis/decionis-sdk
Author-email: Decionis <sdk@decionis.ai>
License: MIT
Keywords: audit,decionis,governance,policy,sdk
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: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.7
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.111; extra == 'fastapi'
Provides-Extra: flask
Requires-Dist: flask>=3; extra == 'flask'
Provides-Extra: lint
Requires-Dist: mypy>=1.10; extra == 'lint'
Requires-Dist: ruff>=0.5; extra == 'lint'
Provides-Extra: test
Requires-Dist: pytest>=8; extra == 'test'
Requires-Dist: respx>=0.21; extra == 'test'
Description-Content-Type: text/markdown

# Decionis Python SDK

Decionis SDKs are execution interceptors. They do not encode policy logic inside
the client application. They capture execution intent, submit it to Decionis,
and continue, block, or escalate based on the signed decision.

```bash
pip install decionis
```

## Decorator

```python
from decionis import DecionisClient, decionis_gate

client = DecionisClient(
    api_key="DECIONIS_API_KEY",
    tenant_id="trading_client_001",
)


@decionis_gate(
    client=client,
    action="OPEN_POSITION",
    policy="cfd-risk-policy",
    actor={"id": "cfd_bot_7", "type": "TRADING_BOT"},
)
def open_position(order):
    return broker.open_position(order)
```

The trading client does not own policy criteria, approvals, escalation rules, or
compliance decisions. Those stay versioned in Decionis.

## Client Gate

```python
@client.gate(
    action="TRANSFER_FUNDS",
    policy="treasury-transfer-policy-v3",
    actor={"id": "treasury-agent", "type": "AI_AGENT"},
)
def transfer_funds(request):
    return payment_service.transfer(request)
```

## Low-Level Enforcement

Use `enforce` when you need to package execution intent manually:

```python
decision = client.enforce(
    tenant_id="bank_001",
    actor={"id": "agent_42", "type": "AI_AGENT"},
    action={"type": "TRANSFER_FUNDS", "resource": "liquidity_pool"},
    context={"workflow": "treasury_ops"},
    policy_refs=["treasury-transfer-policy-v3"],
)
```

`enforce` returns only for `ALLOW`. `BLOCK`, `ESCALATE`, and `REVIEW_REQUIRED`
raise `DecionisBlockedException` with the decision ID, reason codes,
explanation, dossier URL, and original response.

## Configuration

```python
client = DecionisClient(
    api_key="DECIONIS_API_KEY",
    base_url="https://api.decionis.ai",
    timeout=10.0,
    max_retries=2,
    retry_backoff=0.25,
    tenant_id="bank_001",
)
```

## FastAPI

```python
from fastapi import FastAPI
from decionis import DecionisClient
from decionis.middleware.fastapi import FastAPIDecionisMiddleware

app = FastAPI()
client = DecionisClient(api_key="DECIONIS_API_KEY", tenant_id="bank_001")

app.add_middleware(
    FastAPIDecionisMiddleware,
    client=client,
    build_request=lambda scope: {
        "actor": {"id": "api", "type": "SERVICE"},
        "action": {"type": "HTTP_REQUEST"},
        "context": {"path": scope["path"]},
        "policy_refs": ["api-execution-policy-v1"],
    },
)
```

## Release

The package is ready for PyPI Trusted Publishing from GitHub Actions. Releases
are triggered from GitHub Releases and start at `0.1.0`.
