HiAPI
Blog

Tutoriel

Comment appeler happyhorse-1.1/image-to-video sur l'API hiapi : guide curl et Python

Nov 3, 2026
hiapi.ai 博客封面图:错位堆叠的骨白纸页与一片锈红内页,扁平几何风格。

Ce que fait ce point de terminaison, et quand l'utiliser

happyhorse-1.1/image-to-video transforme une seule image statique en une courte vidéo. Vous envoyez une image de première frame à ce point de terminaison, et le modèle génère une animation à partir de cette frame. L'enjeu réel est la continuité : le sujet, la composition et l'apparence de l'image de départ se prolongent dans le clip généré. C'est ce que nous appelons ici la préservation de l'identité — le modèle ne crée pas une scène nouvelle de toutes pièces à partir d'un simple prompt texte, il prolonge une scène que vous avez déjà composée sous forme d'image.

Ainsi, ce point de terminaison convient parfaitement lorsque l'identité visuelle prime sur l'improvisation :

  • Vous disposez déjà d'une image de référence — portrait, photo produit, character sheet — et souhaitez générer un mouvement fidèle à cette image.
  • Vous produisez un court métrage dans un pipeline où tous les autres éléments sont d'abord conçus sous forme d'images.
  • Vous avez besoin d'animatiques ou d'aperçus de mouvement pour des frames de storyboard.

Il est en revanche moins adapté lorsque vous voulez que le modèle réinterprète librement une scène à partir de zéro, ou lorsque vous n'avez pas d'image statique pour ancrer la sortie. Dans ces cas, un flux de travail image-first implique généralement de générer d'abord une image d'ancrage, puis de confier ce résultat à ce point de terminaison.

L'appel lui-même est asynchrone : vous soumettez une tâche, puis vous interrogez jusqu'à ce que la vidéo soit prête. Le reste de ce guide parcourt ce cycle de vie de bout en bout.

Avant d'envoyer la requête

Deux choses doivent être prêtes avant le premier appel.

Clé API

Tous les appels passent par la plateforme hiapi, la clé API étant ajoutée comme identifiant bearer. Gardez la clé dans une variable d'environnement plutôt que dans le contrôle de source, afin que le même code fonctionne en développement local et en CI :

export HIAPI_API_KEY="your_key_here"

En Python, lisez-la à l'exécution via os.environ["HIAPI_API_KEY"]. Ne journalisez jamais la valeur brute du header.

Image de première frame référençable

Ce point de terminaison nécessite une image de départ. Décidez à l'avance comment la transmettre — en tant qu'URL récupérable par la plateforme, ou en tant que ressource téléversée/encodée en base64, selon ce que prennent en charge votre compte et la documentation du point de terminaison. L'essentiel est que la référence soit stable et accessible au moment de la soumission. Si la tâche risque de faire la queue, une URL signée qui expire dans cinq minutes est un mauvais choix.

Il est également utile de connaître le ratio d'aspect et la durée de sortie attendus avant l'appel, car la première frame les contraint généralement. Prendre cette décision à l'avance évite de devoir resoumettre plus tard.

Une fois la clé exportée et la référence d'image fixée, vous pouvez soumettre.

Construire l'entrée de première frame

La première frame est l'ancre de tout ce que le modèle génère ensuite. Concrètement, traitez-la comme un contrat d'identité : tout ce qui est clairement visible dans cette image — visage, vêtements, logo, palette de couleurs, angle de caméra — est ce sur quoi le modèle doit s'appuyer. Si un détail de l'image statique est flou ou masqué, la sortie le sera aussi.

Quels que soient les paramètres propres au modèle, plusieurs principes de préparation s'appliquent :

  • Choisissez une frame nette et bien éclairée. Les artefacts de compression et le bruit prononcé réduisent ce que le modèle peut préserver. Une image nette et uniformément éclairée est une meilleure ancre qu'une image spectaculaire mais floue.
  • Placez le sujet là où vous voulez que le mouvement commence. Recadrer et composer dans l'image statique coûte moins cher que d'espérer que le modèle recadre.
  • Conservez le ratio d'aspect de la sortie attendue. Si la vidéo finale est en paysage, préparez une image d'ancrage en paysage ; le remplissage ultérieur ne restaurera pas la composition perdue.
  • Évitez les indices contradictoires. Une image statique qui se lit dans un sens tout en suggérant une action hors champ donne au modèle un point de départ instable.

