milliyin commited on
Commit
5b2a882
Β·
verified Β·
1 Parent(s): 6c96d59

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -44
app.py CHANGED
@@ -34,27 +34,31 @@ def check_backend_connection():
34
  """Ping the HF Space and cache the client object."""
35
  try:
36
  test_client = Client("SnapwearAI/SAKS-backend", hf_token=HF_TOKEN)
37
- backend_status.update({
38
- "client": test_client,
39
- "connected": True,
40
- "error_message": "",
41
- "last_check": time.time(),
42
- })
 
 
43
  logger.info("βœ… Backend connection established")
44
  return True, "🟒 Model is ready"
45
  except Exception as e:
46
- backend_status.update({
47
- "client": None,
48
- "connected": False,
49
- "last_check": time.time(),
50
- "error_message": str(e),
51
- })
 
 
52
  err = str(e).lower()
53
  if "timeout" in err or "read operation timed out" in err:
54
  return False, "🟑 Model is starting up. Please wait 3‑4β€―min."
55
  return False, f"πŸ”΄ Backend error: {e}"
56
 
57
- # initial probe
58
  check_backend_connection()
59
 
60
  # ───────── Helpers ─────────
@@ -79,7 +83,6 @@ def base64_to_image(b64: str) -> Image.Image | None:
79
  # ───────── UI ↔ Backend bridge ─────────
80
  def call_backend_with_retry(input_image: Image.Image, category: str, gender: str, *, max_retries: int = MAX_RETRIES):
81
  """Single‑shot call (no more than `max_retries` times)."""
82
-
83
  if input_image is None:
84
  return None, None, "❌ Please upload an image."
85
 
