Z-Image-Turbo-API / SETUP_GUIDE.md
mohamedislegend4's picture
Upload 9 files
d6e90da verified
|
Raw
History Blame Contribute Delete
10.4 kB

Z-Image-Turbo API Wrapper - Complete Setup Guide

Overview

This wrapper provides a simple REST API endpoint that handles:

  1. Calling the Gradio Z-Image-Turbo API
  2. Polling for results (async handling)
  3. Returning the direct image URL

Two implementations provided:

  • Python (Flask)
  • Node.js (Express)

Python Setup (Recommended)

Prerequisites

  • Python 3.8+
  • pip

Installation

  1. Clone/Download files
# Get app.py, requirements.txt, USAGE_EXAMPLES.md
ls -la
# Should see: app.py, requirements.txt, USAGE_EXAMPLES.md
  1. Install dependencies
pip install -r requirements.txt
  1. Run the server
python app.py

Expected output: ```

Z-Image-Turbo API Wrapper

Gradio API URL: https://mohamedislegend4-z-image-turbo-api.hf.space Starting Flask server...


4. **Test the API**
```bash
# Health check
curl http://localhost:5000/health

# Generate image
curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A beautiful sunset"}'

Production Deployment (Python)

Using Gunicorn:

pip install gunicorn

# Run with 4 workers
gunicorn -w 4 -b 0.0.0.0:5000 --timeout 300 app:app

Using systemd service:

sudo cat > /etc/systemd/system/z-image-api.service << EOF
[Unit]
Description=Z-Image-Turbo API Wrapper
After=network.target

[Service]
Type=notify
User=www-data
WorkingDirectory=/home/www-data/z-image-api
ExecStart=/usr/bin/gunicorn -w 4 -b 0.0.0.0:5000 --timeout 300 app:app
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable z-image-api
sudo systemctl start z-image-api

Node.js Setup

Prerequisites

  • Node.js 14+
  • npm

Installation

  1. Download files
# Get server.js and package.json
ls -la
# Should see: server.js, package.json
  1. Install dependencies
npm install
  1. Run the server
npm start

Or with auto-reload during development:

npm install --save-dev nodemon
npm run dev

Expected output:

[2024-01-15T10:30:45.123Z] INFO: ============================================================
[2024-01-15T10:30:45.124Z] INFO: Z-Image-Turbo API Wrapper (Node.js)
[2024-01-15T10:30:45.125Z] INFO: ============================================================
[2024-01-15T10:30:45.126Z] INFO: Gradio API URL: https://...
[2024-01-15T10:30:45.127Z] INFO: Server running on: http://localhost:5000
  1. Test the API
# Health check
curl http://localhost:5000/health

# Generate image
curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A beautiful sunset"}'

Production Deployment (Node.js)

Using PM2:

npm install -g pm2

# Start
pm2 start server.js --name "z-image-api" -i 4

# Make it restart on boot
pm2 startup
pm2 save

Using Docker:

cat > Dockerfile << 'EOF'
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY server.js .

EXPOSE 5000

CMD ["node", "server.js"]
EOF

docker build -t z-image-api .
docker run -d -p 5000:5000 --name z-image-api z-image-api

Docker Deployment (Both)

Python Version

cat > Dockerfile << 'EOF'
FROM python:3.10-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "--timeout", "300", "app:app"]
EOF

# Build
docker build -t z-image-api-python .

# Run
docker run -d -p 5000:5000 --name z-image-api z-image-api-python

Docker Compose (Both)

version: '3.8'

services:
  # Python version
  z-image-python:
    image: z-image-api-python
    ports:
      - "5000:5000"
    environment:
      - FLASK_ENV=production
    restart: unless-stopped

  # Node.js version (use one or the other)
  z-image-node:
    image: z-image-api-node
    ports:
      - "5001:5000"
    environment:
      - NODE_ENV=production
    restart: unless-stopped

  # Nginx reverse proxy
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - z-image-python
      - z-image-node
    restart: unless-stopped

API Usage Quick Start

Basic Request

curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A serene forest landscape at dawn",
    "steps": 20,
    "height": 512,
    "width": 512
  }'

Response Format

{
  "success": true,
  "prompt": "A serene forest landscape at dawn",
  "steps": 20,
  "height": 512,
  "width": 512,
  "image_url": "https://example.com/path/to/image.png",
  "image_path": "/tmp/path/to/image",
  "size": 234567,
  "mime_type": "image/png",
  "filename": "image.png"
}

Download Generated Image