Ne présumez pas de paramètres propres au modèle au-delà de la documentation du point de terminaison. L'approche la plus sûre est de laisser l'image elle-même porter l'intention, puis de limiter les champs de la requête à ce qu'ils couvrent explicitement.

Envoyer une requête fonctionnelle avec curl

Soumettre une tâche ne demande qu'un seul POST. La structure est la suivante : une requête authentifiée vers le point de terminaison, dont le corps JSON porte l'identifiant du modèle et l'entrée image.

curl -sS -X POST "https://api.hiapi.ai/v1/video/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1/image-to-video",
    "input": {
      "image": "https://your-bucket.example.com/first-frame.jpg"
    }
  }'

Décomposition étape par étape :

  1. Le point de terminaison. La cible du POST est la route de génération vidéo de l'API hiapi. Si vous écrivez des scripts pour plusieurs environnements, placez-la dans une variable.
  2. Le header d'authentification. Authorization: Bearer $HIAPI_API_KEY — le shell développe la variable d'environnement que vous avez exportée précédemment.
  3. Le type de contenu. application/json, car le corps est du JSON.
  4. Le corps. model sélectionne happyhorse-1.1/image-to-video ; input.image est votre référence de première frame. Consultez la référence du point de terminaison pour connaître le nom exact du champ image et sa structure acceptés sur votre compte.

Une réponse réussie n'est pas la vidéo elle-même — c'est un handle de tâche. Attendez-vous à recevoir un identifiant et un champ de statut, généralement quelque chose comme queued ou processing. Notez cet ID ; vous l'utiliserez pour interroger lors des étapes suivantes. Lancez d'abord la commande une fois et affichez la réponse, afin de voir sa structure avant d'écrire le script.

Envoyer la même requête avec Python

La version Python est un portage direct, pas une nouvelle intégration. Même route, mêmes headers, même corps JSON.

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
URL = "https://api.hiapi.ai/v1/video/generations"

payload = {
    "model": "happyhorse-1.1/image-to-video",
    "input": {
        "image": "https://your-bucket.example.com/first-frame.jpg"
    },
}

resp = requests.post(
    URL,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=60,
)
resp.raise_for_status()
job = resp.json()
print(job)

Notes de correspondance :

  • requests avec json=payload sérialise le dictionnaire comme le ferait la chaîne -d de curl — si vous utilisez json=, ne définissez pas Content-Type manuellement ; la bibliothèque s'en charge. Le header explicite ci-dessus est inoffensif mais redondant.
  • raise_for_status() convertit tôt les échecs de la couche HTTP en exception, avant que vous ne commenciez à interroger une tâche inexistante.
  • timeout n'est qu'une protection côté client sur l'appel de soumission. La génération s'exécute côté serveur et n'y est pas soumise.

Gardez le payload dans une variable et réutilisez-la. Lorsque vous changerez de modèle ou d'image plus tard, vous ne devriez modifier qu'un seul dictionnaire, et non deux implémentations parallèles.

Gérer les tâches asynchrones et l'interrogation

La génération image-vers-vidéo prend plus de temps qu'un cycle requête/réponse. L'API renvoie donc immédiatement une référence de tâche et attend que vous reveniez vérifier plus tard. Le cycle de vie est : soumettre, recevoir un ID, interroger le statut, récupérer le résultat.

Extrayez l'ID de tâche de la réponse de soumission — le nom du champ dépend du schéma de réponse documenté pour ce point de terminaison, donc lisez-le une fois et codez en dur la recherche de clé plutôt que la valeur :

job_id = job["id"]  # check the endpoint docs for the exact field

Interrogez ensuite à intervalle régulier :

import time

poll_url = f"https://api.hiapi.ai/v1/video/generations/{job_id}"

while True:
    status = requests.get(
        poll_url,
        headers={"Authorization": f"Bearer {API_KEY}"},
        timeout=30,
    ).json()

    if status["status"] == "succeeded":
        break
    if status["status"] == "failed":
        raise RuntimeError(status)
    time.sleep(5)

