HiAPI
Blog

Tutoriale

Come chiamare gpt-image-2/text-to-image@ext tramite l'API HiAPI: curl e Python

Una guida pratica alle richieste per sviluppatori che integrano la generazione di immagini da testo

Oct 31, 2026
黑绿底上,黄铜色与深绿色扁平缎带以经纬交织方式构成开放式网格,这是教程文章的封面图。

Cosa offre gpt-image-2/text-to-image@ext

gpt-image-2/text-to-image@ext è un modello di generazione di immagini da testo esposto tramite l'interfaccia unificata di HiAPI. Devi solo inviare un prompt e i parametri di generazione opzionali allo stesso endpoint per ottenere i dati dell'immagine generata. Non serve installare alcun componente specifico del modello, né integrare SDK separati per ogni fornitore, né gestire account distinti: la stessa API key e la stessa struttura di richiesta coprono il resto delle capacità della piattaforma.

Scegli questo modello quando il tuo prodotto deve trasformare descrizioni testuali in immagini nuove: copy di marketing in visual principali, prompt degli utenti in miniature, strumenti di design che renderizzano concept su richiesta. Poiché la chiamata è una normale richiesta HTTP, si integra facilmente in servizi backend, worker di coda o script, senza alcuna libreria client.

È la scelta giusta quando l'input è testo e l'output è una bitmap che intendi archiviare e distribuire autonomamente. Se in futuro dovrai passare a un'altra linea di immagini sulla piattaforma, la logica di integrazione — autenticazione, envelope della richiesta, gestione dell'output — resta invariata; cambieranno solo l'identificatore del modello e il blocco dei parametri.

Come leggere questa guida

Questa guida procede per livelli. Prima una richiesta minima che restituisce un'immagine, poi la versione Python, quindi la decisione strutturale tra chiamata singola e polling asincrono, infine la gestione dell'output. Ogni livello è testabile in modo indipendente, così quando qualcosa va storto sai esattamente quale modifica l'ha introdotto.

Prerequisiti e autenticazione

Prima di inviare la prima richiesta ti servono due cose: un account HiAPI e un'API key associata. Crea la key nella dashboard dell'account e conservala come qualsiasi segreto: variabile d'ambiente in locale, secrets manager in produzione. Non salvarla nei repository di codice e non incollarla in codice client che viene inviato al browser.

L'autenticazione avviene tramite bearer token nell'header della richiesta. Il formato è sempre lo stesso:

Authorization: Bearer $HIAPI_API_KEY

Imposta la variabile una volta nella shell e gli esempi che seguono potranno referenziarla senza esporre la chiave:

export HIAPI_API_KEY="your-key-here"

Cosa verificare prima di iniziare

  • La key è attiva e ha accesso alla generazione di immagini.
  • Il tuo ambiente può effettuare richieste HTTPS in uscita verso l'endpoint HiAPI.
  • Sai dove verranno scritti i file generati: una cartella locale per i test, object storage in produzione.

Se la key manca o è malformata, il problema si manifesta subito alla prima chiamata come errore di autenticazione: è il momento più precoce e più chiaro per scoprirlo.

Una richiesta curl minima funzionante

Inizia dalla richiesta più piccola che possa produrre un'immagine. Tutto tranne il prompt è opzionale, e mantenere la prima chiamata essenziale significa che qualsiasi errore sarà quasi certamente legato all'autenticazione o alla struttura della richiesta, non a conflitti tra parametri.

curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/text-to-image@ext",
    "prompt": "一枚斑驳的黄铜指南针放在折叠的纸质地图上,柔和的窗光,浅景深",
    "size": "1024x1024",
    "n": 1
  }'