RESPONSE=$(curl -s -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A beautiful sunset"}')

IMAGE_URL=$(echo $RESPONSE | jq -r '.image_url')

if [ "$IMAGE_URL" != "null" ]; then
  curl -o my_image.png "$IMAGE_URL"
  echo "Downloaded to my_image.png"
fi

Configuration

Environment Variables

Create a .env file:

# API Configuration
GRADIO_API_URL=https://mohamedislegend4-z-image-turbo-api.hf.space
PORT=5000

# Server Configuration
WORKERS=4
TIMEOUT=300
DEBUG=False

# Polling Configuration
MAX_POLL_ATTEMPTS=120
POLL_INTERVAL=1

Python: Load Environment Variables

Modify app.py:

from dotenv import load_dotenv
import os

load_dotenv()

GRADIO_API_URL = os.getenv("GRADIO_API_URL", "https://...")
MAX_POLL_ATTEMPTS = int(os.getenv("MAX_POLL_ATTEMPTS", 120))

Node.js: Load Environment Variables

Modify server.js:

require('dotenv').config();

const PORT = process.env.PORT || 5000;
const GRADIO_API_URL = process.env.GRADIO_API_URL || 'https://...';
const MAX_POLL_ATTEMPTS = parseInt(process.env.MAX_POLL_ATTEMPTS) || 120;

Troubleshooting

Issue: "Connection refused"

Solution: Make sure the server is running

# Python
python app.py

# Node.js
npm start

Issue: "Timeout waiting for image"

Cause: The Gradio API is slow or overloaded Solutions:

  • Reduce steps parameter (default 20, try 8-15)
  • Use smaller image dimensions (try 256x256 or 512x512)
  • Try again later

Issue: "Empty image_url in response"

Cause: The Gradio API didn't return image data Debug: Check server logs for error messages

Issue: High latency/slow responses

Cause:

  • First request needs model initialization
  • Network latency to Gradio API Solutions:
  • Use a server closer to the Gradio API
  • Consider running Z-Image-Turbo locally

Issue: "Port already in use"

Solution: Change port or kill existing process

# Find process on port 5000
lsof -i :5000

# Kill it
kill -9 <PID>

# Or use different port
python app.py --port 5001

Performance Tuning

For Python (Gunicorn)

# Adjust workers based on CPU cores
# Rule: workers = (2 × cores) + 1

gunicorn -w 8 -b 0.0.0.0:5000 \
  --timeout 300 \
  --max-requests 1000 \
  --max-requests-jitter 100 \
  app:app

For Node.js (Cluster)

const cluster = require('cluster');
const os = require('os');

if (cluster.isMaster) {
  const numWorkers = os.cpus().length;
  for (let i = 0; i < numWorkers; i++) {
    cluster.fork();
  }
} else {
  app.listen(PORT);
}

Caching Responses

from functools import lru_cache

@app.route('/api/generate', methods=['POST'])
@lru_cache(maxsize=100)
def generate():
    # ... implementation

Reverse Proxy Setup (Nginx)

upstream z_image_api {
    server localhost:5000 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name api.example.com;

    location /api/ {
        proxy_pass http://z_image_api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Increase timeout for image generation
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
        
        # Buffering
        proxy_buffering on;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }

    location /health {
        proxy_pass http://z_image_api;
    }
}

Monitoring & Logging

Python Logs

# Real-time
tail -f app.log

# With Flask's built-in logging
# Logs appear in console by default

Node.js Logs

# PM2 logs
pm2 logs z-image-api

# Docker logs
docker logs -f z-image-api

Health Check Script

#!/bin/bash

while true; do
  HEALTH=$(curl -s http://localhost:5000/health | jq -r '.status')
  if [ "$HEALTH" == "ok" ]; then
    echo "✓ API is healthy"
  else
    echo "✗ API is down!"
    # Restart if needed
  fi
  sleep 60
done

API Rate Limiting

Python with Flask-Limiter

pip install Flask-Limiter
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(
    app=app,
    key_func=get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)

@app.route('/api/generate', methods=['POST'])
@limiter.limit("5 per minute")
def generate():
    # ... implementation

Node.js with express-rate-limit

npm install express-rate-limit
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1 minute
  max: 5 // 5 requests per minute
});

app.post('/api/generate', limiter, (req, res) => {
  // ... implementation
});

Next Steps

  1. Start the server (Python or Node.js)
  2. Test with curl (see examples above)
  3. Integrate into your application
  4. Deploy to production (Docker, systemd, PM2, etc.)
  5. Monitor performance (logs, metrics, health checks)

See USAGE_EXAMPLES.md for more detailed code examples!