@@ -126,11 +129,55 @@ def call_backend_with_retry(input_image: Image.Image, category: str, gender: str
126
 
127
  return None, None, "❌ Unknown error"
128
 
129
- # ───────── CSS ─────────
130
  css = """
131
  body, .gradio-container {
132
  font-family: 'Inter', sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
 
 
 
 
 
 
134
  #button {
135
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
136
  color: #ffffff;
@@ -139,22 +186,48 @@ body, .gradio-container {
139
  border-radius: 12px;
140
  padding: 12px 24px;
141
  transition: all 0.3s ease;
 
142
  }
 
143
  #button:hover {
144
  transform: translateY(-2px);
145
  box-shadow: 0 8px 25px rgba(102,126,234,0.3);
146
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  """
148
 
149
  # ───────── Gradio Blocks ─────────
150
  with gr.Blocks(css=css, title="Jewellery Photography Preview") as demo:
151
  # Hero
152
  gr.HTML("""
153
- <div style="text-align: center; margin-bottom: 20px;">
154
- <h1 style="font-size: 2.5em;">🎨 Raresence: AI-Powered Jewellery Photo Preview</h1>
155
- <p style="color: #666;">Upload a jewellery image, select model, and get professional photos instantly</p>
156
  </div>
157
- """)
 
158
 
159
  # Status banner
160
  status_html = gr.HTML()
@@ -165,53 +238,39 @@ with gr.Blocks(css=css, title="Jewellery Photography Preview") as demo:
165
  return f'<div class="status-banner {cls}">{msg}</div>'
166
 
167
  status_html.value = _update_status()
168
- gr.Button("πŸ”„ Check Status").click(fn=_update_status, outputs=status_html)
169
 
170
  # 2‑column layout
171
  with gr.Row():
172
  # left inputs
173
  with gr.Column(scale=0.4):
174
- gr.HTML("""
175
- <div style="text-align:center; margin-bottom: 10px;">
176
- <h3>πŸ–ΌοΈ Upload Jewellery Image</h3>
177
- <p style="color: #666; font-size: 14px;">Select a clear jewellery image for best results</p>
178
- </div>
179
- """)
180
  with gr.Tabs():
181
- with gr.TabItem("Setting"):
182
  category = gr.Dropdown(label="Jewellery category", choices=["Rings", "Bracelets", "Watches", "Earrings"], value="Bracelets")
183
  gender = gr.Dropdown(label="Model gender", choices=["male", "female"], value="female")
184
  input_img = gr.Image(label="Upload image", type="pil", height=400)
185
 
186
- # Example images
187
  gr.Examples(
188
- examples=[
189
- ["examples/ring1.jpg"],
190
- ["examples/bracelet1.jpg"],
191
- ["examples/watch1.jpg"],
192
- ["examples/earring1.jpg"],
193
- ],
194
- inputs=[input_img],
195
  label="Example Images",
 
 
 
 
 
 
196
  )
197
 
198
  # right outputs
199
  with gr.Column():
200
- gr.HTML("""
201
- <div style="text-align:center; margin-bottom: 10px;">
202
- <h3>🎨 AI Generated Results</h3>
203
- <p style="color: #666; font-size: 14px;">Preview overlay detection and final professional background</p>
204
- </div>
205
- """)
206
- info = gr.Markdown(value="...")
207
  with gr.Row():
208
  run_btn = gr.Button("🎯 Generate", elem_id="button", variant="primary")
209
  with gr.Row():
210
  with gr.Column():
211
- info1 = gr.Markdown(value="### Detection overlay")
212
  out_overlay = gr.Image(height=400)
213
  with gr.Column():
214
- info2 = gr.Markdown(value="### Final result")
215
  out_bg = gr.Image(height=400)
216
  out_status = gr.Text(label="Status", interactive=False)
217
 
 
34
  """Ping the HF Space and cache the client object."""
35
  try:
36
  test_client = Client("SnapwearAI/SAKS-backend", hf_token=HF_TOKEN)
37
+ backend_status.update(
38
+ {
39
+ "client": test_client,
40
+ "connected": True,
41
+ "error_message": "",
42
+ "last_check": time.time(),
43
+ }
44
+ )
45
  logger.info("βœ… Backend connection established")
46
  return True, "🟒 Model is ready"
47
  except Exception as e:
48
+ backend_status.update(
49
+ {
50
+ "client": None,
51
+ "connected": False,
52
+ "last_check": time.time(),
53
+ "error_message": str(e),
54
+ }
55
+ )
56
  err = str(e).lower()
57
  if "timeout" in err or "read operation timed out" in err:
58
  return False, "🟑 Model is starting up. Please wait 3‑4β€―min."
59
  return False, f"πŸ”΄ Backend error: {e}"
60
 
61
+ # Initial probe
62
  check_backend_connection()
63
 
64
  # ───────── Helpers ─────────
 
83
  # ───────── UI ↔ Backend bridge ─────────
84
  def call_backend_with_retry(input_image: Image.Image, category: str, gender: str, *, max_retries: int = MAX_RETRIES):
85
  """Single‑shot call (no more than `max_retries` times)."""
 
86
  if input_image is None:
87
  return None, None, "❌ Please upload an image."
88
 
 
129
 
130
  return None, None, "❌ Unknown error"
131
 
132
+ # ───────── CSS Styling ─────────
133
  css = """
134
  body, .gradio-container {
135
  font-family: 'Inter', sans-serif;
136
+ background-color: #f9fafb;
137
+ }
138
+
139
+ h1, h3 {
140
+ font-weight: 700;
141
+ color: #333333;
142
+ }
143
+
144
+ h1 {
145
+ font-size: 2.2em;
146
+ margin-bottom: 0.3em;
147
+ }
148
+
149
+ h3 {
150
+ font-size: 1.3em;
151
+ margin-bottom: 0.2em;
152
+ }
153
+
154
+ p {
155
+ color: #555555;
156
+ }
157
+
158
+ .status-banner {
159
+ padding: 10px;
160
+ border-radius: 8px;
161
+ font-weight: 500;
162
+ text-align: center;
163
+ margin-bottom: 15px;
164
+ }
165
+
166
+ .status-ready {
167
+ background-color: #d1fae5;
168
+ color: #065f46;
169
+ }
170
+
171
+ .status-starting {
172
+ background-color: #fef9c3;
173
+ color: #92400e;
174
  }
175
+
176
+ .status-error {
177
+ background-color: #fee2e2;
178
+ color: #991b1b;
179
+ }
180
+
181
  #button {
182
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
183
  color: #ffffff;
 
186
  border-radius: 12px;
187
  padding: 12px 24px;
188
  transition: all 0.3s ease;
189
+ font-size: 1em;
190
  }
191
+
192
  #button:hover {
193
  transform: translateY(-2px);
194
  box-shadow: 0 8px 25px rgba(102,126,234,0.3);
195
  }
196
+
197
+ .gr-examples {
198
+ background: #f3f4f6;
199
+ border-radius: 8px;
200
+ padding: 10px;
201
+ margin-top: 10px;
202
+ }
203
+
204
+ .gr-examples p {
205
+ font-weight: 600;
206
+ color: #444444;
207
+ margin-bottom: 8px;
208
+ }
209
+
210
+ .markdown-output h3 {
211
+ color: #4b5563;
212
+ font-size: 1.1em;
213
+ margin-bottom: 6px;
214
+ }
215
+
216
+ .markdown-output p {
217
+ color: #6b7280;
218
+ font-size: 0.95em;
219
+ }
220
  """
221
 
222
  # ───────── Gradio Blocks ─────────
223
  with gr.Blocks(css=css, title="Jewellery Photography Preview") as demo:
224
  # Hero
225
  gr.HTML("""
226
+ <div style="display: flex; align-items: center; justify-content: center; gap: 15px; margin-bottom: 20px;">
227
+ <h1 style="margin: 0; font-size: 2.5em;">🎨 Raresence: AI-Powered Jewellery Photo Preview</h1>
 
228
  </div>
229
+ <p style="text-align: center; color: #666; margin-top: 10px;">Upload Jewellery, select your model, and get professional Photos instantly!</p>
230
+ """)
231
 
232
  # Status banner
233
  status_html = gr.HTML()
 
238
  return f'<div class="status-banner {cls}">{msg}</div>'
239
 
240
  status_html.value = _update_status()
241
+ gr.Button("πŸ”„ CheckΒ Status").click(fn=_update_status, outputs=status_html)
242
 
243
  # 2‑column layout
244
  with gr.Row():
245
  # left inputs
246
  with gr.Column(scale=0.4):
 
 
 
 
 
 
247
  with gr.Tabs():
248
+ with gr.TabItem("Settings"):
249
  category = gr.Dropdown(label="Jewellery category", choices=["Rings", "Bracelets", "Watches", "Earrings"], value="Bracelets")
250
  gender = gr.Dropdown(label="Model gender", choices=["male", "female"], value="female")
251
  input_img = gr.Image(label="Upload image", type="pil", height=400)
252
 
 
253
  gr.Examples(
 
 
 
 
 
 
 
254
  label="Example Images",
255
+ inputs=input_img,
256
+ examples=[
257
+ ["examples/ring.png"],
258
+ ["examples/bracelet.png"],
259
+ ["examples/watch.png"]
260
+ ]
261
  )
262
 
263
  # right outputs
264
  with gr.Column():
265
+ info = gr.Markdown(value="### Preview Results", elem_classes=["markdown-output"])
 
 
 
 
 
 
266
  with gr.Row():
267
  run_btn = gr.Button("🎯 Generate", elem_id="button", variant="primary")
268
  with gr.Row():
269
  with gr.Column():
270
+ info1 = gr.Markdown(value="### Detection overlay", elem_classes=["markdown-output"])
271
  out_overlay = gr.Image(height=400)
272
  with gr.Column():
273
+ info2 = gr.Markdown("### Final result", elem_classes=["markdown-output"])
274
  out_bg = gr.Image(height=400)
275
  out_status = gr.Text(label="Status", interactive=False)
276