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

Z-Image-Turbo API Wrapper

Simple REST API wrapper for the Z-Image-Turbo Gradio space that returns direct image URLs

What is this?

This project wraps the Gradio-based Z-Image-Turbo API and provides:

  • βœ… Simple REST endpoints
  • βœ… Automatic polling for async results
  • βœ… Direct image URL response
  • βœ… Both Python (Flask) and Node.js (Express) implementations
  • βœ… Production-ready with Docker support
  • βœ… Easy deployment (systemd, PM2, Docker Compose, etc.)

Features

  • Simple API: Single endpoint - POST /api/generate with a prompt
  • Direct URLs: Returns the image URL directly (no base64, no polling needed from client)
  • Async Handling: Handles the Gradio async polling internally
  • Error Handling: Graceful error responses with helpful messages
  • CORS Support: Ready for web frontend integration
  • Configurable: Adjustable timeout, polling intervals, parameters
  • Logging: Detailed logging for debugging
  • Health Checks: Built-in health endpoint
  • Scalable: Multi-worker support (Gunicorn, PM2, Docker)

Quick Start

Option 1: Python (Recommended)

# Setup
bash setup.sh

# Run
source venv/bin/activate
python app.py

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

Option 2: Node.js

# Setup
bash setup-node.sh

# Run
npm start

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

Option 3: Docker

# Python
docker build -t z-image-api -f Dockerfile.python .
docker run -p 5000:5000 z-image-api

# Node.js
docker build -t z-image-api -f Dockerfile.nodejs .
docker run -p 5000:5000 z-image-api

API Endpoints

GET /health

Health check endpoint

curl http://localhost:5000/health

Response:

{"status": "ok"}

GET /api/info

Get API information and available parameters

curl http://localhost:5000/api/info

POST /api/generate

Generate an image

Request:

curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A beautiful sunset over mountains",
    "steps": 20,
    "height": 512,
    "width": 512
  }'

Parameters:

Parameter Type Default Required Description
prompt string - βœ“ Yes Text description of the image
steps integer 20 No Inference steps (1-50)
height integer 512 No Image height in pixels
width integer 512 No Image width in pixels

Response:

{
  "success": true,
  "prompt": "A beautiful sunset over mountains",
  "steps": 20,
  "height": 512,
  "width": 512,
  "image_url": "https://example.com/path/to/image.png",
  "image_path": "/path/to/local/image",
  "size": 123456,
  "mime_type": "image/png",
  "filename": "image.png"
}

Error Response:

{
  "success": false,
  "error": "Error message describing what went wrong"
}

Usage Examples

Curl

Simple generation:

curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A cat sitting on a window sill"}'

Extract and download image:

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

IMAGE_URL=$(echo $RESPONSE | jq -r '.image_url')
curl -o my_image.png "$IMAGE_URL"

Python

import requests

response = requests.post(
    'http://localhost:5000/api/generate',
    json={
        'prompt': 'A magical forest',
        'steps': 25,
        'height': 768,
        'width': 768
    }
)

result = response.json()
if result['success']:
    print(f"Image URL: {result['image_url']}")
    # Download it
    img = requests.get(result['image_url'])
    with open('image.png', 'wb') as f:
        f.write(img.content)

JavaScript

async function generateImage(prompt) {
  const response = await fetch('http://localhost:5000/api/generate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      prompt: prompt,
      steps: 20,
      height: 512,
      width: 512
    })
  });

  const result = await response.json();
  if (result.success) {
    console.log('Image URL:', result.image_url);
    // Use the image URL
    document.getElementById('image').src = result.image_url;
  }
}

generateImage('A beautiful landscape');

cURL with timeout handling

#!/bin/bash

TIMEOUT=600  # 10 minutes
PROMPT="A futuristic city with neon lights"

echo "Generating image..."
RESPONSE=$(curl -s -X POST http://localhost:5000/api/generate \
  --max-time $TIMEOUT \
  -H "Content-Type: application/json" \
  -d "{\"prompt\": \"$PROMPT\", \"steps\": 25}")

if [ $? -eq 0 ]; then
  SUCCESS=$(echo $RESPONSE | jq -r '.success')
  if [ "$SUCCESS" == "true" ]; then
    IMAGE_URL=$(echo $RESPONSE | jq -r '.image_url')
    echo "βœ“ Generated: $IMAGE_URL"
  else
    ERROR=$(echo $RESPONSE | jq -r '.error')
    echo "βœ— Error: $ERROR"
  fi
