ESPAÇO PUBLICITÁRIO DISPONÍVEL · FALE CONOSCO

Integrando a API REST do Dezgo em Aplicações Web: Guia de Arquitetura Pay-as-You-Go para Text-to-Image e Inpainting

365Finds Editorial
11.430 artigos Wiki catalogados

Use o 365 Wiki com sua IA

Copie o prompt abaixo, cole na IA que você já usa e faça sua pergunta.

Baixar o Skill completo

Experimente primeiro com o prompt. Se você usa o 365 Wiki com frequência, instale o Skill completo do 365Wiki para não precisar colá-lo novamente. Se não usa uma IA específica, as versões web do Gemini ou Microsoft Copilot também servem.

Ao implementar recursos de geração de imagens e retoque localizado (inpainting) em aplicações web modernas, desenvolvedores solo e equipes enxutas frequentemente enfrentam um dilema complexo de infraestrutura. De um lado, auto-hospedar modelos abertos de difusão em instâncias dedicadas com GPU (como AWS EC2 G5, RunPod ou Modal) acarreta alta sobrecarga operacional: configuração de drivers CUDA, atualizações de dependências vLLM/Diffusers, latência de inicialização a frio e um piso de custo fixo entre 150 e 400 dólares mensais por hardware ocioso. Do outro lado, plataformas comerciais de SaaS (como Midjourney ou Leonardo) exigem assinaturas mensais fixas e planos fechados com créditos que expiram, gerando desperdício em produtos com tráfego variável.

O Dezgo resolve esse problema oferecendo uma API REST sem servidor sustentada por um modelo financeiro genuinamente pré-pago e sob demanda (pay-as-you-go). Com uma recarga inicial a partir de 10 dólares cujos créditos nunca expiram, desenvolvedores podem renderizar imagens Stable Diffusion de 512x512 pixels por cerca de 0,0019 dólares cada, com cobranças proporcionais calculadas de forma transparente com base na resolução e nos passos de amostragem.

Este guia prático orienta engenheiros full stack e backend na implementação de uma integração robusta com o Dezgo: autenticação via X-Dezgo-Key, consumo dos endpoints /text2image e /inpainting_sdxl, monitoramento de saldo em tempo real por meio de cabeçalhos HTTP e orquestração de filas assíncronas para evitar gargalos de timeout.


Comparativo de Arquitetura: GPUs Próprias vs. SaaS Tradicional vs. Dezgo

Antes de codificar, vale avaliar como as opções disponíveis se comportam em termos de custos e operação:

CritérioInstâncias GPU Próprias (EC2 / RunPod)SaaS Comercial Fechado (Midjourney)API REST do Dezgo
Custo Mínimo FixoElevado ($150–$500+/mês em capacidade ociosa)Médio-Alto ($10–$60+/mês por usuário ativo)Zero ($10 de recarga pré-paga única sem mensalidade)
Custo UnitárioVariável; oneroso durante vales de tráfegoPacotes fixos; créditos não usados expiram~$0,0019 por imagem 512px; cálculo por passo e pixel
Carga de ManutençãoAlta (drivers, vazamento de memória e escala)Mínima (plataforma fechada sem controle)Mínima (requisições HTTP REST padrão; sem gerenciar GPU)
Suporte a ModelosTotal (qualquer checkpoint HuggingFace ou LoRA)Baixo (restrito a modelos proprietários)Alto (SD 1.5, SD 2.1, SDXL, Lightning e LoRAs)
Formato de RetornoExige desenvolvimento de protocolo próprioBots de Discord ou polling não padronizadoStream binário direto (image/png) no corpo HTTP

O principal diferencial do Dezgo é entregar a imagem diretamente como arquivo binário na resposta HTTP, acompanhada de metadados financeiros detalhados em cabeçalhos dedicados.


Autenticação e Arquitetura de Segurança

Todas as chamadas à API do Dezgo devem conter a chave de autenticação informada no cabeçalho HTTP X-Dezgo-Key. O token é gerado no painel da sua conta em dezgo.com/account.

