Update app.py
Browse files
app.py
CHANGED
|
@@ -25,7 +25,7 @@ KEYS = {
|
|
| 25 |
}
|
| 26 |
|
| 27 |
# ==========================================
|
| 28 |
-
# 2. API Functions
|
| 29 |
# ==========================================
|
| 30 |
|
| 31 |
def get_image_from_url(url):
|
|
@@ -33,7 +33,6 @@ def get_image_from_url(url):
|
|
| 33 |
return Image.open(BytesIO(response.content))
|
| 34 |
|
| 35 |
def generate_stability(prompt):
|
| 36 |
-
print("Trying Stability AI...")
|
| 37 |
response = requests.post(
|
| 38 |
"https://api.stability.ai/v2beta/stable-image/generate/core",
|
| 39 |
headers={"Authorization": f"Bearer {KEYS['stability']}", "Accept": "image/*"},
|
|
@@ -44,8 +43,18 @@ def generate_stability(prompt):
|
|
| 44 |
return Image.open(BytesIO(response.content)), "Stability AI"
|
| 45 |
raise Exception("Stability Error")
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
def generate_segmind(prompt):
|
| 48 |
-
print("Trying Segmind...")
|
| 49 |
response = requests.post(
|
| 50 |
"https://api.segmind.com/v1/sdxl1.0-txt2img",
|
| 51 |
headers={"x-api-key": KEYS['segmind']},
|
|
@@ -55,20 +64,18 @@ def generate_segmind(prompt):
|
|
| 55 |
return Image.open(BytesIO(response.content)), "Segmind (SDXL)"
|
| 56 |
raise Exception("Segmind Error")
|
| 57 |
|
| 58 |
-
def
|
| 59 |
-
print("Trying GetImg AI...")
|
| 60 |
response = requests.post(
|
| 61 |
-
"https://api.
|
| 62 |
-
headers={"Authorization": f"Bearer {KEYS['
|
| 63 |
-
json={"
|
| 64 |
)
|
| 65 |
if response.status_code == 200:
|
| 66 |
-
image_data = base64.b64decode(response.json()["
|
| 67 |
-
return Image.open(BytesIO(image_data)), "
|
| 68 |
-
raise Exception("
|
| 69 |
|
| 70 |
def generate_deepai(prompt):
|
| 71 |
-
print("Trying DeepAI...")
|
| 72 |
response = requests.post(
|
| 73 |
"https://api.deepai.org/api/text2img",
|
| 74 |
data={'text': prompt},
|
|
@@ -79,8 +86,17 @@ def generate_deepai(prompt):
|
|
| 79 |
return get_image_from_url(url), "DeepAI"
|
| 80 |
raise Exception("DeepAI Error")
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
def generate_edenai(prompt):
|
| 83 |
-
print("Trying Eden AI...")
|
| 84 |
response = requests.post(
|
| 85 |
"https://api.edenai.run/v2/image/generation",
|
| 86 |
headers={"Authorization": f"Bearer {KEYS['edenai']}"},
|
|
@@ -92,20 +108,7 @@ def generate_edenai(prompt):
|
|
| 92 |
return get_image_from_url(url), "Eden AI"
|
| 93 |
raise Exception("Eden AI Error")
|
| 94 |
|
| 95 |
-
def generate_fireworks(prompt):
|
| 96 |
-
print("Trying Fireworks AI...")
|
| 97 |
-
response = requests.post(
|
| 98 |
-
"https://api.fireworks.ai/inference/v1/image_generation/accounts/fireworks/models/stable-diffusion-xl-1024-v1-0",
|
| 99 |
-
headers={"Authorization": f"Bearer {KEYS['fireworks']}"},
|
| 100 |
-
json={"text_prompts": [{"text": prompt}]}
|
| 101 |
-
)
|
| 102 |
-
if response.status_code == 200:
|
| 103 |
-
image_data = base64.b64decode(response.json()[0]["base64"])
|
| 104 |
-
return Image.open(BytesIO(image_data)), "Fireworks AI"
|
| 105 |
-
raise Exception("Fireworks Error")
|
| 106 |
-
|
| 107 |
def generate_modelslab(prompt):
|
| 108 |
-
print("Trying ModelsLab...")
|
| 109 |
response = requests.post(
|
| 110 |
"https://modelslab.com/api/v6/images/text2img",
|
| 111 |
json={"key": KEYS['modelslab'], "prompt": prompt, "width": "512", "height": "512"}
|
|
@@ -115,19 +118,7 @@ def generate_modelslab(prompt):
|
|
| 115 |
return get_image_from_url(url), "ModelsLab"
|
| 116 |
raise Exception("ModelsLab Error")
|
| 117 |
|
| 118 |
-
def generate_google_imagen(prompt):
|
| 119 |
-
print("Trying Google AI (Imagen)...")
|
| 120 |
-
response = requests.post(
|
| 121 |
-
f"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict?key={KEYS['google']}",
|
| 122 |
-
json={"instances": [{"prompt": prompt}]}
|
| 123 |
-
)
|
| 124 |
-
if response.status_code == 200:
|
| 125 |
-
image_data = base64.b64decode(response.json()['predictions'][0]['bytesBase64Encoded'])
|
| 126 |
-
return Image.open(BytesIO(image_data)), "Google Imagen"
|
| 127 |
-
raise Exception("Google Imagen Error")
|
| 128 |
-
|
| 129 |
def generate_openrouter(prompt):
|
| 130 |
-
print("Trying OpenRouter (FLUX)...")
|
| 131 |
response = requests.post(
|
| 132 |
"https://openrouter.ai/api/v1/chat/completions",
|
| 133 |
headers={"Authorization": f"Bearer {KEYS['openrouter']}"},
|
|
@@ -137,16 +128,13 @@ def generate_openrouter(prompt):
|
|
| 137 |
}
|
| 138 |
)
|
| 139 |
if response.status_code == 200:
|
| 140 |
-
# Openrouter returns an image link inside the text response for Image models
|
| 141 |
content = response.json()['choices'][0]['message']['content']
|
| 142 |
-
# Extracting markdown image link or raw link
|
| 143 |
if "http" in content:
|
| 144 |
url = content.split("(")[-1].split(")")[0] if "(" in content else content.strip()
|
| 145 |
return get_image_from_url(url), "OpenRouter"
|
| 146 |
raise Exception("OpenRouter Error")
|
| 147 |
|
| 148 |
def generate_stable_horde(prompt):
|
| 149 |
-
print("Trying Stable Horde (Async)...")
|
| 150 |
response = requests.post(
|
| 151 |
"https://stablehorde.net/api/v2/generate/async",
|
| 152 |
headers={"apikey": KEYS['stablehorde']},
|
|
@@ -154,7 +142,7 @@ def generate_stable_horde(prompt):
|
|
| 154 |
)
|
| 155 |
if response.status_code == 202:
|
| 156 |
job_id = response.json()['id']
|
| 157 |
-
for _ in range(15):
|
| 158 |
time.sleep(2)
|
| 159 |
check = requests.get(f"https://stablehorde.net/api/v2/generate/status/{job_id}")
|
| 160 |
if check.status_code == 200 and check.json().get("done", False):
|
|
@@ -163,9 +151,8 @@ def generate_stable_horde(prompt):
|
|
| 163 |
raise Exception("Stable Horde Error/Timeout")
|
| 164 |
|
| 165 |
# ==========================================
|
| 166 |
-
# 3. Fallback Logic
|
| 167 |
# ==========================================
|
| 168 |
-
# প্রথমে সবচেয়ে ভালো API গুলো, তারপর লিমিট শেষ হলে নিচের দিকে যাবে
|
| 169 |
API_PIPELINE = [
|
| 170 |
generate_stability,
|
| 171 |
generate_getimg,
|
|
@@ -179,39 +166,65 @@ API_PIPELINE = [
|
|
| 179 |
generate_stable_horde
|
| 180 |
]
|
| 181 |
|
|
|
|
|
|
|
|
|
|
| 182 |
def generate_image_with_fallback(prompt):
|
| 183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
for api_func in API_PIPELINE:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
try:
|
|
|
|
| 186 |
image, source = api_func(prompt)
|
| 187 |
if image:
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
| 189 |
except Exception as e:
|
| 190 |
-
|
|
|
|
|
|
|
| 191 |
continue
|
| 192 |
|
| 193 |
-
|
|
|
|
|
|
|
| 194 |
|
| 195 |
# ==========================================
|
| 196 |
# 4. Gradio Web UI
|
| 197 |
# ==========================================
|
| 198 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
| 199 |
gr.Markdown("<h1 style='text-align: center;'>🎨 All-in-One AI Image Generator (10 APIs)</h1>")
|
| 200 |
-
gr.Markdown("<p style='text-align: center;'>একটি API এর লিমিট শেষ হলে স্বয়ংক্রিয়ভাবে অন্যটি থেকে ছবি তৈরি হবে।</p>")
|
| 201 |
|
| 202 |
with gr.Row():
|
| 203 |
with gr.Column(scale=1):
|
| 204 |
-
prompt_input = gr.Textbox(label="ইমেজের বর্ণনা লিখুন (Prompt)", placeholder="A highly detailed futuristic city
|
| 205 |
generate_btn = gr.Button("Generate Image", variant="primary")
|
| 206 |
-
|
|
|
|
|
|
|
| 207 |
|
| 208 |
with gr.Column(scale=1):
|
| 209 |
image_output = gr.Image(label="জেনারেট হওয়া ছবি", type="pil")
|
| 210 |
|
|
|
|
| 211 |
generate_btn.click(
|
| 212 |
fn=generate_image_with_fallback,
|
| 213 |
inputs=[prompt_input],
|
| 214 |
-
outputs=[image_output,
|
| 215 |
)
|
| 216 |
|
| 217 |
if __name__ == "__main__":
|
|
|
|
| 25 |
}
|
| 26 |
|
| 27 |
# ==========================================
|
| 28 |
+
# 2. API Functions
|
| 29 |
# ==========================================
|
| 30 |
|
| 31 |
def get_image_from_url(url):
|
|
|
|
| 33 |
return Image.open(BytesIO(response.content))
|
| 34 |
|
| 35 |
def generate_stability(prompt):
|
|
|
|
| 36 |
response = requests.post(
|
| 37 |
"https://api.stability.ai/v2beta/stable-image/generate/core",
|
| 38 |
headers={"Authorization": f"Bearer {KEYS['stability']}", "Accept": "image/*"},
|
|
|
|
| 43 |
return Image.open(BytesIO(response.content)), "Stability AI"
|
| 44 |
raise Exception("Stability Error")
|
| 45 |
|
| 46 |
+
def generate_getimg(prompt):
|
| 47 |
+
response = requests.post(
|
| 48 |
+
"https://api.getimg.ai/v1/essential/text-to-image",
|
| 49 |
+
headers={"Authorization": f"Bearer {KEYS['getimg']}"},
|
| 50 |
+
json={"prompt": prompt}
|
| 51 |
+
)
|
| 52 |
+
if response.status_code == 200:
|
| 53 |
+
image_data = base64.b64decode(response.json()["image"])
|
| 54 |
+
return Image.open(BytesIO(image_data)), "GetImg AI"
|
| 55 |
+
raise Exception("GetImg Error")
|
| 56 |
+
|
| 57 |
def generate_segmind(prompt):
|
|
|
|
| 58 |
response = requests.post(
|
| 59 |
"https://api.segmind.com/v1/sdxl1.0-txt2img",
|
| 60 |
headers={"x-api-key": KEYS['segmind']},
|
|
|
|
| 64 |
return Image.open(BytesIO(response.content)), "Segmind (SDXL)"
|
| 65 |
raise Exception("Segmind Error")
|
| 66 |
|
| 67 |
+
def generate_fireworks(prompt):
|
|
|
|
| 68 |
response = requests.post(
|
| 69 |
+
"https://api.fireworks.ai/inference/v1/image_generation/accounts/fireworks/models/stable-diffusion-xl-1024-v1-0",
|
| 70 |
+
headers={"Authorization": f"Bearer {KEYS['fireworks']}"},
|
| 71 |
+
json={"text_prompts": [{"text": prompt}]}
|
| 72 |
)
|
| 73 |
if response.status_code == 200:
|
| 74 |
+
image_data = base64.b64decode(response.json()[0]["base64"])
|
| 75 |
+
return Image.open(BytesIO(image_data)), "Fireworks AI"
|
| 76 |
+
raise Exception("Fireworks Error")
|
| 77 |
|
| 78 |
def generate_deepai(prompt):
|
|
|
|
| 79 |
response = requests.post(
|
| 80 |
"https://api.deepai.org/api/text2img",
|
| 81 |
data={'text': prompt},
|
|
|
|
| 86 |
return get_image_from_url(url), "DeepAI"
|
| 87 |
raise Exception("DeepAI Error")
|
| 88 |
|
| 89 |
+
def generate_google_imagen(prompt):
|
| 90 |
+
response = requests.post(
|
| 91 |
+
f"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict?key={KEYS['google']}",
|
| 92 |
+
json={"instances": [{"prompt": prompt}]}
|
| 93 |
+
)
|
| 94 |
+
if response.status_code == 200:
|
| 95 |
+
image_data = base64.b64decode(response.json()['predictions'][0]['bytesBase64Encoded'])
|
| 96 |
+
return Image.open(BytesIO(image_data)), "Google Imagen"
|
| 97 |
+
raise Exception("Google Imagen Error")
|
| 98 |
+
|
| 99 |
def generate_edenai(prompt):
|
|
|
|
| 100 |
response = requests.post(
|
| 101 |
"https://api.edenai.run/v2/image/generation",
|
| 102 |
headers={"Authorization": f"Bearer {KEYS['edenai']}"},
|
|
|
|
| 108 |
return get_image_from_url(url), "Eden AI"
|
| 109 |
raise Exception("Eden AI Error")
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
def generate_modelslab(prompt):
|
|
|
|
| 112 |
response = requests.post(
|
| 113 |
"https://modelslab.com/api/v6/images/text2img",
|
| 114 |
json={"key": KEYS['modelslab'], "prompt": prompt, "width": "512", "height": "512"}
|
|
|
|
| 118 |
return get_image_from_url(url), "ModelsLab"
|
| 119 |
raise Exception("ModelsLab Error")
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
def generate_openrouter(prompt):
|
|
|
|
| 122 |
response = requests.post(
|
| 123 |
"https://openrouter.ai/api/v1/chat/completions",
|
| 124 |
headers={"Authorization": f"Bearer {KEYS['openrouter']}"},
|
|
|
|
| 128 |
}
|
| 129 |
)
|
| 130 |
if response.status_code == 200:
|
|
|
|
| 131 |
content = response.json()['choices'][0]['message']['content']
|
|
|
|
| 132 |
if "http" in content:
|
| 133 |
url = content.split("(")[-1].split(")")[0] if "(" in content else content.strip()
|
| 134 |
return get_image_from_url(url), "OpenRouter"
|
| 135 |
raise Exception("OpenRouter Error")
|
| 136 |
|
| 137 |
def generate_stable_horde(prompt):
|
|
|
|
| 138 |
response = requests.post(
|
| 139 |
"https://stablehorde.net/api/v2/generate/async",
|
| 140 |
headers={"apikey": KEYS['stablehorde']},
|
|
|
|
| 142 |
)
|
| 143 |
if response.status_code == 202:
|
| 144 |
job_id = response.json()['id']
|
| 145 |
+
for _ in range(15):
|
| 146 |
time.sleep(2)
|
| 147 |
check = requests.get(f"https://stablehorde.net/api/v2/generate/status/{job_id}")
|
| 148 |
if check.status_code == 200 and check.json().get("done", False):
|
|
|
|
| 151 |
raise Exception("Stable Horde Error/Timeout")
|
| 152 |
|
| 153 |
# ==========================================
|
| 154 |
+
# 3. Fallback Logic with Live Status (Yield)
|
| 155 |
# ==========================================
|
|
|
|
| 156 |
API_PIPELINE = [
|
| 157 |
generate_stability,
|
| 158 |
generate_getimg,
|
|
|
|
| 166 |
generate_stable_horde
|
| 167 |
]
|
| 168 |
|
| 169 |
+
def get_clean_name(func_name):
|
| 170 |
+
return func_name.replace("generate_", "").capitalize()
|
| 171 |
+
|
| 172 |
def generate_image_with_fallback(prompt):
|
| 173 |
+
if not prompt.strip():
|
| 174 |
+
yield None, "⚠️ **দয়া করে একটি প্রম্পট লিখুন!**"
|
| 175 |
+
return
|
| 176 |
+
|
| 177 |
+
live_status = "### 📡 লাইভ কানেকশন লগ:\n\n"
|
| 178 |
+
yield None, live_status # শুরুতে স্ট্যাটাস ক্লিয়ার করবে
|
| 179 |
+
|
| 180 |
for api_func in API_PIPELINE:
|
| 181 |
+
api_name = get_clean_name(api_func.__name__)
|
| 182 |
+
|
| 183 |
+
# ১. কানেক্ট করার চেষ্টা করছে (UI তে দেখাবে)
|
| 184 |
+
current_status = live_status + f"⏳ **{api_name}**-এর সাথে কানেক্ট করা হচ্ছে...\n"
|
| 185 |
+
yield None, current_status
|
| 186 |
+
|
| 187 |
try:
|
| 188 |
+
# ২. API কল
|
| 189 |
image, source = api_func(prompt)
|
| 190 |
if image:
|
| 191 |
+
# ৩. সফল হলে
|
| 192 |
+
final_status = live_status + f"✅ **সফল!** {source} থেকে ছবি জেনারেট হয়েছে।\n"
|
| 193 |
+
yield image, final_status
|
| 194 |
+
return # এখানেই থেমে যাবে
|
| 195 |
except Exception as e:
|
| 196 |
+
# ৪. ফেইল করলে বা লিমিট শেষ হলে
|
| 197 |
+
live_status += f"❌ **{api_name}:** লিমিট শেষ বা সার্ভার ডাউন।\n"
|
| 198 |
+
yield None, live_status # ফেইল মেসেজ আপডেট করে পরের লুপে যাবে
|
| 199 |
continue
|
| 200 |
|
| 201 |
+
# ৫. সবগুলো ফেইল করলে
|
| 202 |
+
live_status += "\n🚫 **দুঃখিত! সবগুলো API-এর লিমিট শেষ বা কাজ করছে না।**"
|
| 203 |
+
yield None, live_status
|
| 204 |
|
| 205 |
# ==========================================
|
| 206 |
# 4. Gradio Web UI
|
| 207 |
# ==========================================
|
| 208 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
| 209 |
gr.Markdown("<h1 style='text-align: center;'>🎨 All-in-One AI Image Generator (10 APIs)</h1>")
|
| 210 |
+
gr.Markdown("<p style='text-align: center;'>একটি API এর লিমিট শেষ হলে স্বয়ংক্রিয়ভাবে অন্যটি থেকে ছবি তৈরি হবে এবং ���পনি লাইভ কানেকশন দেখতে পাবেন।</p>")
|
| 211 |
|
| 212 |
with gr.Row():
|
| 213 |
with gr.Column(scale=1):
|
| 214 |
+
prompt_input = gr.Textbox(label="ইমেজের বর্ণনা লিখুন (Prompt)", placeholder="A highly detailed futuristic city...", lines=3)
|
| 215 |
generate_btn = gr.Button("Generate Image", variant="primary")
|
| 216 |
+
|
| 217 |
+
# লাইভ স্ট্যাটাস দেখানোর বক্স
|
| 218 |
+
status_box = gr.Markdown("স্ট্যাটাস: এখানে কানেকশন লগ দেখাবে...")
|
| 219 |
|
| 220 |
with gr.Column(scale=1):
|
| 221 |
image_output = gr.Image(label="জেনারেট হওয়া ছবি", type="pil")
|
| 222 |
|
| 223 |
+
# বাটনে ক্লিক করলে লাইভ আপডেট (yield) শুরু হবে
|
| 224 |
generate_btn.click(
|
| 225 |
fn=generate_image_with_fallback,
|
| 226 |
inputs=[prompt_input],
|
| 227 |
+
outputs=[image_output, status_box]
|
| 228 |
)
|
| 229 |
|
| 230 |
if __name__ == "__main__":
|