hellosindh commited on
Commit
6d10a5b
·
verified ·
1 Parent(s): d5d275b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -54
app.py CHANGED
@@ -23,6 +23,7 @@ ID2TAG = model.config.id2label
23
  BOS_ID = 2
24
  EOS_ID = 3
25
 
 
26
  ENTITY_CONFIG = {
27
  "PERSON": {"color": "#c084fc", "bg": "rgba(192,132,252,0.15)", "sindhi": "ماڻهو"},
28
  "LOCATION": {"color": "#818cf8", "bg": "rgba(129,140,248,0.15)", "sindhi": "جڳهه"},
@@ -33,9 +34,9 @@ ENTITY_CONFIG = {
33
  }
34
 
35
  FALLBACK_CFG = {
36
- "color": "#6b7280",
37
- "bg": "rgba(107,114,128,0.15)",
38
- "sindhi": "ٻيو",
39
  }
40
 
41
 
@@ -133,7 +134,9 @@ def predict_ner(sentence):
133
  <div style="
134
  background:linear-gradient(135deg,#1a0533 0%,#0f0f2e 100%);
135
  border:1px solid #7c3aed30;border-radius:16px;
136
- padding:24px 28px;font-size:1.25em;line-height:3.4em;
 
 
137
  direction:rtl;text-align:right;
138
  font-family:'Lateef','Scheherazade New',serif;
139
  min-height:90px;">
@@ -156,7 +159,7 @@ def _empty_html():
156
  border:1px solid #7c3aed20;border-radius:16px;
157
  padding:40px;text-align:center;min-height:90px;
158
  display:flex;align-items:center;justify-content:center;">
159
- <span style="color:#4c1d95;font-size:1.1em;
160
  font-family:'Lateef','Scheherazade New',serif;">
161
  ڪو بہ سنڌي جملو لکو
162
  </span>
@@ -168,7 +171,8 @@ def _empty_summary():
168
  <div style="
169
  background:#1a0533;border:1px solid #7c3aed20;
170
  border-radius:16px;padding:24px;
171
- text-align:center;color:#4c1d95;font-size:0.9em;
 
172
  font-family:'Lateef','Scheherazade New',serif;">
173
  اعتماد جوڳا نتيجا نہ مليا
174
  </div>
@@ -179,7 +183,6 @@ def _build_summary(entities):
179
  return _empty_summary()
180
 
181
  counts = Counter(e["type"] for e in entities)
182
- total = len(entities)
183
  cards = ""
184
 
185
  for etype, cnt in sorted(counts.items(), key=lambda x: -x[1]):
@@ -190,36 +193,27 @@ def _build_summary(entities):
190
  border-radius:10px;padding:10px 14px;
191
  display:flex;justify-content:space-between;
192
  align-items:center;margin-bottom:8px;direction:rtl;">
193
- <span style="color:{cfg['color']};font-weight:600;font-size:0.9em;
194
  font-family:'Lateef','Scheherazade New',serif;">
195
  {cfg['sindhi']}
196
  </span>
197
  <span style="
198
  background:{cfg['color']};color:#0a0a1a;
199
  font-weight:800;border-radius:20px;
200
- padding:1px 10px;font-size:0.82em;
201
  min-width:24px;text-align:center;">
202
  {cnt}
203
  </span>
204
  </div>
205
  """
206
 
 
207
  return f"""
208
  <div style="
209
  background:linear-gradient(135deg,#1a0533,#0f0f2e);
210
  border:1px solid #7c3aed30;border-radius:16px;
211
- padding:18px 16px;">
212
- <div style="
213
- color:#c084fc;font-weight:700;font-size:0.9em;
214
- margin-bottom:12px;padding-bottom:10px;
215
- border-bottom:1px solid #7c3aed25;
216
- direction:rtl;text-align:right;
217
- font-family:'Lateef','Scheherazade New',serif;">
218
- مجموعي:
219
- <span style="color:#f1f5f9;font-size:1.1em;">{total}</span>
220
- سڃاڻپ
221
- </div>
222
- <div>{cards}</div>
223
  </div>
224
  """
225
 
@@ -229,14 +223,14 @@ def _build_confidence(entities):
229
 
230
  bars = ""
231
  for ent in entities:
232
- cfg = ENTITY_CONFIG.get(ent["type"], FALLBACK_CFG)
233
- pct = int(ent["score"] * 100)
234
 
235
  bars += f"""
236
  <div style="margin-bottom:16px;direction:rtl;">
237
  <div style="display:flex;justify-content:space-between;
238
  align-items:center;margin-bottom:6px;">
239
- <span style="color:#e2e8f0;font-size:1em;font-weight:500;
240
  font-family:'Lateef','Scheherazade New',serif;">
241
  {ent['text']}
242
  </span>
@@ -245,7 +239,7 @@ def _build_confidence(entities):
245
  background:{cfg['color']}18;
246
  border:1px solid {cfg['color']}40;
247
  color:{cfg['color']};
248
- font-size:0.7em;padding:2px 8px;
249
  border-radius:4px;font-weight:700;
250
  font-family:'Lateef','Scheherazade New',serif;">
251
  {ent['sindhi']}
@@ -284,16 +278,16 @@ def _build_confidence(entities):
284
  """
285
 
286
  def _build_legend(entities):
287
- """Only show legend for entity types that were actually found."""
288
- found_types = set(e["type"] for e in entities)
289
  items = ""
290
  for etype in found_types:
291
  cfg = ENTITY_CONFIG.get(etype, FALLBACK_CFG)
292
  items += (
293
  f'<span style="background:{cfg["bg"]};'
294
  f'border:1px solid {cfg["color"]}40;'
295
- f'color:{cfg["color"]};padding:4px 12px;'
296
- f'border-radius:6px;font-size:0.82em;font-weight:600;'
297
  f'font-family:\'Lateef\',\'Scheherazade New\',serif;">'
298
  f'{cfg["sindhi"]}</span>'
299
  )
@@ -301,13 +295,7 @@ def _build_legend(entities):
301
  <div style="
302
  background:linear-gradient(135deg,#1a0533,#0f0f2e);
303
  border:1px solid #7c3aed20;border-radius:14px;
304
- padding:14px 18px;">
305
- <div style="color:#9333ea;font-weight:700;font-size:0.8em;
306
- letter-spacing:0.5px;margin-bottom:10px;
307
- direction:rtl;text-align:right;
308
- font-family:'Lateef','Scheherazade New',serif;">
309
- اسمن جي نشاندهي
310
- </div>
311
  <div style="display:flex;flex-wrap:wrap;gap:8px;direction:rtl;">
312
  {items}
313
  </div>
@@ -332,8 +320,9 @@ def _build_csv(entities):
332
 
333
 
334
  CSS = """
335
- @import url('https://fonts.googleapis.com/css2?family=Lateef&family=Scheherazade+New:wght@400;700&family=Outfit:wght@400;600;700;800&display=swap');
336
 
 
337
  *, body, .gradio-container {
338
  font-family: 'Outfit', sans-serif !important;
339
  }
@@ -345,62 +334,106 @@ body, .gradio-container {
345
  margin: 0 auto !important;
346
  padding: 16px !important;
347
  }
 
 
348
  label > span {
349
  color: #9333ea !important;
350
  font-size: 0.82em !important;
351
  font-weight: 700 !important;
352
  letter-spacing: 0.8px !important;
353
  text-transform: uppercase !important;
 
354
  }
 
 
355
  textarea {
356
  background: #130825 !important;
357
  border: 1px solid #6d28d960 !important;
358
  border-radius: 14px !important;
359
  color: #e2e8f0 !important;
360
- font-size: 1.15em !important;
361
  direction: rtl !important;
362
  font-family: 'Lateef', 'Scheherazade New', serif !important;
363
  caret-color: #c084fc !important;
364
- line-height: 2em !important;
 
365
  }
366
  textarea:focus {
367
  border-color: #c084fc !important;
368
  box-shadow: 0 0 0 3px #7c3aed15 !important;
369
  outline: none !important;
370
  }
 
 
 
 
 
 
 
371
  button.primary {
372
  background: linear-gradient(135deg, #6d28d9, #9333ea, #c084fc) !important;
373
  border: none !important;
374
  border-radius: 12px !important;
375
  color: #fff !important;
376
  font-weight: 800 !important;
377
- font-size: 0.95em !important;
 
378
  letter-spacing: 0.5px !important;
379
  transition: all 0.3s ease !important;
380
- padding: 13px !important;
381
  width: 100% !important;
 
382
  }
383
  button.primary:hover {
384
  box-shadow: 0 6px 24px #7c3aed50 !important;
385
  transform: translateY(-1px) !important;
386
  }
387
- .examples-holder, .examples table {
 
 
 
 
 
 
 
 
 
 
 
388
  background: #130825 !important;
389
  border: 1px solid #6d28d930 !important;
390
  border-radius: 10px !important;
391
- margin-top: 0 !important;
 
 
 
392
  }
393
  .examples table td {
394
  color: #94a3b8 !important;
395
  font-family: 'Lateef', 'Scheherazade New', serif !important;
396
- font-size: 1em !important;
397
  direction: rtl !important;
 
 
 
 
 
 
398
  }
399
  .examples table tr:hover td {
400
  color: #c084fc !important;
401
  background: #1a0533 !important;
402
  cursor: pointer !important;
403
  }
 
 
 
 
 
 
 
 
 
404
  ::-webkit-scrollbar { width: 5px; }
405
  ::-webkit-scrollbar-track { background: #08081a; }
406
  ::-webkit-scrollbar-thumb { background: #6d28d9; border-radius: 3px; }
@@ -410,7 +443,7 @@ HEADER = """
410
  <div style="
411
  background:linear-gradient(135deg,#1a0533 0%,#0f0f2e 60%,#160a2e 100%);
412
  border:1px solid #7c3aed25;border-radius:20px;
413
- padding:32px 28px 24px;margin-bottom:20px;
414
  text-align:center;position:relative;overflow:hidden;">
415
  <div style="
416
  position:absolute;top:0;left:0;right:0;bottom:0;
@@ -425,7 +458,7 @@ HEADER = """
425
  سنڌي اسمن جي سڃاڻپ
426
  </h1>
427
  <p style="
428
- font-family:'Outfit',monospace;
429
  color:#6d28d9;font-size:0.72em;
430
  letter-spacing:3px;margin:0;">
431
  SINDHI NAMED ENTITY RECOGNITION
@@ -434,7 +467,6 @@ HEADER = """
434
  </div>
435
  """
436
 
437
-
438
  EXAMPLES = [
439
  ["شيخ اياز شڪارپور ۾ پيدا ٿيو"],
440
  ["يونيورسٽي آف سنڌ حيدرآباد ۾ آھي"],
@@ -450,7 +482,7 @@ with gr.Blocks(css=CSS, title="سنڌي NER") as demo:
450
  gr.HTML(HEADER)
451
 
452
  with gr.Row():
453
- # ── Left: input + examples + button ──────────
454
  with gr.Column(scale=3):
455
  inp = gr.Textbox(
456
  label="سنڌي جملو لکو",
@@ -458,27 +490,28 @@ with gr.Blocks(css=CSS, title="سنڌي NER") as demo:
458
  lines=4,
459
  rtl=True
460
  )
461
- # Examples inside the same column, above button
 
 
462
  gr.Examples(
463
- label="مثالي جملا",
464
  examples=EXAMPLES,
465
  inputs=inp,
 
466
  )
467
- btn = gr.Button("🔍 ڳوليو", variant="primary")
468
 
469
- # ── Right: summary ────────────────────────────
470
  with gr.Column(scale=2):
471
  summary_out = gr.HTML(value=_empty_summary())
472
 
473
  gr.HTML("<div style='height:6px'></div>")
474
 
475
- # Highlighted result
476
  highlighted_out = gr.HTML(value=_empty_html())
477
 
478
  # Confidence bars
479
  conf_out = gr.HTML()
480
 
481
- # Legend — hidden until search runs
482
  legend_out = gr.HTML(visible=False)
483
 
484
  # CSV download
@@ -496,6 +529,7 @@ with gr.Blocks(css=CSS, title="سنڌي NER") as demo:
496
  </div>
497
  """)
498
 
 
499
  btn.click(
500
  fn=predict_ner,
501
  inputs=inp,
 
23
  BOS_ID = 2
24
  EOS_ID = 3
25
 
26
+ # ── Entity config — Sindhi labels ─────────────────
27
  ENTITY_CONFIG = {
28
  "PERSON": {"color": "#c084fc", "bg": "rgba(192,132,252,0.15)", "sindhi": "ماڻهو"},
29
  "LOCATION": {"color": "#818cf8", "bg": "rgba(129,140,248,0.15)", "sindhi": "جڳهه"},
 
34
  }
35
 
36
  FALLBACK_CFG = {
37
+ "color": "#6b7280",
38
+ "bg": "rgba(107,114,128,0.15)",
39
+ "sindhi": "ادارو", # unknown entities shown as ادارو
40
  }
41
 
42
 
 
134
  <div style="
135
  background:linear-gradient(135deg,#1a0533 0%,#0f0f2e 100%);
136
  border:1px solid #7c3aed30;border-radius:16px;
137
+ padding:24px 28px;
138
+ font-size:1.3em;
139
+ line-height:3.2em;
140
  direction:rtl;text-align:right;
141
  font-family:'Lateef','Scheherazade New',serif;
142
  min-height:90px;">
 
159
  border:1px solid #7c3aed20;border-radius:16px;
160
  padding:40px;text-align:center;min-height:90px;
161
  display:flex;align-items:center;justify-content:center;">
162
+ <span style="color:#4c1d95;font-size:1.2em;
163
  font-family:'Lateef','Scheherazade New',serif;">
164
  ڪو بہ سنڌي جملو لکو
165
  </span>
 
171
  <div style="
172
  background:#1a0533;border:1px solid #7c3aed20;
173
  border-radius:16px;padding:24px;
174
+ text-align:center;color:#4c1d95;
175
+ font-size:1.1em;
176
  font-family:'Lateef','Scheherazade New',serif;">
177
  اعتماد جوڳا نتيجا نہ مليا
178
  </div>
 
183
  return _empty_summary()
184
 
185
  counts = Counter(e["type"] for e in entities)
 
186
  cards = ""
187
 
188
  for etype, cnt in sorted(counts.items(), key=lambda x: -x[1]):
 
193
  border-radius:10px;padding:10px 14px;
194
  display:flex;justify-content:space-between;
195
  align-items:center;margin-bottom:8px;direction:rtl;">
196
+ <span style="color:{cfg['color']};font-weight:600;font-size:1em;
197
  font-family:'Lateef','Scheherazade New',serif;">
198
  {cfg['sindhi']}
199
  </span>
200
  <span style="
201
  background:{cfg['color']};color:#0a0a1a;
202
  font-weight:800;border-radius:20px;
203
+ padding:1px 10px;font-size:0.85em;
204
  min-width:24px;text-align:center;">
205
  {cnt}
206
  </span>
207
  </div>
208
  """
209
 
210
+ # No مجموعي header — just cards directly
211
  return f"""
212
  <div style="
213
  background:linear-gradient(135deg,#1a0533,#0f0f2e);
214
  border:1px solid #7c3aed30;border-radius:16px;
215
+ padding:16px 14px;">
216
+ {cards}
 
 
 
 
 
 
 
 
 
 
217
  </div>
218
  """
219
 
 
223
 
224
  bars = ""
225
  for ent in entities:
226
+ cfg = ENTITY_CONFIG.get(ent["type"], FALLBACK_CFG)
227
+ pct = int(ent["score"] * 100)
228
 
229
  bars += f"""
230
  <div style="margin-bottom:16px;direction:rtl;">
231
  <div style="display:flex;justify-content:space-between;
232
  align-items:center;margin-bottom:6px;">
233
+ <span style="color:#e2e8f0;font-size:1.1em;font-weight:500;
234
  font-family:'Lateef','Scheherazade New',serif;">
235
  {ent['text']}
236
  </span>
 
239
  background:{cfg['color']}18;
240
  border:1px solid {cfg['color']}40;
241
  color:{cfg['color']};
242
+ font-size:0.85em;padding:2px 8px;
243
  border-radius:4px;font-weight:700;
244
  font-family:'Lateef','Scheherazade New',serif;">
245
  {ent['sindhi']}
 
278
  """
279
 
280
  def _build_legend(entities):
281
+ """Show only entity types found in this result."""
282
+ found_types = list(dict.fromkeys(e["type"] for e in entities)) # preserve order
283
  items = ""
284
  for etype in found_types:
285
  cfg = ENTITY_CONFIG.get(etype, FALLBACK_CFG)
286
  items += (
287
  f'<span style="background:{cfg["bg"]};'
288
  f'border:1px solid {cfg["color"]}40;'
289
+ f'color:{cfg["color"]};padding:5px 14px;'
290
+ f'border-radius:6px;font-size:1em;font-weight:600;'
291
  f'font-family:\'Lateef\',\'Scheherazade New\',serif;">'
292
  f'{cfg["sindhi"]}</span>'
293
  )
 
295
  <div style="
296
  background:linear-gradient(135deg,#1a0533,#0f0f2e);
297
  border:1px solid #7c3aed20;border-radius:14px;
298
+ padding:14px 18px;margin-top:4px;">
 
 
 
 
 
 
299
  <div style="display:flex;flex-wrap:wrap;gap:8px;direction:rtl;">
300
  {items}
301
  </div>
 
320
 
321
 
322
  CSS = """
323
+ @import url('https://fonts.googleapis.com/css2?family=Lateef:wght@400;700&family=Scheherazade+New:wght@400;700&family=Outfit:wght@400;600;700;800&display=swap');
324
 
325
+ /* Base — Outfit for UI chrome only */
326
  *, body, .gradio-container {
327
  font-family: 'Outfit', sans-serif !important;
328
  }
 
334
  margin: 0 auto !important;
335
  padding: 16px !important;
336
  }
337
+
338
+ /* Labels */
339
  label > span {
340
  color: #9333ea !important;
341
  font-size: 0.82em !important;
342
  font-weight: 700 !important;
343
  letter-spacing: 0.8px !important;
344
  text-transform: uppercase !important;
345
+ font-family: 'Outfit', sans-serif !important;
346
  }
347
+
348
+ /* Textarea — Lateef font, large size */
349
  textarea {
350
  background: #130825 !important;
351
  border: 1px solid #6d28d960 !important;
352
  border-radius: 14px !important;
353
  color: #e2e8f0 !important;
354
+ font-size: 1.4em !important;
355
  direction: rtl !important;
356
  font-family: 'Lateef', 'Scheherazade New', serif !important;
357
  caret-color: #c084fc !important;
358
+ line-height: 2.2em !important;
359
+ padding: 14px 16px !important;
360
  }
361
  textarea:focus {
362
  border-color: #c084fc !important;
363
  box-shadow: 0 0 0 3px #7c3aed15 !important;
364
  outline: none !important;
365
  }
366
+ textarea::placeholder {
367
+ color: #4c1d95 !important;
368
+ font-family: 'Lateef', 'Scheherazade New', serif !important;
369
+ font-size: 1em !important;
370
+ }
371
+
372
+ /* Search button */
373
  button.primary {
374
  background: linear-gradient(135deg, #6d28d9, #9333ea, #c084fc) !important;
375
  border: none !important;
376
  border-radius: 12px !important;
377
  color: #fff !important;
378
  font-weight: 800 !important;
379
+ font-size: 1em !important;
380
+ font-family: 'Lateef', 'Scheherazade New', serif !important;
381
  letter-spacing: 0.5px !important;
382
  transition: all 0.3s ease !important;
383
+ padding: 14px !important;
384
  width: 100% !important;
385
+ margin-top: 8px !important;
386
  }
387
  button.primary:hover {
388
  box-shadow: 0 6px 24px #7c3aed50 !important;
389
  transform: translateY(-1px) !important;
390
  }
391
+
392
+ /* Examples — below button, clean look */
393
+ .examples-holder {
394
+ background: transparent !important;
395
+ border: none !important;
396
+ padding: 0 !important;
397
+ margin-top: 10px !important;
398
+ }
399
+ .examples-holder > .label-wrap {
400
+ display: none !important;
401
+ }
402
+ .examples table {
403
  background: #130825 !important;
404
  border: 1px solid #6d28d930 !important;
405
  border-radius: 10px !important;
406
+ width: 100% !important;
407
+ }
408
+ .examples table thead {
409
+ display: none !important;
410
  }
411
  .examples table td {
412
  color: #94a3b8 !important;
413
  font-family: 'Lateef', 'Scheherazade New', serif !important;
414
+ font-size: 1.15em !important;
415
  direction: rtl !important;
416
+ text-align: right !important;
417
+ padding: 8px 14px !important;
418
+ border-bottom: 1px solid #1e1040 !important;
419
+ }
420
+ .examples table tr:last-child td {
421
+ border-bottom: none !important;
422
  }
423
  .examples table tr:hover td {
424
  color: #c084fc !important;
425
  background: #1a0533 !important;
426
  cursor: pointer !important;
427
  }
428
+
429
+ /* File download */
430
+ .file-preview {
431
+ background: #130825 !important;
432
+ border: 1px solid #6d28d940 !important;
433
+ border-radius: 10px !important;
434
+ }
435
+
436
+ /* Scrollbar */
437
  ::-webkit-scrollbar { width: 5px; }
438
  ::-webkit-scrollbar-track { background: #08081a; }
439
  ::-webkit-scrollbar-thumb { background: #6d28d9; border-radius: 3px; }
 
443
  <div style="
444
  background:linear-gradient(135deg,#1a0533 0%,#0f0f2e 60%,#160a2e 100%);
445
  border:1px solid #7c3aed25;border-radius:20px;
446
+ padding:28px 28px 22px;margin-bottom:20px;
447
  text-align:center;position:relative;overflow:hidden;">
448
  <div style="
449
  position:absolute;top:0;left:0;right:0;bottom:0;
 
458
  سنڌي اسمن جي سڃاڻپ
459
  </h1>
460
  <p style="
461
+ font-family:'Outfit',sans-serif;
462
  color:#6d28d9;font-size:0.72em;
463
  letter-spacing:3px;margin:0;">
464
  SINDHI NAMED ENTITY RECOGNITION
 
467
  </div>
468
  """
469
 
 
470
  EXAMPLES = [
471
  ["شيخ اياز شڪارپور ۾ پيدا ٿيو"],
472
  ["يونيورسٽي آف سنڌ حيدرآباد ۾ آھي"],
 
482
  gr.HTML(HEADER)
483
 
484
  with gr.Row():
485
+ # ── Left column: input button examples ──
486
  with gr.Column(scale=3):
487
  inp = gr.Textbox(
488
  label="سنڌي جملو لکو",
 
490
  lines=4,
491
  rtl=True
492
  )
493
+ btn = gr.Button("🔍 ڳوليو", variant="primary")
494
+
495
+ # Examples BELOW button
496
  gr.Examples(
 
497
  examples=EXAMPLES,
498
  inputs=inp,
499
+ label=None,
500
  )
 
501
 
502
+ # ── Right column: summary ────────────────────
503
  with gr.Column(scale=2):
504
  summary_out = gr.HTML(value=_empty_summary())
505
 
506
  gr.HTML("<div style='height:6px'></div>")
507
 
508
+ # Highlighted output
509
  highlighted_out = gr.HTML(value=_empty_html())
510
 
511
  # Confidence bars
512
  conf_out = gr.HTML()
513
 
514
+ # Legend — hidden until search, no header text
515
  legend_out = gr.HTML(visible=False)
516
 
517
  # CSV download
 
529
  </div>
530
  """)
531
 
532
+ # Wire up both click and enter
533
  btn.click(
534
  fn=predict_ner,
535
  inputs=inp,