HiAPI
Blog

Tutorial

So rufst du flux-2-klein-4b/text-to-image über die HiAPI-API auf: curl, Python und eine funktionierende Anfrage

Eine praxisnahe Anleitung, um die kostengünstige Bildstufe in deine Pipeline einzubinden

Oct 31, 2026
平面玻璃风格封面图:数层半透明玻璃斜向叠压,把浅灰底场折射成冷蓝色带,构图安静克制。

Warum flux-2-klein-4b/text-to-image sich für kostenempfindliche Workloads eignet

Nicht jede Bildpipeline braucht das schwerste Modell im Katalog. Ein großer Teil des Produktionsverkehrs ist repetitiv: Produktbilder, Variantenvorschauen, Thumbnails für Produktlisten, Social Cards aus derselben Vorlage. Für diese Szenarien ist flux-2-klein-4b/text-to-image als bewusst leichtere Stufe konzipiert – du tauschst ein wenig höchste Wiedergabetreue gegen Durchsatz und Vorhersagbarkeit, und bei der geplanten Batch-Generierung Tausender Assets ist das oft der richtige Kompromiss.

Zwei Arten von Workloads profitieren am meisten:

  • E-Commerce-Produktbilder. Du hast meist eine saubere Basisbeschreibung („matte Keramiktasse, 350 ml, warmgrau, auf nahtlosem weißem Hintergrund“) und musst massenhaft Rendering-Varianten für Farben, Winkel und Komposition erzeugen. Konsistenz ist wichtiger als künstlerischer Ausdruck.
  • Batch-Generierung für interne oder Long-Tail-Oberflächen. Kategorie-Banner, A/B-Test-Creatives, Platzhalterbilder für Entwurfslisten – bei diesen Assets ist der marginale Qualitätsgewinn den höheren Betriebsaufwand nicht wert.

Wenn du Key Visuals, feine Texturen und Kompositionen erstellst, bei denen das Bild selbst das Produkt ist, wähle die schwerere Stufe. Wenn Generierungsvolumen, Latenz und Kosten pro Bild die Entscheidung dominieren, wähle flux-2-klein-4b/text-to-image. Der Rest dieses Tutorials verwendet diese Stufe durchgängig: Request-Struktur, curl-Aufruf, Python-Hilfsfunktion, Seitenverhältnis-Strategie und asynchroner Lebenszyklus.

Vorbereitung vor dem Senden der Anfrage

Vor dem ersten Aufruf müssen drei Dinge geklärt sein.

1. API-Schlüssel von HiAPI

Erstelle einen Schlüssel in der HiAPI-Konsole. Jede hier beschriebene Anfrage authentifiziert sich mit diesem Schlüssel, und der Schlüssel ist die einzige benötigte Berechtigung – es gibt keine separate modellspezifische Registrierung.

2. Schlüssel von der Quellcodeverwaltung fernhalten

Behandle den Schlüssel wie jedes andere Geheimnis. Eine bewährte Vorgehensweise:

export HIAPI_API_KEY="your-key-here"

Lies ihn dann in Shell und Python aus der Umgebung. Committe ihn niemals, und wenn du einen Dotfile-Loader verwendest, füge .env zu .gitignore hinzu. Wenn der Schlüssel geleakt ist, rotiere ihn in der Konsole, statt zu versuchen, die Historie zu bereinigen.

3. Modellbezeichner bestätigen

Der Bezeichner-String wird im Request-Body unverändert verwendet und erscheint in manchen Konfigurationen auch in der URL:

flux-2-klein-4b/text-to-image

Kopiere ihn exakt – 4b und das Suffix /text-to-image sind beide Teil des Namens. Tippfehler hier sind die häufigste Ursache für 404- oder „unknown model“-Fehler. Sobald der Schlüssel in der Umgebung vorhanden und der Bezeichner bestätigt ist, kannst du die Nutzlast aufbauen.

Aufbau einer Anfrage an flux-2-klein-4b/text-to-image

