Metadata-Version: 2.4
Name: clipwise
Version: 0.1.0b10
Summary: Non-interactive Python SDK and CLI for Clipwise video generation, assets, uploads, products, polling, and tool results
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.27
Requires-Dist: typing-extensions>=4.8
Description-Content-Type: text/markdown

# Clipwise Python SDK and CLI

`clipwise` is the Python SDK and command line interface for the Clipwise
generation API. It lets scripts, agents, and LLM tools list available video
formats, inspect the parameters each format accepts, upload or select reusable
assets, start non-interactive generation jobs, and poll until the result is
ready. Completed jobs expose their usable outputs in `generation.outputs`,
including final video URLs, transcripts, generated media ids, and tool result
payloads such as generated audio/image URLs.

The package only talks to `/api/sdk/v1/*` endpoints. It does not import Django,
does not use internal frontend endpoints, and defaults to the production API at
`https://app.clipwise.ai`.

## Install

```bash
pip install clipwise
```

For local development inside the backend repository:

```bash
cd backend_clipwise/clipwise_cli
pip install -e .
```

## Create An API Token

1. Go to [clipwise.ai](https://clipwise.ai) and log in.
2. Open the dashboard profile menu.
3. Choose **API Tokens**.
4. Click **Create token**.
5. Select the scopes your script needs. For generation workflows, include
   `generations:write`, `generations:read`, `resources:read`, and
   `resources:write`.
6. Copy the token immediately. Clipwise only shows the full token once.

## Configure

Set the API token from the Clipwise dashboard before using the SDK or CLI.

```bash
export CLIPWISE_API_KEY="cw_live_..."
```

The base URL is optional. It already defaults to `https://app.clipwise.ai`.
Only set it for staging, local development, or a private deployment.

```bash
export CLIPWISE_BASE_URL="https://app.clipwise.ai"
```

You can also save the key locally:

```bash
clipwise auth set-key cw_live_...
clipwise auth show
clipwise auth clear
```

## Python Quick Start

```python
from clipwise import Clipwise

client = Clipwise()

# Let the backend return all active tools and formats.
formats = client.formats.list()

# Inspect the exact inputs for a format before generating.
inventory = client.formats.retrieve("inventory_shoot")
print(inventory["format"]["required_inputs"])
print(inventory["format"]["optional_inputs"])
print(inventory["format"]["resource_requirements"])

# Start a non-interactive generation job.
job = client.generations.create(
    format="smart",
    prompt="Create a 30 second founder launch video for a new AI product",
)

# Poll until complete.
result = client.generations.wait(job["id"])
print(result["generation"]["outputs"])
```

## CLI Quick Start

```bash
clipwise formats list --json
clipwise formats show inventory_shoot --json

clipwise generate \
  --format smart \
  --prompt "Create a 30 second founder launch video for a new AI product" \
  --json

clipwise wait gen_abc123 --json
```

## How LLMs Should Use This Package

LLMs should not guess the parameters for a format. They should inspect the
format schema first.

1. Run `clipwise formats list --json` or `client.formats.list()`.
2. Pick a format by `slug`, `template_name`, `display_name`, or `aliases`.
3. Run `clipwise formats show FORMAT --json` or `client.formats.retrieve(FORMAT)`.
4. Read these fields from the response:
   - `description`
   - `what_it_does`
   - `required_inputs`
   - `optional_inputs`
   - `resource_requirements`
   - `output_types`
   - `examples`
5. For every resource-backed input, list or upload the resource before
   generation. When listing assets for a specific format, pass
   `video_format=FORMAT` or `--video-format FORMAT`; Clipwise will return
   compatible assets and hide internal matching details.
6. Start the job with `clipwise generate ... --json` or
   `client.generations.create(...)`.
7. Poll with `clipwise status JOB_ID --json`, `clipwise wait JOB_ID --json`,
   `client.generations.retrieve(job_id)`, or `client.generations.wait(job_id)`.

Do not pass `--platform all`; all active Clipwise surfaces are returned by
default. Use `--platform clipwise` or `--platform video_company` only when the
user explicitly wants one product surface.

If a script passes an asset id that does not belong to the selected format,
Clipwise rejects the generation request instead of starting a brittle job.

## SDK Reference

### Client

```python
from clipwise import Clipwise

client = Clipwise(
    api_key=None,      # Defaults to CLIPWISE_API_KEY or saved config.
    base_url=None,     # Defaults to CLIPWISE_BASE_URL or https://app.clipwise.ai.
    timeout=30,
)
```

### Formats

```python
client.formats.list(kind=None, platform=None, include_inactive=False)
client.formats.retrieve(format_id_or_slug)
```

`kind` may be `format` or `tool`. `platform` may be `clipwise` or
`video_company`. Leave both unset for the default all-active catalog.

### Resources

```python
client.resources.types()
client.resources.list(resource_type, page=None, limit=None, **filters)
client.resources.retrieve(resource_type, resource_id)
client.resources.upload(resource_type, file, **metadata)
client.resources.generate(resource_type, prompt, **metadata)
client.resources.delete(resource_type, resource_id)
```

Resource list responses include pagination when the backend can page them.
Use `page` and `limit` for every list call that an agent may repeat.
Pass `video_format` when choosing assets for a known format so the API only
returns compatible actors, locations, poses, and references.

### Uploads

```python
client.uploads.create(file, purpose="image", **metadata)
client.uploads.list(page=None, limit=None, **filters)
client.uploads.delete(upload_id)
```

Generic uploads are useful for source videos, source images, source audio, and
other one-off generation inputs.

### Products

```python
client.products.list(page=None, limit=None)
client.products.create(name=None, image_ids=None, url=None, **metadata)
client.products.update(product_id, **metadata)
client.products.delete(product_id)
```

### Voices

```python
client.voices.list(**filters)
client.voices.clone(file, name=None, language=None, description=None)
```

### Generations

```python
client.generations.create(idempotency_key=None, **params)
client.generations.retrieve(generation_id)
client.generations.wait(generation_id, timeout=1800, interval=5)
client.generations.cancel(generation_id)
```

`create()` returns immediately with a generation id. It does not run an
interactive flow. Use `wait()` only when your script wants to block until
completion.

`cancel()` succeeds only when Clipwise can cancel a real backing Celery task or
generated media job, or when the job has not started yet. If a workflow has
already moved into a non-cancellable `VideoTask` stage, the API raises
`ClipwiseError` with code `unsupported_cancellation` instead of pretending the
underlying work stopped.

For completed VideoCompany tools such as `text_to_audio`, status and wait
responses include top-level tool data under `generation.outputs.result` and,
when available, `generation.outputs.generated_media_id`. The CLI prints
`outputs.result.url` in non-JSON mode when no final video URL exists.

Local file paths passed to known file parameters are uploaded first and replaced
with the uploaded resource id automatically.

## CLI Reference

Global flags:

```bash
clipwise --api-key cw_live_... --base-url https://app.clipwise.ai --timeout 30 --json ...
```

Commands:

```bash
clipwise auth set-key cw_live_...
clipwise auth show
clipwise auth clear

clipwise formats list --json
clipwise formats list --kind tool --json
clipwise formats list --platform video_company --json
clipwise formats show ugc_video --json

clipwise resources types --json
clipwise resources list avatars --video-format ugc_video --page 1 --limit 20 --json
clipwise resources list poses --video-format ugc_product_background --page 1 --limit 20 --json
clipwise resources list background_music --page 1 --limit 20 --json
clipwise resources list overlays --type overlay --page 1 --limit 20 --json
clipwise resources show RESOURCE_TYPE RESOURCE_ID --json
clipwise resources upload product_images ./product.png --product-type skincare --json
clipwise resources upload reference_ads ./ad.mp4 --type video --json
clipwise resources upload background_music ./track.mp3 --json
clipwise resources upload overlays ./overlay.webm --type underlay --json
clipwise resources generate avatars --prompt "Female presenter in a studio" --video-format ugc_video --json
clipwise resources generate background_images --prompt "Luxury bathroom counter" --video-format ugc_product_background --json

clipwise uploads create ./input.mp4 --purpose video --json
clipwise uploads list --page 1 --limit 20 --json

clipwise products list --page 1 --limit 20 --json
clipwise products create --name "Serum" --image-id UPLOAD_ID --product-type skincare --json
clipwise products update PRODUCT_ID --name "New name" --json
clipwise products delete PRODUCT_ID --json

clipwise voices list --json
clipwise voices clone ./voice.wav --name "My voice" --language en --json

clipwise generate --format smart --prompt "..." --json
clipwise status gen_... --json
clipwise wait gen_... --timeout 1800 --poll-interval 5 --json
clipwise cancel gen_... --json
```

## Generation Parameters

Common generation flags:

- `--format`: format slug, template name, display name, alias, or `smart`.
- `--mode`: mode for formats that support sub-modes, such as inventory shoot.
- `--prompt`: prompt text or path to a text file.
- `--script`: script text or path to a text file.
- `--language`: target language where supported.
- `--aspect-ratio`: aspect ratio where supported.
- `--duration`: target duration where supported.
- `--image`, `--images`: source image path/id or comma-separated image list.
- `--video`: source video path/id/URL depending on format.
- `--audio`: source audio path/id.
- `--avatar`: avatar id.
- `--voice`: voice id.
- `--background-image`: background image id or local image path.
- `--reference-image`: pose/reference image id or local image path.
- `--reference-video`: reference video id or local video path.
- `--product-id`: product id.
- `--product-image`: product image id or local image path.
- `--product-images`: comma-separated product image ids or local file paths.
- `--product-type`: product category/type where supported.
- `--product-description`: product description text.
- `--ad-format`: static ad format where supported.
- `--variations`: number of asset variations where supported.
- `--metadata`: JSON string or path to a JSON file.
- `--idempotency-key`: safe retry key.
- `--wait`: block and poll after creating the job.

## Resource Types

Use `clipwise resources types --json` for the live catalog. Current resource
types include:

- `avatars`: curated, uploaded, and generated presenter/avatar assets.
- `voices`: voice catalog and cloned user voices.
- `background_music`: background music catalog and user uploaded tracks.
- `overlays`: overlay and underlay video assets.
- `templates`: Clipwise layout/style templates.
- `background_images`: curated, uploaded, and generated backgrounds.
- `poses`: pose/reference images, including inventory-shoot references.
- `products`: user product records and product image collections.
- `product_images`: uploaded product references.
- `generic_uploads`: user uploaded image, video, and audio files.
- `reference_ads`: reference ad images and videos.
- `reference_videos`: motion reference videos for viral dancing.
- `generated_media`: generated image, video, and audio history.

Important mappings:

- Inventory shoot product mode uses `ugc_product_background`.
- Inventory shoot model mode uses `ugc_model_shoot`.
- `--reference-image` for inventory shoots maps to a `pose`.
- Product images can be uploaded with
  `clipwise resources upload product_images FILE`.
- Reference ad videos can be uploaded with
  `clipwise resources upload reference_ads FILE --type video`.
- Background music can be uploaded with
  `clipwise resources upload background_music FILE`.
- Overlays and underlays can be uploaded with
  `clipwise resources upload overlays FILE --type overlay|underlay`.
- Standalone resource generation currently supports `avatars` and
  `background_images`.
- Background music generation is workflow-scoped; leave it to the selected
  video format unless you are uploading an existing track.

## Format Reference

The live API is the source of truth. The table below documents the format
schemas exposed by `formats list` and `formats show`.

| Format or Tool | What It Does | Required Inputs | Common Optional Inputs | Resource Requirements |
|---|---|---|---|---|
| `smart`, `ai_viral_videos` | Turns a prompt into a complete short-form video with script, scenes, visuals, voice, music, subtitles, and final render. | `prompt` | `language`, `aspect_ratio`, `duration`, `tone`, `style`, `audience`, `voice`, `avatar`, `logo` | none |
| `business_videos` | Creates business explainers, sales education clips, and professional social videos from a prompt. | `prompt` | `language`, `audience`, `tone`, `style`, `voice`, `logo`, `background_music` | optional voice, logo, music |
| `ecommerce_product_video` | Creates product marketing videos from product details and optional product images. | `prompt` | `product_name`, `product_description`, `product_images`, `language`, `aspect_ratio`, `voice`, `logo` | `product_images`, `voice`, `logo` |
| `reddit_style` | Creates Reddit-style narration videos with story framing, generated visuals, and subtitles. | `prompt` | `language`, `duration`, `voice`, `background_music` | `voice`, `background_music` |
| `quiz` | Creates quiz videos with timed questions, answer options, visual beats, and quiz overlays. | `prompt` | `questions_count`, `options_count`, `language`, `duration`, `background_music`, `overlay` | `background_music`, `overlay` |
| `dialogue_video` | Creates character or dialogue-driven videos with storyboarded dialogue scenes. | `prompt` | `language`, `duration`, `style`, `character_consistency_prompts` | `voices`, `avatars` |
| `viral_dancing_video` | Creates viral dancing videos with a selected avatar and reference video. | `avatar`, `reference_video` | `prompt` | `avatars`, `reference_videos` |
| `ugc_video` | Creates UGC-style talking-head ads from a script and optional product, actor, voice, background, and pose. | `script` | `product_images`, `product_type`, `product_description`, `avatar`, `voice`, `background_image`, `pose`, `generate_subtitle` | `product_images`, `avatars`, `voices`, `background_images`, `poses` |
| `ugc_actor_video` | Creates actor-led UGC videos where the selected actor/avatar is central. | `script` | `product_images`, `avatar`, `voice`, `background_image`, `pose`, `directive_instructions` | `product_images`, `avatars`, `voices`, `background_images`, `poses` |
| `ugc_clone` | Creates clone-yourself UGC videos from the user's configured profile and a script. | `script` | `directive_instructions`, `language`, `background_image`, `generate_subtitle` | `background_images` |
| `ugc_model_shoot` | Generates model/product shoot assets by combining a product reference with an avatar/model, background, and pose reference. | `variations` | `product_image`, `product_type`, `product_description`, `avatar`, `background_image`, `pose`, `aspect_ratio` | `product_images`, `avatars`, `background_images`, `poses` |
| `ugc_product_background` | Generates product shots by placing products into selected backgrounds and reference compositions. | `variations` | `product_image`, `product_type`, `product_description`, `background_image`, `reference_image`, `pose`, `aspect_ratio` | `product_images`, `background_images`, `poses` |
| `b_roll_video` | Generates multiple b-roll situations and related video/image assets for products, avatars, and backgrounds. | `video_context`, `product_type`, `aspect_ratio` | `product_images`, `avatar`, `background_image` | `product_images`, `avatars`, `background_images` |
| `static_ad` | Creates static ad images and posts from a product and optional reference ad layout. | `product_id`, `ad_format` | `product_image_upload_id`, `reference_ad_id`, `language`, `custom_instructions`, `variations`, `data` | `products`, `product_images`, `reference_ads` |
| `ad_replicate` | Recreates a reference video ad while swapping in a selected avatar or actor and optional voice. | `avatar`, `reference_video` | `voice`, `directive_instructions`, `background_source` | `avatars`, `reference_ads`, `voices` |
| `avatar_lipsync` | Animates an avatar to lip-sync to uploaded or generated audio. | `avatar`, `audio` | `directive_instruction`, `background_image` | `avatars`, `audio`, `background_images` |
| `image_to_video` | Converts a source image or generated image into a short motion clip. | `image`, `prompt` | `model`, `duration`, `resolution`, `generate_audio` | `source_images` |
| `text_to_image` | Creates an image from a prompt and can use uploaded or generated images as references. | `prompt` | `media_ids`, `model`, `resolution`, `aspect_ratio` | optional source images |
| `text_to_audio` | Generates spoken audio from a script using a selected voice. | `script`, `voice` | none | `voices` |
| `video_to_text` | Extracts transcript or script text from a video file, generated video, or URL. | `video` | `url` | `source_videos` |
| `generate_subtitle` | Generates subtitles or captions for a source video. | `video` | `script`, `subtitle_typography` | `source_videos` |

## Examples

### Smart Prompt-To-Video

```bash
clipwise generate \
  --format smart \
  --prompt "Create a founder-led launch video for an AI analytics tool" \
  --wait \
  --json
```

```python
job = client.generations.create(
    format="smart",
    prompt="Create a founder-led launch video for an AI analytics tool",
)
result = client.generations.wait(job["id"])
```

### Inventory Product Shoot

Select an existing pose/reference:

```bash
clipwise resources list poses \
  --video-format ugc_product_background \
  --page 1 \
  --limit 20 \
  --json
```

Generate with an existing pose id:

```bash
clipwise generate \
  --format inventory_shoot \
  --mode product_shoot \
  --product-image ./product.png \
  --reference-image POSE_ID \
  --variations 4 \
  --json
```

Or upload a local reference image directly:

```bash
clipwise generate \
  --format inventory_shoot \
  --mode product_shoot \
  --product-image ./product.png \
  --reference-image ./reference.png \
  --variations 4 \
  --json
```

### UGC Video

List/select compatible actor, voice, location, and pose resources first:

```bash
clipwise resources list avatars --video-format ugc_video --page 1 --limit 20 --json
clipwise resources list voices --page 1 --limit 20 --json
clipwise resources list background_images --page 1 --limit 20 --json
clipwise resources list poses --video-format ugc_video --page 1 --limit 20 --json
```

```bash
clipwise generate \
  --format ugc_video \
  --script "I tried this serum for seven days and here is what changed..." \
  --product-image ./serum.png \
  --product-type skincare \
  --avatar AVATAR_ID \
  --voice VOICE_ID \
  --background-image LOCATION_ID \
  --reference-image POSE_ID \
  --json
```

### Video To Text

```bash
clipwise generate \
  --format video_to_text \
  --video ./input.mp4 \
  --json
```

### Avatar Lipsync

```bash
clipwise resources upload avatars ./avatar.png --json
clipwise uploads create ./voice.wav --purpose audio --json

clipwise generate \
  --format avatar_lipsync \
  --avatar AVATAR_ID \
  --audio AUDIO_UPLOAD_ID \
  --json
```

### Static Ad

```bash
clipwise products create \
  --name "Vitamin C Serum" \
  --image-id PRODUCT_IMAGE_UPLOAD_ID \
  --product-type skincare \
  --json

clipwise generate \
  --format static_ad \
  --product-id PRODUCT_ID \
  --ad-format instagram_square \
  --variations 4 \
  --json
```

## Pagination

All asset-fetching code should use pagination.

```bash
clipwise resources list poses --page 1 --limit 20 --json
clipwise uploads list --page 1 --limit 20 --json
clipwise products list --page 1 --limit 20 --json
```

SDK:

```python
client.resources.list("poses", page=1, limit=20)
client.resources.list("avatars", video_format="ugc_video", page=1, limit=20)
client.uploads.list(page=1, limit=20)
client.products.list(page=1, limit=20)
```

## Error Handling

SDK errors raise `ClipwiseError` with useful fields:

```python
from clipwise import Clipwise, ClipwiseError

client = Clipwise()

try:
    job = client.generations.create(format="video_to_text", video="./missing.mp4")
except ClipwiseError as exc:
    print(exc.code)
    print(exc.status_code)
    print(exc.request_id)
    print(exc.details)
```

The CLI exits with status code `2` for API or SDK errors and prints structured
JSON when `--json` is passed.

## Security Notes

API tokens are scoped. Create the narrowest token that can complete your task.
Asset listing endpoints are paginated but still expose assets visible to the
token's user and scopes, so do not give broad `resources:read` tokens to
untrusted automations.
