# cygn

Official Python SDK for the [Cygn Enterprise API](https://cygn.me) — deepfake detection, C2PA content signing, sonic watermarking, and voice ID.

Zero dependencies. Python 3.9+.

## Installation

```bash
pip install cygn
```

## Quick Start

```python
from cygn import CygnEnterprise
import base64

cygn = CygnEnterprise(license_key="cygn_ent_xxxx")

# Camera capture: sign a photo at the moment it's taken
with open("photo.jpg", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

result = cygn.sign_image(
    image=image_b64,
    provenance="captured",
    app_name="MyDeliveryApp Camera",
)

# result.signed_image is a base64-encoded C2PA-signed JPEG
```

## Authentication

Two methods:

```python
# License Key (simpler)
cygn = CygnEnterprise(license_key="cygn_ent_xxxx")

# Cygn-Token (Ed25519 cryptographic identity)
cygn = CygnEnterprise(cygn_token="eyJhbGci...")
```

## API Methods

### Deepfake Detection

```python
result = cygn.detect_deepfake(content=image_b64, media_type="image")
# result.score, result.verdict, result.signals
```

See your enterprise dashboard for current pricing.

### C2PA Content Signing

```python
result = cygn.sign_image(
    image=image_b64,
    provenance="captured",      # "captured" or "cygned"
    app_name="Zomato Camera",   # your app branding
    did="did:key:z6Mkv...",     # optional signer DID
)
# result.signed_image (base64), result.signed_at
```

See your enterprise dashboard for current pricing.

### Provenance Bundle (Deepfake Detection + Signing)

```python
result = cygn.provenance_bundle(
    image=image_b64,
    provenance="captured",
    app_name="Zomato Rider",
    did="did:key:z6Mkv...",
    display_name="Rider #4521",
)
# result.signed_image, result.deepfake.verdict, result.deepfake.score
```

See your enterprise dashboard for current pricing.

### Sonic Watermarking

See your enterprise dashboard for current pricing.

### Voice ID

See your enterprise dashboard for current pricing.

### Usage & Balance

```python
usage = cygn.get_usage()
# usage.balance (paise), usage.total_spent, usage.current_month

balance = cygn.get_balance()  # returns balance in paise
```

## Error Handling

```python
from cygn import CygnEnterprise, CygnAPIError

try:
    result = cygn.sign_image(image=image_b64)
except CygnAPIError as e:
    print(e.status)    # HTTP status code (e.g. 402)
    print(e.code)      # VALIDATION_ERROR, UNAUTHORIZED, INSUFFICIENT_BALANCE, etc.
    print(e.balance)   # remaining balance (if available)
    print(e.cost)      # operation cost (if available)
```

| Status | Code | Meaning |
|--------|------|---------|
| 400 | VALIDATION_ERROR | Invalid request body |
| 401 | UNAUTHORIZED | Missing or invalid auth |
| 402 | INSUFFICIENT_BALANCE | Top up required |
| 403 | FORBIDDEN | Revoked or invalid license |
| 413 | FILE_TOO_LARGE | Payload exceeds limit |
| 415 | UNSUPPORTED_MEDIA_TYPE | Unsupported file format |
| 429 | RATE_LIMITED | Too many requests |
| 503 | SERVICE_UNAVAILABLE | Temporary outage |

## Use Case: Food Delivery Camera App

```python
# Rider captures photo of delivered food
result = cygn.provenance_bundle(
    image=camera_capture_b64,
    provenance="captured",
    app_name="Zomato Rider",
    did="did:key:z6Mkv...",
    display_name="Rider #4521",
)

if result.deepfake.verdict == "likely_authentic":
    save_signed_photo(result.signed_image)
```

## License

Apache-2.0
