HiAPI
Blogue

Tutorial

Como chamar seedream-5.0-lite/text-to-image pela API HiAPI: guia com curl e Python

Exercício prático de requisição para desenvolvedores: integração de texto para imagem via HiAPI

Oct 31, 2026
极简建筑感封面图:暖灰混凝土平面与斜切的青灰蓝色块、一道细鼠尾草绿接缝,构成安静的布里库特风格几何构图。

O que essa integração realmente faz

Fazer uma chamada de texto para imagem na HiAPI é uma breve conversa entre o seu código e uma fila de tarefas assíncrona. Você envia uma requisição descrevendo a imagem que deseja; a plataforma valida a requisição, aceita a tarefa e devolve um identificador. A imagem não vem na primeira resposta — ela é gerada depois. Em seguida, seu código monitora a tarefa até que ela informe conclusão e, por fim, baixa a imagem da URL exposta pela tarefa.

Esse formato importa porque determina como você escreve a integração. Há três momentos distintos: submissão, polling e obtenção. Cada um tem seus próprios modos de falha. A submissão falha quando o payload está malformado ou o caminho do modelo é inválido. O polling falha quando o loop está mal escrito — rápido demais, curto demais, ou incapaz de distinguir "ainda em execução" de "concluído". A obtenção falha quando você trata a URL de saída como um endereço permanente ou esquece de gravar os bytes em disco.

Por baixo, seedream-5.0-lite/text-to-image é um modelo genérico de texto para imagem na plataforma HiAPI. Você o chama pelo identificador exato do modelo. Os parâmetros que você envia são os comuns desse tipo de chamada: nome do modelo, prompt e quaisquer parâmetros de controle de tamanho ou quantidade de saída indicados na documentação do endpoint. Você não precisa de nenhum SDK especial; um cliente HTTPS comum é suficiente.

Ao final deste exercício, você terá uma requisição reproduzível com curl, uma função Python em torno dela, dicas de como formular prompts para que o texto renderizado fique legível, e um loop de polling que realmente termina. Tudo roda pelo mesmo endpoint HiAPI, portanto, assim que uma chamada funcionar, o resto é ajuste de parâmetros.

Construindo a requisição com curl

Comece pela linha de comando. Uma chamada curl funcional é a base do payload — quando ela funciona, qualquer outra linguagem é apenas exercício de tradução.

Você precisa de duas coisas antes da primeira chamada: sua chave de API HiAPI e a URL base da API. A chave vai no cabeçalho Authorization como token bearer. Mantenha-a fora do histórico do shell sempre que possível; variáveis de ambiente são o hábito mais simples.

export HIAPI_API_KEY="your_api_key_here"

A requisição em si é um POST com corpo JSON. O identificador do modelo é o segmento de caminho a chamar, e o prompt descreve a imagem:

curl -sS -X POST "$HIAPI_BASE_URL" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite/text-to-image",
    "prompt": "A minimalist poster for a coffee shop called North Roast, warm cream background, bold dark lettering"
  }'

Defina HIAPI_BASE_URL com o endpoint de submissão de texto para imagem mostrado na documentação da plataforma; o caminho varia conforme a interface do produto, então copie em vez de adivinhar.

Antes de escrever mais código, leia a resposta. Uma submissão bem-sucedida retorna um objeto JSON com o identificador da tarefa e um campo de status. O status geralmente indica que a tarefa está na fila ou em processamento — ainda não concluída. Isso é esperado. Anote os nomes exatos dos campos retornados; você os usará nas próximas duas seções.

Dois erros no nível do curl causam a maioria das primeiras falhas. O primeiro é chave ausente ou com escopo errado: a resposta é um erro de autenticação, não de modelo. O segundo é corpo malformado — aspas não escapadas dentro do prompt, vírgula final, aspas simples onde o JSON exige aspas duplas. Se a plataforma rejeitar o payload, formate-o com jq e valide-o isoladamente antes de culpar o modelo.