Spiegazione campo per campo

  • model — l'identificatore del modello. È l'unico valore che lega la richiesta a gpt-image-2/text-to-image@ext; deve essere esatto.
  • prompt — la descrizione del contenuto. Sii specifico su soggetto, stile e illuminazione; i prompt vaghi producono immagini vaghe e sono più difficili da diagnosticare rispetto a un errore di parametri.
  • size — le dimensioni dell'output. Può essere omesso durante la validazione della pipeline, accettando il valore predefinito.
  • n — il numero di immagini generate per chiamata. Mantienilo a 1 durante l'integrazione, così un fallimento corrisponde esattamente a un output.

Scrivi la risposta su file, così puoi ispezionarla senza che i dati binari sporchino il terminale:

curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @payload.json -o response.json

Una volta che restituisce un'immagine, hai una baseline funzionante nota. Ogni modifica successiva dovrebbe essere una singola modifica reversibile rispetto a essa.

Portare la richiesta in Python

La versione Python è la stessa richiesta, solo con un trasporto diverso. Usa requests: è la scelta meno soggetta a sorprese e corrisponde uno a uno ai campi curl che hai già validato.

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]

payload = {
    "model": "gpt-image-2/text-to-image@ext",
    "prompt": "一枚斑驳的黄铜指南针放在折叠的纸质地图上,柔和的窗光",
    "size": "1024x1024",
    "n": 1,
}

response = requests.post(
    f"{BASE_URL}/v1/images/generations",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=120,
)

response.raise_for_status()
data = response.json()

Punti chiave da interpretare

  • json=payload imposta il content type e serializza il corpo in un solo passaggio: niente concatenazione manuale di stringhe, nessun bug di escaping.
  • In pratica timeout non è opzionale. La generazione di immagini è più lenta di una tipica chiamata a un'API JSON; senza timeout il worker si blocca quando l'upstream rallenta.
  • raise_for_status() trasforma i fallimenti HTTP in eccezioni che puoi intercettare e classificare, invece di lasciar fluire a valle un corpo di risposta malformato.

Mantieni il payload come dict, non come stringa inline. Quando in futuro aggiungerai parametri ti basterà aggiungere chiavi: la struttura della richiesta resta invariata e non dovrai mai più fare il debug del livello di trasporto.

Se preferisci un client in stile SDK, lo stesso endpoint e gli stessi header valgono ugualmente; cambia solo la sintassi della chiamata. Valida prima con curl, poi adotta il client su cui la tua applicazione è standardizzata.

Scegliere tra chiamata singola e polling asincrono

Questa è una decisione di progettazione, non di sintassi, e influenza la logica di retry e archiviazione più di qualsiasi altra scelta nell'integrazione.

Chiamata singola

Usa un ciclo richiesta-risposta singolo quando:

  • Generi on demand e c'è un utente in attesa.
  • Il tuo livello HTTP tollera connessioni lunghe.
  • Generi un'immagine alla volta, non in batch.

Imposta il timeout in modo generoso rispetto al tempo di generazione più lento che hai osservato e trattalo come un fallimento ritentabile, non come un errore definitivo.

Polling asincrono

Scegli l'asincrono per l'elaborazione batch, quando le richieste provengono da worker di coda o quando il chiamante non deve bloccarsi. Il pattern è: invia, ottieni un handle, poi interroga lo stato di completamento.

import time

def poll_until_done(fetch_status, handle, interval=2, max_wait=300):
    deadline = time.monotonic() + max_wait
    while time.monotonic() < deadline:
        status = fetch_status(handle)
        if status["state"] == "succeeded":
            return status
        if status["state"] == "failed":
            raise RuntimeError(status.get("error", "generation failed"))
        time.sleep(interval)
    raise TimeoutError("generation did not finish in time")

Regole per un ciclo di polling affidabile

  • Backoff. Parti da un intervallo breve e aumentalo gradualmente; un polling costante e serrato spreca quota e budget di rate.
  • Limita l'attesa. Una scadenza max_wait impedisce che attività orfane occupino un worker per sempre.
  • Persisti l'handle. Se il worker si riavvia, devi poter riprendere il polling invece di reinviare e pagare una generazione duplicata.
  • Tratta il fallimento come stato terminale di ogni attività. Lo stato failed va registrato, non ritentato silenziosamente in un ciclo serrato.

