Metadata-Version: 2.4
Name: effing-cloud-sdk
Version: 0.1.0
Summary: Official Python SDK for Effing Cloud.
Author: Effing
License: Proprietary
Keywords: effing,ffmpeg,rendering,video
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Multimedia :: Video
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# effing-cloud-sdk (Python)

Official Python SDK for [Effing Cloud](https://cloud.effing.dev).

Mint signed render URLs for image, annie, and effie modules deployed to Effing
Cloud — no manual segment construction, no need to install `itsdangerous` or
any other third-party package.

## Install

```bash
pip install effing-cloud-sdk
```

Zero runtime dependencies. Python 3.10+.

The PyPI distribution is named `effing-cloud-sdk`; the Python import name is
`effing_cloud_sdk` (underscores).

## Usage

The recommended API is the `EffingCloudClient` class. Configure it once with
your tenant slug, project slug, and URL secret, then call `mint_signed_url()`
for each render.

```python
import os
from effing_cloud_sdk import EffingCloudClient

client = EffingCloudClient(
    tenant="acme",
    project="posters",
    secret=os.environ["EFFING_URL_SECRET"],
)

url = client.mint_signed_url(
    kind="effie",
    id="poster",
    props={"imageUrl": "https://cdn.example.com/sky.jpg", "duration": 5},
    bounds={"width": 1080, "height": 1920},
)

# https://fn.effing.dev/acme/posters/effie/<segment>
```

`kind` is one of `"image" | "annie" | "effie"` — the module type you want to
invoke.

### Prop naming: snake_case is fine

You can write idiomatic Python in `props`. The server runs a recursive
`snake_case → camelCase` conversion on the deserialized payload before
invoking your module, so `{"image_url": "..."}` here surfaces as
`props.imageUrl` inside the running module. Already-camelCase keys pass
through unchanged, so mixing styles works too.

### One-shot function

A standalone `mint_signed_url()` function is also exported:

```python
from effing_cloud_sdk import mint_signed_url

url = mint_signed_url(
    tenant="acme",
    project="posters",
    kind="effie",
    id="poster",
    props={...},
    bounds={"width": 1080, "height": 1920},
    secret=os.environ["EFFING_URL_SECRET"],
)
```

### Tagging runs

Tags travel inside the signed segment and surface in your run / render
reports. Pass them as a dict (recommended) or as a list of bare values and/or
`name:value` strings:

```python
url = client.mint_signed_url(
    kind="effie",
    id="poster",
    props={...},
    bounds={"width": 1080, "height": 1920},
    tags={"campaign": "summer", "env": "prod"},
)

# Array form — useful for bare tags or pre-formatted entries.
url = client.mint_signed_url(
    kind="effie",
    id="poster",
    props={...},
    bounds={"width": 1080, "height": 1920},
    tags=["vip", "env:prod"],
)
```

Tag names in the dict form must not contain `:` — that character is reserved
as the name/value separator in the array form.

### Custom base URL

```python
EffingCloudClient(
    tenant="acme",
    project="posters",
    secret=os.environ["EFFING_URL_SECRET"],
    base_url="https://fn.example.com",
)
```

## API

All public callables are **keyword-only** — pass every argument by name.

### `EffingCloudClient(*, tenant, project, secret, base_url="https://fn.effing.dev")`

| Argument   | Type  | Default                 | Description                                    |
| ---------- | ----- | ----------------------- | ---------------------------------------------- |
| `tenant`   | `str` | —                       | Your tenant slug.                              |
| `project`  | `str` | —                       | Your project slug.                             |
| `secret`   | `str` | —                       | URL secret from `effing-cloud url-secret`.     |
| `base_url` | `str` | `https://fn.effing.dev` | Override for self-hosted or staging endpoints. |

#### `client.mint_signed_url(*, kind, id, props, bounds, tags=None) -> str`

Returns the fully-qualified signed URL.

### `mint_signed_url(*, tenant, project, kind, id, props, bounds, secret, tags=None, base_url=...)`

Standalone equivalent.

### Types

```python
FnKind = Literal["image", "annie", "effie"]
FnTags = Mapping[str, str] | Sequence[str]

class FnBounds(TypedDict):
    width: int
    height: int
```