Règles pour garder une interrogation raisonnable :

  • Interrogez à intervalle fixe, pas en boucle serrée. Pour des tâches de cette ampleur, quelques secondes entre les vérifications suffisent ; marteler le point de terminaison ajoute de la charge sans faire produire le résultat plus tôt.
  • Limitez le temps d'attente total. Un while True sans plafond est un blocage qui finira par arriver. Suivez le temps écoulé et échouez bruyamment au-delà d'un budget raisonnable.
  • Gérez les deux états terminaux. Succès et échec sont tous deux des réponses. Traitez les chaînes de statut inconnues comme non terminales, mais journalisez-les afin de remarquer les changements de schéma.
  • N'interrogez pas une tâche depuis plusieurs workers parallèles. Un poller par tâche, ou coordonnez via une file d'attente.

Une fois le statut terminal, passez au téléchargement du résultat.

Télécharger et stocker la sortie

La vidéo terminée est exposée comme ressource dans la réponse de la tâche terminée — généralement une URL, parfois avec une date d'expiration. Après une interrogation réussie, la première étape consiste à récupérer cette référence et à copier les octets dans un stockage que vous contrôlez.

video_url = status["output"]["video_url"]  # inspect the real response shape

with requests.get(video_url, stream=True, timeout=120) as r:
    r.raise_for_status()
    with open(f"out/{job_id}.mp4", "wb") as f:
        for chunk in r.iter_content(chunk_size=1 << 20):
            f.write(chunk)

Conseils de stockage applicables à tout pipeline :

  • Copiez les artefacts persistants, ne vous contentez pas de les lier. Une URL signée ou à durée limitée est un moyen de transport, pas un stockage. Persistez le fichier, puis stockez votre propre clé d'objet en base de données avec l'ID de tâche.
  • Traitez les gros fichiers en flux. iter_content maintient la mémoire stable ; charger toute la vidéo dans une variable ferait dépendre le plafond mémoire de la taille de la ressource.
  • Enregistrez la provenance. Conservez le job_id, la référence de l'image d'entrée et l'identifiant du modèle avec la ressource. Lorsque vous devrez reproduire le clip, cet enregistrement est la recette.
  • Vérifiez le statut HTTP avant d'écrire. Une écriture partielle due à une réponse d'erreur est pire qu'un échec propre, car elle ressemble à un fichier valide.

Une fois le fichier sur disque ou dans le stockage objet, le pipeline est bouclé et vous pouvez passer à la frame suivante.

Erreurs et pièges à surveiller

La plupart des échecs sur ce point de terminaison sont prévisibles. Liste courte :

  • Entrée de première frame mal formée ou inaccessible. La cause la plus fréquente de rejet de soumission. Vérifiez que l'URL de l'image se résout publiquement, que le format est accepté par le point de terminaison et que le payload imbrique correctement le champ image. Reproduisez avec curl pour distinguer un problème d'authentification d'un problème de payload.
  • Interroger avant que la tâche existe. Lire l'ID dans un mauvais champ, ou interroger une route qui ne correspond pas à la réponse de soumission, produit un 404 qui ressemble à un échec de tâche. Affichez une fois la réponse de soumission et fixez la recherche de clé en conséquence.
  • Attente non bornée. Sans timeout, une tâche bloquée suspend indéfiniment le worker. Fixez un budget, échouez et alertez.
  • Lien de ressource perdu. La génération réussit, mais l'URL est consommée une fois puis jamais copiée. Enregistrez les octets au moment de la récupération et conservez vos propres clés ; ne comptez pas sur le lien renvoyé comme stockage à long terme.
  • Fuite d'authentification. Coller la clé dans un notebook et la commettre accidentellement est un problème récurrent. Chargez-la depuis l'environnement et, en cas de doute, faites une rotation.
  • Présumer de paramètres non documentés du point de terminaison. Si vous avez besoin d'un paramètre qui n'est pas listé, c'est qu'il n'existe pas. Exprimez l'intention uniquement via l'image de première frame et les champs documentés.

Une fois ces points maîtrisés, le flux asynchrone devient banal — exactement ce que vous voulez dans un pipeline de production. Pour les noms de champs et valeurs acceptées propres au point de terminaison, gardez la référence du point de terminaison ouverte pendant la construction.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API