Decidilo presto. Retrofitare la semantica asincrona su un percorso di codice sincrono significa riscrivere contemporaneamente chiamante, archiviazione e gestione degli errori.

Gestire l'output dell'immagine

La risposta contiene l'immagine generata, ma sono dati all'interno di un envelope JSON: non un URL hotlinkabile. Trattali come output binario di tua proprietà.

Decodifica e persistenza

import base64

item = data["data"][0]
image_bytes = base64.b64decode(item["b64_json"])

with open("out.png", "wb") as f:
    f.write(image_bytes)

Se la risposta porta un URL invece di dati inline, recuperalo subito e scrivi i byte nel tuo storage. Gli URL generati sono temporanei; qualsiasi cosa fornisci ai tuoi utenti dovrebbe stare dietro la tua infrastruttura.

Verifica prima di distribuire

  • Controlla i magic number. I PNG iniziano con \x89PNG; una pagina di errore HTML no. Un controllo di pochi byte intercetta quei problemi di proxy che restituiscono HTTP 200 con un corpo errato.
  • Registra la dimensione. Annota la lunghezza in byte, così i download troncati emergono nel monitoraggio.
  • Archiviazione deterministica. Nomina i file per ID di generazione anziché per testo del prompt e salva prompt, parametri e metadati della risposta insieme all'immagine. Questa combinazione ti permette di riprodurre o verificare qualsiasi output in futuro.
  • Imposta correttamente il content type, derivandolo dal file reale e non da un'ipotesi.

Conserva i metadati insieme all'artefatto

Scrivi un piccolo record di accompagnamento: identificatore del modello, prompt completo, dimensioni e quantità, timestamp e qualsiasi ID di richiesta presente nella risposta. Sei mesi dopo, quando qualcuno chiederà perché questa immagine è così, questo record sarà la tua unica risposta.

Debug dei guasti comuni

La maggior parte dei guasti alla prima integrazione rientra in tre categorie. Controllale in questo ordine: il costo diagnostico va all'incirca dal più basso al più alto.

Errori di autenticazione

401 o 403 significano che la key è errata, revocata o non inviata. Ricostruisci l'header senza chiave per confermare che il prefisso Bearer e lo spazio siano intatti, e verifica che la variabile d'ambiente sia effettivamente popolata nel processo che effettua la richiesta: la trappola comune è averla impostata nella shell ma non nel worker o nel container.

Corpo della richiesta malformato

400 di solito indica il corpo della richiesta. Torna alla richiesta minima della sezione curl e aggiungi i campi uno alla volta. I colpevoli comuni:

  • La stringa model non corrisponde esattamente a gpt-image-2/text-to-image@ext.
  • Il corpo non è JSON valido: virgole di troppo o virgolette non escapate.
  • Tipo di parametro errato; n è un numero, non una stringa.
  • Manca Content-Type: application/json e il server non riesce a interpretare il corpo.

Timeout e risposte lente

Se la connessione cade prima che l'immagine venga restituita, molto probabilmente hai superato il timeout del client, non riscontrato un guasto del modello. Per il design a chiamata singola aumenta il timeout; per qualsiasi forma batch passa al polling asincrono. In caso di retry assicurati di non generare duplicati: se una richiesta potrebbe essere già riuscita, controlla se esiste già un risultato prima di reinviarla.

Quando nessuna delle precedenti si applica

Cattura la risposta completa della richiesta fallita — codice di stato, header e corpo — e riproduci con un comando curl minimo. Un guasto che persiste con la richiesta minima è un problema di integrazione del tuo ambiente; un guasto che sparisce punta ai parametri che hai aggiunto.

Inizia a creare con artefatti IA persistenti

Ottieni la tua chiave API e chiama modelli di immagini, video e audio tramite un'unica API basata sui task.

Leggi la documentazione API