File size: 11,695 Bytes
32916ad
a139729
f70b882
0cb45c2
 
815023a
 
 
a139729
0cb45c2
815023a
0cb45c2
 
815023a
0cb45c2
da73168
0cb45c2
815023a
340a989
815023a
 
 
 
0cb45c2
 
 
815023a
 
 
 
 
0cb45c2
815023a
0cb45c2
815023a
0cb45c2
 
 
 
3c4d821
 
 
c8061ec
af92437
c8061ec
815023a
da73168
815023a
 
 
 
 
 
 
 
 
0cb45c2
 
 
815023a
0cb45c2
 
 
 
815023a
0cb45c2
815023a
c8061ec
815023a
0cb45c2
815023a
 
3c4d821
815023a
da73168
815023a
 
0cb45c2
815023a
 
 
 
 
 
 
da73168
815023a
 
 
 
 
0cb45c2
 
c8061ec
 
0cb45c2
da73168
 
0cb45c2
 
af92437
0cb45c2
815023a
0cb45c2
c8061ec
815023a
 
 
0cb45c2
 
 
 
815023a
da73168
0cb45c2
 
815023a
 
 
 
 
3c4d821
 
815023a
3c4d821
 
815023a
 
0cb45c2
815023a
da73168
 
815023a
 
 
da73168
815023a
 
da73168
815023a
0cb45c2
815023a
 
 
c8061ec
815023a
 
0cb45c2
da73168
815023a
0cb45c2
815023a
 
 
 
 
 
da73168
815023a
da73168
c8061ec
815023a
c8061ec
815023a
da73168
0cb45c2
815023a
da73168
815023a
af92437
815023a
 
 
3c4d821
af92437
0cb45c2
af92437
 
 
 
3c4d821
 
 
da73168
af92437
 
 
 
da73168
 
 
 
af92437
 
815023a
af92437
815023a
af92437
 
 
 
815023a
 
af92437
815023a
 
 
 
 
 
 
 
da73168
 
 
 
815023a
 
 
 
 
 
 
 
 
 
 
 
0cb45c2
da73168
0cb45c2
da73168
 
 
0cb45c2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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()