Spaces:
Configuration error
Configuration error
| # 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** | |
| ```bash | |
| # Get app.py, requirements.txt, USAGE_EXAMPLES.md | |
| ls -la | |
| # Should see: app.py, requirements.txt, USAGE_EXAMPLES.md | |
| ``` | |
| 2. **Install dependencies** | |
| ```bash | |
| pip install -r requirements.txt | |
| ``` | |
| 3. **Run the server** | |
| ```bash | |
| python app.py | |
| ``` | |
| Expected output: | |
| ``` | |
| ============================================================ | |
| Z-Image-Turbo API Wrapper | |
| ============================================================ | |
| Gradio API URL: https://mohamedislegend4-z-image-turbo-api.hf.space | |
| Starting Flask server... | |
| ============================================================ | |
| * Running on http://0.0.0.0:5000 | |
| ``` | |
| 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: | |
| ```bash | |
| pip install gunicorn | |
| # Run with 4 workers | |
| gunicorn -w 4 -b 0.0.0.0:5000 --timeout 300 app:app | |
| ``` | |
| Using systemd service: | |
| ```bash | |
| 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** | |
| ```bash | |
| # Get server.js and package.json | |
| ls -la | |
| # Should see: server.js, package.json | |
| ``` | |
| 2. **Install dependencies** | |
| ```bash | |
| npm install | |
| ``` | |
| 3. **Run the server** | |
| ```bash | |
| npm start | |
| ``` | |
| Or with auto-reload during development: | |
| ```bash | |
| 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 | |
| ``` | |
| 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 (Node.js) | |
| Using PM2: | |
| ```bash | |
| 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: | |
| ```bash | |
| 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 | |
| ```bash | |
| 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) | |
| ```yaml | |
| 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 | |
| ```bash | |
| 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 | |
| ```json | |
| { | |
| "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 | |
| ```bash | |
| 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: | |
| ```bash | |
| # 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`: | |
| ```python | |
| 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`: | |
| ```javascript | |
| 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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) | |
| ```bash | |
| # 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) | |
| ```javascript | |
| 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 | |
| ```python | |
| from functools import lru_cache | |
| @app.route('/api/generate', methods=['POST']) | |
| @lru_cache(maxsize=100) | |
| def generate(): | |
| # ... implementation | |
| ``` | |
| --- | |
| ## Reverse Proxy Setup (Nginx) | |
| ```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 | |
| ```bash | |
| # Real-time | |
| tail -f app.log | |
| # With Flask's built-in logging | |
| # Logs appear in console by default | |
| ``` | |
| ### Node.js Logs | |
| ```bash | |
| # PM2 logs | |
| pm2 logs z-image-api | |
| # Docker logs | |
| docker logs -f z-image-api | |
| ``` | |
| ### Health Check Script | |
| ```bash | |
| #!/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 | |
| ```bash | |
| pip install Flask-Limiter | |
| ``` | |
| ```python | |
| 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 | |
| ```bash | |
| npm install express-rate-limit | |
| ``` | |
| ```javascript | |
| 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! | |