Tutorial
Tutorial de la API recraft-v4-styles/text-to-image: curl, Python y sondeo asíncrono
Recorrido completo de una solicitud con generación a partir de imágenes de referencia de estilo en HiAPI
Qué puede hacer recraft-v4-styles/text-to-image por ti
recraft-v4-styles/text-to-image es un endpoint de generación de imágenes por referencia de estilo. Le proporcionas un prompt de texto que describe lo que quieres ver, junto con una o varias imágenes de referencia que describen el aspecto visual. El modelo fusiona ambos: el prompt aporta el contenido y la intención compositiva, y las imágenes de referencia aportan el estilo visual.
Esta distinción importa a la hora de elegir el endpoint. Cuando el aspecto se puede expresar completamente con palabras —por ejemplo, «una ilustración vectorial plana de una taza de café, a dos colores, con contorno grueso»—, la generación de imágenes a partir de un prompt es la herramienta correcta. Sin embargo, en el trabajo real de producto, la mayoría de los casos implican un aspecto de marca que resulta difícil de describir pero fácil de mostrar. Una imagen clave ya existente, un render aprobado previamente o una muestra de un sistema de diseño definen la especificación de estilo con mucha más precisión que un párrafo de adjetivos. Ese es precisamente el vacío que cubre este endpoint.
Desde el punto de vista de un desarrollador, puedes verlo como una transformación de dos entradas: prompt + referencia de estilo -> imagen. Todo lo relacionado con su integración se deriva de esta forma. No te limitas a serializar una cadena: estás ensamblando una carga útil pequeña compuesta por varias partes, en la que las imágenes de referencia son una entrada de primer nivel. Tu código de construcción de la solicitud debe tratarlas como tal, y tu capa de validación debe rechazar, antes de que la tarea salga de tu servicio, aquellas que solo tengan prompt y carezcan de una referencia de estilo utilizable.
El endpoint es asíncrono. Enviar la solicitud devuelve una tarea; después sondeas esa tarea y, finalmente, la imagen llega como una URL, no como bytes en línea. Se trata de un diseño deliberado para cargas de trabajo de imágenes: la generación tarda lo suficiente como para que mantener abierta una conexión HTTP resulte desperdiciado y frágil. Una vez que aceptas el ciclo «enviar-sondear-descargar», el resto de la integración es simple trabajo de tubería de API.
Anatomía de una solicitud que funciona
Antes de escribir cualquier código, define los grupos de campos. Una solicitud a recraft-v4-styles/text-to-image consta de tres partes lógicas.
El prompt
El prompt es tu instrucción de contenido. Redáctalo en torno a lo que debe aparecer en la imagen: sujeto, composición, encuadre, número de objetos, tratamiento del fondo. Evita gastar el presupuesto del prompt en adjetivos de estilo que las imágenes de referencia ya transmiten; los conflictos de señal entre el prompt y las referencias suelen producir resultados borrosos. Mantén el prompt breve, concreto y verificable.
Las entradas de referencia de estilo
Esta es la parte que distingue al endpoint de una llamada ordinaria de generación de imágenes a partir de texto. Las referencias de estilo son las imágenes que se proporcionan junto con el prompt para definir el lenguaje visual. Al reunirlas, trátalas como un conjunto cuidadosamente seleccionado y no como un montón desordenado de imágenes:
- La consistencia importa más que la cantidad. Unas pocas imágenes de referencia que comparten un mismo aspecto coherente enseñan más al modelo que muchas referencias de estilos dispares.
- La resolución y el encuadre importan. Las imágenes de referencia deben representar el resultado que deseas, no miniaturas ni fragmentos muy recortados.
- Deben ser accesibles. Si pasas tus imágenes de referencia como URL, esas URL deben poder obtenerse públicamente en el momento de la solicitud. Un enlace firmado que caduca a los sesenta segundos hará fallar una tarea lenta.
Guarda tu conjunto de referencias en la configuración y no disperso por el código, para que puedas versionarlo junto con los recursos de marca.
Opciones de salida
El resto de los campos describen el artefacto que quieres que se devuelva; son controles que afectan a la imagen devuelta, no a su contenido. Los nombres exactos de los parámetros y los valores aceptables figuran en la página de referencia de este endpoint; consúltalos allí en lugar de adivinarlos, y centralízalos en un único lugar del código para que un cambio de especificación solo afecte a un archivo.
Un hábito útil: construye el cuerpo JSON como un diccionario/objeto en el lenguaje que elijas, regístralo una vez a nivel de depuración en la primera ejecución y examina su estructura a simple vista antes de culpar al modelo de un mal resultado.
Llamada con curl
Empieza con curl. Elimina toda la capa de abstracción de bibliotecas entre tú y el formato de transmisión, de modo que si la solicitud está mal, lo descubrirás de inmediato.
El envío es una solicitud POST con un cuerpo JSON y una cabecera de autenticación que lleva tu clave de API de 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"
]
}'
Algunas notas sobre lo que ves:
- Mantén la clave en una variable de entorno (
$HIAPI_API_KEY), nunca en línea en el historial del shell ni en scripts confirmados. - La carga útil de
-des JSON puro. Las reglas de comillas del shell son una fuente habitual de problemas; si encuentras errores de análisis, vuelca el cuerpo de la solicitud a un archivo y usa-d @body.jsonen su lugar. - Los nombres de campo que se muestran aquí siguen la anatomía de la solicitud de la sección anterior; antes de publicar, confirma los nombres exactos y las opciones de salida aceptables en la página de referencia de este endpoint.
La respuesta no es una imagen. Es una confirmación de tarea: un identificador de la generación que acabas de poner en cola y un campo de estado que te indica que aún no ha terminado. Lee con atención el cuerpo de la respuesta en la primera ejecución y anota el nombre del campo que guarda el ID de la tarea; esa cadena es el asa de todas tus operaciones posteriores. Guárdala. Si tu primera respuesta contiene un objeto de error, detente y corrige la solicitud; sondear un ID que nunca recibiste es el callejón sin salida más habitual.
Implementar la misma solicitud en Python
Porta la llamada curl a Python una vez y tendrás una primitiva reutilizable. El ejemplo siguiente usa requests y refleja exactamente el cuerpo de la solicitud.
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)
Al adaptar este código, hay dos decisiones de diseño que merece la pena conservar:
- Establece siempre un timeout. El envío debe devolver rápidamente; si se cuelga, quieres una excepción, no un proceso bloqueado.
- Devuelve el JSON analizado, no el objeto de respuesta. El código posterior debe depender de la carga útil de la tarea, no de los detalles internos de
requests. Esto hace que sustituir la capa de transporte más adelante sea trivial.
Como se ha indicado, define el conjunto de imágenes de referencia a nivel de módulo o de configuración. Cuando evolucione el aspecto de la marca, solo tendrás que actualizar una lista, sin tener que buscarla en los puntos de llamada. Y mantén la construcción del cuerpo de la solicitud en una única función, de modo que cualquier campo que requiera el endpoint solo haya que añadirlo en un lugar.
Sondear el resultado asíncrono
La generación es asíncrona, por lo que la tarea que enviaste pasa por varios estados hasta completarse. Tu cliente necesita un bucle de espera que compruebe el estado, aplique una espera creciente entre comprobaciones y, finalmente, desista.
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")
En este bucle, lo importante es lo siguiente:
- Trata los estados desconocidos como pendientes. Compara con los estados terminales explícitos en lugar de con una lista permitida de estados en curso; si la plataforma añade un estado intermedio, tu bucle seguirá esperando en lugar de fallar.
- Espera creciente. Sondear cada segundo de forma fija durante cinco minutos son cinco minutos de solicitudes desperdiciadas. Empieza con un intervalo pequeño, duplícalo y ponle un límite.
- Limita el tiempo de espera. Todo bucle necesita una fecha límite, y la fecha límite debe manifestarse como una excepción que el llamador pueda manejar.
- Ramifica según el fallo. Los estados terminales de fallo llevan información de diagnóstico. Registra el cuerpo completo de la respuesta: esa es la diferencia entre «se ha roto» y «la URL de referencia devolvió un 403».
Si vas a procesar muchas imágenes, no duermas dentro del manejador de solicitudes web. Envía la tarea, persiste el ID de la tarea y deja que un proceso de trabajo en segundo plano o una tarea programada impulse el sondeo. La página de referencia del endpoint documenta los valores de estado exactos y la ruta de sondeo; revísala cada vez que actualices tu cliente.
Descargar y almacenar la salida
Cuando la tarea alcanza el estado terminal de éxito, la respuesta contiene la URL de la imagen generada. Esa URL es el punto de entrega entre la API y tu capa de almacenamiento.
Obtén su contenido como bytes y escríbelo donde lo necesites:
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)
Para cualquier escenario que vaya más allá de la experimentación local, no dejes el artefacto únicamente en la URL devuelta. Trata la imagen generada como un puntero temporal y cópiala a un almacenamiento que controles: un bucket de almacenamiento de objetos, el origen de tu CDN o tu tubería de medios. Hay tres razones:
- Ciclo de vida. Las URL de salida generadas no tienen garantía de persistir indefinidamente. Volver a descargar desde una URL obsoleta durante un reintento es un fallo silencioso en potencia.
- Claves estables. Tu aplicación necesita un identificador determinista que pueda ir en una fila de base de datos, no una URL que cambia cada vez que se regenera.
- Trazabilidad. Almacenar el prompt, la versión del conjunto de referencias de estilo y el ID de la tarea junto con la imagen te permite reproducir o auditar cualquier recurso más adelante. Guarda esos metadatos en un registro adjunto o en una columna de la base de datos.
Al subir a un almacenamiento de objetos, transmite el cuerpo de la respuesta en flujo en lugar de almacenar en memoria toda la imagen grande, y establece el tipo de contenido a partir de las cabeceras de la respuesta. Si devuelves las imágenes a los clientes a través de tu propia CDN, este paso es también el lugar para aplicar cabeceras de caché.
Solución de problemas en la primera ejecución
La mayoría de los primeros intentos fallan de unas pocas formas predecibles. Compruébalas en orden.
El cuerpo de la solicitud es rechazado
Los errores de tipo 400 suelen significar que el JSON está mal formado o que falta un campo obligatorio. Ejecuta primero la versión curl y comprueba el cuerpo exacto que envías. Problemas habituales: comillas del shell que rompen el JSON, enviar como cadena un campo que la API espera como array, o un valor de opción de salida fuera del rango aceptable. La página de referencia del endpoint es la fuente autoritativa de nombres de campo y valores; compara tu cuerpo con ella literalmente.
Tienes prompt pero ninguna referencia de estilo utilizable
El endpoint se construye en torno a las referencias de estilo. Si tu solicitud incluye un prompt pero las imágenes de referencia están vacías, no son accesibles o devuelven un error de autenticación al obtenerlas, la tarea se rechazará o producirá una salida que ignore el aspecto que pretendías. Valida cada URL de referencia obteniéndola con el mismo cliente sin credenciales que usaría la plataforma. Las referencias que requieren una cookie de sesión o una cadena de consulta firmada se consideran inválidas.
Nunca obtienes un ID de tarea
La respuesta de envío es una confirmación, no una imagen. Si escribes código que espera bytes de imagen en la primera respuesta, fallará en cada ejecución. Analiza la respuesta, extrae el ID de la tarea y solo entonces empieza a sondear. Registra la respuesta completa del envío durante las primeras ejecuciones para que puedas ver su forma.
Sondeas con demasiada frecuencia
Cientos de comprobaciones de estado en un minuto no harán que la tarea termine antes, sino que es más probable que activen un límite de velocidad. Usa un intervalo creciente con un límite superior y un único proceso de trabajo por tarea. Si despachas muchas tareas, añade un límite de concurrencia pequeño para que una ráfaga de envíos no se convierta en una ráfaga de sondeos.
La tarea termina pero la descarga falla
Un 403 o un 404 al obtener la URL de salida suele significar que la URL ha caducado, o que la tarea falló después de una comprobación de estado que interpretaste mal. Confirma que el estado terminal es el de éxito y vuelve a leer la respuesta para obtener el campo de salida real. Almacena el artefacto en cuanto esté disponible, en lugar de posponer la descarga.
Resuelve estos problemas en el orden en que se ejecuta la tubería —envío, sondeo, descarga— y los fallos de la primera ejecución casi siempre se resolverán en correcciones evidentes. La referencia del endpoint y su esquema de solicitud son la forma más rápida de confirmar cualquier duda a nivel de campo.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado