t2i / app.py
Dws321's picture
Update app.py
340a989 verified
import os
import gradio as gr
from huggingface_hub import InferenceClient
import itertools
import threading
import time
import json
import datetime
# ==========================================
# 1. HARD-CODED CONFIGURATION & PRESETS
# ==========================================
SECRET_API_KEY = os.getenv("APP_PASSWORD")
raw_tokens = [os.getenv(f"HF_TOKEN_{i}") for i in range(1, 11)]
raw_tokens.append(os.getenv("HF_TOKEN"))
valid_tokens = [t for t in raw_tokens if t is not None and t.strip() != ""]
clients = [InferenceClient("stabilityai/stable-diffusion-xl-base-1.0", token=t) for t in valid_tokens]
if not clients:
print("⚠️ WARNING: Space Settings में कोई HF_TOKEN नहीं मिला! ऐप काम नहीं करेगा।")
client_pool = itertools.cycle(clients) if clients else None
lock = threading.Lock()
# ✨✨✨ LOCKED PRESETS (हार्ड-कोडेड) ✨✨✨
LOCKED_SEED = 83492751
STYLE_SUFFIX = ", a masterfully detailed oil painting, rich expressionist brushwork, visible oil textures, rich colors, cinematic lighting, masterpiece, 8k resolution, in the style of Rembrandt and Van Gogh"
DEFAULT_NEGATIVE_PROMPT = "blurry, text, watermark, bad anatomy, deformed, amateur, low quality, photorealistic, photography"
# ==========================================
# 2. CORE LOGIC (RATIO + STYLE LOCK + FAILOVER)
# ==========================================
def generate_image(prompt, user_negative_prompt, ratio, api_key):
if api_key != SECRET_API_KEY:
raise gr.Error("❌ Access Denied: Invalid API Password!")
if not client_pool:
raise gr.Error("❌ Server Error: API Tokens missing.")
if ratio == "YouTube Video (16:9)":
w, h = 1024, 576
else:
w, h = 576, 1024
# प्रॉम्प्ट को हार्ड-कोडेड स्टाइल के साथ बदलना
cleaned_prompt = prompt.strip()
if not cleaned_prompt:
raise gr.Error("❌ Empty Prompt!")
final_prompt = f"{cleaned_prompt}{STYLE_SUFFIX}"
if user_negative_prompt.strip():
final_negative_prompt = f"{DEFAULT_NEGATIVE_PROMPT}, {user_negative_prompt.strip()}"
else:
final_negative_prompt = DEFAULT_NEGATIVE_PROMPT
attempts = len(clients)
last_error = ""
start_time = time.time()
for attempt in range(attempts):
with lock:
current_client = next(client_pool)
try:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] 🚀 Attempt {attempt + 1}/{attempts} - Generating image...")
image = current_client.text_to_image(
final_prompt,
negative_prompt=final_negative_prompt,
width=w,
height=h,
seed=LOCKED_SEED, # सीड लॉक है!
guidance_scale=7.5,
num_inference_steps=40
)
duration = round(time.time() - start_time, 2)
log_data = {
"timestamp": timestamp,
"status": "Success",
"ratio": ratio,
"duration": duration,
"token_index": valid_tokens.index(current_client.token),
"prompt_snippet": cleaned_prompt[:30] + "..."
}
return image, log_data
except Exception as e:
last_error = str(e)
print(f"⚠️ Token failed. Switching... Error: {last_error[:50]}")
continue
raise gr.Error(f"⚠️ All tokens exhausted. Please try again later. Details: {last_error}")
# ==========================================
# 3. STUDIO UI & FULL API DOCUMENTATION
# ==========================================
with gr.Blocks(theme=gr.themes.Soft(primary_hue="amber"), title="Sparkling Gyan API Pro v3") as app:
gr.Markdown("""
<div style="text-align: center; margin-bottom: 25px; border-bottom: 2px solid #ffca28; padding-bottom: 15px;">
<h1 style="color: #ffca28; font-size: 2.5rem; margin-bottom: 5px;">✨ Sparkling Gyan Image Studio Pro v3 ✨</h1>
<p style="font-size: 1.1rem; color: #aaa;">Pro-Grade AI Generator with LOCKED Distributed Token Engine & MASTER Oil Painting Style</p>
</div>
""")
with gr.Tabs():
# -------- TAB 1: STUDIO APP --------
with gr.TabItem("🎨 Studio App"):
with gr.Row():
with gr.Column(scale=2):
auth_key = gr.Textbox(label="🔑 API Password (Coded in secrets)", type="password", placeholder="अपना सीक्रेट पासवर्ड डालें...")
prompt_in = gr.Textbox(label="📝 Scene Prompt", lines=4, placeholder="Describe your cosmic/mythological scene here...")
neg_prompt_in = gr.Textbox(label="🚫 Negative Prompt (Optional)", value="photorealistic, 3d, realistic")
ratio_choice = gr.Radio(
choices=["YouTube Video (16:9)", "YouTube Shorts (9:16)"],
label="📐 Select Video Format / Ratio",
value="YouTube Video (16:9)"
)
gen_btn = gr.Button("🚀 Generate AI Image (with Locked Presets)", variant="primary")
with gr.Column(scale=1):
# यहाँ f-string इस्तेमाल किया है क्योंकि यहाँ कोई JS का कोड नहीं है
gr.Markdown(f"""
<div style="background-color: #1a1a1a; padding: 15px; border-radius: 10px; border: 1px solid #333; margin-bottom: 15px;">
<h4 style="color: #ffca28; margin-top: 0; text-align: center;">🛡️ Locked Studio Presets 🛡️</h4>
<p style="margin: 5px 0;"><b>Style:</b> Masterful Oil Painting (Rembrandt/Van Gogh Style)</p>
<p style="margin: 5px 0;"><b>Seed:</b> <code style="color: #4caf50;">{LOCKED_SEED}</code> (Always Locked)</p>
<p style="margin: 5px 0;"><b>Quality:</b> Masterpiece, 8k Resolution</p>
</div>
""")
image_out = gr.Image(label="Generated Output (Auto-Ratio)")
gen_btn.click(
fn=generate_image,
inputs=[prompt_in, neg_prompt_in, ratio_choice, auth_key],
outputs=[image_out, gr.State()],
api_name="predict"
)
# -------- TAB 2: SERVER LOGS --------
with gr.TabItem("📋 Server Logs"):
gr.Markdown("""
### 📋 Server Generation Logs
यहाँ आपको जनरेट की गई इमेजेज की हिस्ट्री दिखेगी। यह जानकारी बैकएंड से आती है।
""")
logs_output = gr.JSON(label="Last Generation Log")
gen_btn.click(fn=lambda x, y: y, inputs=[image_out, gr.State()], outputs=logs_output, queue=False)
# -------- TAB 3: API DOCUMENTATION --------
with gr.TabItem("📚 API Documentation"):
# यहाँ मैंने f-string हटा दिया है ताकि JS के ब्रैकेट्स एरर न दें!
gr.Markdown("""
### 🛠️ Developer API v3 Guide
Hugging Face (Gradio 4) डायरेक्ट POST रिक्वेस्ट को ब्लॉक करता है। इसलिए API कॉल करने के लिए आधिकारिक **Gradio Client** का ही इस्तेमाल करें।
**Space ID:** `Dws321/t2i`
<div style="background-color: #1a1a1a; padding: 10px; border-radius: 5px; border: 1px solid #333;">
<b>🚀 Locked Presets:</b> API बैकएंड में तेल चित्रकला (Oil Painting) स्टाइल और सीड `""" + str(LOCKED_SEED) + """` को अपने आप जोड़ती है। आपको इन्हें प्रॉम्प्ट में डालने की ज़रूरत नहीं है।
</div>
**API Parameters (Data Array Order):**
1. `prompt` (String) - Describe your scene. Style will be auto-added.
2. `negative_prompt` (String) - Things to avoid.
3. `ratio` (String: "YouTube Video (16:9)" या "YouTube Shorts (9:16)")
4. `api_key` (String: आपका सीक्रेट `APP_PASSWORD`)
---
#### 1. Python Example (Using `gradio_client`)
सबसे पहले इनस्टॉल करें: `pip install gradio_client`
```python
from gradio_client import Client
# अपने HF Space का लिंक यहाँ डालें
client = Client("Dws321/t2i")
try:
result = client.predict(
prompt="A cosmic black hole swallowing a planet",
negative_prompt="photorealistic, 3d, realistic",
ratio="YouTube Shorts (9:16)",
api_key="आपका_सीक्रेट_पासवर्ड",
api_name="/predict"
)
print("✅ इमेज सफलतापूर्वक डाउनलोड हो गई:", result)
except Exception as e:
print("❌ एरर:", e)
```
---
#### 2. JavaScript / HTML Example (Gradio JS Client)
Gradio 4 के लिए आपको NPM या CDN से `@gradio/client` इम्पोर्ट करना होगा। रॉ (raw) `fetch` इस्तेमाल न करें।
```html
<script type="module">
import { client } from "[https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js](https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js)";
async function generateMyImage() {
try {
const app = await client("Dws321/t2i");
const result = await app.predict("/predict", [
"Lord Shiva meditating, in cosmic space",
"photorealistic, 3d",
"YouTube Video (16:9)",
"YOUR_SECRET_PASSWORD"
]);
console.log("✅ Success! Image Link:", result.data[0].url);
document.getElementById('output').src = result.data[0].url;
} catch (error) {
console.error("❌ Error:", error);
}
}
generateMyImage();
</script>
<img id="output" src="">
```
""")
# ==========================================
# 4. APP LAUNCH & QUEUE SYSTEM
# ==========================================
app.queue(default_concurrency_limit=1).launch()