Text-zu-Bild-Anfragen auf HiAPI sind bewusst schlank gehalten. Du lieferst den Modellbezeichner und eine Nutzlast mit Generierungsparametern; zurück kommt entweder das Ergebnis oder ein Job-Handle, je nachdem, wie der Endpunkt dieses Modells konfiguriert ist.

Die entscheidenden Felder

  • model — der exakte Bezeichner, flux-2-klein-4b/text-to-image.
  • prompt — ein String, der das Bild beschreibt. Dies ist das Feld mit dem größten Einfluss auf die Ausgabequalität; investiere hier Aufwand, bevor du irgendetwas anderes änderst.
  • Größe oder Seitenverhältnis — wie du die Ausgabebildkomposition angibst. Bevorzuge eine Seitenverhältnis-Angabe statt fest codierter Pixelpaare, denn sie bleibt stabil, auch wenn sich das zugrunde liegende Auflösungsverhalten ändert.

Wie die Antwort aussieht

Die Antwort kommt in zwei Formen, und dein Client sollte beide verarbeiten können:

  1. Synchrone Nutzlast — die Antwort enthält direkt den Speicherort des generierten Bildes (eine URL).
  2. Asynchrone Job-Nutzlast — die Antwort enthält eine Job-ID und einen Status (pending, processing, succeeded, failed sind typische Status). Anschließend fragst du mit dieser ID den Status-Endpunkt ab, bis ein Endzustand erreicht ist und die Nutzlast den Ausgabespeicherort enthält.

Erfinde keine Parameter, die du nicht verifizieren kannst. Wenn ein Feld nicht zum dokumentierten Request dieses Modells gehört, nimm es nicht auf – unbekannte Felder sind die zweithäufigste Quelle verwirrender 400-Fehler. Beginne mit model, prompt und Seitenverhältnis, erhalte zuerst ein funktionierendes Bild und füge dann optionale Parameter einzeln hinzu, wobei du nach jeder Änderung die Ausgabe prüfst.

Dein erster funktionierender curl-Aufruf

Im Folgenden eine vollständige Anfrage, die du ins Terminal einfügen kannst. Sie setzt voraus, dass HIAPI_API_KEY wie oben beschrieben exportiert wurde.

curl -sS -X POST "https://api.hiapi.ai/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-2-klein-4b/text-to-image",
    "prompt": "Studio product photo of a matte ceramic mug, warm grey, soft diffused light, seamless white background, centered composition",
    "aspect_ratio": "1:1"
  }'

Leite die Ausgabe durch einen JSON-Formatierer (| jq .), um die Antwort lesbar zu machen. Du siehst entweder direkt eine Bild-URL oder ein Job-Objekt mit id und status.

Das Ergebnis interpretieren

  • Wenn du eine Bild-URL erhältst, öffne sie im Browser. Das bestätigt, dass Schlüssel, Modellbezeichner und Prompt funktionieren.
  • Wenn du ein Job-Objekt erhältst, notiere die id – du wirst sie in einem späteren Abschnitt abfragen.

Häufige Fehler diagnostizieren

  • 401 / 403 — Schlüssel fehlt, ist falsch formatiert oder wird nicht über den Header Authorization: Bearer übergeben. Prüfe, ob die Umgebungsvariable in der Shell, die curl ausführt, tatsächlich exportiert ist.
  • 404 oder „unknown model“ — der Bezeichner ist falsch. Er muss genau flux-2-klein-4b/text-to-image lauten.
  • 400 mit Validierungsmeldung — meist fehlt prompt, ein Parametername wird nicht unterstützt oder das Seitenverhältnis liegt nicht in der akzeptierten Menge. Reduziere die Nutzlast auf die drei Kernfelder und versuche es erneut.
  • 429 — du sendest Anfragen schneller, als deine Stufe erlaubt. Füge Backoff hinzu, statt in einer engen Schleife zu wiederholen.

Sobald curl funktioniert, hast du eine nachweislich funktionierende Anfrage, mit der du die Python-Version abgleichen kannst, wenn dort etwas schiefgeht.

Dieselbe Anfrage nach Python portieren

Die Python-Version ist ein dünner Wrapper um dieselbe Nutzlast. Strukturiere sie als Funktion, damit der Rest der Pipeline sie aufrufen kann, ohne die HTTP-Logik zu duplizieren.

import os
import time
import requests

API_BASE = "https://api.hiapi.ai/v1"
MODEL = "flux-2-klein-4b/text-to-image"

def generate_image(prompt: str, aspect_ratio: str = "1:1") -> dict:
    """Submit a text-to-image job and return the parsed response."""
    api_key = os.environ["HIAPI_API_KEY"]
    payload = {
        "model": MODEL,
        "prompt": prompt,
        "aspect_ratio": aspect_ratio,
    }
    response = requests.post(
        f"{API_BASE}/images/generations",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=60,
    )
    if response.status_code >= 400:
        # Surface the server's message rather than a bare status code.
        raise RuntimeError(f"HiAPI error {response.status_code}: {response.text}")
    return response.json()

Einige Gewohnheiten, die sich sofort auszahlen:

  • Lies den Schlüssel innerhalb der Funktion aus der Umgebung, nicht beim Import, damit dasselbe Modul in Notebooks, Skripten und geplanten Aufgaben funktioniert.
  • Prüfe den Statuscode explizit und nimm den Response-Body in die Exception auf. Die Validierungsmeldungen von HiAPI sagen dir, welches Feld falsch ist; ein bloßes raise_for_status() verdeckt das.
  • Setze Timeouts. Ohne Timeout kann eine hängende Verbindung einen Worker unbegrenzt blockieren.
  • Halte die Nutzlast als dict, damit du sie loggen, diffen und um optionale Parameter erweitern kannst, ohne String-Formatierung neu zu schreiben.

Nun ein minimaler Treiber:

result = generate_image(
    "Studio product photo of a matte ceramic mug, warm grey, "
    "soft diffused light, seamless white background, centered composition"
)
print(result)

Seitenverhältnisse wählen, die in der Produktion bestehen

Das Seitenverhältnis ist der Parameter, der am ehesten später Nacharbeit verursacht, weil nachgelagerte Systeme eine bestimmte Bildkomposition voraussetzen. Entscheide es pro Oberfläche, nicht pro Anfrage.

Praktische Zuordnung

  • Quadrat (1:1) — Marktplatz-Listings, Produktraster, Avatare und Thumbnail-Positionen. Das ist ein sicherer Standard im E-Commerce, weil die meisten Produktkacheln quadratisch sind und Zuschneiden schlecht aussieht.
  • Hochformat (3:4 oder 4:5) — Social-Feed-Positionen und Produktbilder im Lookbook-Stil. Bietet vertikalen Produkten wie Flaschen und Kleidung Platz, ohne Letterboxing.
  • Querformat (16:9) — Banner, Hero-Leisten, E-Mail-Header, Video-Thumbnails.

Warum das Verhältnis vorgelagert festgelegt werden sollte

Wenn das Verhältnis zur Renderzeit von dem Code gewählt wird, der gerade die API aufruft, erhältst du einen Produktkatalog, in dem die Hälfte der Kacheln quadratisch und die andere Hälfte hochkant ist, und du zahlst eine Neugenerierung, um das zu beheben. Kodiere das Verhältnis stattdessen in deinem Content-Modell – ein Feld surface oder placement, das deterministisch auf ein Verhältnis abgebildet wird – und generiere daraus. Verwende 1:1 für Positionen, die Zuschneiden tolerieren; verwende das vom Layout geforderte Verhältnis für Positionen mit festem Layout.

Dieselbe Disziplin gilt für Prompts: Binde Bildkompositionshinweise („zentrierte Komposition“, „vollständiges Produkt im Bild“, „linker Freiraum für Text“) in die Prompt-Vorlage ein, nicht in einmalige Aufruf-Strings. Vorlagen lassen tausend generierte Bilder so aussehen, als kämen sie aus derselben Pipeline – genau das braucht ein Produktkatalog.

Ein Hinweis: Nicht jedes Modell akzeptiert jedes Verhältnis. Sende dein gewähltes Verhältnis einmal, bestätige den Erfolg und rolle es erst dann für den gesamten Batch aus.

Asynchrone Jobs bis zum Abschluss abfragen

Wenn flux-2-klein-4b/text-to-image ein Job-Handle statt eines Bildes zurückgibt, behandle es als Zustandsmaschine. Der Ablauf: einreichen → Job-ID erhalten → Status abfragen → Endzustand → Ausgabe lesen.

def wait_for_job(job_id: str, timeout_s: int = 300, interval_s: int = 2) -> dict:
    api_key = os.environ["HIAPI_API_KEY"]
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        response = requests.get(
            f"{API_BASE}/jobs/{job_id}",
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=30,
        )
        response.raise_for_status()
        job = response.json()
        status = job.get("status")
        if status == "succeeded":
            return job
        if status == "failed":
            raise RuntimeError(f"Job {job_id} failed: {job.get('error')}")
        time.sleep(interval_s)
    raise TimeoutError(f"Job {job_id} did not finish in {timeout_s}s")

Jeden Status behandeln

  • pending / processing — weiter warten. Beginne mit kurzen Intervallen und erwäge sanftes Backoff (z. B. die Schlafzeit bis zu einer Obergrenze erhöhen), um den Status-Endpunkt bei langen Warteschlangen nicht zu überlasten.
  • succeeded — die Nutzlast enthält jetzt den Ausgabespeicherort. Beende das Polling sofort.
  • failed — nicht blind wiederholen. Protokolliere die Fehlermeldung; bei einem Prompt- oder Parameterproblem schlägt ein erneut gesendeter identischer Request auf dieselbe Weise fehl.

Wissen, wann man aufhört

Begrenze die Schleife immer mit einer Wall-Clock-Deadline. Ein Worker, der endlos pollt, ist ein Leck. Bei Timeout gib die Job-ID aus, damit du sie manuell prüfen kannst – wenn der Job später erfolgreich war, kannst du die Ausgabe trotzdem abrufen. Für Batches führe mehrere Jobs parallel aus und frage sie gemeinsam ab, statt Einreichung und Wartezeit für jedes Bild zu serialisieren.

Ausgaben herunterladen und speichern

Generierte Bilder erscheinen an einem abrufbaren Speicherort in der Job- oder Generierungsantwort. Rufe es serverseitig ab und persistiere es selbst – verlinke die zurückgegebene URL nicht hot in Produktseiten, denn sie ist ein Auslieferungsartefakt, nicht deine Speicherschicht.

def download_image(url: str, path: str) -> str:
    response = requests.get(url, timeout=120)
    response.raise_for_status()
    with open(path, "wb") as f:
        f.write(response.content)
    return path

Ein vorhersehbares Namensschema verwenden

Ein Pfad wie images/{surface}/{sku}/{variant}-{ratio}.png gibt dir drei Dinge: Assets werden natürlich nach Produkt gruppiert, die Oberfläche sagt dir, welche Bildkomposition angefordert wurde, und das Verhältnis im Dateinamen macht versehentliche Duplikate offensichtlich. Wenn du Varianten derselben SKU neu generierst, nimm einen kurzen Hash des Prompts in den Dateinamen auf – so überschreibt ein erneuter Lauf nicht stillschweigend frühere Versuche, die du vielleicht vergleichen möchtest.

Den Kreis schließen

Protokolliere die Job-ID zusammen mit der gespeicherten Datei – in einem Manifest, einer Datenbankzeile oder einer Begleitdatei. Wenn ein nachgelagertes System ein Bild als schlecht meldet, ist die Job-ID das, womit du den ursprünglichen Prompt und die Parameter zurückholen kannst. Zusammen mit inhaltsadressierten Dateinamen ergibt das eine reproduzierbare Prüfspur vom gespeicherten Asset bis zur exakten Anfrage, die es erzeugt hat.

Wenn Einreichung, Polling und Download verbunden sind, wird flux-2-klein-4b/text-to-image zu einem gewöhnlichen Schritt in deiner Pipeline: Arbeit einreihen, mit Deadline pollen, unter stabilen Namen speichern. Von dort aus ist Skalierung nur noch eine Frage von Parallelität und Vorlagen, nicht von neuem Code.

Ä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