Quando a submissão retorna um identificador, você tem uma requisição válida. Tudo depois disso é esperar e obter.

Portando para Python

A versão Python deve ser uma função pequena e reutilizável — não um script com um único prompt fixo. Use requests (ou httpx, se preferir); a chamada em si não exige cliente especial.

import os
import requests

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

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def submit_image(prompt: str, **params) -> dict:
    payload = {
        "model": "seedream-5.0-lite/text-to-image",
        "prompt": prompt,
        **params,
    }
    response = requests.post(BASE_URL, headers=HEADERS, json=payload, timeout=30)
    response.raise_for_status()
    return response.json()

Há três escolhas intencionais aqui. A chave e a URL base vêm do ambiente, então a função pode ser commitada com segurança. O parâmetro coringa **params permite passar tamanho de saída ou outras opções documentadas sem editar a função. E raise_for_status() converte erros HTTP em exceções imediatamente, que é o que você quer — um 4xx na submissão nunca vira uma tarefa válida, então falhar rápido é melhor do que inspecionar um corpo de resposta confuso.

O dicionário retornado é o registro da sua tarefa. Imprima-o uma vez durante o desenvolvimento para conhecer as chaves exatas do identificador e do status. Não indexe às cegas; um pequeno acessor mantém o restante do código legível:

job = submit_image("A flat illustration of a paper plane over a city map")
print(job)

Se ele imprimir uma tarefa enfileirada, a portabilidade a partir do curl está correta. Se lançar exceção, a mensagem de raise_for_status() dirá se foi problema de autenticação ou de payload — os mesmos dois tipos de problema que você teria no shell.

Escrevendo prompts para conhecimento de mundo e texto renderizado

Modelos de texto para imagem são mais fortes quando o prompt descreve o que deve estar visível, e mais fracos quando sugere conhecimento que o modelo precisa inferir. seedream-5.0-lite/text-to-image aproveita contexto geral de mundo — objetos reconhecíveis, convenções comuns de design, estilos tipográficos — mas você ainda precisa fornecer conteúdo suficiente para ancorar esse contexto.

Para prompts de cena, descreva o sujeito, a composição e o estilo visual. 'A cozy reading nook by a window, soft afternoon light, three-quarter view, muted earth tones' diz ao modelo tanto o que desenhar quanto como estilizar. Prompts vagos geram imagens genéricas; prompts específicos geram imagens utilizáveis.

Texto renderizado é onde os prompts costumam falhar. Se você precisa de texto dentro da imagem, siga algumas regras:

  • Cite a string exata. Escreva o texto desejado entre aspas, para deixar claro que é literal, não descritivo.
  • Mantenha curto. Títulos curtos ou nomes de marca renderizam de forma confiável; parágrafos não.
  • Indique posição e estilo. 'The word "North" centered at the top in a bold sans-serif' é melhor que 'some text at the top'.
  • Evite textos concorrentes. Vários elementos de texto distintos na mesma imagem tendem a virar caracteres embaralhados. Se precisar de vários, mantenha-os curtos e bem separados.
  • Itere uma variável por vez. Mude a formulação, não a formulação, o layout e o estilo ao mesmo tempo, senão você não saberá o que resolveu o problema.

Para qualquer coisa que envolva contexto reconhecível — categoria de produto, tipo de pôster, tipo de placa — nomeie explicitamente. O conhecimento prévio do modelo é mais útil quando o prompt oferece uma âncora. 'A vintage travel poster for a coastal town' carrega mais contexto aproveitável do que 'a poster'.

Não invente parâmetros. Se o prompt não produziu a posição de texto desejada, ajuste primeiro a formulação do próprio prompt antes de tentar opções que você não viu documentadas.

Tratando tarefas assíncronas e baixando a saída

