Akhmad123 commited on
Commit
7c960db
·
verified ·
1 Parent(s): 8a1c757

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -232
app.py CHANGED
@@ -1,250 +1,63 @@
1
- import gradio as gr
2
- import requests
3
- import base64
4
- import uuid
5
- import os
6
- import json
7
- import time
8
- from groq import Groq
9
- from fpdf import FPDF, XPos, YPos
10
-
11
  # ============================
12
- # CONFIG (AMAN)
13
  # ============================
14
- HF_API_KEY = os.getenv("HF_API_KEY")
15
- GROQ_API_KEY = os.getenv("GROQ_API_KEY")
16
-
17
- HEADERS = {
18
- "Authorization": f"Bearer {HF_API_KEY}",
19
- "Content-Type": "application/json"
20
- }
21
-
22
- client = Groq(api_key=GROQ_API_KEY)
23
 
24
- # ============================
25
- # MODEL ENDPOINTS (FREE)
26
- # ============================
27
- MODEL_ENDPOINTS = {
28
- "SD Turbo": "stabilityai/sd-turbo",
29
- "Playground v2.5": "playgroundai/playground-v2.5-1024px-aesthetic",
30
- "SDXL": "stabilityai/stable-diffusion-xl-base-1.0",
31
- "PixArt-XL": "PixArt-alpha/PixArt-XL-2-1024-MS"
32
- }
33
 
34
- # ============================
35
- # ENGINE GAMBAR v3.2 (ULTRA STABLE)
36
- # ============================
37
- def hf_generate_image_ultra(prompt, log_callback):
38
-
39
- fallback_rounds = [
40
- ["SD Turbo", "Playground v2.5", "SDXL", "PixArt-XL"],
41
- ["Playground v2.5", "SDXL", "PixArt-XL", "SD Turbo"],
42
- ["SDXL", "PixArt-XL", "Playground v2.5", "SD Turbo"]
43
- ]
44
-
45
- delays = [30, 60, 120, 180, 300, 600]
46
-
47
- attempt = 1
48
- total_attempts = 12
49
-
50
- for round_idx, models in enumerate(fallback_rounds, start=1):
51
- for model_name in models:
52
-
53
- log_callback(f"[Try {attempt}/{total_attempts}] Model: {model_name}")
54
-
55
- model = MODEL_ENDPOINTS[model_name]
56
- url = f"https://api-inference.huggingface.co/models/{model}"
57
-
58
- payload = {
59
- "inputs": prompt,
60
- "options": {"wait_for_model": True}
61
- }
62
-
63
- try:
64
- response = requests.post(url, headers=HEADERS, json=payload)
65
-
66
- # Cek JSON error
67
- try:
68
- data = response.json()
69
- if "error" in data:
70
- log_callback(f" → HF Error: {data['error']}")
71
- time.sleep(delays[min(attempt-1, len(delays)-1)])
72
- attempt += 1
73
- continue
74
- except:
75
- pass
76
-
77
- # Cek MIME type
78
- content_type = response.headers.get("Content-Type", "")
79
-
80
- if "image" in content_type:
81
- filename = f"img_{uuid.uuid4().hex}.png"
82
- os.makedirs("outputs", exist_ok=True)
83
- filepath = os.path.join("outputs", filename)
84
-
85
- with open(filepath, "wb") as f:
86
- f.write(response.content)
87
-
88
- if os.path.getsize(filepath) > 10000:
89
- log_callback(" → SUCCESS (image bytes)")
90
- return filepath
91
- else:
92
- log_callback(" → FAILED (image too small)")
93
-
94
- # Cek base64
95
- try:
96
- data = response.json()
97
- if "generated_image" in data:
98
- b64 = data["generated_image"].split(",")[-1]
99
- img_bytes = base64.b64decode(b64)
100
-
101
- filename = f"img_{uuid.uuid4().hex}.png"
102
- os.makedirs("outputs", exist_ok=True)
103
- filepath = os.path.join("outputs", filename)
104
-
105
- with open(filepath, "wb") as f:
106
- f.write(img_bytes)
107
-
108
- if os.path.getsize(filepath) > 10000:
109
- log_callback(" → SUCCESS (base64)")
110
- return filepath
111
- else:
112
- log_callback(" → FAILED (base64 too small)")
113
- except:
114
- pass
115
-
116
- except Exception as e:
117
- log_callback(f" → Exception: {str(e)}")
118
-
119
- # Delay adaptif
120
- delay = delays[min(attempt-1, len(delays)-1)]
121
- log_callback(f" → Waiting {delay} seconds before retry...")
122
- time.sleep(delay)
123
-
124
- attempt += 1
125
-
126
- log_callback("❌ Gagal menghasilkan gambar setelah 12 percobaan.")
127
- return None
128
 