Regra Fundamental: Nunca Chame o Dezgo Diretamente do Frontend

Como as chaves do Dezgo debitam diretamente do saldo em dinheiro pré-pago da sua conta e não possuem permissões restritas para usuários finais, expor o valor de X-Dezgo-Key no navegador ou em scripts do cliente representa um risco financeiro severo. Qualquer usuário mal-intencionado poderá interceptar o token e esgotar seu saldo em poucos minutos.

A arquitetura recomendada exige que todas as requisições passem por um servidor backend confiável ou API proxy:

[Navegador do Usuário]
       │
       │ 1. POST /api/generate (Sessão / Token JWT / Cota interna)
       ▼
[Backend da sua Aplicação]
       │
       │ 2. Validação de dados, dedução de créditos da aplicação
       │ 3. Injeção do cabeçalho secreto "X-Dezgo-Key"
       │ 4. POST https://api.dezgo.com/text2image
       ▼
[Motor REST do Dezgo]
       │
       │ 5. Retorno de stream PNG binário + cabeçalhos de custo
       ▼
[Backend da sua Aplicação]
       │
       │ 6. Leitura de x-dezgo-job-amount-usd e x-dezgo-balance-total-usd
       │ 7. Upload para Object Storage (S3 / R2) ou stream para o cliente
       ▼
[Navegador do Usuário]

Passo 1: Integração de Text-to-Image (/text2image)

O endpoint de geração a partir de texto aceita requisições no formato multipart/form-data ou application/json (com imagens em base64) e retorna o arquivo de imagem diretamente como stream binário (image/png ou image/jpeg).

Parâmetros Principais da Requisição

Exemplo de Implementação Backend em Node.js / TypeScript

// server/services/dezgoService.ts
import { Buffer } from "node:buffer";

interface TextToImageOptions {
  prompt: string;
  negativePrompt?: string;
  model?: string;
  guidance?: number;
  steps?: number;
  width?: number;
  height?: number;
}

interface GenerationResult {
  imageBuffer: Buffer;
  contentType: string;
  jobCostUsd: number;
  remainingBalanceUsd: number;
}

export async function generateTextToImage(
  options: TextToImageOptions
): Promise<GenerationResult> {
  const apiKey = process.env.DEZGO_API_KEY;
  if (!apiKey) {
    throw new Error("A variável de ambiente DEZGO_API_KEY não foi configurada.");
  }

  const formData = new FormData();
  formData.append("prompt", options.prompt);
  if (options.negativePrompt) {
    formData.append("negative_prompt", options.negativePrompt);
  }
  if (options.model) {
    formData.append("model", options.model);
  }
  if (options.guidance) {
    formData.append("guidance", options.guidance.toString());
  }
  if (options.steps) {
    formData.append("steps", options.steps.toString());
  }
  if (options.width) {
    formData.append("width", options.width.toString());
  }
  if (options.height) {
    formData.append("height", options.height.toString());
  }

  const response = await fetch("https://api.dezgo.com/text2image", {
    method: "POST",
    headers: {
      "X-Dezgo-Key": apiKey,
    },
    body: formData,
  });

  if (!response.ok) {
    const errorBody = await response.text();
    handleDezgoError(response.status, errorBody);
  }

  // Leitura de metadados financeiros contidos nos cabeçalhos de resposta
  const jobCostUsd = parseFloat(
    response.headers.get("x-dezgo-job-amount-usd") || "0"
  );
  const remainingBalanceUsd = parseFloat(
    response.headers.get("x-dezgo-balance-total-usd") || "0"
  );

  const arrayBuffer = await response.arrayBuffer();
  const imageBuffer = Buffer.from(arrayBuffer);
  const contentType = response.headers.get("content-type") || "image/png";

  return {
    imageBuffer,
    contentType,
    jobCostUsd,
    remainingBalanceUsd,
  };
}

