HiAPI
Blog

Tutorial

Kandinsky 6.0 Pro Text-zu-Video auf HiAPI: curl- und Python-Tutorial

Eine anfrageorientierte praktische Demonstration: Aufbau des Aufrufs vom Prompt zum Videoclip, Absenden der Anfrage, Abfragen des Fertigstellungsstatus und Herunterladen des Ergebnisses

Nov 3, 2026
米色纸层与石墨色顶边、一块陶土色纸片层叠成阶梯状的封面图,呈现平静的地层节奏。

Was der Aufruf kandinsky-6.0-pro/text-to-video leistet

kandinsky-6.0-pro/text-to-video wandelt Text-Prompts in kurze Videoclips um. Du sendest einen Prompt und einige Generierungsparameter, und das Modell erzeugt eine Videodatei, die du speichern und abspielen kannst. Das ist das gesamte Produkt: Prompt rein, Videoclip raus.

Das entscheidende architektonische Detail: Dies ist kein synchroner Aufruf. Du erhältst das Video nicht direkt im Antwortkörper der ersten Anfrage. Stattdessen erstellst du einen Auftrag, die API gibt die Kennung dieses Auftrags zurück, und das Modell arbeitet anschließend im Hintergrund. Dein Code muss den Auftragsstatus prüfen, bis er die Fertigstellung meldet – dann steht das Ergebnis zum Download bereit.

Dieses Muster hat mehrere Konsequenzen, um die du dein Design von Anfang an herum aufbauen solltest:

  • Der Client muss pollen. Ein einzelner POST kann kein fertiges Video zurückgeben, daher benötigt jede Integration eine Statusabfrageschleife oder eine erneute Prüfung ähnlich einem Webhook.
  • Die Anfrage sollte auf deiner Seite idempotent sein. Wenn das Skript nach dem Absenden abstürzt, willst du nicht stillschweigend einen zweiten Auftrag erstellen. Erfasse die Auftragskennung und speichere sie dauerhaft.
  • Die Latenz ist variabel. Videogenerierung ist langsamer als Bild- oder Textaufrufe, daher ist Warten normal und kein Fehler.

Der Rest dieses Tutorials folgt dieser Lebenszyklusreihenfolge: Vorbereitung, Absenden mit curl, Polling, Herunterladen und anschließend Nachbau desselben Ablaufs in Python. Betrachte den Code als funktionierendes Gerüst – Endpunktpfade und Feldnamen solltest du stets gegen die API-Referenz des Modells abgleichen, da sich diese Details mit der Weiterentwicklung der Plattform ändern können.

Bevor du die erste Anfrage sendest

Vier Dinge müssen vor dem ersten Aufruf bereitstehen.

1. HiAPI-Konto und API-Schlüssel

Die Authentifizierung erfolgt mit einem API-Schlüssel, der von deinem HiAPI-Konto ausgestellt wird. Halte den Schlüssel möglichst aus der Versionskontrolle und der Shell-Historie heraus. Üblich ist, ihn als Umgebungsvariable zu exportieren und im Code von dort zu lesen:

export HIAPI_API_KEY="your-key-here"

Jede der folgenden Anfragen setzt voraus, dass der Schlüssel als Bearer-Token im Authorization-Header gesendet wird. Falls du noch keinen Schlüssel erstellt hast, tu dies zuerst im Konto-Dashboard.

2. HTTP-Client

Mit curl lässt sich ausreichend prüfen, ob eine Anfrage funktioniert. Für alles, was wiederholt ausgeführt werden muss, verwende Python 3 und die requests-Bibliothek – nur eine Abhängigkeit, lesbarer Code und später leicht in einen Scheduler oder Dienst einzubinden:

python3 -m pip install requests

3. Ein Ort für die Ausgaben

Videodateien sind deutlich größer als JSON-Antworten. Entscheide vorab, ob du in ein lokales Verzeichnis schreibst oder in einen Objektspeicher streamst. In diesem Tutorial genügt ein lokales ./output-Verzeichnis:

mkdir -p output

4. Kenne deinen Prompt

Schreibe den Prompt, bevor du den Code schreibst. Ein konkreter, beschreibender Prompt – Motiv, Aktion, Kamerabewegung, visueller Stil – gibt dir eine Ausgangsbasis zum Vergleichen, wenn Probleme auftreten. Wenn der Prompt eine benannte Konstante im Skript ist und kein an der Shell-Eingabeaufforderung eingegebener String, ist es viel einfacher, jeweils nur eine Variable zu ändern.

Das ist die vollständige Liste der Voraussetzungen. Kein SDK zu installieren, kein Build-Schritt; die Plattform ist über normales HTTPS erreichbar.