129
- # ============================
130
- # GROQ TEXT GENERATOR
131
- # ============================
132
- def ai(prompt):
133
- res = client.chat.completions.create(
134
- model="llama-3.3-70b-versatile",
135
- messages=[{"role": "user", "content": prompt}],
136
- max_tokens=800
137
- )
138
- return res.choices[0].message.content
139
 
140
- # ============================
141
- # COMIC PANEL GENERATOR
142
- # ============================
143
- def generate_panels(story, style, chapters):
144
- panels_per_chapter = 8
145
- all_chapters = []
146
-
147
- for c in range(1, chapters+1):
148
- prompt = f"""
149
- Buatkan {panels_per_chapter} panel komik.
150
- Cerita: {story}
151
- Style visual: {style}
152
- Format:
153
- Panel 1: ...
154
- Panel 2: ...
155
- ...
156
- Panel {panels_per_chapter}: ...
157
- """
158
- raw = ai(prompt)
159
- lines = [l for l in raw.split("\n") if l.strip().startswith("Panel")]
160
- all_chapters.append(lines[:panels_per_chapter])
161
-
162
- return all_chapters
163
 
164
- # ============================
165
- # VISUAL PROMPT BUILDER
166
- # ============================
167
- def build_visual_prompt(panel_text, style):
168
- return f"""
169
- {style}, soft lighting, clean shapes, child-friendly,
170
- cinematic depth, high detail.
171
- Scene: {panel_text}
172
- """
173
 
174
- # ============================
175
- # PDF BUILDER
176
- # ============================
177
- class ComicPDF(FPDF):
178
- pass
179
 
180
- def build_pdf(story, style, chapters, log_callback):
181
- pdf = ComicPDF()
182
- pdf.set_auto_page_break(True, margin=15)
183
 
184
- panels = generate_panels(story, style, chapters)
 
 
185
 
186
- for c_idx, chapter in enumerate(panels, start=1):
187
- pdf.add_page()
188
- pdf.set_font("Helvetica", "B", 16)
189
- pdf.cell(0, 10, f"Bab {c_idx}", new_x=XPos.LMARGIN, new_y=YPos.NEXT)
190
 
191
- for p_idx, panel in enumerate(chapter, start=1):
192
- pdf.set_font("Helvetica", "B", 12)
193
- pdf.cell(0, 8, f"Panel {p_idx}", new_x=XPos.LMARGIN, new_y=YPos.NEXT)
194
 
195
- visual_prompt = build_visual_prompt(panel, style)
 
196
 
197
- log_callback(f"\n=== GENERATING PANEL {p_idx} ===")
198
- img_path = hf_generate_image_ultra(visual_prompt, log_callback)
 
199
 
200
- if img_path:
201
- pdf.image(img_path, x=20, w=170)
202
 
203
- pdf.set_font("Helvetica", "", 11)
204
- pdf.multi_cell(0, 6, panel)
205
- pdf.ln(4)
206
 
207
- filename = f"comic_{uuid.uuid4().hex}.pdf"
208
- pdf.output(filename)
209
- return filename
210
 
