Check an image URL before you pay for image-to-video: Python preflight

A bad first-frame URL fails the job with an input download error. A short Python check of status, content type and size catches most bad URLs first.

5 min readSume
All posts

The short answer

Before you send a first-frame image to Sume, fetch the URL yourself and check three things: the status is 200, the content type starts with image/, and the size is what you expect. A bad URL surfaces as Could not download an input media URL (image_url). A short Python check catches it before the job is queued.

What the failure looks like

Sume downloads your image_url itself. If the download fails, the job fails with the message Could not download an input media URL (image_url). The usual causes are a private link, a signed URL that expired, a redirect to a login page, or a page that returns HTML with a 200. The model never sees a picture in any of those cases.

The preflight

The function below reads only the headers and a bounded number of bytes, so it is cheap. It returns the problem, or None.

import requests

def check_image(url, max_mb=20):
    r = requests.get(url, stream=True, timeout=15, allow_redirects=True)
    try:
        if r.status_code != 200:
            return f"status {r.status_code}"
        kind = r.headers.get("content-type", "")
        if not kind.startswith("image/"):
            return f"content-type {kind or 'missing'}"
        size = int(r.headers.get("content-length", 0))
        if size > max_mb * 1024 * 1024:
            return f"{size} bytes is over {max_mb} MB"
        return None
    finally:
        r.close()

print(check_image("https://example.com/first-frame.png"))

Which limits are yours

The 20 MB default in the script is your own guard, not a Sume limit. Set it to what your pipeline needs. The Sume lip-sync routes have their own file rules: the audio must be on the Sume media host and at most 10 MB.

What a check cannot see

A 200 with the right type can still be a bad frame: a thumbnail, a transparent PNG with the subject cut out, or a picture with a watermark. Open the image once. If the picture is a different ratio from the model's, the result is cropped or adapted, so check the model's supported ratios.

Then submit

After the check passes, send the request with an Idempotency-Key. A rerun with the same key and body returns the existing job, and a rerun with the same key and a different body is a conflict, so change the key when you change the image.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume