mroccuper commited on
Commit
9d3c685
·
verified ·
1 Parent(s): b33083d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -196
app.py CHANGED
@@ -1,210 +1,76 @@
1
  import os
2
  import gradio as gr
3
  import google.generativeai as genai
4
- from PIL import Image, ImageEnhance, ImageFilter
5
  import io
6
  import base64
7
- import json
8
  import time
9
- import traceback
10
- try:
11
- import pyperclip
12
- except ImportError:
13
- pyperclip = None
14
 
15
- # --- Environment Configuration ---
16
- GEMINI_KEY = os.environ.get("GEMINI_KEY", "")
17
- DEFAULT_PORT = int(os.environ.get("PORT", 7860))
18
-
19
- # --- Style Template Optimization ---
20
- BASE_TEMPLATE = """Describe this design as a concise Flux 1.1 Pro prompt focusing on:
21
- - Key visual elements
22
- - Technical specifications
23
- - Style consistency
24
- - Functional requirements"""
25
 
 
26
  STYLE_INSTRUCTIONS = {
27
- "General": BASE_TEMPLATE,
28
- "Realistic": f"{BASE_TEMPLATE}\nPHOTOREALISTIC RULES: Use photography terms, texture details, accurate lighting",
29
- "Kawaii": f"{BASE_TEMPLATE}\nKAWAII RULES: Rounded shapes, pastel colors, cute expressions",
30
- "Vector": f"{BASE_TEMPLATE}\nVECTOR RULES: Clean lines, geometric shapes, B&W gradients",
31
- "Silhouette": f"{BASE_TEMPLATE}\nSILHOUETTE RULES: High contrast, minimal details, strong outlines"
32
- }
33
-
34
- # --- Flux Configuration ---
35
- FLUX_SPECS = {
36
- "aspect_ratios": ["1:1", "16:9", "4:3", "9:16"],
37
- "formats": ["SVG", "PNG", "PDF"],
38
- "color_modes": ["B&W", "CMYK", "RGB"],
39
- "dpi_options": [72, 150, 300, 600]
40
  }
41
 
42
- # --- Quality Control System ---
43
- class QualityValidator:
44
- VALIDATION_TEMPLATE = """Analyze this Flux prompt:
45
- 1. Score style adherence (1-5)
46
- 2. List technical issues
47
- 3. Suggest improvements
48
- Respond ONLY as JSON: {"score": x/10, "issues": [], "suggestions": []}"""
49
 
50
- @classmethod
51
- def validate(cls, prompt, model):
52
  try:
53
- response = model.generate_content([cls.VALIDATION_TEMPLATE, prompt])
54
- return json.loads(response.text)
55
- except:
56
- return {"score": 0, "issues": ["Validation failed"], "suggestions": []}
57
-
58
- # --- Image Processing Pipeline ---
59
- def preprocess_image(img):
60
- """Convert and enhance uploaded images"""
61
- try:
62
- if isinstance(img, str): # Handle file paths
63
- img = Image.open(img)
64
- img = img.convert("RGB")
65
- img = ImageEnhance.Contrast(img).enhance(1.2)
66
- img = img.filter(ImageFilter.SHARPEN)
67
- return img
68
- except Exception as e:
69
- raise ValueError(f"Image processing error: {str(e)}")
70
-
71
- # --- Core Generation Engine ---
72
- def generate_prompt(image, api_key, style, creativity, neg_prompt, aspect, color_mode, dpi):
73
- try:
74
- # Validate inputs
75
- if not image:
76
- raise ValueError("Please upload an image")
77
 