Eine funktionierende curl-Anfrage

Das erste Ziel ist ein Befehl, der einen Auftrag zurückgibt (kein Video). Bringe ihn zum Laufen, bevor du irgendwelchen Code hinzufügst.

Die Anfrage besteht aus drei Teilen: dem Endpunkt des Modells, dem Authorization-Header und dem JSON-Anfragekörper mit Prompt und Generierungsparametern.

curl -X POST "https://api.hiapi.ai/v1/models/kandinsky-6.0-pro/text-to-video/jobs" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A slow drone shot over a misty pine forest at sunrise, soft golden light, cinematic",
    "duration_seconds": 5,
    "aspect_ratio": "16:9"
  }'

Lies die Antwort sorgfältig. Du suchst nach:

  • einer Auftragskennung – dem Handle, das du für das Polling verwendest. Sie kann id, job_id oder ähnlich heißen.
  • einem anfänglichen Statusfeld, üblicherweise ähnlich wie queued oder processing.
  • etwaigen zurückgegebenen Parametern, mit denen du bestätigen kannst, dass der Anfragekörper wie erwartet geparst wurde.

Eine Antwort mit Auftragskennung und einem Nicht-Fehler-Status bedeutet, dass die Anfrage akzeptiert wurde. Enthielte diese Antwort direkt eine Videodatei, wäre etwas anderes passiert als hier beschrieben.

Bestätige den Vertrag, bevor du darauf aufbaust

Die obigen Feldnamen – Endpunktpfad, duration_seconds, aspect_ratio, Kennungsschlüssel – sind die Details, die sich je nach Modell und Zeitpunkt am ehesten ändern. Verlässliche Quelle der Wahrheit ist die API-Referenzseite des Modells. Prüfe sie einmal, kopiere die exakten Namen als Konstanten in dein Skript und strukturiere den Code so, dass eine Namensänderung eine einzeilige Bearbeitung ist und keine Suche im gesamten Codebestand.

Bei einem 4xx liefert der Fehlerkörper mehr Informationen als der Statuscode. 401 bedeutet falscher oder fehlender Schlüssel; Validierungsfehler der 422-Klasse weisen üblicherweise auf das problematische Feld hin.

Auftrag absenden und bis zur Fertigstellung pollen

Sobald der Absendeaufruf funktioniert, lautet der Lebenszyklus: absenden, Kennung erfassen, pollen, im Endzustand anhalten.

Absenden

Der POST aus dem vorigen Abschnitt erstellt den Auftrag. Was der Code als Nächstes auch tut, er sollte die zurückgegebene Kennung an einem dauerhaften Ort speichern – einer Variablen im Skript, einer Zeile in einer Auftragstabelle, einer Nachricht in einer Queue. Wenn der Prozess stirbt, nachdem die Absendeantwort eingegangen ist, aber bevor die Kennung persistiert wurde, verlierst du die Möglichkeit, diesen Auftrag zu pollen.

Pollen

Beim Polling wird eine GET-Anfrage an die Auftragsressource gesendet, mit der von dir erfassten Kennung:

curl "https://api.hiapi.ai/v1/models/kandinsky-6.0-pro/text-to-video/jobs/$JOB_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Die Antwort meldet den aktuellen Status des Auftrags. In der Praxis wirst du eine kleine Anzahl von Zuständen sehen: in der Warteschlange oder ausstehend, in Bearbeitung, abgeschlossen sowie irgendeine Form von Fehlschlag oder Abbruch. Entwirf deine Schleife um diese Kategorien statt um exakte Strings – ordne, was auch immer die API zurückgibt, deinen running, done, failed im Code zu, damit Umbenennungen deine Wiederholungslogik nicht brechen.

Entscheide, wie lange du wartest

Zwei Zahlen sind wichtig: das Polling-Intervall und der Gesamt-Timeout.

  • Intervall. Polle alle paar Sekunden, nicht in einer engen Schleife. Eine enge Schleife bringt keinen zusätzlichen Nutzen und kann Rate-Limits auslösen. Bei Videoaufträgen sind mehrere Sekunden zwischen den Anfragen angemessen.
  • Timeout. Setze eine Obergrenze. Videogenerierung braucht Zeit, aber „für immer warten“ ist keine akzeptable Antwort für ein Produktionsskript. Wähle ein maximales realistisches Zeitbudget und behandle Überschreitungen als Fehlschlag, den du protokollieren und bewusst wiederholen kannst.

Ein Muster, das den Praxiseinsatz übersteht

