Tutoriale
Tutorial API recraft-v4-styles/text-to-image: curl, Python e polling asincrono
Una guida completa all'invio di richieste con immagini di riferimento per lo stile su HiAPI
Cosa può fare per te recraft-v4-styles/text-to-image
recraft-v4-styles/text-to-image è un endpoint di generazione di immagini con riferimento di stile. Gli fornisci un prompt testuale che descrive ciò che vuoi vedere, insieme a una o più immagini di riferimento che descrivono l'aspetto dello stile. Il modello fonde i due elementi: il prompt trasporta il contenuto e l'intento compositivo, le immagini di riferimento trasportano lo stile visivo.
Questa distinzione è importante nella scelta dell'endpoint. Quando l'aspetto può essere espresso interamente a parole — ad esempio «un'illustrazione vettoriale piatta di una tazza di caffè, due colori, contorni spessi» — la generazione di immagini da solo prompt è lo strumento giusto. Tuttavia, nel lavoro di prodotto reale, la maggior parte dei casi coinvolge un'identità di brand difficile da descrivere ma facile da mostrare. Un key visual esistente, un rendering già approvato o un campione di design system definisce la specifica di stile in modo molto più preciso di un paragrafo di aggettivi. È esattamente questo il vuoto che l'endpoint colma.
Dal punto di vista dello sviluppatore, puoi considerarlo una trasformazione a due ingressi: prompt + riferimento di stile -> immagine. Tutto ciò che lo integra deriva da questa forma. Non stai semplicemente serializzando una stringa, ma assemblando un piccolo payload composto da più parti, in cui le immagini di riferimento sono input di prima classe. Il tuo codice di costruzione della richiesta deve trattarle come tali, e il tuo livello di validazione deve rifiutare, prima che il job lasci il tuo servizio, i task che contengono solo un prompt e nessun riferimento di stile utilizzabile.
L'endpoint è asincrono. Inviare la richiesta restituisce un job, che poi interroghi ripetutamente, e l'immagine finale arriva come URL, non come byte inline. Si tratta di una scelta deliberata per i carichi di lavoro sulle immagini: la generazione richiede abbastanza tempo che mantenere aperta una connessione HTTP è sia dispendioso che fragile. Una volta accettato il ciclo «invio-polling-download», il resto dell'integrazione è ordinario lavoro di pipeline API.
Anatomia di una richiesta funzionante
Prima di scrivere qualsiasi codice, chiarisci i raggruppamenti dei campi. Una richiesta recraft-v4-styles/text-to-image contiene tre parti logiche.
Il prompt
Il prompt è la tua istruzione sul contenuto. Scrivilo in base a ciò che deve contenere l'immagine: soggetto, composizione, inquadratura, numero di oggetti, trattamento dello sfondo. Evita di spendere il budget del prompt in aggettivi di stile che le immagini di riferimento già trasmettono; i segnali in conflitto tra prompt e immagini di riferimento tendono a produrre risultati ambigui. Mantieni il prompt breve, specifico e verificabile.
Gli input di riferimento per lo stile
Questa è la parte che distingue l'endpoint da una normale chiamata di generazione di immagini da testo. I riferimenti di stile sono immagini fornite insieme al prompt che definiscono il linguaggio visivo. Quando li assembli, trattali come un set curato, non come un mucchio disordinato di immagini:
- La coerenza vale più della quantità. Poche immagini di riferimento che condividono lo stesso aspetto coerente insegnano al modello più di molte immagini con stili diversi.
- Risoluzione e inquadratura contano. Le immagini di riferimento devono rappresentare l'output che desideri, non miniature o frammenti pesantemente ritagliati.
- Devono essere accessibili. Se le tue immagini di riferimento vengono passate come URL, questi URL devono essere pubblicamente recuperabili al momento della richiesta. Un link firmato che scade dopo sessanta secondi farà fallire un job lento.
Conserva il tuo insieme di immagini di riferimento nella configurazione, non sparso nel codice, così puoi versionarlo insieme agli asset del brand.
Le opzioni di output
I campi rimanenti descrivono l'artefatto che vuoi ricevere: sono le manopole che influenzano l'immagine restituita, non il suo contenuto. I nomi esatti dei parametri e i valori accettabili sono elencati nella pagina di riferimento dell'endpoint; leggili lì invece di indovinare, e centralizzali in un unico punto del codice, così una modifica alle specifiche tocca un solo file.
Un'abitudine utile: costruisci il corpo JSON come dizionario/oggetto nel linguaggio scelto, registralo una volta a livello di debug alla prima esecuzione e ispezionalo a occhio nella sua struttura prima di dare la colpa al modello per un cattivo risultato.
Chiamare con curl
Inizia con curl. Elimina ogni livello di astrazione della libreria tra te e il formato di rete, quindi se la richiesta è sbagliata te ne accorgi subito.
L'invio è una richiesta POST con corpo JSON e header di autenticazione che trasporta la tua chiave API HiAPI:
curl -sS -X POST "https://api.hiapi.ai/v1/recraft-v4-styles/text-to-image" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "a ceramic coffee cup on a linen tablecloth, soft daylight",
"style_references": [
"https://your-cdn.example.com/style/ref-01.png"
]
}'
Alcune note su ciò che vedi:
- Conserva la chiave in una variabile d'ambiente (
$HIAPI_API_KEY), mai inline nella cronologia della shell o in script sottoposti a commit. - Il payload di
-dè JSON puro. Le regole di quoting nella shell sono una fonte comune di problemi: se ottieni errori di parsing, scrivi il corpo in un file e usa-d @body.json. - I nomi dei campi mostrati qui seguono l'anatomia della richiesta della sezione precedente; prima di andare in produzione, conferma i nomi esatti e le opzioni di output accettabili sulla pagina di riferimento dell'endpoint.
La risposta non è un'immagine. È una conferma del job: un identificatore della generazione appena messa in coda, più un campo di stato che ti dice che non è ancora completata. Alla prima esecuzione leggi attentamente il corpo della risposta e annota il nome del campo che contiene l'ID del job: quella stringa è il riferimento per tutte le operazioni successive. Salvala. Se la tua prima risposta contiene un oggetto di errore, fermati e correggi la richiesta; fare polling su un ID che non hai mai ricevuto è il vicolo cieco più comune.
Implementare la stessa richiesta in Python
Porta la chiamata curl in Python una volta e avrai una primitiva riutilizzabile. L'esempio seguente usa requests e rispecchia esattamente il corpo della richiesta.
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",
}
STYLE_REFERENCES = [
"https://your-cdn.example.com/style/ref-01.png",
]
def submit_generation(prompt: str) -> dict:
body = {
"prompt": prompt,
"style_references": STYLE_REFERENCES,
}
resp = requests.post(
f"{BASE_URL}/recraft-v4-styles/text-to-image",
headers=HEADERS,
json=body,
timeout=30,
)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
job = submit_generation(
"a ceramic coffee cup on a linen tablecloth, soft daylight"
)
print(job)
Quando adatti questo codice, due scelte di progettazione meritano di essere mantenute:
- Imposta sempre un timeout. L'invio deve tornare rapidamente; se si blocca, vuoi un'eccezione, non un processo bloccato.
- Restituisci il JSON analizzato, non l'oggetto risposta. Il codice a valle deve dipendere dal payload del job, non dalle implementazioni interne di
requests. Questo rende banale sostituire il livello di trasporto in futuro.
Come sopra, definisci l'insieme di immagini di riferimento a livello di modulo o di configurazione. Quando l'identità del brand evolve, devi aggiornare un solo elenco invece di cercare nei vari punti di chiamata. E mantieni la costruzione del corpo della richiesta in un'unica funzione, così qualsiasi campo richiesto dall'endpoint va aggiunto in un solo posto.
Eseguire il polling dei risultati asincroni
La generazione è asincrona, quindi il job che hai inviato attraversa più stati prima di completarsi. Il tuo client ha bisogno di un ciclo di attesa che controlli lo stato, faccia backoff tra i controlli e alla fine si arrenda.
import time
def wait_for_result(job_id: str, timeout_s: int = 300, interval_s: float = 3.0) -> dict:
deadline = time.monotonic() + timeout_s
delay = interval_s
while time.monotonic() < deadline:
resp = requests.get(
f"{BASE_URL}/recraft-v4-styles/text-to-image/{job_id}",
headers=HEADERS,
timeout=30,
)
resp.raise_for_status()
data = resp.json()
status = data.get("status")
if status in ("succeeded", "failed"):
return data
time.sleep(delay)
delay = min(delay * 1.5, 15.0)
raise TimeoutError(f"job {job_id} did not finish in {timeout_s}s")
In questo ciclo, ciò che conta:
- Tratta gli stati sconosciuti come in sospeso. Confronta con gli stati terminali espliciti, non con una lista di stati in corso consentiti; se la piattaforma aggiunge stati intermedi, il tuo ciclo continuerà ad attendere invece di bloccarsi.
- Fai backoff. Un polling fisso ogni secondo per cinque minuti equivale a cinque minuti di richieste sprecate. Parti da un intervallo piccolo, raddoppia con un tetto massimo.
- Limita l'attesa. Ogni ciclo ha bisogno di una scadenza, e la scadenza deve manifestarsi come un'eccezione che il chiamante può gestire.
- Ramifica sul fallimento. Lo stato terminale di fallimento trasporta informazioni diagnostiche. Registra il corpo completo della risposta: è la differenza tra «si è rotto» e «l'URL di riferimento ha restituito 403».
Se gestisci molte immagini, non dormire all'interno del gestore delle richieste web. Invia, persisti l'ID del job e lascia che un processo worker in background o un'attività pianificata gestisca il polling. La pagina di riferimento dell'endpoint documenta i valori di stato esatti e il percorso di polling; controllala ogni volta che aggiorni il client.
Scaricare e archiviare l'output
Quando il job raggiunge lo stato terminale di successo, la risposta contiene l'URL dell'immagine generata. Quell'URL è il punto di passaggio tra l'API e il tuo livello di archiviazione.
Recuperalo come byte e scrivilo dove ti serve:
def download_image(url: str, dest_path: str) -> None:
resp = requests.get(url, timeout=60)
resp.raise_for_status()
with open(dest_path, "wb") as f:
f.write(resp.content)
Per qualsiasi scenario oltre alla sperimentazione locale, non lasciare l'artefatto solo sull'URL restituito. Tratta l'immagine generata come un puntatore temporaneo e copiala in uno storage che controlli: bucket di object storage, origin del tuo CDN o pipeline media. Tre sono le ragioni:
- Ciclo di vita. Gli URL di output generati non sono garantiti persistenti a tempo indefinito. Riscaricare da un URL obsoleto durante un nuovo tentativo è un potenziale fallimento silenzioso.
- Chiavi stabili. La tua applicazione ha bisogno di un identificatore deterministico da inserire in una riga di database, non di un URL che cambia a ogni rigenerazione.
- Tracciabilità. Archiviare prompt, versione dell'insieme di riferimenti di stile e ID del job insieme all'immagine ti consente di riprodurre o verificare qualsiasi asset in seguito. Conserva questi metadati in un record di accompagnamento o in una colonna del database.
Quando carichi su object storage, trasmetti in streaming il corpo della risposta invece di bufferizzare interamente in memoria le immagini grandi, e imposta il content type dagli header della risposta. Se restituisci le immagini ai client attraverso il tuo CDN, questo è anche il punto in cui applicare gli header di cache.
Risoluzione dei problemi alla prima esecuzione
La maggior parte dei primi tentativi fallisce in alcuni modi prevedibili. Controllali in ordine.
Corpo della richiesta rifiutato
Gli errori di tipo 400 di solito significano JSON malformato o campi obbligatori mancanti. Esegui prima la versione curl e controlla il corpo esatto che stai inviando. Problemi comuni: il quoting della shell che rompe il JSON, inviare come stringa un campo che l'API si aspetta come array, o valori delle opzioni di output fuori dall'intervallo accettabile. La pagina di riferimento dell'endpoint è la fonte autorevole per nomi e valori dei campi: confronta letteralmente il tuo corpo con essa.
Hai il prompt ma nessun riferimento di stile utilizzabile
L'endpoint è costruito attorno ai riferimenti di stile. Se la tua richiesta contiene un prompt ma i riferimenti sono vuoti, irraggiungibili o restituiscono errori di autenticazione al recupero, il job verrà rifiutato o produrrà un output che ignora l'aspetto previsto. Verifica ogni URL di riferimento recuperandolo con lo stesso client senza credenziali che userebbe la piattaforma. Un riferimento che richiede cookie di sessione o query string firmate è da considerarsi rotto.
Non ottieni mai un ID del job
La risposta di invio è una conferma, non un'immagine. Se il tuo codice si aspetta byte di immagine nella prima risposta, fallirà a ogni esecuzione. Analizza la risposta, estrai l'ID del job e solo allora inizia il polling. Registra la risposta di invio completa nelle prime esecuzioni, così puoi vederne la forma.
Fai polling troppo frequentemente
Centinaia di controlli di stato in un minuto non fanno completare il job più in fretta, e hanno maggiori probabilità di attivare limiti di frequenza. Usa intervalli crescenti con un tetto massimo, un solo processo worker per job. Se invii molti job, aggiungi un piccolo limite di concorrenza, così un picco di invii non diventa un picco di polling.
Il job si completa ma il download fallisce
Un 403 o 404 durante il recupero dell'URL di output di solito significa che l'URL è scaduto, o che il job è fallito dopo un controllo di stato che hai interpretato male. Conferma che lo stato terminale sia di successo, poi rileggi la risposta per ottenere il campo di output effettivo. Archivia l'artefatto non appena è disponibile, invece di rimandare il download.
Affronta questi problemi nell'ordine in cui la pipeline li attraversa — invio, polling, download — e i fallimenti alla prima esecuzione si ridurranno quasi sempre a correzioni ovvie. Il riferimento dell'endpoint e i suoi schemi di richiesta sono il modo più rapido per confermare qualsiasi dubbio a livello di campo.
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