Metadata-Version: 2.4
Name: sct-client
Version: 2.2.0
Summary: Python SDK for the SCT (Secure Compact Tokenization) API
Project-URL: Homepage, https://sct.simosphereai.com
Project-URL: Documentation, https://docs.simosphereai.com/sct/sdk/python
Project-URL: Repository, https://gitlab.simo-online.com/simosphereos/secure-compact-tokenization
Project-URL: Changelog, https://gitlab.simo-online.com/simosphereos/secure-compact-tokenization/-/blob/main/CHANGELOG.md
Author-email: SIMO GmbH <info@simo-online.com>
License-Expression: MIT
Keywords: compliance,encryption,gdpr,pii,pseudonymization,tokenization
Classifier: Development Status :: 4 - Beta
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 :: Cryptography
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# SCT Python SDK

Python client library for the **SCT (Secure Compact Tokenization)** API.
Pseudonymize, de-pseudonymize, detect PII, compress bulky output, and optimize
LLM tokens with a single import — sync (`SCTClient`) or async (`AsyncSCTClient`).

## Installation

```bash
pip install sct-client
```

## Quick Start

```python
from sct_client import SCTClient

with SCTClient(api_key="sct_YOUR_API_KEY") as sct:
    # Pseudonymize a JSON record
    result = sct.pseudonymize(
        '{"name": "Max Mustermann", "email": "max@example.com"}',
        format="json",
        auto_detect_pii=True,
    )
    print(result.pseudonymized_data)
    print(f"Processed {result.record_count} records in {result.duration_ms}ms")
```

## Pseudonymize and De-pseudonymize

```python
from sct_client import SCTClient

sct = SCTClient(api_key="sct_YOUR_API_KEY")

# Pseudonymize with specific fields
result = sct.pseudonymize(
    '{"name": "Erika Musterfrau", "age": 42, "email": "erika@example.com"}',
    format="json",
    encryption_method="aes-256-gcm",
    fields=["name", "email"],
)

# Reverse the pseudonymization
original = sct.de_pseudonymize(
    result.pseudonymized_data,
    encryption_key="YOUR_ENCRYPTION_KEY",
    format="json",
)
print(original.original_data)

sct.close()
```

## PII Detection

```python
with SCTClient(api_key="sct_YOUR_API_KEY") as sct:
    result = sct.detect_pii(
        "Bitte kontaktieren Sie Max Mustermann unter max@example.com oder 0171-1234567."
    )
    for entity in result.entities:
        print(f"  {entity['entity_type']}: {entity['value']}")
```

## Token Optimization

Reduce LLM token usage while preserving meaning:

```python
import os

with SCTClient(api_key=os.environ["SCT_API_KEY"]) as sct:
    result = sct.optimize_tokens(
        "This is a long document that could be compressed for LLM processing...",
        model="gpt-4o",
        aggressive_fillers=True,  # opt-in extra filler-word removal
    )
    print(f"Tokens: {result.original_tokens} -> {result.optimized_tokens}")
    print(f"Reduction: {result.reduction_pct:.1%}")

    # Just count tokens without optimizing
    count = sct.count_tokens("How many tokens is this?", model="claude-3")
    print(f"Token count: {count.token_count}")
```

## Output Compression

Compress bulky tool/observation output (test runners, linters, diffs, grep, …)
before it hits an LLM. The engine picks a structured parser, a noise-strip
filter, or the prose optimizer, and is guaranteed never to cost more tokens than
the raw input. `compress_output()` is an alias of `compress()`.

```python
import os

with SCTClient(api_key=os.environ["SCT_API_KEY"]) as sct:
    result = sct.compress(
        raw_pytest_output,
        format="pytest",      # omit to let the engine sniff the format
        model="gpt-4o",
        verbosity="compact",  # compact | verbose | ultra
    )
    print(result.compressed)
    print(f"Saved {result.tokens_saved} tokens ({result.savings_pct}%)")
    print(f"tier={result.tier} format_used={result.format_used}")
```

## Async

`AsyncSCTClient` mirrors the full sync surface (built on `httpx.AsyncClient`)
for LangChain `ainvoke`/`abatch` and other async paths:

```python
import os

from sct_client import AsyncSCTClient

async with AsyncSCTClient(api_key=os.environ["SCT_API_KEY"]) as sct:
    ps = await sct.pseudonymize('{"name": "Max"}', auto_detect_pii=True)
    comp = await sct.compress(bulky_text, format="jest")
    original = await sct.de_pseudonymize(ps.pseudonymized_data, ps.encryption_key)
```

## End-to-End Encrypted Streaming

For large datasets, use streaming sessions with client-side encryption:

```python
with SCTClient(api_key="sct_YOUR_API_KEY") as sct:
    # Single-request E2E processing
    result = sct.stream_e2e(
        kek="YOUR_KEK",
        envelope={
            "wrapped_dek": "...",
            "ciphertext": "...",
            "nonce": "...",
        },
        mode="pseudonymize",
        throughput_tier="real_time",
    )

    # Multi-chunk session
    session = sct.create_session(kek="YOUR_KEK", mode="pseudonymize")

    sct.send_chunk(session.session_id, index=0, envelope={...})
    sct.send_chunk(session.session_id, index=1, envelope={...}, is_last=True)

    audit = sct.get_session_audit(session.session_id)
    sct.close_session(session.session_id)
```

## Error Handling

The SDK raises typed exceptions for every error category:

```python
from sct_client import SCTClient
from sct_client.exceptions import (
    SCTAuthenticationError,
    SCTRateLimitError,
    SCTValidationError,
)

with SCTClient(api_key="sct_YOUR_API_KEY") as sct:
    try:
        result = sct.pseudonymize("")
    except SCTValidationError as exc:
        print(f"Invalid request: {exc} — details: {exc.details}")
    except SCTAuthenticationError:
        print("Check your API key")
    except SCTRateLimitError as exc:
        print(f"Slow down — retry after {exc.retry_after}s")
```

## Configuration

| Parameter | Default | Description |
|-----------|---------|-------------|
| `api_key` | *(required)* | Your SCT API key (`sct_...`) |
| `base_url` | `https://sct.simosphereai.com/api/v1` | API base URL |
| `timeout` | `30.0` | Request timeout in seconds |

## Encryption Methods

| Method | Description |
|--------|-------------|
| `aes-256-gcm` | AES-256 in GCM mode (default, recommended) |
| `fpe-ff1` | Format-Preserving Encryption (FF1) |

## License

MIT