In der Produktion ist der Polling-Schritt üblicherweise vom Absende-Schritt entkoppelt, statt in einem schlafenden Prozess zu sitzen. Ein Worker sendet ab, protokolliert den Auftrag und beendet sich; eine regelmäßige erneute Prüfung greift unfertige Aufträge auf und pollt sie. Das ist robuster gegenüber Neustarts und leichter zu beobachten. Für dieses Tutorial genügt eine einfache Schleife in einem einzigen Prozess – strukturiere sie nur als Funktion statt als Inline-Code, dann ist das spätere Verschieben in einen periodisch geplanten Worker einfach.

Den generierten Videoclip herunterladen

Ein abgeschlossener Auftrag ist noch keine Datei auf deiner Festplatte. Die Statusantwort eines abgeschlossenen Auftrags verweist auf die Ausgabe – üblicherweise eine URL, manchmal ein verschachteltes Objekt, das die URL enthält. Lies dieses Feld und verwende es als Eingabe für den Download-Schritt.

curl -L "$OUTPUT_URL" -o output/clip.mp4

Prüfe die folgenden Punkte, um sicherzustellen, dass der Download wirklich erfolgreich war:

  • Folge Weiterleitungen. Ausgabe-URLs werden häufig über Weiterleitungen bereitgestellt; curl behandelt das mit -L, Python mit allow_redirects=True.
  • Prüfe den Inhaltstyp. Ein abgeschlossener Auftrag sollte eine Video-Nutzlast erzeugen. Wenn als clip.mp4 stattdessen JSON oder eine HTML-Fehlerseite gespeichert wird, ist der Download schiefgegangen, nicht die Generierung.
  • Prüfe die Größe. Null-Byte- oder verdächtig kleine Dateien sind fehlgeschlagene Downloads. Vergleiche, falls Antwortheader vorhanden sind, die Bytezahl mit der dort angegebenen Größe.
  • Bedenke Ablaufzeiten. Ausgabe-URLs sind üblicherweise zeitlich begrenzt. Lade sofort nach Abschluss herunter und kopiere die Datei bei Bedarf zur Dauerhaftigkeit in deinen eigenen Speicher, statt die URL als dauerhafte Referenz zu speichern.

Für jeden Einsatz jenseits eines Tutorials streame den Download an das Ziel, statt die ganze Datei in den Speicher zu laden, und schreibe zuerst unter einem temporären Dateinamen und benenne dann um – so sieht ein unvollständiger Download für nachgelagerten Code nie wie eine vollständige Datei aus.

Dieselbe Anfrage in Python umsetzen

Hier ist der curl-Ablauf, nachgebaut als aufrufbare Funktion: absenden, pollen, herunterladen. Die anzupassenden Namen sind oben als Konstanten gesammelt.

import os
import time
import requests

API_BASE = "https://api.hiapi.ai/v1"
MODEL_PATH = "/models/kandinsky-6.0-pro/text-to-video"
API_KEY = os.environ["HIAPI_API_KEY"]

HEADERS = {"Authorization": f"Bearer {API_KEY}"}

RUNNING_STATES = {"queued", "pending", "processing", "running"}
DONE_STATES = {"completed", "succeeded", "done"}
FAILED_STATES = {"failed", "cancelled", "error"}


def generate_clip(prompt, out_path, timeout_s=600, interval_s=5):
    # 1. submit
    resp = requests.post(
        API_BASE + MODEL_PATH + "/jobs",
        headers={**HEADERS, "Content-Type": "application/json"},
        json={"prompt": prompt, "duration_seconds": 5, "aspect_ratio": "16:9"},
        timeout=30,
    )
    resp.raise_for_status()
    job = resp.json()
    job_id = job["id"]
    print(f"submitted job {job_id}")

    # 2. poll
    deadline = time.monotonic() + timeout_s
    while time.monotonic() < deadline:
        status_resp = requests.get(
            f"{API_BASE}{MODEL_PATH}/jobs/{job_id}",
            headers=HEADERS,
            timeout=30,
        )
        status_resp.raise_for_status()
        data = status_resp.json()
        state = str(data.get("status", "")).lower()

        if state in DONE_STATES:
            break
        if state in FAILED_STATES:
            raise RuntimeError(f"job {job_id} ended in state {state}: {data}")
        time.sleep(interval_s)
    else:
        raise TimeoutError(f"job {job_id} did not finish within {timeout_s}s")

    # 3. download
    url = data["output"]["url"] if isinstance(data.get("output"), dict) else data["output"]
    with requests.get(url, stream=True, allow_redirects=True, timeout=60) as r:
        r.raise_for_status()
        tmp = out_path + ".part"
        with open(tmp, "wb") as f:
            for chunk in r.iter_content(chunk_size=1 << 16):
                f.write(chunk)
        os.replace(tmp, out_path)
    print(f"saved {out_path}")
    return job_id


