ESPACIO PUBLICITARIO DISPONIBLE · HABLEMOS

Integración de la API REST de Dezgo en aplicaciones web: Guía de arquitectura de pago por uso para text-to-image e inpainting

365Finds Editorial
11.430 artículos Wiki recopilados

Usa 365 Wiki con tu IA

Copia el prompt de abajo, pégalo en la IA que ya usas y haz tu pregunta.

Descargar el Skill completo

Pruébalo primero con el prompt. Si usas 365 Wiki a menudo, instala el Skill completo de 365Wiki y no tendrás que volver a pegarlo. Si no tienes una IA habitual, también sirven las versiones web de Gemini o Microsoft Copilot.

Al incorporar funciones de generación de imágenes y repintado por zonas (inpainting) en aplicaciones web modernas, los desarrolladores independientes y los equipos reducidos a menudo se enfrentan a un dilema técnico y financiero. Por un lado, alojar modelos de difusión de código abierto en instancias de GPU dedicadas (como AWS EC2 G5, RunPod o Modal) acarrea una carga operativa considerable: mantenimiento de controladores CUDA, actualizaciones de librerías vLLM/Diffusers, gestión de arranques en frío y un coste base fijo que oscila fácilmente entre 150 y 400 dólares mensuales por recursos inactivos. Por otro lado, las plataformas comerciales de SaaS (como Midjourney o Leonardo) imponen suscripciones mensuales obligatorias, cuotas rígidas y créditos que caducan, lo que resulta ineficiente para productos con volumen de tráfico fluctuante.

Dezgo resuelve este conflicto mediante una API REST sin servidor basada en un esquema auténtico de pago por uso (pay-as-you-go). Con una recarga inicial mínima de 10 dólares cuyos créditos nunca caducan, los desarrolladores pueden generar imágenes estándar de Stable Diffusion de 512x512 píxeles por aproximadamente 0,0019 dólares cada una, escalando de manera predecible según las dimensiones y el número de pasos de muestreo.

Esta guía técnica explica paso a paso cómo integrar la API oficial de Dezgo en una arquitectura web para producción: el mecanismo de autenticación mediante X-Dezgo-Key, la gestión de llamadas a los extremos /text2image e /inpainting_sdxl, la supervisión en tiempo real del saldo a través de las cabeceras HTTP y la implementación de colas asíncronas para mitigar tiempos de espera.


Comparativa de arquitectura: GPUs autogestionadas frente a SaaS tradicional y Dezgo

Antes de comenzar la implementación, conviene analizar las ventajas operativas y económicas de cada opción:

ParámetroClúster GPU propio (EC2 / RunPod)SaaS comercial tradicional (Midjourney)API REST de Dezgo
Coste mínimo mensualElevado ($150–$500+ al mes en reposo)Medio-Alto ($10–$60+ al mes por usuario)Cero ($10 de prepago inicial sin suscripción)
Coste unitarioVariable; muy ineficiente en valles de tráficoPlanes fijos; créditos no consumidos expiran~$0,0019 por imagen 512px; cálculo por píxel y paso
Carga de mantenimientoCrítica (drivers CUDA, autoescalado, memoria)Mínima (caja negra sin control de infraestructura)Mínima (llamadas HTTP REST estándar; cero ops GPU)
Flexibilidad de modelosTotal (cualquier peso HuggingFace o LoRA propio)Baja (modelos cerrados y propietarios)Alta (SD 1.5, SD 2.1, SDXL, Lightning y LoRAs)
Contrato de respuestaRequiere desarrollo propio de la interfaz APIBots de Discord o sondeos no estándaresFlujo binario directo (image/png) en la respuesta

Dezgo destaca porque entrega el archivo de imagen directamente en el cuerpo de la respuesta HTTP y transmite la contabilidad exacta de cada llamada en las cabeceras de respuesta.


Autenticación y arquitectura de seguridad

Todas las solicitudes dirigidas a la API de Dezgo requieren autenticación mediante la cabecera HTTP X-Dezgo-Key. Esta clave se genera en la consola de usuario en dezgo.com/account.

La regla fundamental: No invocar a Dezgo desde el navegador del cliente

La clave de API de Dezgo debita fondos directamente de tu saldo prepagado y no ofrece permisos granulares para usuarios finales. Si expones X-Dezgo-Key en el código de frontend o en solicitudes de red del navegador, cualquier usuario malintencionado podrá extraer la clave y agotar tu saldo en pocos minutos.

La arquitectura de una aplicación web segura debe canalizar siempre las solicitudes a través de un servidor backend o un proxy de API de confianza:

[Navegador del cliente]
       │
       │ 1. POST /api/generate (Sesión de usuario / Token / Cuota interna)
       ▼
[Backend de tu aplicación]
       │
       │ 2. Validar entrada, descontar créditos internos
       │ 3. Inyectar cabecera secreta "X-Dezgo-Key"
       │ 4. POST https://api.dezgo.com/text2image
       ▼
[Motor REST de Dezgo]
       │
       │ 5. Devuelve flujo binario PNG + cabeceras de facturación
       ▼
[Backend de tu aplicación]
       │
       │ 6. Leer x-dezgo-job-amount-usd y x-dezgo-balance-total-usd
       │ 7. Guardar en almacenamiento de objetos (S3 / R2) o transmitir al cliente
       ▼
[Navegador del cliente]

Paso 1: Implementación de Text-to-Image (/text2image)

El extremo de generación de texto a imagen admite peticiones formateadas como multipart/form-data o application/json (con cargas codificadas en base64) y devuelve directamente el flujo binario de la imagen renderizada (image/png o image/jpeg).

Parámetros clave de la solicitud

Implementación en el backend con 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("La variable de entorno DEZGO_API_KEY no está 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);
  }

  // Extracción de datos de facturación desde las cabeceras HTTP de respuesta
  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(`Error en los parámetros de Dezgo (400): ${message}`);
    case 401:
      throw new Error("Autenticación fallida en Dezgo (401): Verifique X-Dezgo-Key.");
    case 402:
      throw new Error("Saldo insuficiente en Dezgo (402): Cuenta prepago agotada.");
    case 429:
      throw new Error("Límite de tasa excedido en Dezgo (429): Demasiadas peticiones.");
    default:
      throw new Error(`Error de servidor en Dezgo (${status}): ${message}`);
  }
}

Paso 2: Implementación de Inpainting con SDXL (/inpainting_sdxl)

El repintado por zonas (inpainting) permite modificar partes específicas de una imagen existente conservando el resto intacto. Dezgo ofrece dos extremos principales: /inpainting (para arquitecturas SD 1.5 y 2.x) e /inpainting_sdxl (para Stable Diffusion XL en resoluciones altas con mayor definición).

Requisitos de las imágenes de entrada

