Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
Cosa fa l'endpoint hailuo-2.3/text-to-video
Se hai un prompt testuale e vuoi generare da esso una breve clip video, hailuo-2.3/text-to-video è l'endpoint che fa per te. Riceve un prompt in linguaggio naturale che descrive la scena, il soggetto e il movimento che vuoi vedere; restituisce quindi la clip video generata. Il modello è ottimizzato per output di breve durata, quindi dà il meglio di sé quando richiedi un momento compatto e autoconclusivo, anziché una narrazione lunga.
Su HiAPI, la chiamata segue lo stesso schema degli altri endpoint di generazione asincrona: invii la richiesta, il servizio accetta il task e poi esegui il polling finché il risultato non è pronto. Questo rende l'endpoint perfetto per pipeline backend: strumenti di content creation, generatori di prototipi, attività batch o qualsiasi scenario in cui servano alcuni secondi di video su richiesta senza avere una persona seduta davanti a un editor video.
La richiesta contiene un prompt e alcuni parametri di controllo della generazione; la risposta contiene l'identificatore del task e, in seguito, l'URL del video completato. Non devi gestire GPU o pesi del modello: HiAPI si occupa del calcolo e restituisce il link all'output. Se hai già usato altre API text-to-video, la forma complessiva ti sarà familiare, ma lo stile dei prompt di hailuo-2.3 premia maggiormente il ragionamento sulla fisica del movimento, non solo la descrizione visiva (lo vedremo nel dettaglio più avanti).
Prerequisiti e credenziali API
Prima della prima chiamata, assicurati di avere tre cose pronte:
- Una chiave API del tuo account HiAPI. Trattala come una password: non inserirla nel controllo di versione, caricala da una variabile d'ambiente e ruotala se viene compromessa.
- Un client HTTP. Gli esempi shell riportati sotto richiedono solo
curl. Gli esempi Python richiedono Python 3.8+ e la libreriarequests(pip install requests). - L'URL base dell'API HiAPI. Tutte le richieste vanno inviate all'host dell'API HiAPI, con il percorso dell'endpoint
hailuo-2.3/text-to-video. Ti autentichi inviando un bearer token nell'headerAuthorization.
Imposta la chiave in una variabile d'ambiente, così non comparirà nel tuo codice:
export HIAPI_API_KEY="your_api_key_here"
In Python, puoi leggerla con os.environ["HIAPI_API_KEY"]. In curl, farai riferimento alla stessa variabile con $HIAPI_API_KEY.
C'è un'altra cosa da decidere in anticipo: dove verranno archiviati i video generati. L'API restituisce l'URL dell'output, che deve essere recuperato tempestivamente e salvato nel tuo bucket o file system: non costruire una pipeline che presupponga che tale URL sia un asset permanente.
Richiesta eseguibile con curl
Di seguito è riportata una chiamata curl completa per inviare un task di text-to-video. Sostituisci il prompt con la tua descrizione della scena. Il corpo della richiesta è JSON; i campi chiave sono il prompt e i parametri di generazione che controllano durata e forma dell'output.
curl -X POST "https://api.hiapi.ai/v1/hailuo-2.3/text-to-video" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "una biglia di vetro rotola giù da uno scivolo di legno, accelera e cade su un pavimento di pietra, rimbalza due volte e si ferma",
"duration": 6
}'
Dopo un invio riuscito viene restituito un oggetto JSON contenente l'identificatore del task. Somiglia a questo:
{
"id": "job_abc123",
"status": "queued"
}
La parte chiave è id. La generazione non avviene in modo sincrono: l'endpoint accoda il task e restituisce subito la risposta. Conserva id; lo userai per interrogare lo stato e ottenere infine l'URL del video.
Se ricevi un errore di autenticazione, controlla che la chiave sia stata esportata nella stessa sessione shell. Se ricevi un errore di validazione, verifica che il corpo JSON sia nel formato corretto e che il prompt sia presente. Una risposta 429 indica che stai inviando richieste troppo rapidamente e devi fare backoff: la sezione sulla produzione spiega i dettagli.
La stessa chiamata in Python
La versione Python fa la stessa cosa, ma è racchiusa in una funzione riutilizzabile, comoda da inserire in una pipeline. Invia il task e restituisce l'identificatore del task.
import os
import requests
HIAPI_BASE = "https://api.hiapi.ai/v1"
def submit_text_to_video(prompt: str, duration: int = 6) -> str:
"""Invia un task hailuo-2.3/text-to-video e restituisce il suo id."""
api_key = os.environ["HIAPI_API_KEY"]
response = requests.post(
f"{HIAPI_BASE}/hailuo-2.3/text-to-video",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json={"prompt": prompt, "duration": duration},
timeout=30,
)
response.raise_for_status()
data = response.json()
return data["id"]
if __name__ == "__main__":
job_id = submit_text_to_video(
"una biglia di vetro rotola giù da uno scivolo di legno, accelera e cade su un pavimento di pietra, rimbalza due volte e si ferma"
)
print("submitted job:", job_id)
Alcuni dettagli che vale la pena mantenere:
raise_for_status()converte le risposte non 2xx in eccezioni, che è proprio il comportamento desiderato in una pipeline. Fallire rumorosamente in fase di invio è meglio che interrogare un task mai creato.- Il timeout della richiesta di invio è volutamente breve. L'invio deve essere rapido; l'attesa prolungata avviene nella fase di polling, non qui.
- Il parametro
durationè un parametro separato, così chi chiama può richiedere clip più brevi o più lunghe senza duplicare la logica di costruzione della richiesta.
Una volta che la funzione restituisce il valore, hai tutto ciò che serve per proseguire con il polling dello stato.
Scrivere prompt sulla fisica del movimento per clip da 6-10 secondi
Le clip brevi non perdonano. In sei o dieci secondi non puoi costruire un personaggio, edificare un mondo e chiudere una trama: per questo i prompt più efficaci descrivono una singola azione continua, con chiare conseguenze fisiche. Pensa al prompt come alla descrizione di un'istantanea cinematografica, non a una storia.
Inizia con soggetto e azione
Parti da ciò che si muove e da ciò che fa. "una biglia di vetro rotola giù da uno scivolo di legno" fornisce subito al modello soggetto, materiale e direzione del movimento. Un incipit vago come "una bella scena" non gli dà nulla da animare.
Descrivi le forze, non solo l'aspetto
Un prompt sulla fisica del movimento significa nominare le forze in gioco: gravità, attrito, quantità di moto, peso, elasticità. Parole come rotolare, accelerare, rimbalzare, fermarsi, oscillare, ribaltarsi, schizzare, strapparsi implicano un modello fisico. Per un oggetto che rimbalza, indica quante volte rimbalza e dove si ferma infine. Per un oggetto che cade, indica su cosa atterra e se si frantuma, si ammacca o rimbalza.
Mantieni la camera esplicita e semplice
Un'inquadratura fissa o un singolo movimento lento di camera di solito basta per una clip breve. Se sia la camera sia il soggetto fanno cose complesse, la clip diventa confusa e il movimento sembra rumore. Specifica il tipo di inquadratura solo quando è importante per l'azione: primo piano, campo largo, camera a seguire.
Costruisci un arco dell'evento
Un modello utile per clip da 6-10 secondi è: preparazione → azione → conseguenza. La biglia è in cima allo scivolo; rotola giù e accelera; cade, rimbalza due volte e si ferma. Questo arco fornisce al modello inizio, parte centrale e fine, tutti adatti alla durata della clip. Evita di richiedere più azioni non correlate; un evento fisico ben descritto si legge molto meglio di tre eventi abbozzati.
Infine, mantieni il prompt specifico. Materiali, illuminazione e texture delle superfici aiutano il modello a dare concretezza al movimento: una biglia sul legno si comporta diversamente da una biglia sul ghiaccio, e dirlo guida il risultato.
Gestire i task asincroni tramite polling
La generazione richiede tempo, per questo l'endpoint è asincrono. Dopo aver inviato il task ricevi un id; poi interroghi l'endpoint di stato finché il task non raggiunge uno stato terminale. Un ciclo di polling robusto gestisce tre cose: intervallo, timeout ed esposizione degli errori.
import time
import requests
HIAPI_BASE = "https://api.hiapi.ai/v1"
def wait_for_video(job_id: str, api_key: str, interval: float = 3.0, max_wait: float = 600.0) -> str:
"""Esegue il polling finché il task non è completato e restituisce l'URL del video di output."""
deadline = time.time() + max_wait
url = f"{HIAPI_BASE}/hailuo-2.3/text-to-video/{job_id}"
while time.time() < deadline:
response = requests.get(
url,
headers={"Authorization": f"Bearer {api_key}"},
timeout=30,
)
response.raise_for_status()
data = response.json()
status = data.get("status")
if status == "completed":
return data["output"]["video_url"]
if status in ("failed", "cancelled"):
raise RuntimeError(f"il task {job_id} è terminato con stato {status}: {data.get('error')}")
time.sleep(interval)
raise TimeoutError(f"il task {job_id} non è stato completato entro {max_wait} secondi")
Note su questo ciclo:
- Esegui il polling a intervalli, non in un ciclo stretto. Un paio di secondi tra un controllo e l'altro bastano ed evitano di martellare l'API.
- Limita sempre il tempo totale di attesa. Un task bloccato non deve tenere appeso un worker per sempre. Il valore
max_waitqui è piuttosto prudente; adattalo alla lunghezza delle clip e allo stato della coda. - Tratta
failedcome un ramo reale. Espone il payload di errore invece di ritentare ciecamente: problemi di prompt o parametri non si risolvono da soli. - Restituisci l'URL del video, non la risposta grezza. Chi chiama questa funzione non deve conoscere la struttura della risposta.
Per carichi di lavoro maggiori, separa le fasi di invio e polling in worker distinti: un worker accoda i task e memorizza gli ID, un altro esegue polling e download. Così disaccoppi la latenza delle richieste dal tempo di generazione.
Scaricare e archiviare l'output
Quando il polling restituisce l'URL del video, scarica i byte e scrivili in una posizione persistente. Fallo tempestivamente: l'URL restituito è un link di consegna, non un archivio permanente di asset. Scarica in streaming invece di caricare l'intero file in memoria; scrivi prima in un percorso temporaneo e poi rinomina, così un download parziale non sembrerà mai un file completo.
import os
import tempfile
import requests
def download_video(video_url: str, dest_path: str) -> None:
"""Scrive in modo atomico il video completato in streaming su dest_path."""
os.makedirs(os.path.dirname(dest_path) or ".", exist_ok=True)
with requests.get(video_url, stream=True, timeout=120) as response:
response.raise_for_status()
fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(dest_path) or ".")
try:
with os.fdopen(fd, "wb") as f:
for chunk in response.iter_content(chunk_size=1 << 16):
f.write(chunk)
os.replace(tmp_path, dest_path)
except Exception:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
raise
api_key = os.environ["HIAPI_API_KEY"]
video_url = wait_for_video("job_abc123", api_key)
download_video(video_url, f"out/{'job_abc123'}.mp4")
Alcune scelte pratiche:
- Nomina i file in base all'ID del task. Ti dà una chiave stabile e resistente ai conflitti, e rende banale associare il file alla richiesta che lo ha prodotto.
- Archivia i metadati insieme al video. Salva il prompt originale, la durata e il timestamp in un JSON o in un database di supporto. Sei mesi dopo vorrai sapere da cosa è stata generata una certa clip.
- In produzione carica su object storage. Scrivere su disco locale va bene per i prototipi; una pipeline reale dovrebbe inviare i file al tuo bucket e registrare la chiave dell'oggetto, così i video sopravvivono ai riavvii dei worker.
Suggerimenti per la produzione e modalità di errore comuni
La maggior parte delle prime integrazioni inciampa negli stessi punti. Ecco cosa tenere d'occhio.
Ritenta le cose giuste
Ritenta sugli errori transitori: errori di rete, timeout, risposte 429 e 5xx, usando backoff esponenziale con jitter. Non ritentare sugli errori di validazione 4xx: un prompt malformato o un parametro errato fallirà sempre allo stesso modo. Se il task di generazione stesso fallisce, esponi l'errore e decidi con attenzione se reinviarlo.
Separa invio e polling
In produzione, invio e polling dovrebbero essere passaggi distinti, di solito in processi diversi. Dopo un invio riuscito, memorizza subito l'ID del task in una coda o in un database. Se un worker si arresta, puoi riprendere il polling invece di perdere il task.
Imposta timeout ovunque
Richiesta di invio, polling dello stato e download del file devono avere ciascuno il proprio timeout. La mancanza di un timeout nella fase di download è la causa classica di worker bloccati.
Mantieni i prompt nel raggio di azione del modello
Nell'intervallo di sei-dieci secondi richiedi una singola azione fisicamente plausibile. Quando il prompt chiede troppo, ottieni una clip caotica dal movimento confuso. Se la qualità dell'output è incoerente, accorcia prima il prompt e semplifica l'azione, poi valuta di cambiare i parametri.
Gestisci correttamente le credenziali
Carica la chiave API da variabili d'ambiente o da un gestore di segreti, mai da file versionati. Usa chiavi diverse per ogni ambiente, così una chiave di sviluppo compromessa non può raggiungere la produzione.
Attenzione alle assunzioni sulla scadenza degli URL
L'errore più comune in produzione è trattare l'URL del video restituito come un link permanente e visualizzarlo nell'interfaccia utente per mesi. Scarica e ri-ospita il file come parte del task, e memorizza il tuo URL.
Con queste abitudini, l'integrazione è breve: invia, esegui il polling, scarica, archivia.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato
-
Tutoriale
Come usare kling-4.0/text-to-video tramite l'API HiAPI: curl, Python e un esempio di richiesta funzionante
Guida pratica per sviluppatori: prompt cinematografici, audio sincronizzato, polling asincrono e download dell'output