else
  echo "βœ— Request failed or timed out"
fi

Files Included

β”œβ”€β”€ app.py                 # Flask implementation (Python)
β”œβ”€β”€ server.js              # Express implementation (Node.js)
β”œβ”€β”€ requirements.txt       # Python dependencies
β”œβ”€β”€ package.json           # Node.js dependencies
β”œβ”€β”€ setup.sh               # Python quick setup script
β”œβ”€β”€ setup-node.sh          # Node.js quick setup script
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ SETUP_GUIDE.md         # Detailed setup and deployment guide
β”œβ”€β”€ USAGE_EXAMPLES.md      # More detailed usage examples
└── Dockerfile             # Docker build file

Configuration

Environment Variables

Create a .env file:

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

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

# Polling Settings
MAX_POLL_ATTEMPTS=120
POLL_INTERVAL=1

Python Configuration

Edit the constants in app.py:

GRADIO_API_URL = "https://mohamedislegend4-z-image-turbo-api.hf.space"
MAX_POLL_ATTEMPTS = 120  # 2 minutes
POLL_INTERVAL = 1  # seconds

Node.js Configuration

Edit the constants in server.js:

const PORT = process.env.PORT || 5000;
const GRADIO_API_URL = 'https://mohamedislegend4-z-image-turbo-api.hf.space';
const MAX_POLL_ATTEMPTS = 120;
const POLL_INTERVAL = 1000; // ms

Performance Tips

Image Generation Parameters

Parameter Fast Balanced High Quality
steps 8-12 20-25 40-50
height 256 512 768-1024
width 256 512 768-1024
time 10-20s 30-60s 60-120s

Server Optimization

Python (Gunicorn):

gunicorn -w 8 -b 0.0.0.0:5000 \
  --timeout 300 \
  --max-requests 1000 \
  --worker-class sync \
  app:app

Node.js (PM2):

pm2 start server.js -i 4 --name z-image-api
pm2 save

Deployment

Systemd (Python)

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

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

[Install]
WantedBy=multi-user.target
EOF

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

Docker Compose

See SETUP_GUIDE.md for complete Docker Compose configuration.

Troubleshooting

"Connection refused"

  • Ensure the server is running
  • Check if port 5000 is in use: lsof -i :5000

"Timeout waiting for result"

  • The Gradio API is slow or overloaded
  • Try reducing steps or image size
  • Check if mohamedislegend4-z-image-turbo-api.hf.space is accessible

"Empty image_url"

  • The Gradio API didn't return image data
  • Check server logs for details
  • Try again with simpler parameters

Slow responses

  • First request initializes the model (slow)
  • Subsequent requests are faster
  • Network latency to Gradio API affects speed

See SETUP_GUIDE.md for more troubleshooting tips.

How It Works

Client Request
    ↓
Flask/Express Server (this wrapper)
    ↓
Call Gradio Endpoint: /gradio_api/call/v2/generate
    ↓
Get event_id
    ↓
Poll Result: /gradio_api/call/generate/{event_id} (every 1 second)
    ↓
Wait for result (up to 2 minutes)
    ↓
Extract image data
    ↓
Return image_url to client
    ↓
Client Response with image_url

What's Next?

  1. Start the server (see Quick Start)
  2. Test with curl (see API Endpoints)
  3. Integrate into your app (see Usage Examples)
  4. Deploy to production (see SETUP_GUIDE.md)
  5. Monitor and optimize (see SETUP_GUIDE.md)

Requirements

Python:

  • Python 3.8+
  • Flask 3.0+
  • Requests 2.31+

Node.js:

  • Node.js 14+
  • Express 4.18+
  • Axios 1.6+

Both:

  • Internet connection (to reach Gradio API)
  • Reasonable timeout (images can take 30-120 seconds)

License

MIT

Support

For issues or questions:

  1. Check SETUP_GUIDE.md troubleshooting section
  2. Check server logs
  3. Ensure Gradio API is accessible
  4. Review USAGE_EXAMPLES.md for code samples

Credits

  • Built for: Z-Image-Turbo by Tongyi-MAI
  • Gradio Space: mohamedislegend4/Z-Image-Turbo-API
  • Wrapper created: 2024

Ready to generate images? Start with:

# Python
bash setup.sh && source venv/bin/activate && python app.py

# Node.js
bash setup-node.sh && npm start

Then test with:

curl -X POST http://localhost:5000/api/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Your image description here"}'