if __name__ == "__main__":
    generate_clip(
        "A slow drone shot over a misty pine forest at sunrise, soft golden light, cinematic",
        "output/clip.mp4",
    )

Warum es so geschrieben ist

  • Statusmengen statt exakter Übereinstimmung. Zurückgegebene Status auf running/done/failed abzubilden bedeutet, dass neue Zwischenzustände die Schleife nicht brechen.
  • Monotone Deadline. time.monotonic() ist von Uhrzeitanpassungen unabhängig, daher ist der Timeout exakt.
  • Atomares Schreiben. Erst in .part schreiben und dann umbenennen bedeutet, dass ein abgebrochener Download nie eine abgeschnittene Datei hinterlässt, die gültig aussieht.
  • Auftrags-ID zurückgeben. Der Aufrufer kann sie protokollieren, speichern und bei Bedarf erneut pollen – das ist der erste Schritt, um das Polling aus diesem Prozess herauszunehmen.

Passe Endpunktpfad, Anfragefeldnamen und Antwortsperrschlüssel an die API-Referenz des Modells an. Alles andere – Schleife, Timeout, Download – ist generisch.

Fehlerzustände und Debugging-Checkliste

Wenn ein Lauf fehlschlägt, isoliere zuerst die Phase, bevor du irgendetwas änderst. Jede Phase hat unterschiedliche Fehlermerkmale.

Authentifizierungsfehler

Ein 401 oder 403 beim Absenden bedeutet, dass der Schlüssel fehlt, falsch ist oder nicht gesendet wurde. Prüfe, ob die Umgebungsvariable in der Shell bzw. dem Prozess, der den Code ausführt, tatsächlich gesetzt ist – ein in einem Terminal exportierter Schlüssel ist für einen Cron-Job unsichtbar. Gib die ersten Zeichen des Schlüssels aus, um zu bestätigen, dass er aufgelöst wurde, und niemals den vollständigen Schlüssel.

Fehlerhaftes Anfrageformat

Fehler der Klasse 400 oder 422 beim Absenden bedeuten, dass der Anfragekörper die Validierung nicht bestanden hat. Der Antwortkörper weist üblicherweise auf das Feld hin. Häufige Ursachen: falsch geschriebener Parameter, Dauer außerhalb des unterstützten Bereichs oder leerer Prompt. Vergleiche dein JSON Feld für Feld mit der API-Referenz; ein einzelner umbenannter Schlüssel ist die häufigste Ursache.

Auftrag bleibt im laufenden Zustand hängen

Wenn das Polling nie einen Endzustand erreicht, prüfe drei Dinge: Die Kennung, die du pollst, ist die, die du abgesendet hast; das Polling-Intervall ist nicht so kurz, dass es durch Rate-Limits blockiert wird; der Timeout ist für das Modell lang genug. Protokolliere bei jedem Polling die rohe Statusantwort, um zu sehen, ob der Status voranschreitet oder einfriert.

Auftrag abgeschlossen, aber Download fehlgeschlagen

Ein abgeschlossener Auftrag mit fehlgeschlagenem Download ist ein Dateiverarbeitungsproblem, kein Generierungsproblem. Prüfe, ob Weiterleitungen gefolgt wird, ob die URL nicht abgelaufen ist und ob der Inhaltstyp Video und nicht JSON ist. Probiere die URL separat mit curl -L aus, um sie vom Skript getrennt zu untersuchen.

Derselbe Prompt schlägt wiederholt fehl

Wenn ein Prompt durchgehend fehlschlägt, während andere erfolgreich sind, verdächtige zuerst Inhaltsrichtlinien oder die Prompt-Länge statt der Infrastruktur. Ändere eine Variable – kürze den Prompt, vereinfache die Szenenbeschreibung – und versuche es erneut.

Eine allgemeine Regel

Protokolliere für jeden Auftrag vier Dinge: die Auftragskennung, den Endzustand, die tatsächliche Laufzeit und den HTTP-Status des Downloads. Diese vier Werte verwandeln die meisten „es hat nicht funktioniert“-Meldungen in weniger als einer Minute in eine konkrete, behebbare Phase.

Ähnliche Artikel

Alle Artikel ansehen →

Starte mit persistenten KI-Artefakten

Hol dir deinen API-Key und rufe Bild-, Video- und Audiomodelle über eine einzige task-basierte API auf.

API-Dokumentation lesen