Metadata-Version: 2.4
Name: shim-sdk
Version: 0.1.1
Summary: Official Python SDK for Shim — JSON repair for LLM outputs
Project-URL: Homepage, https://shim.so
Project-URL: Documentation, https://docs.shim.so
Project-URL: Repository, https://github.com/shimso/shim-core
Project-URL: Issues, https://github.com/shimso/shim-core/issues
Author-email: Shim <support@shim.so>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agent,anthropic,json,json-repair,json-schema,langchain,llm,llm-output,malformed-json,openai,output-fixing-parser,repair,shim,streaming-json,validation
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.9
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 :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# shim-sdk

Python SDK for [Shim](https://shim.so). Intercept malformed JSON from LLMs. Repair it. Return valid data.

One dependency: `httpx`. Sync and async clients included.

## Installation

```bash
pip install shim-sdk
```

```bash
# Poetry
poetry add shim-sdk
```

```bash
# uv
uv add shim-sdk
```

## Quick Start

```python
from shim import ShimClient

with ShimClient(api_key="sk_live_...") as shim:
    result = shim.repair(raw_output='{"name": "John", "age": 30')

    if result.success:
        print(result.repaired)  # {'name': 'John', 'age': 30}
```

## Async

```python
from shim import AsyncShimClient

async with AsyncShimClient(api_key="sk_live_...") as shim:
    result = await shim.repair(raw_output='{"name": "John", "age": 30')
    print(result.repaired)
```

## Schema Validation

Pass a JSON Schema to enforce types. Shim coerces values and reports what it changed.

```python
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age":  {"type": "number"}
    },
    "required": ["name", "age"]
}

with ShimClient(api_key="sk_live_...") as shim:
    result = shim.repair(
        raw_output='{"name": "John", "age": "30"',
        schema=schema,
        mode="strict"
    )

    print(result.repaired)             # {'name': 'John', 'age': 30}
    print(result.metadata.confidence)  # 'medium' — schema repair present
```

## Streaming

Schema and mode are set at `stream.start()`. Push chunks as they arrive. Finalize when the stream ends.

```python
from shim import ShimClient

with ShimClient(api_key="sk_live_...") as shim:
    session = shim.stream.start(
        schema={"type": "object", "properties": {"name": {"type": "string"}}},
        mode="strict"
    )

    # Push chunks as they arrive from LLM
    shim.stream.push(session.session_id, '{"name": "Jo')
    shim.stream.push(session.session_id, 'hn", "age": 30')

    # Finalize when stream ends
    result = shim.stream.finalize(session.session_id)
    print(result.repaired)  # {'name': 'John', 'age': 30}
```

### Async streaming

```python
from shim import AsyncShimClient

async with AsyncShimClient(api_key="sk_live_...") as shim:
    session = await shim.stream.start()

    await shim.stream.push(session.session_id, '{"name": "Jo')
    await shim.stream.push(session.session_id, 'hn", "age": 30')

    result = await shim.stream.finalize(session.session_id)
    print(result.repaired)  # {'name': 'John', 'age': 30}
```

## Error Handling

The SDK raises `httpx.HTTPStatusError` for transport-level failures. Shim itself always returns HTTP 200 — application errors are in the response body.

```python
import httpx
from shim import ShimClient

with ShimClient(api_key="sk_live_...") as shim:
    try:
        result = shim.repair(raw_output="not json at all")

        if not result.success:
            for error in result.metadata.errors:
                print(f"{error.code}: {error.message}")
                print(f"  recoverable: {error.recoverable}")
    except httpx.HTTPStatusError as e:
        print(f"Transport error: {e.response.status_code}")
```

## Types

Full type definitions included. All response objects are dataclasses with autocomplete.

| Type | Description |
|------|-------------|
| `RepairResponse` | Top-level batch / finalize response |
| `RepairMetadata` | Confidence, repairs, warnings, errors |
| `RepairDetail` | Single repair operation (type, confidence, field) |
| `Warning` | Non-critical issue |
| `RepairError` | Critical failure with recoverability flag |
| `StreamSession` | Session ID + expiry from `stream.start()` |
| `StreamingState` | Incremental parse state from `stream.push()` |

## Support

- Docs: [docs.shim.so](https://docs.shim.so)
- Issues: [GitHub Issues](https://github.com/shimso/shim-core/issues)

## License

MIT