211
- # ============================
212
- # GRADIO UI
213
- # ============================
214
- def run_comic(story, style, chapters):
215
- logs = []
216
-
217
- def log_callback(msg):
218
- logs.append(msg)
219
-
220
- pdf_file = build_pdf(story, style, chapters, log_callback)
221
- return pdf_file, "\n".join(logs)
222
-
223
-
224
- with gr.Blocks() as app:
225
-
226
- gr.Markdown("# 🌟 AIPromptLab 3.2 — Ultra Stable Free Mode (HuggingFace Engine)")
227
-
228
- with gr.Tab("Comic Generator"):
229
- story = gr.Textbox(label="Ide Cerita Komik")
230
- style = gr.Dropdown(
231
- label="Style Visual",
232
- choices=[
233
- "Pastel 3D Isometric",
234
- "Cute 3D Cartoon",
235
- "Realistic Cinematic",
236
- "Lowpoly Diorama",
237
- "Claymation 3D",
238
- "Toy Photography",
239
- "Anime 3D Soft Light"
240
- ],
241
- value="Pastel 3D Isometric"
242
- )
243
- chapters = gr.Slider(1, 10, value=1, step=1, label="Jumlah Bab")
244
- btn = gr.Button("Generate Comic PDF")
245
- out_pdf = gr.File()
246
- out_log = gr.Textbox(label="Log Proses", lines=30)
247
-
248
- btn.click(run_comic, [story, style, chapters], [out_pdf, out_log])
249
-
250
- app.launch(ssr_mode=False)
 
 
 
 
 
 
 
 
 
 
 
1
  # ============================
2
+ # FIREWORKS AI MODULE (HYBRID MODE)
3
  # ============================
4
+ import base64
5
+ import requests
 
 
 
 
 
 
 
6
 
7
+ FIREWORKS_API_KEY = os.getenv("FIREWORKS_API_KEY")
 
 
 
 
 
 
 
 
8
 
9
+ def fireworks_generate(prompt, model_name, log_callback):
10
+ """
11
+ Generate image using Fireworks AI.
12
+ Returns filepath or None.
13
+ """
14
+ url = "https://api.fireworks.ai/inference/v1/image/generate"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ payload = {
17
+ "model": model_name,
18
+ "prompt": prompt,
19
+ "size": "1024x1024",
20
+ "num_images": 1
21
+ }
 
 
 
 
22
 
23
+ headers = {
24
+ "Authorization": f"Bearer {FIREWORKS_API_KEY}",
25
+ "Content-Type": "application/json"
26
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ try:
29
+ response = requests.post(url, json=payload, headers=headers, timeout=40)
30
+ data = response.json()
 
 
 
 
 
 
31
 
32
+ if "images" not in data:
33
+ log_callback(f" → Fireworks Error: {data}")
34
+ return None
 
 
35
 
36
+ b64 = data["images"][0]["image_base64"]
37
+ img_bytes = base64.b64decode(b64)
 
38
 
39
+ filename = f"fw_{uuid.uuid4().hex}.png"
40
+ os.makedirs("outputs", exist_ok=True)
41
+ filepath = os.path.join("outputs", filename)
42
 
43
+ with open(filepath, "wb") as f:
44
+ f.write(img_bytes)
 
 
45
 
46
+ if os.path.getsize(filepath) < 10000:
47
+ log_callback(" Fireworks FAILED (image too small)")
48
+ return None
49
 
50
+ log_callback(" → Fireworks SUCCESS")
51
+ return filepath
52
 
53
+ except Exception as e:
54
+ log_callback(f" → Fireworks Exception: {str(e)}")
55
+ return None
56
 
 
 
57
 
58
+ def fireworks_schnell(prompt, log_callback):
59
+ return fireworks_generate(prompt, "black-forest-labs/FLUX.1-schnell", log_callback)
 
60
 
 
 
 
61
 
62
+ def fireworks_dev(prompt, log_callback):
63
+ return fireworks_generate(prompt, "black-forest-labs/FLUX.1-dev", log_callback)