Tutoriale
Come chiamare gpt-image-2/image-to-image su HiAPI: curl, Python e una richiesta funzionante
Guida pratica per sviluppatori alle richieste image-to-image: inviare un'immagine di riferimento, monitorare il task e scaricare il risultato
Cosa si aspetta l'endpoint image-to-image
Il modello gpt-image-2/image-to-image su HiAPI è un endpoint di generazione di immagini asincrono. A differenza delle chiamate sincrone che attendono bloccando il ritorno dell'immagine, questo endpoint riceve la richiesta, la mette in coda e restituisce un handle di task. Successivamente devi monitorare il task fino al completamento.
A livello di richiesta devi fornire tre cose:
- ID del modello:
gpt-image-2/image-to-image. - Un'immagine di riferimento: l'immagine sorgente su cui il modello deve basarsi per trasformare o costruire. Questo è l'input decisivo della modalità image-to-image — senza di esso, stai facendo text-to-image.
- Prompt e opzioni: un'istruzione testuale che descrive l'output desiderato, più i campi opzionali elencati nella documentazione del modello (ad esempio dimensioni o formato di output). Invia solo i parametri elencati nella documentazione del modello.
La risposta non è l'immagine stessa, ma un oggetto task contenente un identificatore e uno stato. Considera questo stato come unica fonte di verità: pending o processing significa continua ad attendere, succeeded significa che il risultato è pronto, failed significa che qualcosa è andato storto e devi smettere di fare polling.
Progetta il tuo client intorno a questo ciclo di vita fin dall'inizio. Tutto il resto in questo tutorial — curl, Python, polling, download — si basa sul fatto che "invio e completamento sono due momenti distinti".
Prepara la tua chiave HiAPI e l'immagine di riferimento
Prima di scrivere qualsiasi codice, prepara due cose.
Una chiave API. Creane una nella console HiAPI e salvala in una variabile d'ambiente, invece di incollarla direttamente nello script:
export HIAPI_API_KEY="your-key-here"
Tratta la chiave come un segreto. Non salvarla nel repository e non registrarla nei log delle richieste.
Un'immagine di riferimento. Scegli un file immagine locale che vuoi trasformare. Mantieni dimensioni ragionevoli — immagini sorgente troppo grandi e ad alta risoluzione sono la causa più comune di richieste lente o rifiutate. Metti un PNG o JPEG nella stessa directory dello script: è la soluzione più semplice per la prima esecuzione:
ls -lh ./reference.png
Annota il percorso del file; lo farai riferimento sia negli esempi curl che in quelli Python. Se prevedi di chiamare il modello da un server, verifica che il processo abbia i permessi di lettura su quel percorso e che il file sia un'immagine valida (non un file rinominato con estensione errata).
Con la chiave esportata e l'immagine su disco, hai tutto il necessario per la prima richiesta.
Una richiesta curl funzionante
Il modo più rapido per verificare le credenziali e la struttura del corpo della richiesta è eseguire una chiamata curl. Invia il task e stampa l'oggetto task:
curl -sS https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/image-to-image",
"input": {
"image": "https://example.com/reference.png",
"prompt": "Turn this photo into a watercolor illustration"
}
}'
Due note su questo esempio. Primo, l'immagine di riferimento viene passata come URL tramite il campo input.image; se la documentazione dell'endpoint supporta per il tuo caso l'upload inline base64 o multipart, usa quella forma, ma mantieni lo stesso nome del campo. Secondo, il prompt è dove descrivi la trasformazione — sii specifico su stile, composizione e quali elementi devono rimanere invariati.
Esegui il comando e leggi la risposta. Un invio riuscito restituisce un ID task e uno stato non terminale. Se ricevi 401, la chiave è mancante o errata. Se ricevi 422 o un errore di validazione simile, controlla il corpo della richiesta — di solito è l'ID del modello o il formato del campo image a essere errato.
Salva l'ID del task. I passaggi successivi dipendono da esso.
Fare la stessa cosa con Python
La versione Python deve corrispondere esattamente alla chiamata curl, mantenendo espliciti autenticazione e costruzione del corpo della richiesta, evitando che qualcosa venga nascosto da un livello di astrazione. Usa requests:
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = "https://api.hiapi.ai/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "gpt-image-2/image-to-image",
"input": {
"image": "https://example.com/reference.png",
"prompt": "Turn this photo into a watercolor illustration",
},
}
response = requests.post(f"{BASE_URL}/tasks", json=payload, headers=headers, timeout=30)
response.raise_for_status()
task = response.json()
print(task["id"], task["status"])
Se la tua integrazione invia un file locale invece di un URL, codifica e allega l'immagine secondo la documentazione dell'endpoint, senza inventare campi. La disciplina è la stessa del curl: costruisci il corpo della richiesta come un normale dizionario, invialo, controlla lo stato HTTP prima di analizzare la risposta.
Incapsula la logica di invio in una funzione che restituisce l'ID del task. Così il codice di polling della sezione successiva sarà indipendente da come è stato creato il task.
Eseguire polling del task asincrono fino al completamento
La chiamata di invio restituisce mentre l'immagine è ancora in generazione. Per ottenere il risultato, esegui polling sull'endpoint dello stato del task finché il task non raggiunge uno stato terminale. Un ciclo robusto ha tre caratteristiche: un ritardo tra i polling, un tempo massimo di attesa e una gestione esplicita degli stati di fallimento.
import time
def wait_for_task(task_id, headers, base_url, timeout=300, interval=3):
deadline = time.time() + timeout
while time.time() < deadline:
r = requests.get(f"{base_url}/tasks/{task_id}", headers=headers, timeout=30)
r.raise_for_status()
task = r.json()
status = task["status"]
if status == "succeeded":
return task
if status == "failed":
raise RuntimeError(f"Task failed: {task}")
time.sleep(interval)
raise TimeoutError(f"Task {task_id} did not finish within {timeout}s")
Alcuni miglioramenti pratici:
- Backoff: inizia con un intervallo breve e aumentalo gradualmente, oppure mantieni un intervallo fisso sufficientemente ampio da non martellare l'API. La generazione di immagini non è istantanea.
- Timeout: imposta sempre un limite al tempo totale di attesa. Altrimenti un task bloccato sospenderà il tuo worker a tempo indefinito.
- Stati terminali: considera terminali solo
succeededefailed. Qualsiasi altro stato significa continuare il polling. Se l'API in futuro aggiungerà stati intermedi, il tuo ciclo continuerà a funzionare correttamente.
Se devi eseguire molti task, esegui il polling in un worker in background o in una coda, invece di bloccare una richiesta web. Il ciclo di vita è lo stesso, cambia solo il modello di concorrenza.
Scaricare e verificare il risultato
Una volta che il task riporta successo, l'oggetto task contiene la posizione dell'immagine generata — di solito un URL in un campo di output. Scaricala e scrivila su disco:
task = wait_for_task(task_id, headers, BASE_URL)
image_url = task["output"]["image"]
img = requests.get(image_url, timeout=60)
img.raise_for_status()
with open("result.png", "wb") as f:
f.write(img.content)
Se l'URL firmato ha una scadenza, scarica subito dopo il completamento, oppure salva direttamente il file, invece di conservare l'URL per usarlo più tardi. Se il tuo endpoint restituisce base64 invece di un URL, decodificalo prima di scrivere.
Un rapido controllo di integrità evita confusi errori a valle:
from PIL import Image
with Image.open("result.png") as im:
im.verify()
print("valid image, bytes:", os.path.getsize("result.png"))
Se il file non è un'immagine decodificabile, verify() solleverà un'eccezione, il che permette di individuare download troncati e pagine di errore salvate come immagine. Controllare la dimensione in byte ti dice anche se la risposta è ragionevole. A questo punto il ciclo è completo: invio, polling, download, verifica.
Diagnosticare i guasti comuni
La maggior parte delle prime integrazioni fallisce in alcuni modi prevedibili. Diagnostica in questo ordine.
Errori di autenticazione (401/403). Chiave mancante, formattata male o priva di permessi. Verifica che la variabile d'ambiente sia esportata nella shell o nel processo che esegue la richiesta e che l'header Authorization usi il prefisso esatto previsto dall'API.
Immagine di riferimento non valida o troppo grande (400/422). L'URL dell'immagine potrebbe non essere raggiungibile dal lato API, il file potrebbe essere corrotto, oppure le dimensioni o la dimensione del file superano i limiti. Prova prima con un PNG piccolo e verificato. Se passi un URL, assicurati che sia accessibile pubblicamente; se passi dati inline, verifica che la codifica sia corretta.
Timeout del polling. Se il task raggiunge continuamente il tuo timeout, aumenta il limite, allunga l'intervallo, oppure controlla se il task è in realtà già fallito e non stai mostrando il motivo. Registra l'ultimo oggetto task prima di sollevare l'eccezione, così puoi vedere lo stato.
Rate limit (429). Fai backoff e riprova con jitter, invece di riprovare immediatamente. Se invii molti task in parallelo, limita la concorrenza per evitare che picchi di traffico attivino i limiti, e rendi i retry idempotenti registrando l'ID del task.
Per qualsiasi categoria di errore, registra lo stato HTTP, il corpo della risposta troncato e l'ID del task — queste tre informazioni di solito bastano a capire se il problema è nell'autenticazione, nel corpo della richiesta o nella tempistica. Usa prima l'esempio curl per isolare se il problema è nel tuo codice o nell'input, poi trasferisci la correzione in Python.
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
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
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