function handleDezgoError(status: number, message: string): never {
  switch (status) {
    case 400:
      throw new Error(`Requisição inválida no Dezgo (400): ${message}`);
    case 401:
      throw new Error("Falha de autenticação no Dezgo (401): Verifique X-Dezgo-Key.");
    case 402:
      throw new Error("Saldo insuficiente no Dezgo (402): Saldo pré-pago esgotado.");
    case 429:
      throw new Error("Limite de taxa excedido no Dezgo (429): Muitas chamadas simultâneas.");
    default:
      throw new Error(`Erro do servidor Dezgo (${status}): ${message}`);
  }
}

Passo 2: Integração de SDXL Inpainting (/inpainting_sdxl)

O inpainting permite substituir partes específicas de uma imagem através de uma máscara demarcada, mantendo o restante da composição preservado. O Dezgo oferece o endpoint /inpainting para modelos convencionais e /inpainting_sdxl para Stable Diffusion XL em altas resoluções.

Especificações das Imagens de Entrada

Para efetuar o inpainting, é necessário enviar dois arquivos:

  1. init_image: A imagem base original a ser modificada (PNG ou JPEG).
  2. mask_image: Uma máscara monocromática com as dimensões idênticas às de init_image. Áreas brancas (#FFFFFF) indicam onde o modelo deve pintar novos elementos, enquanto áreas pretas (#000000) preservam os pixels originais.

Exemplo de Implementação Backend em Python (FastAPI / Requests)

# app/services/dezgo_inpainting.py
import os
import requests
from typing import Dict, Any, Tuple

DEZGO_API_KEY = os.environ.get("DEZGO_API_KEY")
INPAINTING_SDXL_URL = "https://api.dezgo.com/inpainting_sdxl"

def execute_sdxl_inpainting(
    prompt: str,
    init_image_bytes: bytes,
    mask_image_bytes: bytes,
    negative_prompt: str = "",
    guidance: float = 7.5,
    steps: int = 30,
) -> Tuple[bytes, Dict[str, Any]]:
    """
    Submete uma solicitação de inpainting SDXL ao Dezgo via multipart/form-data.
    """
    if not DEZGO_API_KEY:
        raise ValueError("A variável DEZGO_API_KEY não foi encontrada no ambiente.")

    headers = {
        "X-Dezgo-Key": DEZGO_API_KEY
    }

    files = {
        "init_image": ("init.png", init_image_bytes, "image/png"),
        "mask_image": ("mask.png", mask_image_bytes, "image/png"),
    }

    data = {
        "prompt": prompt,
        "negative_prompt": negative_prompt,
        "guidance": str(guidance),
        "steps": str(steps),
    }

    response = requests.post(
        INPAINTING_SDXL_URL,
        headers=headers,
        files=files,
        data=data,
        timeout=60
    )

    if response.status_code == 402:
        raise RuntimeError("Saldo pré-pago no Dezgo esgotado. Recarga necessária.")
    elif response.status_code != 200:
        raise RuntimeError(f"Erro no inpainting do Dezgo [{response.status_code}]: {response.text}")

    metadata = {
        "job_cost_usd": float(response.headers.get("x-dezgo-job-amount-usd", "0")),
        "remaining_balance_usd": float(response.headers.get("x-dezgo-balance-total-usd", "0")),
        "content_type": response.headers.get("Content-Type", "image/png"),
    }

    return response.content, metadata

Passo 3: Fluxos Assíncronos e Prevenção de Timeout em Aplicações Web

A API do Dezgo opera de modo síncrono, mantendo a conexão HTTP aberta até que o processamento do modelo seja concluído (geralmente entre 2 e 8 segundos). Em infraestruturas serverless com limites rígidos de execução (como o teto padrão de 10 segundos no tier gratuito da Vercel), requisições diretas podem sofrer timeouts de gateway.

Arquitetura com Fila Redis e Notificações por SSE

Em ambientes de produção, desacopla-se a requisição do usuário do processamento de imagem por meio de filas gerenciadas pelo Redis (como BullMQ no Node.js ou Celery no Python):

[Cliente Web] ── 1. POST /api/jobs (prompt e máscara) ──► [Servidor Web API]
                                                                │
                                                                ▼
[Cliente Web] ◄─ 3. Retorna 202 Accepted { jobId } ─── 2. Enfileira no Redis
       │                                                        │
       │                                                        ▼
       │ 4. Aguarda via SSE / WebSocket ou polling      [Fila Redis / BullMQ]
       │                                                        │
       │                                                        ▼ 5. Consome tarefa
       │                                                [Worker em Background]
       │                                                        │
       │                                                        ├── 6. Chama API Dezgo
       │                                                        ├── 7. Grava no S3 / R2
       │                                                        └── 8. Atualiza DB
       ◄── 9. Notifica conclusão com URL da imagem no CDN ──────┘

Código do Worker com BullMQ

// workers/renderWorker.ts
import { Worker, Job } from "bullmq";
import { generateTextToImage } from "../services/dezgoService";
import { uploadToS3 } from "../services/storageService";
import { db } from "../services/db";

export const renderWorker = new Worker("image-generation-queue", async (job: Job) => {
  const { prompt, userId, jobId } = job.data;

  // 1. Processa geração no Dezgo
  const { imageBuffer, contentType, jobCostUsd, remainingBalanceUsd } =
    await generateTextToImage({ prompt, steps: 30 });

  // 2. Armazena a imagem no bucket S3 ou Cloudflare R2
  const cdnUrl = await uploadToS3({
    key: `renders/${userId}/${jobId}.png`,
    body: imageBuffer,
    contentType,
  });

  // 3. Atualiza registro na base de dados
  await db.jobs.update({
    where: { id: jobId },
    data: {
      status: "COMPLETED",
      outputUrl: cdnUrl,
      costUsd: jobCostUsd,
    },
  });

  // 4. Emite alerta se o saldo pré-pago estiver baixo
  if (remainingBalanceUsd < 5.0) {
    console.warn(`[Aviso Financeiro] Saldo do Dezgo reduzido: restam $${remainingBalanceUsd.toFixed(2)}.`);
  }

  return { cdnUrl, jobCostUsd };
});

Gerenciamento de Saldo e Boas Práticas Operacionais

O Dezgo não possui cobrança automática com recarga automática por cartão de crédito. Os créditos devem ser adicionados manualmente pelo painel de controle antes que a conta chegue a zero. Por isso, acompanhar as métricas das respostas HTTP é crucial para manter a estabilidade do sistema.

Informações Contábeis nos Cabeçalhos HTTP

Em cada resposta bem-sucedida, o Dezgo retorna as seguintes informações:

Verificação de Saldo Sem Renderizar Imagens

Para consultar o saldo atual sem disparar processamento nem gastar créditos, utilize o endpoint de transações:

curl -s -H "X-Dezgo-Key: YOUR_API_KEY" https://api.dezgo.com/account/tx/last

Essa requisição retorna um payload JSON contendo o índice da última transação e o valor atual do campo balance.

Resoluções de Erros Comuns

  1. HTTP 402 (Payment Required): O saldo pré-pago foi zerado. Capture este status no backend para disparar alertas urgentes para a equipe e apresentar uma mensagem clara ao usuário final ("Geração em fila por manutenção"), prevenindo erros genéricos 500.
  2. HTTP 429 (Too Many Requests): Limite de chamadas simultâneas atingido. Implemente lógica de retry com backoff exponencial no worker (ex.: 1s, 2s, 4s).
  3. HTTP 400 (Bad Request): Normalmente causado por divergência na proporção entre imagem base e máscara. Valide sempre as dimensões em pixels antes de despachar a chamada para o Dezgo.

Conclusão

Para desenvolvedores independentes e produtos com orçamento enxuto, o Dezgo elimina os altos custos fixos de manter GPUs ociosas e as restrições contratuais de assinaturas mensais fechadas. Estruturando uma camada de backend segura, um mecanismo de fila assíncrona e rotinas de monitoramento de saldo via cabeçalhos, é possível entregar geração de imagens sob demanda com excelente estabilidade e custos unitários abaixo de um centavo por imagem.

Referências