O polling é onde a integração falha silenciosamente. A tarefa é assíncrona, então você precisa de um loop que verifique o status, espere entre verificações, desista em algum momento e saiba exatamente quais valores de status significam "concluído".

import time

def wait_for_job(job_id: str, poll_interval: float = 3.0, timeout: float = 180.0) -> dict:
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        response = requests.get(
            f"{BASE_URL}/{job_id}", headers=HEADERS, timeout=30
        )
        response.raise_for_status()
        job = response.json()

        status = job.get("status")
        if status in {"succeeded", "completed"}:
            return job
        if status in {"failed", "error", "cancelled"}:
            raise RuntimeError(f"Job {job_id} ended with status {status}")

        time.sleep(poll_interval)
    raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")

Ajuste o caminho de polling e as strings de status conforme a documentação da plataforma — esses dois detalhes são os mais propensos a divergir do esboço acima. O essencial é a estrutura: um prazo monotônico, espera entre verificações, conjuntos explícitos de sucesso e falha, e um timeout que lança exceção em vez de retornar uma tarefa pela metade.

Quando a tarefa reporta sucesso, a resposta contém a URL da saída. Trate essa URL como temporária. Baixe os bytes imediatamente, em vez de guardar o link:

def download_image(url: str, path: str) -> None:
    response = requests.get(url, timeout=60)
    response.raise_for_status()
    with open(path, "wb") as f:
        f.write(response.content)

job = wait_for_job(job_id)
download_image(job["output"]["url"], "out.png")

Antes de seguir, confirme que o arquivo é uma imagem real — abra-o, confira as dimensões ou ao menos verifique se o tamanho em bytes não é anormalmente pequeno. Se o servidor fechar a conexão normalmente, um download truncado pode parecer sucesso para o requests.

Erros comuns e como corrigi-los

A maioria das falhas nas primeiras integrações se divide em quatro categorias. Trate-as em ordem.

Submissão rejeitada

Se a primeira chamada retornar 4xx, imprima o corpo da resposta. Erro de autenticação significa chave ausente, expirada ou não enviada como token bearer. Erro de esquema significa payload malformado — campo de modelo errado, prompt ausente ou parâmetro documentado com erro de digitação. Valide o JSON isoladamente e compare com o exemplo funcional de curl.

A tarefa nunca conclui

O loop gira para sempre ou atinge o timeout. Verifique primeiro o intervalo de polling: martelar o endpoint sem esperar pode disparar limites de taxa, fazendo uma tarefa saudável parecer travada. Em seguida, verifique a comparação de status — se a plataforma retorna success e você compara com succeeded, toda tarefa parecerá não concluída. Registre o valor bruto de status uma vez, em vez de adivinhar.

A URL de saída retorna 404 ou 403

A URL de saída é assinada e tem prazo de validade. Se você fez polling por muito tempo antes de obter, o link pode ter expirado. Obtenha imediatamente após a conclusão e, se precisar guardar o resultado, salve o arquivo em vez do link.

A imagem renderiza, mas o texto fica embaralhado

Isso é problema de prompt, não de código. Encurte o texto, cite com exatidão, reduza a quantidade de elementos de texto e torne as instruções de estilo mais explícitas. Execute novamente alterando apenas uma coisa por vez, para saber qual ajuste ajudou.

A requisição trava ou dá timeout

Sempre defina timeouts explícitos nas chamadas de submissão e de polling. Uma requisição sem timeout pode bloquear indefinidamente um worker, e um loop de polling sem prazo transforma uma interrupção transitória em um processo travado.

Quando ocorrer comportamento inesperado, reduza ao menor chamado curl que ainda falha. Se a requisição HTTP bruta se comporta mal, a camada Python não é o problema — assim que o curl voltar a funcionar, portar de volta para Python é mecânico. A página do modelo seedream-5.0-lite/text-to-image lista os parâmetros e o formato de resposta atuais, então consulte-a antes de presumir nomes de campos.

Artigos relacionados

Ver todos os artigos →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API