Metadata-Version: 2.4
Name: serialalice
Version: 1.1.2
Summary: The official Serial Alice SDK — certify AI energy consumption in one function call
Project-URL: Homepage, https://serialalice.pt
Project-URL: Documentation, https://docs.serialalice.pt
Project-URL: Repository, https://github.com/SerialAlicev3/serial-alice
Project-URL: Bug Tracker, https://github.com/SerialAlicev3/serial-alice/issues
License: MIT
Keywords: ai,attestation,certification,energy,sustainability
Classifier: Development Status :: 5 - Production/Stable
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 :: Python Modules
Requires-Python: >=3.9
Provides-Extra: all
Requires-Dist: httpx>=0.24; extra == 'all'
Requires-Dist: requests>=2.28; extra == 'all'
Provides-Extra: async
Requires-Dist: httpx>=0.24; extra == 'async'
Provides-Extra: http
Requires-Dist: requests>=2.28; extra == 'http'
Description-Content-Type: text/markdown

# Serial Alice SDK for Python

The official Python SDK for [Serial Alice](https://serialalice.pt) — certify AI energy consumption in one function call.

## Install

```bash
pip install serialalice
```

No required dependencies. Uses `requests` if available, falls back to stdlib `urllib`.

## Quick start

```python
from serialalice import SerialAlice

alice = SerialAlice(api_key="sa_xxx")

cert = alice.certify({
    "model":            "mistralai/Mistral-7B-Instruct-v0.3",
    "hardware":         "H100-SXM-80GB",
    "provider":         "RunPod",
    "energy_wh":        0.00419,
    "tokens_input":     50,
    "tokens_output":    200,
    "duration_seconds": 4.2,
})

print(cert.id)              # sa-abc123...
print(cert.verify_url)      # https://api.serialalice.pt/...
print(cert.trust_score)     # 0.85
print(cert.signature_valid) # True
print(cert.anchor_status)   # PENDING → ANCHORED
```

## Certificate object

```python
cert.id               # "sa-abc123..."
cert.verify_url       # public verification URL (no auth)
cert.download_url     # full certificate bundle URL
cert.signature_valid  # Ed25519 signature intact
cert.anchor_status    # "PENDING" | "ANCHORED" | "FAILED"
cert.anchor_tx        # Polygon tx hash (once anchored)
cert.trust_score      # 0.0–1.0
cert.trust_posture    # "hardware_measured" | "self_reported"
cert.claim_type       # "hardware_measured" | "scheduling_decision"
cert.energy_wh        # measured energy in Wh
cert.uwh_per_token    # µWh per output token
cert.model_id         # HuggingFace model ID
cert.hardware         # GPU label
cert.issued_at        # ISO 8601 timestamp

# Methods
bundle = cert.download_bundle()   # full signed JSON bundle
valid  = cert.verify()            # re-check signature now
d      = cert.to_dict()           # export as plain dict
```

## Auto-derived fields

You don't need to provide:
- `tokens_total` — derived as `tokens_input + tokens_output`
- `uwh_per_token` — derived as `energy_wh * 1e6 / tokens_output`
- `nvml_samples` — derived as `duration_seconds * 10`
- `batch_size` — defaults to `1`

## Other methods

```python
# Retrieve an existing certificate
cert = alice.get_certificate("sa-abc123...")

# Quick signature check (public endpoint)
valid = alice.verify("sa-abc123...")

# List recent certificates for this tenant
certs = alice.list_certificates(limit=20)
```

## Error handling

```python
from serialalice import (
    SerialAlice,
    AuthenticationError,   # invalid API key or missing scope
    IssuanceError,         # server rejected the request
    ValidationError,       # invalid workload payload
    TimeoutError,          # polling timed out
    NotFoundError,         # certificate not found
)

try:
    cert = alice.certify(workload)
except AuthenticationError:
    print("Check your API key and scopes")
except ValidationError as e:
    print(f"Bad payload: {e}")
except TimeoutError:
    print("Try increasing poll_timeout")
```

## Configuration

```python
alice = SerialAlice(
    api_key="sa_xxx",
    base_url="https://api.serialalice.pt",   # default
    poll_interval=1.0,   # seconds between polls (default: 1)
    poll_timeout=60.0,   # max wait for cert (default: 60)
    timeout=30.0,        # HTTP request timeout (default: 30)
)
```

## Links

- [Documentation](https://api.serialalice.pt/docs)
- [Serial Alice Platform](https://serialalice.pt)
- [GitHub](https://github.com/SerialAlicev3/serial-alice)
- [Issue Tracker](https://github.com/SerialAlicev3/serial-alice/issues)
