diff --git a/.runpod/hub.json b/.runpod/hub.json
new file mode 100644
index 000000000..97d098f39
--- /dev/null
+++ b/.runpod/hub.json
@@ -0,0 +1,66 @@
+{
+ "title": "ComfyUI - AI Image Generation",
+ "description": "ComfyUI serverless deployment with network storage support for models. Generate high-quality images using Stable Diffusion XL with custom workflows.",
+ "type": "serverless",
+ "category": "image",
+ "iconUrl": "https://raw.githubusercontent.com/comfyanonymous/ComfyUI/master/web/favicon.ico",
+ "config": {
+ "runsOn": "GPU",
+ "containerDiskInGb": 20,
+ "presets": [
+ {
+ "name": "SDXL Base",
+ "defaults": {
+ "MODEL_NAME": "sd_xl_base_1.0.safetensors",
+ "STEPS": "25",
+ "CFG": "8.0"
+ }
+ },
+ {
+ "name": "High Quality",
+ "defaults": {
+ "MODEL_NAME": "sd_xl_base_1.0.safetensors",
+ "STEPS": "50",
+ "CFG": "7.0"
+ }
+ }
+ ],
+ "env": [
+ {
+ "key": "HF_HUB_DISABLE_TELEMETRY",
+ "value": "1"
+ },
+ {
+ "key": "DO_NOT_TRACK",
+ "value": "1"
+ },
+ {
+ "key": "MODEL_NAME",
+ "input": {
+ "name": "Model Name",
+ "type": "string",
+ "description": "Checkpoint model file name to use",
+ "default": "sd_xl_base_1.0.safetensors"
+ }
+ },
+ {
+ "key": "STEPS",
+ "input": {
+ "name": "Generation Steps",
+ "type": "string",
+ "description": "Number of denoising steps",
+ "default": "25"
+ }
+ },
+ {
+ "key": "CFG",
+ "input": {
+ "name": "CFG Scale",
+ "type": "string",
+ "description": "Classifier-free guidance scale",
+ "default": "8.0"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/.runpod/tests.json b/.runpod/tests.json
new file mode 100644
index 000000000..8407c3b87
--- /dev/null
+++ b/.runpod/tests.json
@@ -0,0 +1,94 @@
+{
+ "tests": [
+ {
+ "name": "basic_text_to_image",
+ "input": {
+ "workflow": {
+ "3": {
+ "inputs": {
+ "seed": 42,
+ "steps": 20,
+ "cfg": 8.0,
+ "sampler_name": "euler",
+ "scheduler": "normal",
+ "denoise": 1.0,
+ "model": ["4", 0],
+ "positive": ["6", 0],
+ "negative": ["7", 0],
+ "latent_image": ["5", 0]
+ },
+ "class_type": "KSampler"
+ },
+ "4": {
+ "inputs": {
+ "ckpt_name": "sd_xl_base_1.0.safetensors"
+ },
+ "class_type": "CheckpointLoaderSimple"
+ },
+ "5": {
+ "inputs": {
+ "width": 1024,
+ "height": 1024,
+ "batch_size": 1
+ },
+ "class_type": "EmptyLatentImage"
+ },
+ "6": {
+ "inputs": {
+ "text": "a beautiful landscape, high quality, detailed",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "7": {
+ "inputs": {
+ "text": "blurry, low quality, distorted",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "8": {
+ "inputs": {
+ "samples": ["3", 0],
+ "vae": ["4", 2]
+ },
+ "class_type": "VAEDecode"
+ },
+ "9": {
+ "inputs": {
+ "filename_prefix": "test_output",
+ "images": ["8", 0]
+ },
+ "class_type": "SaveImage"
+ }
+ }
+ },
+ "timeout": 120000
+ },
+ {
+ "name": "simple_prompt_test",
+ "input": {
+ "prompt": "modern software interface, clean design"
+ },
+ "timeout": 60000
+ }
+ ],
+ "config": {
+ "gpuTypeId": "NVIDIA RTX A4000",
+ "gpuCount": 1,
+ "env": [
+ {
+ "key": "HF_HUB_DISABLE_TELEMETRY",
+ "value": "1"
+ },
+ {
+ "key": "DO_NOT_TRACK",
+ "value": "1"
+ }
+ ],
+ "allowedCudaVersions": [
+ "12.1",
+ "11.8"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 9f6eba161..9d2982c7b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,6 +13,29 @@ RUN apt-get update && apt-get install -y \
# Tüm dosyaları kopyala
COPY . /app
+# Model klasörlerini oluştur
+RUN mkdir -p /app/models/checkpoints /app/models/loras /app/models/vae \
+ /app/models/controlnet /app/models/upscale_models \
+ /app/models/text_encoders /app/models/clip \
+ /app/models/diffusion_models /app/models/unet \
+ /app/models/embeddings /app/models/clip_vision
+
+# Storage erişim testi - Build sırasında storage erişimi kontrol et
+RUN echo "🔍 RunPod Build Storage Access Test" && \
+ echo "=================================" && \
+ echo "📁 Testing storage paths:" && \
+ (ls -la /runpod-volume 2>/dev/null && echo "✅ /runpod-volume accessible" || echo "❌ /runpod-volume not accessible") && \
+ (ls -la /workspace 2>/dev/null && echo "✅ /workspace accessible" || echo "❌ /workspace not accessible") && \
+ (ls -la /content 2>/dev/null && echo "✅ /content accessible" || echo "❌ /content not accessible") && \
+ echo "🌐 Network test:" && \
+ (ping -c 1 google.com >/dev/null 2>&1 && echo "✅ Internet access available" || echo "❌ No internet access") && \
+ echo "================================="
+
+# Temel modelleri Docker build sırasında indir
+RUN pip install huggingface-hub && \
+ python download_models.py && \
+ rm -rf /tmp/hf_cache
+
# PyTorch CPU versiyonu ve bağımlılıklar
RUN pip install --no-cache-dir \
torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu && \
diff --git a/README.md b/README.md
index 4204777e9..f6f57681d 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
[![Dynamic JSON Badge][discord-shield]][discord-url]
[![Twitter][twitter-shield]][twitter-url]
[![Matrix][matrix-shield]][matrix-url]
+[![Runpod][runpod-shield]][runpod-url]
[![][github-release-shield]][github-release-link]
[![][github-release-date-shield]][github-release-link]
@@ -18,6 +19,8 @@
[matrix-url]: https://app.element.io/#/room/%23comfyui_space%3Amatrix.org
[website-shield]: https://img.shields.io/badge/ComfyOrg-4285F4?style=flat
[website-url]: https://www.comfy.org/
+[runpod-shield]: https://api.runpod.io/badge/bahadirciloglu/ComfyUI
+[runpod-url]: https://console.runpod.io/hub/bahadirciloglu/ComfyUI
[discord-shield]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fdiscord.com%2Fapi%2Finvites%2Fcomfyorg%3Fwith_counts%3Dtrue&query=%24.approximate_member_count&logo=discord&logoColor=white&label=Discord&color=green&suffix=%20total
[discord-url]: https://www.comfy.org/discord
diff --git a/debug_runpod.sh b/debug_runpod.sh
new file mode 100755
index 000000000..0619734bb
--- /dev/null
+++ b/debug_runpod.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Debug RunPod API call
+
+ENDPOINT_ID="sfkzjudvrj50yq"
+API_KEY="${RUNPOD_API_KEY:-YOUR_API_KEY}"
+BASE_URL="https://api.runpod.ai/v2"
+
+echo "🔍 Debugging RunPod API..."
+echo "📍 Endpoint: $ENDPOINT_ID"
+echo "🔑 API Key: ${API_KEY:0:10}..." # Show only first 10 chars for security
+
+# Simple test with minimal payload
+echo "📤 Testing with simple payload..."
+curl -v -X POST "$BASE_URL/$ENDPOINT_ID/run" \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer $API_KEY" \
+ -d '{"input":{"prompt":"test prompt"}}'
\ No newline at end of file
diff --git a/download_models.py b/download_models.py
new file mode 100644
index 000000000..764172b8c
--- /dev/null
+++ b/download_models.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+"""
+Docker build sırasında temel modelleri indir
+"""
+
+import os
+import sys
+from pathlib import Path
+from huggingface_hub import hf_hub_download
+
+def download_model(repo_id, filename, target_dir):
+ """Model indir ve hedef dizine kopyala"""
+ try:
+ print(f"📥 İndiriliyor: {repo_id}/{filename}")
+
+ # Model'i indir
+ model_path = hf_hub_download(
+ repo_id=repo_id,
+ filename=filename,
+ cache_dir="/tmp/hf_cache"
+ )
+
+ # Hedef dizini oluştur
+ os.makedirs(target_dir, exist_ok=True)
+
+ # Dosyayı kopyala
+ target_path = os.path.join(target_dir, filename)
+ os.system(f"cp '{model_path}' '{target_path}'")
+
+ print(f"✅ Kaydedildi: {target_path}")
+ return True
+
+ except Exception as e:
+ print(f"❌ Hata: {repo_id}/{filename} - {e}")
+ return False
+
+def main():
+ """Temel modelleri indir"""
+ print("🚀 Docker build - Model indirme başlatılıyor...")
+
+ models_base = "/app/models"
+
+ # İndirilecek modeller
+ models_to_download = [
+ # SDXL Base Model
+ {
+ "repo_id": "stabilityai/stable-diffusion-xl-base-1.0",
+ "filename": "sd_xl_base_1.0.safetensors",
+ "target_dir": f"{models_base}/checkpoints"
+ },
+ # SDXL VAE
+ {
+ "repo_id": "stabilityai/sdxl-vae",
+ "filename": "sdxl_vae.safetensors",
+ "target_dir": f"{models_base}/vae"
+ },
+ # CLIP Text Encoder
+ {
+ "repo_id": "openai/clip-vit-large-patch14",
+ "filename": "pytorch_model.bin",
+ "target_dir": f"{models_base}/clip"
+ }
+ ]
+
+ success_count = 0
+
+ for model in models_to_download:
+ if download_model(
+ model["repo_id"],
+ model["filename"],
+ model["target_dir"]
+ ):
+ success_count += 1
+
+ print(f"\n🎉 Model indirme tamamlandı: {success_count}/{len(models_to_download)}")
+
+ # Model klasörlerini listele
+ print("\n📁 Model klasörleri:")
+ for root, dirs, files in os.walk(models_base):
+ level = root.replace(models_base, '').count(os.sep)
+ indent = ' ' * 2 * level
+ print(f"{indent}{os.path.basename(root)}/")
+ subindent = ' ' * 2 * (level + 1)
+ for file in files:
+ file_size = os.path.getsize(os.path.join(root, file))
+ size_mb = file_size / (1024 * 1024)
+ print(f"{subindent}{file} ({size_mb:.1f} MB)")
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/runpod_template_config.md b/runpod_template_config.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/runpod_test_commands.md b/runpod_test_commands.md
new file mode 100644
index 000000000..7e642ebf4
--- /dev/null
+++ b/runpod_test_commands.md
@@ -0,0 +1,91 @@
+# RunPod Container Test Komutları
+
+## 1. Container'a Bağlan
+RunPod dashboard'da "Connect" → "Start Web Terminal"
+
+## 2. Test Scriptini Çalıştır
+```bash
+# Container içinde:
+cd /app
+python test_image_generation.py
+```
+
+## 3. Manuel Test (Alternatif)
+```bash
+# ComfyUI durumunu kontrol et
+curl http://127.0.0.1:8188/system_stats
+
+# Model listesini al
+curl http://127.0.0.1:8188/object_info | jq '.CheckpointLoaderSimple.input.required.ckpt_name'
+
+# Basit workflow gönder
+curl -X POST http://127.0.0.1:8188/prompt \
+ -H "Content-Type: application/json" \
+ -d @test_simple_workflow.json
+```
+
+## 4. Network Storage Kontrolü
+```bash
+# Models klasörünü kontrol et
+ls -la /app/models/
+ls -la /runpod-volume/models/
+
+# Symlink kontrolü
+readlink /app/models
+```
+
+## 5. Model Yükleme (Gerekirse)
+```bash
+# Network storage'a model yükle
+cd /runpod-volume/models/checkpoints
+wget https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors
+
+# ComfyUI'yi yeniden başlat
+pkill -f main.py
+python main.py --listen 0.0.0.0 --port 8188 --cpu
+```
+
+## 6. Beklenen Çıktılar
+
+### Başarılı Durum:
+```
+✅ ComfyUI server çalışıyor
+✅ Yüklü modeller (1 adet):
+ - sd_xl_base_1.0.safetensors
+🎨 Resim üretiliyor...
+ Model: sd_xl_base_1.0.safetensors
+ Prompt: a modern user interface design...
+📝 Prompt ID: abc123
+⏳ Bekleniyor... (15s)
+✅ Resim kaydedildi: test_output/test_ui_design_00001_.png
+🎉 Test tamamlandı!
+```
+
+### Hata Durumu:
+```
+❌ ComfyUI server'a bağlanılamıyor
+❌ Hiç model bulunamadı
+❌ Network storage mount edilmedi
+```
+
+## 7. Troubleshooting
+
+### ComfyUI Başlamazsa:
+```bash
+# Logları kontrol et
+tail -f /var/log/comfyui.log
+
+# Manuel başlat
+cd /app
+python main.py --listen 0.0.0.0 --port 8188 --cpu
+```
+
+### Network Storage Sorunları:
+```bash
+# Mount durumunu kontrol et
+mount | grep runpod-volume
+
+# Manuel mount
+mkdir -p /runpod-volume/models
+ln -sf /runpod-volume/models /app/models
+```
\ No newline at end of file
diff --git a/start_runpod.py b/start_runpod.py
index fe0a42587..b580685e2 100644
--- a/start_runpod.py
+++ b/start_runpod.py
@@ -161,11 +161,12 @@ def main():
# Environment setup
setup_environment()
- # Network storage'ı bekle
- wait_for_storage()
-
- # Network storage mount
- mount_runpod_storage()
+ # Hızlı başlatma için network storage mount'u atla
+ # Modeller zaten Docker image'da mevcut
+ logger.info("Hızlı başlatma modu - modeller image'da mevcut")
+
+ # Model klasörlerini kontrol et
+ ensure_local_model_folders()
# Temel modelleri indir (opsiyonel)
download_essential_models()
diff --git a/test-storage-access.Dockerfile b/test-storage-access.Dockerfile
new file mode 100644
index 000000000..510708a5a
--- /dev/null
+++ b/test-storage-access.Dockerfile
@@ -0,0 +1,40 @@
+FROM python:3.10-slim
+
+# RunPod build sırasında storage erişimi test et
+RUN echo "🔍 RunPod Build Storage Access Test" && \
+ echo "=================================" && \
+ echo "" && \
+ echo "📁 Testing common RunPod storage paths:" && \
+ echo "" && \
+ echo "1. /workspace:" && \
+ (ls -la /workspace 2>/dev/null || echo "❌ /workspace not accessible") && \
+ echo "" && \
+ echo "2. /runpod-volume:" && \
+ (ls -la /runpod-volume 2>/dev/null || echo "❌ /runpod-volume not accessible") && \
+ echo "" && \
+ echo "3. /content:" && \
+ (ls -la /content 2>/dev/null || echo "❌ /content not accessible") && \
+ echo "" && \
+ echo "4. /storage:" && \
+ (ls -la /storage 2>/dev/null || echo "❌ /storage not accessible") && \
+ echo "" && \
+ echo "5. Environment variables:" && \
+ env | grep -i runpod || echo "❌ No RUNPOD env vars found" && \
+ echo "" && \
+ echo "6. Mount points:" && \
+ mount | grep -E "(workspace|runpod|storage)" || echo "❌ No storage mounts found" && \
+ echo "" && \
+ echo "7. Available disk space:" && \
+ df -h && \
+ echo "" && \
+ echo "8. Network connectivity test:" && \
+ (ping -c 1 google.com >/dev/null 2>&1 && echo "✅ Internet access available" || echo "❌ No internet access") && \
+ echo "" && \
+ echo "=================================" && \
+ echo "🏁 Test completed"
+
+# Basit bir uygulama
+WORKDIR /app
+RUN echo 'print("Hello from RunPod build test!")' > app.py
+
+CMD ["python", "app.py"]
\ No newline at end of file
diff --git a/test_build.sh b/test_build.sh
new file mode 100755
index 000000000..ce8c36743
--- /dev/null
+++ b/test_build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# RunPod Build Test Script
+
+echo "🔍 RunPod Storage Access Test"
+echo "============================="
+
+# Docker build ile test et (local)
+echo "📦 Local Docker build test..."
+docker build -f test-storage-access.Dockerfile -t runpod-storage-test . 2>&1 | grep -E "(Storage Access Test|accessible|not accessible)"
+
+echo ""
+echo "🚀 Gerçek test için RunPod Dashboard'da bu Dockerfile'ı kullan:"
+echo " 1. RunPod Dashboard → Templates → Create Template"
+echo " 2. Container Image → Build from Dockerfile"
+echo " 3. test-storage-access.Dockerfile içeriğini yapıştır"
+echo " 4. Build loglarında storage erişim sonuçlarını kontrol et"
+
+echo ""
+echo "📋 Test sonuçlarına göre:"
+echo " ✅ Storage erişimi VARSA → Build sırasında model kopyalama"
+echo " ❌ Storage erişimi YOKSA → HuggingFace'den model indirme"
\ No newline at end of file
diff --git a/test_curl_runpod.sh b/test_curl_runpod.sh
new file mode 100755
index 000000000..dc085b6c8
--- /dev/null
+++ b/test_curl_runpod.sh
@@ -0,0 +1,155 @@
+#!/bin/bash
+# RunPod Serverless API Test with curl
+# Usage: ./test_curl_runpod.sh "your prompt here"
+
+# Configuration
+ENDPOINT_ID="sfkzjudvrj50yq"
+API_KEY="${RUNPOD_API_KEY:-YOUR_API_KEY}" # Set RUNPOD_API_KEY environment variable
+BASE_URL="https://api.runpod.ai/v2"
+
+# Check if API key is set
+if [ "$API_KEY" = "YOUR_API_KEY" ]; then
+ echo "❌ API key not set!"
+ echo "💡 Set your API key: export RUNPOD_API_KEY='your_key_here'"
+ echo " Or edit this script and replace YOUR_API_KEY with your actual key"
+ exit 1
+fi
+
+# Get prompt from command line or use default
+PROMPT="${1:-modern software interface, clean dashboard design, professional UI layout, high quality, detailed}"
+
+echo "🚀 Testing RunPod Serverless API..."
+echo "📍 Endpoint: $ENDPOINT_ID"
+echo "💬 Prompt: $PROMPT"
+
+# Create the JSON payload
+JSON_PAYLOAD=$(cat </dev/null || echo "$STATUS_RESPONSE"
+ exit 0
+ ;;
+ "FAILED")
+ echo "❌ Job failed!"
+ echo "📄 Error response:"
+ echo "$STATUS_RESPONSE" | jq '.' 2>/dev/null || echo "$STATUS_RESPONSE"
+ exit 1
+ ;;
+ "IN_QUEUE"|"IN_PROGRESS")
+ echo "⏳ Job status: $STATUS (${WAIT_TIME}s elapsed)"
+ ;;
+ *)
+ echo "❓ Unknown status: $STATUS"
+ ;;
+ esac
+
+ sleep 5
+ WAIT_TIME=$((WAIT_TIME + 5))
+done
+
+echo "⏰ Timeout after ${MAX_WAIT} seconds"
+echo "📄 Last status response:"
+echo "$STATUS_RESPONSE" | jq '.' 2>/dev/null || echo "$STATUS_RESPONSE"
\ No newline at end of file
diff --git a/test_image_generation.py b/test_image_generation.py
new file mode 100644
index 000000000..5c7ba7a57
--- /dev/null
+++ b/test_image_generation.py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python3
+"""
+ComfyUI Test Script - pars klasöründeki resimlere benzer resim üretimi
+"""
+
+import os
+import json
+import base64
+import requests
+from pathlib import Path
+import time
+
+class ComfyUITester:
+ def __init__(self, comfyui_url="http://127.0.0.1:8188"):
+ self.comfyui_url = comfyui_url
+ self.client_id = "test_client"
+
+ def check_server(self):
+ """ComfyUI server'ın çalışıp çalışmadığını kontrol et"""
+ try:
+ response = requests.get(f"{self.comfyui_url}/system_stats", timeout=5)
+ if response.status_code == 200:
+ print("✅ ComfyUI server çalışıyor")
+ return True
+ else:
+ print(f"❌ ComfyUI server yanıt vermiyor: {response.status_code}")
+ return False
+ except requests.exceptions.RequestException as e:
+ print(f"❌ ComfyUI server'a bağlanılamıyor: {e}")
+ return False
+
+ def get_models(self):
+ """Yüklü modelleri listele"""
+ try:
+ response = requests.get(f"{self.comfyui_url}/object_info")
+ if response.status_code == 200:
+ data = response.json()
+ checkpoints = data.get("CheckpointLoaderSimple", {}).get("input", {}).get("required", {}).get("ckpt_name", [])
+ if isinstance(checkpoints, list) and len(checkpoints) > 1:
+ models = checkpoints[0] # İlk element model listesi
+ print(f"✅ Yüklü modeller ({len(models)} adet):")
+ for model in models[:5]: # İlk 5 modeli göster
+ print(f" - {model}")
+ return models
+ else:
+ print("❌ Model listesi alınamadı")
+ return []
+ except Exception as e:
+ print(f"❌ Model listesi alınamadı: {e}")
+ return []
+
+ def create_basic_workflow(self, model_name="sd_xl_base_1.0.safetensors", prompt="a beautiful landscape"):
+ """Temel SDXL workflow oluştur"""
+ workflow = {
+ "3": {
+ "inputs": {
+ "seed": 42,
+ "steps": 20,
+ "cfg": 8.0,
+ "sampler_name": "euler",
+ "scheduler": "normal",
+ "denoise": 1.0,
+ "model": ["4", 0],
+ "positive": ["6", 0],
+ "negative": ["7", 0],
+ "latent_image": ["5", 0]
+ },
+ "class_type": "KSampler"
+ },
+ "4": {
+ "inputs": {
+ "ckpt_name": model_name
+ },
+ "class_type": "CheckpointLoaderSimple"
+ },
+ "5": {
+ "inputs": {
+ "width": 1024,
+ "height": 1024,
+ "batch_size": 1
+ },
+ "class_type": "EmptyLatentImage"
+ },
+ "6": {
+ "inputs": {
+ "text": prompt,
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "7": {
+ "inputs": {
+ "text": "blurry, low quality, distorted",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "8": {
+ "inputs": {
+ "samples": ["3", 0],
+ "vae": ["4", 2]
+ },
+ "class_type": "VAEDecode"
+ },
+ "9": {
+ "inputs": {
+ "filename_prefix": "test_output",
+ "images": ["8", 0]
+ },
+ "class_type": "SaveImage"
+ }
+ }
+ return workflow
+
+ def generate_image(self, prompt, model_name=None):
+ """Resim üret"""
+ try:
+ # Model seç
+ if not model_name:
+ models = self.get_models()
+ if not models:
+ print("❌ Hiç model bulunamadı")
+ return None
+ model_name = models[0] # İlk modeli kullan
+
+ print(f"🎨 Resim üretiliyor...")
+ print(f" Model: {model_name}")
+ print(f" Prompt: {prompt}")
+
+ # Workflow oluştur
+ workflow = self.create_basic_workflow(model_name, prompt)
+
+ # İsteği gönder
+ response = requests.post(
+ f"{self.comfyui_url}/prompt",
+ json={
+ "prompt": workflow,
+ "client_id": self.client_id
+ },
+ timeout=30
+ )
+ response.raise_for_status()
+
+ prompt_id = response.json()["prompt_id"]
+ print(f"📝 Prompt ID: {prompt_id}")
+
+ # Tamamlanmasını bekle
+ return self.wait_for_completion(prompt_id)
+
+ except Exception as e:
+ print(f"❌ Resim üretimi başarısız: {e}")
+ return None
+
+ def wait_for_completion(self, prompt_id, timeout=300):
+ """İşlemin tamamlanmasını bekle"""
+ start_time = time.time()
+
+ while time.time() - start_time < timeout:
+ try:
+ # Queue durumunu kontrol et
+ queue_response = requests.get(f"{self.comfyui_url}/queue")
+ queue_data = queue_response.json()
+
+ # İşlem hala çalışıyor mu?
+ running = any(item[1]["prompt_id"] == prompt_id for item in queue_data.get("queue_running", []))
+ pending = any(item[1]["prompt_id"] == prompt_id for item in queue_data.get("queue_pending", []))
+
+ if not running and not pending:
+ # İşlem tamamlandı, sonuçları al
+ history_response = requests.get(f"{self.comfyui_url}/history/{prompt_id}")
+ if history_response.status_code == 200:
+ history_data = history_response.json()
+ if prompt_id in history_data:
+ return self.download_results(history_data[prompt_id])
+
+ print(f"⏳ Bekleniyor... ({int(time.time() - start_time)}s)")
+ time.sleep(3)
+
+ except Exception as e:
+ print(f"❌ Durum kontrolü hatası: {e}")
+ time.sleep(5)
+
+ print(f"⏰ Timeout: {timeout} saniye")
+ return None
+
+ def download_results(self, history_data):
+ """Sonuçları indir"""
+ results = []
+
+ if "outputs" in history_data:
+ for node_id, node_output in history_data["outputs"].items():
+ if "images" in node_output:
+ for image_info in node_output["images"]:
+ try:
+ # Resmi indir
+ image_url = f"{self.comfyui_url}/view"
+ params = {
+ "filename": image_info["filename"],
+ "subfolder": image_info.get("subfolder", ""),
+ "type": image_info.get("type", "output")
+ }
+
+ image_response = requests.get(image_url, params=params)
+ image_response.raise_for_status()
+
+ # Test output klasörüne kaydet
+ os.makedirs("test_output", exist_ok=True)
+ output_path = f"test_output/{image_info['filename']}"
+
+ with open(output_path, "wb") as f:
+ f.write(image_response.content)
+
+ results.append({
+ "filename": image_info["filename"],
+ "path": output_path,
+ "node_id": node_id
+ })
+
+ print(f"✅ Resim kaydedildi: {output_path}")
+
+ except Exception as e:
+ print(f"❌ Resim indirme hatası: {e}")
+
+ return results
+
+def main():
+ """Ana test fonksiyonu"""
+ print("🚀 ComfyUI Test Başlatılıyor...")
+
+ tester = ComfyUITester()
+
+ # Server kontrolü
+ if not tester.check_server():
+ print("\n💡 ComfyUI'yi başlatmak için:")
+ print(" python main.py --listen 0.0.0.0 --port 8188")
+ return
+
+ # Model kontrolü
+ models = tester.get_models()
+ if not models:
+ print("\n💡 Model yüklemek için:")
+ print(" 1. models/checkpoints/ klasörüne .safetensors dosyası ekleyin")
+ print(" 2. ComfyUI'yi yeniden başlatın")
+ return
+
+ # Test prompt'ları (pars klasöründeki screenshot'lara benzer)
+ test_prompts = [
+ "a modern user interface design, clean layout, professional software interface",
+ "screenshot of a web application, dashboard design, modern UI elements",
+ "software interface mockup, clean design, professional layout",
+ "application screenshot, user interface design, modern web app",
+ "dashboard interface, clean UI design, professional software layout"
+ ]
+
+ print(f"\n🎨 {len(test_prompts)} adet test resmi üretiliyor...")
+
+ # Her prompt için resim üret
+ for i, prompt in enumerate(test_prompts, 1):
+ print(f"\n--- Test {i}/{len(test_prompts)} ---")
+ result = tester.generate_image(prompt, models[0])
+
+ if result:
+ print(f"✅ Test {i} başarılı: {len(result)} resim üretildi")
+ else:
+ print(f"❌ Test {i} başarısız")
+
+ # Kısa bekleme
+ time.sleep(2)
+
+ print("\n🎉 Test tamamlandı!")
+ print("📁 Üretilen resimler: test_output/ klasöründe")
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/test_runpod_api.py b/test_runpod_api.py
new file mode 100644
index 000000000..2919832db
--- /dev/null
+++ b/test_runpod_api.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python3
+"""
+RunPod Serverless API Test - pars klasöründeki resimlere benzer resim üretimi
+"""
+
+import os
+import json
+import base64
+import requests
+import time
+from pathlib import Path
+
+class RunPodTester:
+ def __init__(self):
+ # RunPod API bilgileri (.env.example'dan alın)
+ self.api_key = os.getenv("RUNPOD_API_KEY", "YOUR_RUNPOD_API_KEY") # .env dosyasından alın
+ self.endpoint_id = "sfkzjudvrj50yq" # Dashboard'dan aldığınız ID
+ self.base_url = "https://api.runpod.ai/v2"
+
+ def create_test_workflow(self, prompt):
+ """Test workflow'u oluştur"""
+ return {
+ "input": {
+ "workflow": {
+ "3": {
+ "inputs": {
+ "seed": 42,
+ "steps": 25,
+ "cfg": 8.0,
+ "sampler_name": "euler",
+ "scheduler": "normal",
+ "denoise": 1.0,
+ "model": ["4", 0],
+ "positive": ["6", 0],
+ "negative": ["7", 0],
+ "latent_image": ["5", 0]
+ },
+ "class_type": "KSampler"
+ },
+ "4": {
+ "inputs": {
+ "ckpt_name": "sd_xl_base_1.0.safetensors"
+ },
+ "class_type": "CheckpointLoaderSimple"
+ },
+ "5": {
+ "inputs": {
+ "width": 1024,
+ "height": 1024,
+ "batch_size": 1
+ },
+ "class_type": "EmptyLatentImage"
+ },
+ "6": {
+ "inputs": {
+ "text": prompt,
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "7": {
+ "inputs": {
+ "text": "blurry, low quality, distorted, ugly, bad anatomy, worst quality",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "8": {
+ "inputs": {
+ "samples": ["3", 0],
+ "vae": ["4", 2]
+ },
+ "class_type": "VAEDecode"
+ },
+ "9": {
+ "inputs": {
+ "filename_prefix": "runpod_test",
+ "images": ["8", 0]
+ },
+ "class_type": "SaveImage"
+ }
+ }
+ }
+ }
+
+ def submit_job(self, prompt):
+ """RunPod'a job gönder"""
+ try:
+ workflow_data = self.create_test_workflow(prompt)
+
+ headers = {
+ "Authorization": f"Bearer {self.api_key}",
+ "Content-Type": "application/json"
+ }
+
+ url = f"{self.base_url}/{self.endpoint_id}/run"
+
+ print(f"🚀 Job gönderiliyor...")
+ print(f" Endpoint: {self.endpoint_id}")
+ print(f" Prompt: {prompt[:50]}...")
+
+ response = requests.post(url, json=workflow_data, headers=headers, timeout=30)
+ response.raise_for_status()
+
+ job_data = response.json()
+ job_id = job_data.get("id")
+
+ print(f"✅ Job gönderildi: {job_id}")
+ return job_id
+
+ except Exception as e:
+ print(f"❌ Job gönderme hatası: {e}")
+ return None
+
+ def check_job_status(self, job_id):
+ """Job durumunu kontrol et"""
+ try:
+ headers = {
+ "Authorization": f"Bearer {self.api_key}",
+ "Content-Type": "application/json"
+ }
+
+ url = f"{self.base_url}/{self.endpoint_id}/status/{job_id}"
+ response = requests.get(url, headers=headers, timeout=10)
+ response.raise_for_status()
+
+ return response.json()
+
+ except Exception as e:
+ print(f"❌ Durum kontrolü hatası: {e}")
+ return None
+
+ def wait_for_completion(self, job_id, timeout=300):
+ """Job'ın tamamlanmasını bekle"""
+ start_time = time.time()
+
+ while time.time() - start_time < timeout:
+ status_data = self.check_job_status(job_id)
+
+ if not status_data:
+ time.sleep(5)
+ continue
+
+ status = status_data.get("status")
+
+ if status == "COMPLETED":
+ print("✅ Job tamamlandı!")
+ return status_data.get("output")
+ elif status == "FAILED":
+ print("❌ Job başarısız!")
+ print(f" Hata: {status_data.get('error', 'Bilinmeyen hata')}")
+ return None
+ elif status in ["IN_QUEUE", "IN_PROGRESS"]:
+ elapsed = int(time.time() - start_time)
+ print(f"⏳ Job çalışıyor... ({status}) - {elapsed}s")
+
+ time.sleep(5)
+
+ print(f"⏰ Timeout: {timeout} saniye")
+ return None
+
+ def save_results(self, output_data, test_name):
+ """Sonuçları kaydet"""
+ if not output_data:
+ return []
+
+ os.makedirs("test_output", exist_ok=True)
+ saved_files = []
+
+ outputs = output_data.get("outputs", [])
+ for i, output in enumerate(outputs):
+ if "data" in output:
+ try:
+ # Base64 decode
+ image_data = base64.b64decode(output["data"])
+
+ # Dosya adı
+ filename = f"{test_name}_{i+1:02d}.png"
+ filepath = f"test_output/{filename}"
+
+ # Kaydet
+ with open(filepath, "wb") as f:
+ f.write(image_data)
+
+ saved_files.append(filepath)
+ print(f"💾 Resim kaydedildi: {filepath}")
+
+ except Exception as e:
+ print(f"❌ Resim kaydetme hatası: {e}")
+
+ return saved_files
+
+def main():
+ """Ana test fonksiyonu"""
+ print("🚀 RunPod Serverless Test Başlatılıyor...")
+
+ tester = RunPodTester()
+
+ # API key kontrolü
+ if tester.api_key == "YOUR_RUNPOD_API_KEY":
+ print("❌ API key ayarlanmamış!")
+ print("💡 test_runpod_api.py dosyasında API key'inizi güncelleyin")
+ print(" API key'i RunPod dashboard → Settings → API Keys'den alabilirsiniz")
+ return
+
+ # pars klasöründeki screenshot'lara benzer prompt'lar
+ test_prompts = [
+ "modern software interface, clean dashboard design, professional UI layout, high quality, detailed",
+ "web application screenshot, user interface mockup, modern design system, clean layout",
+ "software dashboard, data visualization interface, professional web app design, modern UI",
+ "application interface design, clean user experience, professional software layout, modern style",
+ "digital interface mockup, clean web design, professional dashboard layout, modern UI elements"
+ ]
+
+ print(f"\n🎨 {len(test_prompts)} adet test resmi üretiliyor...")
+ print(f"📍 Endpoint: {tester.endpoint_id}")
+
+ all_results = []
+
+ # Her prompt için test
+ for i, prompt in enumerate(test_prompts, 1):
+ print(f"\n--- Test {i}/{len(test_prompts)} ---")
+
+ # Job gönder
+ job_id = tester.submit_job(prompt)
+ if not job_id:
+ continue
+
+ # Tamamlanmasını bekle
+ output = tester.wait_for_completion(job_id)
+
+ # Sonuçları kaydet
+ if output:
+ saved_files = tester.save_results(output, f"ui_design_test_{i}")
+ all_results.extend(saved_files)
+ print(f"✅ Test {i} başarılı: {len(saved_files)} resim")
+ else:
+ print(f"❌ Test {i} başarısız")
+
+ # Rate limiting için bekleme
+ if i < len(test_prompts):
+ print("⏸️ Rate limiting için 10 saniye bekleniyor...")
+ time.sleep(10)
+
+ # Özet
+ print(f"\n🎉 Test tamamlandı!")
+ print(f"📊 Toplam üretilen resim: {len(all_results)}")
+ print(f"📁 Kaydedilen dosyalar:")
+ for file in all_results:
+ print(f" - {file}")
+
+ if all_results:
+ print(f"\n💡 Resimleri görüntülemek için:")
+ print(f" open test_output/")
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/test_simple_workflow.json b/test_simple_workflow.json
new file mode 100644
index 000000000..5e981f3b3
--- /dev/null
+++ b/test_simple_workflow.json
@@ -0,0 +1,59 @@
+{
+ "3": {
+ "inputs": {
+ "seed": 42,
+ "steps": 20,
+ "cfg": 8.0,
+ "sampler_name": "euler",
+ "scheduler": "normal",
+ "denoise": 1.0,
+ "model": ["4", 0],
+ "positive": ["6", 0],
+ "negative": ["7", 0],
+ "latent_image": ["5", 0]
+ },
+ "class_type": "KSampler"
+ },
+ "4": {
+ "inputs": {
+ "ckpt_name": "sd_xl_base_1.0.safetensors"
+ },
+ "class_type": "CheckpointLoaderSimple"
+ },
+ "5": {
+ "inputs": {
+ "width": 1024,
+ "height": 1024,
+ "batch_size": 1
+ },
+ "class_type": "EmptyLatentImage"
+ },
+ "6": {
+ "inputs": {
+ "text": "a modern user interface design, clean layout, professional software interface, high quality, detailed",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "7": {
+ "inputs": {
+ "text": "blurry, low quality, distorted, ugly, bad anatomy",
+ "clip": ["4", 1]
+ },
+ "class_type": "CLIPTextEncode"
+ },
+ "8": {
+ "inputs": {
+ "samples": ["3", 0],
+ "vae": ["4", 2]
+ },
+ "class_type": "VAEDecode"
+ },
+ "9": {
+ "inputs": {
+ "filename_prefix": "test_ui_design",
+ "images": ["8", 0]
+ },
+ "class_type": "SaveImage"
+ }
+}
\ No newline at end of file