Para ejecutar el repintado se requieren dos archivos:

  1. init_image: La imagen original de base que se desea alterar (PNG o JPEG).
  2. mask_image: Una máscara en blanco y negro con exactamente las mismas dimensiones que init_image. Las zonas blancas (#FFFFFF) delimitan el área que la IA debe repintar, mientras que las zonas negras (#000000) protegen los píxeles originales que no deben alterarse.

Implementación en backend con 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]]:
    """
    Envía una tarea de inpainting a Dezgo SDXL mediante multipart/form-data.
    """
    if not DEZGO_API_KEY:
        raise ValueError("DEZGO_API_KEY no está configurada en las variables de entorno.")

    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 prepagado de Dezgo agotado. Se requiere recarga.")
    elif response.status_code != 200:
        raise RuntimeError(f"Fallo en inpainting de 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

Paso 3: Flujos asíncronos y prevención de tiempos de espera

La API de Dezgo es síncrona: mantiene la conexión HTTP abierta hasta que el modelo termina de procesar la imagen (entre 2 y 8 segundos de media). En entornos serverless con límites estrictos de ejecución (como los 10 segundos predeterminados en capas gratuitas de Vercel), esto puede generar errores de tiempo de espera (Gateway Timeout).

Patrón recomendado: Cola de tareas en segundo plano con Redis y SSE

Para garantizar la estabilidad en producción, desacopla la recepción de la petición del proceso de renderizado utilizando una cola como BullMQ o Celery:

[Cliente Web] ── 1. POST /api/jobs (prompt y máscara) ──► [Servidor Web API]
                                                                │
                                                                ▼
[Cliente Web] ◄─ 3. Retorna 202 Accepted { jobId } ─── 2. Añade a cola Redis
       │                                                        │
       │                                                        ▼
       │ 4. Escucha por SSE / WebSocket o sondeo       [Redis / BullMQ]
       │                                                        │
       │                                                        ▼ 5. Procesa tarea
       │                                                [Worker en segundo plano]
       │                                                        │
       │                                                        ├── 6. Invoca API de Dezgo
       │                                                        ├── 7. Sube imagen a S3 / R2
       │                                                        └── 8. Actualiza estado en DB
       ◄── 9. Notifica evento COMPLETED con URL del CDN ────────┘

Ejemplo de Worker con 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. Invocar el servicio de Dezgo
  const { imageBuffer, contentType, jobCostUsd, remainingBalanceUsd } =
    await generateTextToImage({ prompt, steps: 30 });

  // 2. Almacenar la imagen binaria en un bucket S3 o R2
  const cdnUrl = await uploadToS3({
    key: `renders/${userId}/${jobId}.png`,
    body: imageBuffer,
    contentType,
  });

  // 3. Registrar el resultado y el coste en base de datos
  await db.jobs.update({
    where: { id: jobId },
    data: {
      status: "COMPLETED",
      outputUrl: cdnUrl,
      costUsd: jobCostUsd,
    },
  });

  // 4. Alerta preventiva si el saldo restante es bajo
  if (remainingBalanceUsd < 5.0) {
    console.warn(`[Alerta Saldo] Saldo bajo en Dezgo: restan $${remainingBalanceUsd.toFixed(2)}.`);
  }

  return { cdnUrl, jobCostUsd };
});

Gestión de saldo y salvaguardas para producción

Dezgo no dispone de cobro automático recurrente en tarjeta; las recargas se efectúan manualmente en el panel de control. Por este motivo, supervisar las cabeceras de respuesta en cada petición es esencial para evitar interrupciones no programadas del servicio.

Telemetría en cabeceras HTTP

Cada respuesta satisfactoria incluye los siguientes datos contables:

Consulta de saldo sin renderizado

Para verificar el estado contable de la cuenta sin incurrir en costes de generación, se puede consultar el extremo de transacciones:

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

Este comando devuelve un objeto JSON con el índice más reciente y el valor actual del campo balance.

Estrategia de gestión de errores

  1. HTTP 402 (Payment Required): Indica que el saldo prepagado se ha terminado. Captura este código explícitamente en el backend para emitir una alerta crítica al equipo técnico y mostrar al usuario un mensaje adecuado ("Procesando en cola por mantenimiento") en lugar de un error 500 genérico.
  2. HTTP 429 (Too Many Requests): Límite de concurrencia alcanzado. Configura reintentos con retroceso exponencial (por ejemplo, tras 1s, 2s y 4s).
  3. HTTP 400 (Bad Request): Ocurre habitualmente cuando las dimensiones de la máscara y de la imagen original no coinciden. Valida siempre la geometría en píxeles antes de realizar el envío a Dezgo.

Conclusión

Para desarrolladores independientes y aplicaciones web con requisitos de generación bajo demanda, Dezgo ofrece un equilibrio óptimo entre el coste fijo de mantener infraestructura propia de GPU y las restricciones comerciales de las suscripciones mensuales. Mediante un proxy seguro en el backend, una cola asíncrona de tareas y la monitorización activa de las cabeceras de saldo, es posible desplegar una solución de IA visual escalable y rentable con costes por imagen inferiores a un céntimo de dólar.

Referencias