Metadata-Version: 2.4
Name: corent
Version: 0.5.0
Summary: Official Python SDK for Corent — one API for AI image, video, voice, and text generation with built-in routing, failover, and exact receipts.
Project-URL: Homepage, https://corent.tech
Project-URL: Documentation, https://corent.tech/docs
Author-email: Corent <krrocicrypto@gmail.com>
License-Expression: MIT
Keywords: ai,api,corent,image-generation,llm,text-to-speech,video-generation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# Corent Python SDK

One API for AI **image, video, voice, and text** generation. You pick a quality tier; Corent's router picks the best live model, reroutes failures, verifies the output, and returns the exact charge on every response. Failed generations are never billed.

```bash
pip install corent
```

```python
from corent import Corent

client = Corent("co_live_...")  # get a key at https://corent.tech

image = client.images.generate("a lighthouse at dusk", tier="premium", aspect_ratio="9:16")
print(image.url, image.width, image.height, image.cost_cents)

video = client.videos.generate("a paper boat drifting across a puddle",
                               tier="premium", duration_s=5, resolution="1080p")
print(video.url, video.resolution, video.cost_cents)

speech = client.speech.generate("Welcome to Corent.")
print(speech.url, speech.cost_cents)

answer = client.text.generate("Name three uses for a paperclip.", tier="premium")
print(answer.text, answer.cost_cents)
```

## What the SDK handles for you

- **Timeout-safe renders:** images submit as background jobs and are polled; a network hiccup can never lose a finished (and billed) result.
- **Safe retries:** every generate call carries an auto idempotency key; retries can never double-charge.
- **Backoff:** 429/5xx are retried with `Retry-After` respected.
- **Honest receipts:** `width`/`height` are the *measured* pixels of the delivered file, and `cost_cents` is the exact charge.

## Pick a model yourself (direct access)

Pass `model` instead of `tier` to pin an exact model. It is never substituted:
if that model can't deliver, the call fails and you are not charged.

```python
image = client.images.generate("a lighthouse at dusk", model="corent-flux-schnell")
print(image.model)  # "corent-flux-schnell", the name you asked for

client.models()  # the menu: every model with its kind, quality and live status
```

Every name Corent publishes is spelled `corent-…`, that is what `client.models()`
lists, what comes back on `.model`, and what your receipt shows. Older spellings
you may already have hard-coded (`flux-schnell`, `seedream-5.0-direct`) still
resolve, and the SDK sends whatever string you pass straight through, untouched.

Each model has one name. When we can reach it by more than one route, Corent
serves whichever is cheapest at that moment and charges you that price, you
never have to shop between near-identical entries.

## Text (language models)

Every frontier lab on one key and one bill, priced per token.

```python
answer = client.text.generate("Explain reserve-then-settle billing.",
                              system="Answer in two sentences.", tier="premium")
print(answer.text, answer.prompt_tokens, answer.completion_tokens, answer.cost_cents)

# a real conversation, tool calls included
reply = client.text.chat(
    [{"role": "system", "content": "Be terse."},
     {"role": "user", "content": "What's the weather?"}],
    model="corent-claude-opus-5",
)
```

Streaming isn't wrapped here: point any OpenAI-compatible client at
`https://api.corent.tech/v1` with your Corent key and it works as-is.

## Keep a character or product consistent

Pass 1 to 4 reference images and the prompt is applied as an *edit* of them, so
the same face, character, or product carries into a new scene.

```python
shot = client.images.generate(
    "the same woman, now on a beach",
    tier="pro",  # edit-capable models sit at premium and up
    reference_image_urls=["https://cdn.example/her.png"],
)
```

`air` and `lite` cannot do this and say so with a 400.
`client.tiers()` reports `capabilities.supports_reference_images` per tier.

## A consistent character across shots

Make the character once as an image, then hand that image to every clip as a
reference (`@Image 1` in the prompt) on `corent-seedance-2.5`. Ask for the last
frame back and start the next clip from it, so one shot flows into the next
without a cut. Photos of real people are rejected as references; characters
generated inside Corent are accepted.

```python
hero = client.images.generate("a young sailor in a yellow raincoat, portrait, plain background", tier="pro")

shot1 = client.videos.generate(
    "@Image 1 pushes a rowing boat off a misty shore",
    model="corent-seedance-2.5",
    reference_image_urls=[hero.url],
    aspect_ratio="16:9", duration_s=8,
    return_last_frame=True,
)
shot2 = client.videos.generate(
    "the boat drifts out and she looks back at the shore",
    image_url=shot1.last_frame_url,   # the exact frame shot 1 ended on
    return_last_frame=True,
)
print(shot1.url, shot2.url, shot2.duration_s)
```

`reference_video_urls` (up to 10, `@Video 1`) and `reference_audio_urls`
(up to 10, `@Audio 1`) work the same way, and `task` says what to do with
them: `auto`, `reference`, `edit`, `extend`. Two helpers cover the last two:

