Update app.py
Browse files
app.py
CHANGED
|
@@ -5,10 +5,10 @@ import time
|
|
| 5 |
import base64
|
| 6 |
from io import BytesIO
|
| 7 |
from PIL import Image
|
| 8 |
-
from gradio_client import Client
|
| 9 |
|
| 10 |
# ==========================================
|
| 11 |
-
# 1. API Keys
|
| 12 |
# ==========================================
|
| 13 |
KEYS = {
|
| 14 |
"deepai": "16e69995-00d4-4ffd-993c-a026632f6de6",
|
|
@@ -26,7 +26,7 @@ KEYS = {
|
|
| 26 |
}
|
| 27 |
|
| 28 |
# ==========================================
|
| 29 |
-
# 2. API Functions
|
| 30 |
# ==========================================
|
| 31 |
def get_image_from_url(url):
|
| 32 |
response = requests.get(url)
|
|
@@ -127,62 +127,50 @@ def generate_stable_horde(prompt, w, h, ar):
|
|
| 127 |
return get_image_from_url(check.json()['generations'][0]['img'])
|
| 128 |
raise Exception("Error")
|
| 129 |
|
| 130 |
-
#
|
| 131 |
-
# 3. Hugging Face Public Spaces (নতুন হাইব্রিড সংযোজন)
|
| 132 |
-
# ==========================================
|
| 133 |
def generate_hf_flux(prompt, w, h, ar):
|
| 134 |
-
# Black Forest Labs এর অফিশিয়াল FLUX মডেল
|
| 135 |
client = Client("black-forest-labs/FLUX.1-schnell")
|
| 136 |
result = client.predict(prompt=prompt, seed=0, randomize_seed=True, width=1024, height=1024, num_inference_steps=4, api_name="/infer")
|
| 137 |
return Image.open(result[0])
|
| 138 |
|
| 139 |
def generate_hf_sdxl_lightning(prompt, w, h, ar):
|
| 140 |
-
# ByteDance এর সুপার ফাস্ট SDXL Lightning মডেল
|
| 141 |
client = Client("ByteDance/SDXL-Lightning")
|
| 142 |
result = client.predict(prompt, "4-Step", api_name="/generate_image")
|
| 143 |
return Image.open(result)
|
| 144 |
|
| 145 |
def generate_hf_sd3(prompt, w, h, ar):
|
| 146 |
-
# Stability AI এর Stable Diffusion 3.5 Large
|
| 147 |
client = Client("stabilityai/stable-diffusion-3.5-large")
|
| 148 |
result = client.predict(prompt=prompt, negative_prompt="", seed=0, randomize_seed=True, width=1024, height=1024, guidance_scale=4.5, num_inference_steps=40, api_name="/infer")
|
| 149 |
return Image.open(result[0])
|
| 150 |
|
| 151 |
-
|
| 152 |
# ==========================================
|
| 153 |
-
#
|
| 154 |
# ==========================================
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
]
|
| 171 |
-
|
| 172 |
-
def render_dashboard(statuses):
|
| 173 |
-
html_content = "<div style='display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; background-color: #1e1e1e; padding: 15px; border-radius: 10px; border: 1px solid #333; margin-bottom: 20px;'>"
|
| 174 |
-
for name, status in statuses.items():
|
| 175 |
-
# HF স্পেসগুলোকে একটু আলাদা রঙে দেখানোর জন্য
|
| 176 |
-
color = "#00d2ff" if "HF Space" in name else "white"
|
| 177 |
-
html_content += f"<span style='font-size: 15px; font-weight: bold; color: {color};'>{status} {name}</span>"
|
| 178 |
-
html_content += "</div>"
|
| 179 |
-
return html_content
|
| 180 |
|
| 181 |
-
|
|
|
|
|
|
|
|
|
|
| 182 |
if not prompt.strip():
|
| 183 |
-
yield None, "⚠️ **দয়া করে একটি প্রম্পট লিখুন!**"
|
| 184 |
return
|
| 185 |
|
|
|
|
| 186 |
if size == "ল্যান্ডস্কেপ (16:9) - YouTube":
|
| 187 |
w, h, ar = 1024, 576, "16:9"
|
| 188 |
elif size == "পোর্ট্রেট (9:16) - TikTok":
|
|
@@ -190,53 +178,56 @@ def generate_image_with_fallback(prompt, style, size, current_statuses):
|
|
| 190 |
else:
|
| 191 |
w, h, ar = 1024, 1024, "1:1"
|
| 192 |
|
|
|
|
| 193 |
style_modifiers = {
|
| 194 |
"ফটোরিয়ালিস্টিক (Photorealistic)": ", ultra realistic, highly detailed, photorealistic, 8k resolution, raw photo, masterpiece, soft cinematic lighting",
|
| 195 |
"এনিমে (Anime)": ", high quality anime style, studio ghibli, masterpiece, vibrant colors, detailed shading",
|
| 196 |
"থ্রিডি আর্ট (3D)": ", 3d render, unreal engine 5, octane render, beautiful 3d masterpiece",
|
| 197 |
"ডিফল্ট (Default)": ""
|
| 198 |
}
|
| 199 |
-
|
| 200 |
enhanced_prompt = f"{prompt.strip()}{style_modifiers.get(style, '')}, aspect ratio {ar}"
|
| 201 |
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
yield None, f"⏳ **{
|
| 210 |
-
|
| 211 |
try:
|
| 212 |
image = api_func(enhanced_prompt, w, h, ar)
|
| 213 |
if image:
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
except Exception as e:
|
| 218 |
-
|
| 219 |
-
yield None, f"❌ **{api_name}** ফেইল করেছে। পরেরটিতে যাচ্ছে...", render_dashboard(current_statuses), current_statuses
|
| 220 |
-
continue
|
| 221 |
-
|
| 222 |
-
yield None, "🚫 **দুঃখিত! সবগুলো সার্ভার বর্তমানে ব্যস্ত বা লিমিট শেষ।**", render_dashboard(current_statuses), current_statuses
|
| 223 |
|
| 224 |
# ==========================================
|
| 225 |
# 5. Gradio Web UI
|
| 226 |
# ==========================================
|
| 227 |
-
|
|
|
|
| 228 |
|
| 229 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
| 230 |
-
gr.Markdown("<h1 style='text-align: center;'>🎨 Pro AI Image Generator
|
| 231 |
-
|
| 232 |
-
status_board = gr.HTML(render_dashboard(initial_statuses))
|
| 233 |
-
status_state = gr.State(initial_statuses)
|
| 234 |
-
|
| 235 |
-
gr.Markdown("<p style='text-align: center; font-size: 14px;'>⚪ অপেক্ষমান | 🟡 কানেক্টিং | 🟢 কানেক্টেড (সফল) | 🔴 ফেইল/লিমিট শেষ<br><span style='color: #00d2ff;'>নীল রঙের না��গুলো হলো পাবলিক আনলিমিটেড সার্ভার</span></p>")
|
| 236 |
|
| 237 |
with gr.Row():
|
| 238 |
with gr.Column(scale=1):
|
| 239 |
-
prompt_input = gr.Textbox(label="ইমেজের বর্ণনা লিখুন (Prompt)", placeholder="
|
| 240 |
|
| 241 |
with gr.Row():
|
| 242 |
style_input = gr.Dropdown(
|
|
@@ -247,10 +238,18 @@ with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
| 247 |
|
| 248 |
size_input = gr.Dropdown(
|
| 249 |
choices=["স্কয়ার (1:1) - Instagram", "ল্যান্ডস্কেপ (16:9) - YouTube", "পোর্ট্রেট (9:16) - TikTok"],
|
| 250 |
-
label="ছবির সাইজ (
|
| 251 |
value="স্কয়ার (1:1) - Instagram"
|
| 252 |
)
|
| 253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
generate_btn = gr.Button("Generate Image", variant="primary")
|
| 255 |
log_box = gr.Markdown("স্ট্যাটাস: অপেক্ষমান...")
|
| 256 |
|
|
@@ -258,9 +257,9 @@ with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
| 258 |
image_output = gr.Image(label="জেনারেট হওয়া ছবি", type="pil")
|
| 259 |
|
| 260 |
generate_btn.click(
|
| 261 |
-
fn=
|
| 262 |
-
inputs=[prompt_input, style_input, size_input,
|
| 263 |
-
outputs=[image_output, log_box
|
| 264 |
)
|
| 265 |
|
| 266 |
if __name__ == "__main__":
|
|
|
|
| 5 |
import base64
|
| 6 |
from io import BytesIO
|
| 7 |
from PIL import Image
|
| 8 |
+
from gradio_client import Client
|
| 9 |
|
| 10 |
# ==========================================
|
| 11 |
+
# 1. API Keys
|
| 12 |
# ==========================================
|
| 13 |
KEYS = {
|
| 14 |
"deepai": "16e69995-00d4-4ffd-993c-a026632f6de6",
|
|
|
|
| 26 |
}
|
| 27 |
|
| 28 |
# ==========================================
|
| 29 |
+
# 2. API Functions
|
| 30 |
# ==========================================
|
| 31 |
def get_image_from_url(url):
|
| 32 |
response = requests.get(url)
|
|
|
|
| 127 |
return get_image_from_url(check.json()['generations'][0]['img'])
|
| 128 |
raise Exception("Error")
|
| 129 |
|
| 130 |
+
# HF Public Spaces
|
|
|
|
|
|
|
| 131 |
def generate_hf_flux(prompt, w, h, ar):
|
|
|
|
| 132 |
client = Client("black-forest-labs/FLUX.1-schnell")
|
| 133 |
result = client.predict(prompt=prompt, seed=0, randomize_seed=True, width=1024, height=1024, num_inference_steps=4, api_name="/infer")
|
| 134 |
return Image.open(result[0])
|
| 135 |
|
| 136 |
def generate_hf_sdxl_lightning(prompt, w, h, ar):
|
|
|
|
| 137 |
client = Client("ByteDance/SDXL-Lightning")
|
| 138 |
result = client.predict(prompt, "4-Step", api_name="/generate_image")
|
| 139 |
return Image.open(result)
|
| 140 |
|
| 141 |
def generate_hf_sd3(prompt, w, h, ar):
|
|
|
|
| 142 |
client = Client("stabilityai/stable-diffusion-3.5-large")
|
| 143 |
result = client.predict(prompt=prompt, negative_prompt="", seed=0, randomize_seed=True, width=1024, height=1024, guidance_scale=4.5, num_inference_steps=40, api_name="/infer")
|
| 144 |
return Image.open(result[0])
|
| 145 |
|
|
|
|
| 146 |
# ==========================================
|
| 147 |
+
# 3. Pipeline Dictionary
|
| 148 |
# ==========================================
|
| 149 |
+
API_PIPELINE = {
|
| 150 |
+
"Stability AI": generate_stability,
|
| 151 |
+
"GetImg AI": generate_getimg,
|
| 152 |
+
"Segmind": generate_segmind,
|
| 153 |
+
"Fireworks": generate_fireworks,
|
| 154 |
+
"DeepAI": generate_deepai,
|
| 155 |
+
"Google Imagen": generate_google_imagen,
|
| 156 |
+
"Eden AI": generate_edenai,
|
| 157 |
+
"ModelsLab": generate_modelslab,
|
| 158 |
+
"OpenRouter": generate_openrouter,
|
| 159 |
+
"Stable Horde": generate_stable_horde,
|
| 160 |
+
"HF Space: FLUX.1 (Public)": generate_hf_flux,
|
| 161 |
+
"HF Space: SDXL Light (Public)": generate_hf_sdxl_lightning,
|
| 162 |
+
"HF Space: SD3.5 (Public)": generate_hf_sd3
|
| 163 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
+
# ==========================================
|
| 166 |
+
# 4. Generation Logic (Auto + Manual)
|
| 167 |
+
# ==========================================
|
| 168 |
+
def generate_image_logic(prompt, style, size, selected_api):
|
| 169 |
if not prompt.strip():
|
| 170 |
+
yield None, "⚠️ **দয়া করে একটি প্রম্পট লিখুন!**"
|
| 171 |
return
|
| 172 |
|
| 173 |
+
# সাইজ সেটআপ
|
| 174 |
if size == "ল্যান্ডস্কেপ (16:9) - YouTube":
|
| 175 |
w, h, ar = 1024, 576, "16:9"
|
| 176 |
elif size == "পোর্ট্রেট (9:16) - TikTok":
|
|
|
|
| 178 |
else:
|
| 179 |
w, h, ar = 1024, 1024, "1:1"
|
| 180 |
|
| 181 |
+
# স্টাইল সেটআপ
|
| 182 |
style_modifiers = {
|
| 183 |
"ফটোরিয়ালিস্টিক (Photorealistic)": ", ultra realistic, highly detailed, photorealistic, 8k resolution, raw photo, masterpiece, soft cinematic lighting",
|
| 184 |
"এনিমে (Anime)": ", high quality anime style, studio ghibli, masterpiece, vibrant colors, detailed shading",
|
| 185 |
"থ্রিডি আর্ট (3D)": ", 3d render, unreal engine 5, octane render, beautiful 3d masterpiece",
|
| 186 |
"ডিফল্ট (Default)": ""
|
| 187 |
}
|
|
|
|
| 188 |
enhanced_prompt = f"{prompt.strip()}{style_modifiers.get(style, '')}, aspect ratio {ar}"
|
| 189 |
|
| 190 |
+
# লজিক ১: যদি অটোমেটিক সিলেক্ট করা থাকে
|
| 191 |
+
if selected_api == "অটোমেটিক (Auto Fallback)":
|
| 192 |
+
yield None, "⏳ শুরু হচ্ছে..."
|
| 193 |
+
for api_name, api_func in API_PIPELINE.items():
|
| 194 |
+
yield None, f"⏳ **{api_name}**-এর সাথে কানেক্ট করা হচ্ছে..."
|
| 195 |
+
try:
|
| 196 |
+
image = api_func(enhanced_prompt, w, h, ar)
|
| 197 |
+
if image:
|
| 198 |
+
yield image, f"✅ **সফল!** {api_name} থেকে অটোমেটিকভাবে ছবি তৈরি হয়েছে।"
|
| 199 |
+
return
|
| 200 |
+
except Exception as e:
|
| 201 |
+
yield None, f"❌ **{api_name}** ফেইল করেছে। অটোমেটিক পরেরটিতে যাচ্ছে..."
|
| 202 |
+
continue
|
| 203 |
+
yield None, "🚫 **দুঃখিত! সবগুলো সার্ভার ব্যস্ত বা লিমিট শেষ।**"
|
| 204 |
|
| 205 |
+
# লজিক ২: যদি ম্যানুয়ালি নির্দিষ্ট কোনো API সিলেক্ট করা থাকে
|
| 206 |
+
else:
|
| 207 |
+
yield None, f"⏳ শুধুমাত্র **{selected_api}**-এর সাথে কানেক্ট করা হচ্ছে..."
|
| 208 |
+
api_func = API_PIPELINE[selected_api]
|
| 209 |
try:
|
| 210 |
image = api_func(enhanced_prompt, w, h, ar)
|
| 211 |
if image:
|
| 212 |
+
yield image, f"✅ **সফল!** আপনি ম্যানুয়ালি {selected_api} থেকে ছবি বানিয়েছেন।"
|
| 213 |
+
else:
|
| 214 |
+
yield None, f"❌ **দুঃখিত!** {selected_api} এর লিমিট শেষ বা সার্ভার ডাউন।"
|
| 215 |
except Exception as e:
|
| 216 |
+
yield None, f"❌ **দুঃখিত!** {selected_api} এর লিমিট শেষ বা সার্ভার ডাউন। অন্য একটি সিলেক্ট করুন।"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
|
| 218 |
# ==========================================
|
| 219 |
# 5. Gradio Web UI
|
| 220 |
# ==========================================
|
| 221 |
+
# অপশন লিস্ট তৈরি করা হচ্ছে
|
| 222 |
+
api_choices = ["অটোমেটিক (Auto Fallback)"] + list(API_PIPELINE.keys())
|
| 223 |
|
| 224 |
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
| 225 |
+
gr.Markdown("<h1 style='text-align: center;'>🎨 Pro AI Image Generator</h1>")
|
| 226 |
+
gr.Markdown("<p style='text-align: center;'>অটোমেটিক মোড ব্যবহার করুন অথবা পছন্দের সার্ভার থেকে ম্যানুয়ালি ছবি জেনারেট করুন।</p>")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
|
| 228 |
with gr.Row():
|
| 229 |
with gr.Column(scale=1):
|
| 230 |
+
prompt_input = gr.Textbox(label="ইমেজের বর্ণনা লিখুন (Prompt)", placeholder="A highly detailed futuristic city...", lines=3)
|
| 231 |
|
| 232 |
with gr.Row():
|
| 233 |
style_input = gr.Dropdown(
|
|
|
|
| 238 |
|
| 239 |
size_input = gr.Dropdown(
|
| 240 |
choices=["স্কয়ার (1:1) - Instagram", "ল্যান্ডস্কেপ (16:9) - YouTube", "পোর্ট্রেট (9:16) - TikTok"],
|
| 241 |
+
label="ছবির সাইজ (Size)",
|
| 242 |
value="স্কয়ার (1:1) - Instagram"
|
| 243 |
)
|
| 244 |
|
| 245 |
+
# নতুন সার্ভার সিলেকশন মেনু
|
| 246 |
+
api_selector = gr.Dropdown(
|
| 247 |
+
choices=api_choices,
|
| 248 |
+
label="সার্ভার / API সিলেক্ট করুন",
|
| 249 |
+
value="অটোমেটিক (Auto Fallback)",
|
| 250 |
+
interactive=True
|
| 251 |
+
)
|
| 252 |
+
|
| 253 |
generate_btn = gr.Button("Generate Image", variant="primary")
|
| 254 |
log_box = gr.Markdown("স্ট্যাটাস: অপেক্ষমান...")
|
| 255 |
|
|
|
|
| 257 |
image_output = gr.Image(label="জেনারেট হওয়া ছবি", type="pil")
|
| 258 |
|
| 259 |
generate_btn.click(
|
| 260 |
+
fn=generate_image_logic,
|
| 261 |
+
inputs=[prompt_input, style_input, size_input, api_selector],
|
| 262 |
+
outputs=[image_output, log_box]
|
| 263 |
)
|
| 264 |
|
| 265 |
if __name__ == "__main__":
|