78
- api_key = api_key or GEMINI_KEY
79
- if not api_key:
80
- raise ValueError("API key required - set in env (GEMINI_KEY) or input field")
81
-
82
- # Initialize model
83
- genai.configure(api_key=api_key)
84
- model = genai.GenerativeModel("gemini-1.5-pro")
85
-
86
- # Process image
87
- img = preprocess_image(image)
88
- img_bytes = io.BytesIO()
89
- img.save(img_bytes, format="PNG")
90
- img_b64 = base64.b64encode(img_bytes.getvalue()).decode()
91
-
92
- # Build instruction
93
- instruction = f"{STYLE_INSTRUCTIONS[style]}\nAVOID: {neg_prompt}\n"
94
- instruction += f"ASPECT: {aspect}, COLORS: {color_mode}, DPI: {dpi}\n"
95
-
96
- # Generate prompt
97
- response = model.generate_content(
98
- contents=[instruction, {"mime_type": "image/png", "data": img_b64}],
99
- generation_config={"temperature": creativity}
100
- )
101
- raw_prompt = response.text
102
-
103
- # Quality validation
104
- validation = QualityValidator.validate(raw_prompt, model)
105
- if validation.get("score", 0) < 7:
106
- response = model.generate_content(f"Improve this prompt: {raw_prompt}\nIssues: {validation['issues']}")
107
- raw_prompt = response.text
108
-
109
- # Token tracking
110
- input_tokens = len(img_b64) // 4 # Approximate base64 token count
111
- output_tokens = len(raw_prompt.split())
112
-
113
- return {
114
- "prompt": raw_prompt,
115
- "validation": validation,
116
- "stats": {"input": input_tokens, "output": output_tokens}
117
- }
118
-
119
- except Exception as e:
120
- traceback.print_exc()
121
- return {"error": str(e)}
122
-
123
- # --- UI Components ---
124
- def create_advanced_controls():
125
- with gr.Accordion("⚙️ Advanced Settings", open=False):
126
- with gr.Row():
127
- creativity = gr.Slider(0.0, 1.0, 0.7, label="Creativity Level")
128
- neg_prompt = gr.Textbox(label="🚫 Negative Prompts", placeholder="What to avoid")
129
- with gr.Row():
130
- aspect = gr.Dropdown(FLUX_SPECS["aspect_ratios"], label="Aspect Ratio")
131
- color_mode = gr.Dropdown(FLUX_SPECS["color_modes"], label="Color Mode")
132
- dpi = gr.Dropdown(FLUX_SPECS["dpi_options"], label="Output DPI")
133
- return [creativity, neg_prompt, aspect, color_mode, dpi]
134
-
135
- # --- Main Interface ---
136
- def build_interface():
137
- with gr.Blocks(title="Flux Pro Generator", theme=gr.themes.Soft()) as app:
138
- # Security Section
139
- api_key = gr.Textbox(
140
- label="🔑 Gemini API Key",
141
- value=GEMINI_KEY,
142
- type="password",
143
- info="Set GEMINI_KEY environment variable for production"
144
- )
145
-
146
- # Main Workflow
147
- with gr.Row(variant="panel"):
148
- with gr.Column(scale=1):
149
- img_input = gr.Image(
150
- label="🖼️ Upload Design",
151
- type="pil",
152
- sources=["upload"],
153
- interactive=True
154
- )
155
- style = gr.Dropdown(
156
- list(STYLE_INSTRUCTIONS.keys()),
157
- value="General",
158
- label="🎨 Target Style"
159
- )
160
- adv_controls = create_advanced_controls()
161
- gen_btn = gr.Button("✨ Generate Prompt", variant="primary")
162
-
163
- with gr.Column(scale=2):
164
- prompt_output = gr.Textbox(
165
- label="📝 Optimized Prompt",
166
- lines=8,
167
- interactive=False
168
- )
169
- with gr.Row():
170
- copy_btn = gr.Button("📋 Copy")
171
- history_btn = gr.Button("🕒 History")
172
- quality_report = gr.JSON(
173
- label="🔍 Quality Report",
174
- visible=True
175
- )
176
- token_stats = gr.JSON(
177
- label="🧮 Token Usage",
178
- visible=True
179
- )
180
-
181
- # History System
182
- history = gr.State([])
183
-
184
- # Event Handling
185
- gen_btn.click(
186
- lambda *args: generate_prompt(*args),
187
- inputs=[img_input, api_key, style] + adv_controls,
188
- outputs=[prompt_output, quality_report, token_stats]
189
- )
190
-
191
- copy_btn.click(
192
- lambda x: pyperclip.copy(x) if pyperclip else None,
193
- inputs=prompt_output,
194
- outputs=None
195
- )
196
-
197
- return app
198
-
199
- # --- Production Launch ---
200
- if __name__ == "__main__":
201
- app = build_interface()
202
- app.launch(
203
- server_name="0.0.0.0",
204
- server_port=DEFAULT_PORT,
205
- share=False,
206
- auth=(
207
- os.environ.get("APP_USER", "admin"),
208
- os.environ.get("APP_PWD", "admin")
209
- ) if os.environ.get("ENV") == "prod" else None
210
- )
 
