Spaces:
Configuration error
Configuration error
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/generatewith 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
stepsor image size - Check if
mohamedislegend4-z-image-turbo-api.hf.spaceis 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?
- Start the server (see Quick Start)
- Test with curl (see API Endpoints)
- Integrate into your app (see Usage Examples)
- Deploy to production (see SETUP_GUIDE.md)
- 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:
- Check
SETUP_GUIDE.mdtroubleshooting section - Check server logs
- Ensure Gradio API is accessible
- Review
USAGE_EXAMPLES.mdfor 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"}'