```python
fixed = client.videos.edit("Replace the red car in @Video 1 with a blue bicycle", shot1.url)
longer = client.videos.extend("she reaches the far bank and climbs out", shot2.url, duration_s=5)
```

An edit keeps the source clip's length and shape, an extension keeps its
shape, and first/last frame (`image_url` / `end_image_url`) cannot be mixed
with references; the SDK raises `InvalidRequestError` before anything is
sent. `client.models()` reports `supports_reference_images`,
`supports_video_edit`, `supports_video_extend` and `supports_last_frame` per
video model.

## Upload your own files

Hand Corent a file from disk (or raw bytes) and get back a URL every other
call accepts: `image_url`, `mask_url`, `source_image_url`, `reference_image_urls`.
Up to 25 MB. The type is read from the filename's extension unless you name one.

```python
up = client.upload("product.png")            # or bytes: client.upload(data, filename="product.png")
print(up.url, up.content_type, up.bytes)

client.images.generate("the same bottle, on a beach", tier="pro", reference_image_urls=[up.url])
client.videos.generate("the bottle slowly rotates", image_url=up.url)
```

## Image tools: upscale, cut out, edit

Flat price, no tier, synchronous. The edit keeps every pixel outside the mask
exactly as you sent it, which is what an ad needs when the product carries
someone else's trademark.

```python
bigger = client.images.upscale(up.url, prompt="keep the film grain")   # prompt optional
cutout = client.images.remove_background(up.url)                        # PNG, real transparency
mask = client.upload("mask.png")                                        # white = regenerate, black = keep
edited = client.images.edit(up.url, mask.url, "a red can instead of the blue one")
print(edited.url, edited.cost_cents)
```

## Tag spend by your own customer

Pass `customer_id` (1 to 128 characters, your own id) on any generating call
and `client.usage(customer_id=...)` reports that customer's spend alone.
Batches take a default plus a per-item override.

```python
client.images.generate("a fox", tier="air", customer_id="acct_8812")
client.text.generate("Summarise this.", customer_id="acct_8812")
client.batches.images(
    [ImageBatchItem(prompt="a"), ImageBatchItem(prompt="b", customer_id="acct_other")],
    customer_id="acct_8812",  # default for every item without its own
)
client.usage(customer_id="acct_8812")
```

## Batches and webhooks

```python
from corent import ImageBatchItem

# Up to 50 renders in one call. Each item bills at the normal rate.
batch = client.batches.images(
    [ImageBatchItem(prompt="a fox", tier="air"), ImageBatchItem(prompt="a heron", tier="air")],
    idempotency_key="campaign-9",  # a retry replays instead of re-billing
)
progress = client.batches.progress(batch.batch_id)

# Or have the server deliver each result and skip polling entirely.
client.videos.generate(
    "a drone shot",
    tier="premium",
    webhook_url="https://your-server.com/webhooks/corent",
    webhook_secret="your_shared_secret",  # signs every delivery
)
```

## What else you can ask for

```python
# Repeat an image exactly, then change one thing.
first = client.images.generate("a fox in a library", tier="pro")
again = client.images.generate(
    "a fox in a library, wearing glasses",
    tier="pro", seed=12345, negative_prompt="text, watermark",
)

# Four versions of one prompt in one call (four real renders, four charges).
images = client.images.generate_many("a fox", 4, tier="air")

# A transparent logo, at a size you choose.
client.images.generate("a minimal fox mark", transparent=True, width=1024, height=1024)

# Video with sound, going from one picture to another.
client.videos.generate(
    "the camera pulls back",
    tier="premium", audio=True,
    image_url="https://.../start.png", end_image_url="https://.../end.png",
    camera="zoom_out",
)

# Pick a voice, and shape how it reads.
voices = client.voices()
client.speech.generate("Welcome aboard.", voice_id=voices[0]["voice_id"], stability=0.3, speed=1.1)

# Started something by mistake? Stop it. Costs nothing.
client.jobs.cancel(job.id)
```

`audio=True` routes only to models that actually render sound, so a silent
model can never quietly serve the request. Not every model takes every
setting: anything the chosen one could not honour comes back in `meta`
rather than being silently ignored.

## Fine-grained control

```python
job = client.images.generate("...", tier="max_pro", wait=False)  # returns immediately
job = client.jobs.wait(job.id)                                    # resume any time

client.tiers()     # live catalog with honest min-max price ranges
client.models()    # direct-access menu (names, quality, status)
client.balance()   # Balance(balance_cents, held_cents, available_cents)
client.usage()     # what this account has spent; customer_id= narrows it
```

Every generate call sends an `Idempotency-Key`, so the SDK's own retries can
never double-charge. Pass your own `idempotency_key` to make that survive a
process restart too.

Tiers: `air` | `lite` | `premium` | `pro` | `max_pro`, see [corent.tech/pricing](https://corent.tech/pricing). Models: [corent.tech/models](https://corent.tech/models). Docs: [corent.tech/docs](https://corent.tech/docs).