1
  import os
2
  import gradio as gr
3
  import google.generativeai as genai
4
+ from PIL import Image
5
  import io
6
  import base64
 
7
  import time
 
 
 
 
 
8
 
9
+ # Configuration optimized for Hugging Face
10
+ MAX_RETRIES = 3
11
+ TIMEOUT = 10 # Keep under 20s Hugging Face limit
 
 
 
 
 
 
 
12
 
13
+ # Simplified style instructions for faster processing
14
  STYLE_INSTRUCTIONS = {
15
+ "General": "Describe as Flux prompt focusing on key elements",
16
+ "Vector": "Clean vector style with sharp lines and B&W",
17
+ "Realistic": "Photorealistic details with accurate textures",
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
+ def optimize_image(img):
21
+ """Fast image optimization for web"""
22
+ img = img.convert("RGB")
23
+ img.thumbnail((512, 512)) # Reduce image size
24
+ return img
 
 
25
 
26
+ def generate_prompt(image, api_key, style):
27
+ for attempt in range(MAX_RETRIES):
28
  try:
29
+ start_time = time.time()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ # Configure API
32
+ genai.configure(api_key=api_key)
33
+ model = genai.GenerativeModel('gemini-pro-vision')
34
+
35
+ # Optimize image
36
+ img = optimize_image(image)
37
+ img_byte_arr = io.BytesIO()
38
+ img.save(img_byte_arr, format='JPEG', quality=85)
39
+
40
+ # Timeout control
41
+ if time.time() - start_time > TIMEOUT - 2:
42
+ raise TimeoutError("Image processing too slow")
43
+
44
+ response = model.generate_content([
45
+ STYLE_INSTRUCTIONS[style],
46
+ {"mime_type": "image/jpeg", "data": img_byte_arr.getvalue()}
47
+ ], request_options={"timeout": TIMEOUT})
48
+
49
+ return response.text
50
+
51
+ except Exception as e:
52
+ if attempt == MAX_RETRIES - 1:
53
+ return f"Error: {str(e)}"
54
+ time.sleep(1)
55
+
56
+ # Hugging Face optimized interface
57
+ with gr.Blocks() as app:
58
+ gr.Markdown("## 🚀 HF-Friendly Flux Generator")
59
+
60
+ with gr.Row():
61
+ api_key = gr.Textbox(label="Gemini Key", type="password")
62
+ style = gr.Dropdown(list(STYLE_INSTRUCTIONS), label="Style")
63
+
64
+ image_input = gr.Image(type="pil", label="Upload Design")
65
+ generate_btn = gr.Button("Generate", variant="primary")
66
+ output = gr.Textbox(label="Prompt", interactive=False)
67
+
68
+ generate_btn.click(
69
+ generate_prompt,
70
+ inputs=[image_input, api_key, style],
71
+ outputs=output,
72
+ concurrency_limit=3 # Better HF resource management
73
+ )
74
+
75
+ # HF-specific launch settings
76
+ app.queue(concurrency_count=3, max_size=20).launch(debug=True)