Clip-type route table in Python: Sora use cases to Sume models

A 30-line Python route table maps ads, demos and teasers to a Sume model, size and length, refuses a length the model cannot make, and prints the dollar cost.

5 min readSume
All posts

Keep a small route table in code that maps each clip type to a Sume model, resolution, aspect ratio and length, and a limits table that refuses a length the model cannot make. The script below prices 600 ads, 250 demos and 150 teasers and prints $600.00, $420.00 and $94.50. It stops with an error if you route a 12-second demo to a model that stops at 10 seconds.

After OpenAI removed the Videos API and the sora-2 family on 2026-09-24, with no replacement listed, a library tends to need several models, not one. A table in code makes that choice reviewable.

The table and the checker

The limits are from the Sume catalog: wan-3.0 takes 2 to 30 seconds, gemini-omni-flash-1.1 takes 3 to 10 and kling-3 takes 4 to 15. The cents are billable prices for each model, resolution and length in the same catalog. Only four combinations are listed here; add the ones your library uses.

LIMITS = {"wan-3.0": (2, 30), "gemini-omni-flash-1.1": (3, 10), "kling-3": (4, 15)}
CENTS = {
    ("wan-3.0", "720p", 8): 100,
    ("wan-3.0", "1080p", 12): 300,
    ("gemini-omni-flash-1.1", "720p", 5): 63,
    ("kling-3", "1080p", 12): 168,
}
ROUTES = {
    "ad": ("wan-3.0", "720p", "9:16", 8),
    "demo": ("kling-3", "1080p", "16:9", 12),
    "teaser": ("gemini-omni-flash-1.1", "720p", "9:16", 5),
}


def plan(kind, count):
    model, res, aspect, secs = ROUTES[kind]
    lo, hi = LIMITS[model]
    if not lo <= secs <= hi:
        raise ValueError(f"{model} takes {lo}-{hi} s, not {secs}")
    cents = CENTS[(model, res, secs)] * count
    return {"model": model, "resolution": res, "aspect_ratio": aspect,
            "duration": secs, "dollars": cents / 100}

for kind, n in (("ad", 600), ("demo", 250), ("teaser", 150)):
    print(kind, plan(kind, n))
try:
    ROUTES["demo"] = ("gemini-omni-flash-1.1", "1080p", "16:9", 12)
    plan("demo", 1)
except ValueError as err:
    print("refused:", err)

What the script prints

The first loop prints one dict per clip type. Ads: 600 clips x 100 cents on wan-3.0 at 720p and 8 seconds, so 60,000 cents or 600.0 dollars. Demos: 250 x 168 cents on kling-3 at 1080p and 12 seconds, silent, so 420.0 dollars. Teasers: 150 x 63 cents on gemini-omni-flash-1.1 at 720p and 5 seconds, so 94.5 dollars. The three lines total $1,114.50.

The last lines reroute the demo to Omni at 12 seconds and call the planner, which raises ValueError and prints refused: gemini-omni-flash-1.1 takes 3-10 s, not 12. That is the guard doing its job; a missing price would raise a KeyError in the same way, which is also what you want for an unlisted combination.

Why validate before you submit

A length outside the range of a model is a rejected request, not a clamp. Catching it in your own table means a bad route fails when you edit it, not after you queued 250 jobs and read 250 errors. The same check is the right place to refuse a resolution the model does not have, such as 720p on minimax-h3.

The cost function is also a budget check. Compare the dollars it prints with the balance before you start a run; Sume reserves the cost of each job at submit and fails the submit with 402 insufficient_credits if the balance cannot cover it.

Checking the table against the live catalog

Do not trust a copy of the numbers for long. GET /v1/videos/models returns the supported resolutions, aspect ratios, durations and pricing fields for each model, and the list prices can change. A test that loads the catalog and asserts that every route in the table is valid is a cheap guard to run in CI.

Keep the route table in version control, with the reason for each row in a comment. When a model is retired or its price changes, the diff shows which clip types are affected, which is what OpenAI's removal of the sora-2 models taught many teams to want.

  • One row per clip type, not per prompt.
  • Include the idempotency key scheme alongside the route.
  • Fail the build when a route points at a model id missing from the catalog.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume