Tutoriel
Comment appeler flux-2-klein-4b/text-to-image via l'API HiAPI : curl, Python et une requête qui fonctionne
Un tutoriel pratique pour intégrer le palier d'images économiques dans votre pipeline
Pourquoi flux-2-klein-4b/text-to-image convient aux charges de travail sensibles aux coûts
Tous les pipelines d'images n'ont pas besoin du modèle le plus lourd du catalogue. Une grande partie du trafic en production est répétitive : photos produits, aperçus de variantes, vignettes de fiches produits, cartes sociales générées à partir du même gabarit. Pour ces scénarios, flux-2-klein-4b/text-to-image est conçu comme un palier délibérément plus léger — vous échangez un peu de fidélité maximale contre du débit et de la prévisibilité, et c'est généralement le bon compromis lorsque vous générez des milliers d'éléments par lots planifiés.
Deux types de charges de travail en profitent le plus :
- Images de produits e-commerce. Vous disposez généralement d'une description de base propre (« mug en céramique mat, 350 ml, gris chaud, posé sur un fond blanc sans raccord ») et vous devez générer un grand nombre de variantes de rendu couvrant couleurs, angles et compositions. La cohérence compte plus que l'expressivité artistique.
- Génération en masse pour des interfaces internes ou de longue traîne. Bannières de catégories, créations pour tests A/B, images de remplacement pour des listes en brouillon — pour ces éléments, le gain marginal de qualité ne justifie pas un coût d'exécution plus lourd.
Choisissez un palier plus lourd lorsque vous produisez des visuels principaux, des textures fines ou lorsque la composition elle-même est le produit. Choisissez flux-2-klein-4b/text-to-image lorsque le volume de génération, la latence et le coût par image dominent la décision. Le reste de ce tutoriel utilise ce palier de bout en bout : structure de la requête, appel curl, fonction assistant Python, stratégie de ratio d'aspect et cycle de vie asynchrone.
Préparer le terrain avant d'envoyer une requête
Trois choses doivent être en place avant le premier appel.
1. Une clé API depuis HiAPI
Créez une clé dans la console HiAPI. Chaque requête décrite ici s'authentifie avec cette clé, et elle est la seule information d'identification dont vous avez besoin — il n'existe pas de processus d'enregistrement séparé par modèle.
2. Garder la clé hors du contrôle de version
Traitez la clé comme n'importe quel autre secret. Une pratique éprouvée :
export HIAPI_API_KEY="your-key-here"
Puis lisez-la depuis l'environnement dans le shell et en Python. Ne la validez jamais, et si vous utilisez un chargeur de dotfiles, ajoutez .env à .gitignore. Si la clé fuit, faites-la tourner dans la console plutôt que d'essayer de nettoyer l'historique.
3. Confirmer l'identifiant du modèle
La chaîne d'identifiant est utilisée telle quelle dans le corps de la requête et, dans certaines configurations, apparaît aussi dans l'URL :
flux-2-klein-4b/text-to-image
Copiez-la exactement — le 4b et le suffixe /text-to-image font tous deux partie du nom. Une faute de frappe ici est la cause la plus fréquente d'une erreur 404 ou « unknown model ». Une fois la clé présente dans l'environnement et l'identifiant confirmé, vous pouvez construire la charge utile.
Anatomie d'une requête flux-2-klein-4b/text-to-image
Les requêtes de génération d'images à partir de texte sur HiAPI sont délibérément épurées. Vous fournissez l'identifiant du modèle et une charge utile de paramètres de génération ; ce qui revient est soit un résultat, soit un identifiant de tâche, selon la configuration du point de terminaison de ce modèle.
Les champs qui comptent le plus
model— l'identifiant exact,flux-2-klein-4b/text-to-image.prompt— une chaîne décrivant l'image. C'est le champ qui influence le plus la qualité de sortie ; concentrez vos efforts ici avant de toucher à quoi que ce soit d'autre.- Dimensions ou ratio d'aspect — la façon dont vous spécifiez le cadrage de la sortie. Privilégiez une spécification sous forme de ratio d'aspect plutôt qu'une paire de pixels codée en dur, car elle reste stable même si le comportement de résolution sous-jacent change.
À quoi ressemble la réponse
La réponse prend deux formes, et votre client doit gérer les deux :
- Charge utile synchrone — la réponse contient directement l'emplacement de l'image générée (une URL).
- Charge utile de tâche asynchrone — la réponse contient un identifiant de tâche et un statut (
pending,processing,succeeded,failedsont des statuts typiques). Vous interrogez ensuite le point de terminaison de statut avec cet identifiant jusqu'à ce qu'il atteigne un état terminal et que la charge utile porte l'emplacement de sortie.
N'inventez pas de paramètres que vous ne pouvez pas vérifier. Si un champ ne fait pas partie de la requête documentée pour ce modèle, ne l'incluez pas — les champs inconnus sont la deuxième source la plus fréquente d'erreurs 400 déroutantes. Commencez par model, prompt et le ratio d'aspect, obtenez d'abord une image qui fonctionne, puis ajoutez les paramètres optionnels un par un en vérifiant la sortie après chaque modification.
Votre premier appel curl fonctionnel
Voici une requête complète à coller dans un terminal. Elle suppose que HIAPI_API_KEY a été exportée comme décrit ci-dessus.
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"
}'
Faites-la passer par un formateur JSON (| jq .) pour lire la réponse. Vous verrez directement une URL d'image, ou un objet de tâche avec id et status.
Interpréter le résultat
- Si vous obtenez une URL d'image, ouvrez-la dans un navigateur. Cela confirme que la clé, l'identifiant du modèle et le prompt fonctionnent.
- Si vous obtenez un objet de tâche, notez l'
id— vous l'interrogerez dans une section ultérieure.
Diagnostiquer les défaillances courantes
- 401 / 403 — clé absente, mal formée, ou non transmise via l'en-tête
Authorization: Bearer. Vérifiez que la variable d'environnement est bien exportée dans le shell qui exécute curl. - 404 ou « unknown model » — identifiant incorrect. Il doit être exactement
flux-2-klein-4b/text-to-image. - 400 avec un message de validation — généralement un
promptmanquant, un nom de paramètre non pris en charge, ou un ratio d'aspect hors de l'ensemble accepté. Réduisez la charge utile aux trois champs essentiels et réessayez. - 429 — vous envoyez des requêtes plus vite que votre palier ne l'autorise. Ajoutez un backoff plutôt que de réessayer dans une boucle serrée.
Une fois que curl fonctionne, vous disposez d'une requête connue pour fonctionner, à laquelle comparer la version Python en cas de problème.
Porter la même requête en Python
La version Python est une fine enveloppe autour de la même charge utile. Organisez-la en fonctions, afin que le reste de votre pipeline puisse l'appeler sans dupliquer la logique HTTP.
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()
Quelques habitudes qui portent immédiatement leurs fruits :
- Lisez la clé depuis l'environnement à l'intérieur de la fonction, et non à l'import, afin que le même module fonctionne dans un notebook, un script et une tâche planifiée.
- Vérifiez explicitement le code de statut et incluez le corps de la réponse dans l'exception. Les messages de validation de HiAPI vous indiquent quel champ pose problème ; un simple
raise_for_status()masque cette information. - Définissez un timeout. Sans timeout, une connexion bloquée peut suspendre indéfiniment le processus de travail.
- Conservez la charge utile sous forme de dict, afin de pouvoir la journaliser, la comparer et étendre les paramètres optionnels sans réécrire le formatage de chaîne.
Voici maintenant un pilote minimal :
result = generate_image(
"Studio product photo of a matte ceramic mug, warm grey, "
"soft diffused light, seamless white background, centered composition"
)
print(result)
Choisir des ratios d'aspect qui résistent à la production
Le ratio d'aspect est le paramètre le plus susceptible de provoquer des retouches plus tard, car les systèmes en aval supposent un certain cadrage. Décidez interface par interface, et non requête par requête.
Mappage pratique
- Carré (1:1) — fiches marketplace, grilles de produits, avatars et emplacements de vignettes. C'est la valeur par défaut sûre pour l'e-commerce, car la plupart des tuiles produits sont carrées et le recadrage y est de mauvaise qualité.
- Portrait (3:4 ou 4:5) — emplacements de fils sociaux et photos produits de style lookbook. Offre de l'espace aux produits verticaux comme les bouteilles et les vêtements sans ajouter de bandes noires.
- Paysage (16:9) — bannières, bandeaux de visuels principaux, en-têtes d'e-mails, vignettes vidéo.
Pourquoi verrouiller le ratio en amont
Si le ratio est choisi au moment du rendu par le code qui appelle justement l'API, vous obtenez un catalogue dont la moitié des tuiles est carrée et l'autre moitié en portrait, et vous payez une régénération pour corriger cela. À la place, encodez le ratio dans votre modèle de contenu — un champ surface ou placement qui correspond de manière déterministe à un ratio — et générez à partir de ce champ. Utilisez 1:1 pour les emplacements qui tolèrent le recadrage ; utilisez le ratio exigé par la mise en page pour les emplacements à disposition fixe.
La même discipline s'applique aux prompts : incluez les indications de cadrage (« composition centrée », « produit complet dans le cadre », « espace à gauche pour le texte ») dans un gabarit de prompt, et non dans des chaînes ponctuelles par appel. Un gabarit fait ressembler mille images générées à la sortie d'un même pipeline, et c'est exactement ce dont un catalogue produits a besoin.
Une mise en garde : ce n'est pas parce qu'un modèle accepte un ratio qu'il accepte tous les ratios. Envoyez une fois le ratio choisi, confirmez le succès, puis seulement généralisez-le sur tout le lot.
Interroger une tâche asynchrone jusqu'à son achèvement
Lorsque flux-2-klein-4b/text-to-image renvoie un identifiant de tâche plutôt qu'une image, traitez-le comme une machine à états. Le flux est : soumettre → recevoir l'ID de tâche → interroger le statut → état terminal → lire la sortie.
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")
Gérer chaque état
pending/processing— continuez d'attendre. Commencez par un intervalle court et envisagez un backoff progressif (par exemple, augmenter le temps de sommeil jusqu'à un plafond) afin de ne pas marteler le point de terminaison de statut pendant une longue file d'attente.succeeded— la charge utile contient désormais l'emplacement de sortie. Arrêtez immédiatement l'interrogation.failed— ne réessayez pas aveuglément. Journalisez le message d'erreur ; s'il s'agit d'un problème de prompt ou de paramètre, resoumettre la même requête échouera de la même manière.
Savoir quand s'arrêter
Bornez toujours la boucle par une échéance en temps réel. Un processus de travail qui interroge pour toujours est un processus de travail qui fuit. En cas de timeout, exposez l'ID de tâche pour une inspection manuelle — si la tâche réussit plus tard, vous pouvez toujours récupérer la sortie. Pour les lots, exécutez plusieurs tâches en parallèle et interrogez-les ensemble, plutôt que de sérialiser la soumission et l'attente pour chaque image.
Télécharger et stocker la sortie
Les images générées apparaissent dans la tâche ou la réponse de génération sous forme d'un emplacement récupérable. Récupérez-le côté serveur, puis persistez-le vous-même — ne créez pas de lien chaud vers l'URL renvoyée dans vos pages produits, car il s'agit d'un artefact de livraison, pas de votre couche de stockage.
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
Utiliser un schéma de nommage prévisible
Un chemin comme images/{surface}/{sku}/{variant}-{ratio}.png vous apporte trois choses : les éléments sont naturellement regroupés par produit, l'interface vous indique quel cadrage a été demandé, et le ratio dans le nom de fichier rend les doublons accidentels évidents. Si vous régénérez une variante du même SKU, incluez un court hachage du prompt dans le nom de fichier — ainsi une réexécution n'écrasera pas silencieusement une tentative précédente que vous voudriez peut-être comparer.
Fermer la boucle
Enregistrez l'ID de tâche aux côtés du fichier stocké, dans un manifeste, une ligne de base de données ou un fichier annexe. Lorsqu'un système en aval signale une image de mauvaise qualité, l'ID de tâche est ce qui vous permet de récupérer le prompt et les paramètres d'origine. Combiné à des noms de fichiers adressés par contenu, cela vous donne une piste d'audit reproductible depuis l'élément stocké jusqu'à la requête exacte qui l'a produit.
Une fois la soumission, l'interrogation et le téléchargement reliés entre eux, flux-2-klein-4b/text-to-image devient une étape ordinaire de votre pipeline : mettre le travail en file d'attente, interroger avec une échéance, stocker sous un nom stable. À partir de là, la mise à l'échelle n'est plus qu'une question de concurrence et de gabarits, pas de nouveau code.
Articles similaires
Voir tous les articles →-
Tutoriel
Comment appeler hailuo-2.3-fast/image-to-video via l'API HiAPI : curl et Python en pratique
La première requête exploitable du palier image-vers-vidéo rapide et économique — de l'ID du modèle au téléchargement du MP4
-
Tutoriel
Comment appeler hailuo-2.3/text-to-video via l'API HiAPI : curl, Python et exemples de requêtes exécutables
-
Tutoriel
Utiliser Kandinsky 6.0 Pro texte-vers-vidéo sur HiAPI : tutoriel curl et Python
Démonstration pratique axée sur la requête : construire l'appel du prompt au clip vidéo, soumettre la requête, interroger l'état d'achèvement et télécharger le résultat