Hamid191 commited on
Commit
5a65a78
·
verified ·
1 Parent(s): a6cc2d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +237 -43
app.py CHANGED
@@ -1,59 +1,253 @@
 
 
 
 
 
1
  import os
 
2
  import sys
 
3
 
4
- from .config import debug_enabled
5
- from .verdict_agent import VerdictAgent
 
 
 
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- def main(argv=None, ingestor=None, agent=None):
9
- argv = list(sys.argv if argv is None else argv)
10
- debug = "--debug" in argv
11
- argv = [arg for arg in argv if arg != "--debug"]
12
- if debug:
13
- os.environ["HAQEEQAT_DEBUG"] = "1"
14
- if len(argv) != 2:
15
- print(
16
- "Usage: python -m verification.app [--debug] <image|audio|video file>",
17
- file=sys.stderr,
18
- )
19
- return 2
20
- path = argv[1]
21
 
22
- if ingestor is None:
 
 
 
 
 
 
 
 
 
 
 
23
  from ingestion.ingestor import HaqeeqatIngestor
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- ingestor = HaqeeqatIngestor()
26
- if agent is None:
27
- agent = VerdictAgent()
 
 
 
28
 
29
- report = ingestor.ingest(path)
30
- text = report["combined_text"]
31
- if not text.strip():
32
- print("No text could be extracted from the file.", file=sys.stderr)
33
- return 1
34
 
 
 
 
 
 
 
 
35
  result = agent.run(text)
36
- if debug_enabled():
37
- print(f"DEBUG extracted_text: {text!r}")
38
- print(f"DEBUG claim_urdu: {result.claim_urdu}")
39
- print(f"DEBUG claim_english: {result.claim_english}")
40
- print(f"DEBUG verdict: {result.verdict.value if result.verdict else None}")
41
- print(f"DEBUG confidence: {result.confidence:.2f}")
42
- print(f"DEBUG evidence_count: {len(result.evidence)}")
43
- for i, item in enumerate(result.evidence):
44
- print(f"DEBUG evidence[{i}]: {item.source_domain} | {item.title} | {item.url}")
45
  if not result.is_checkworthy:
46
- print("کوئی قابلِ تصدیق دعویٰ نہیں")
47
- return 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- print(f"دعویٰ: {result.claim_urdu}")
50
- print(f"فیصلہ: {result.verdict_label_urdu} (confidence {result.confidence:.2f})")
51
- print(f"وجوہات: {result.reasoning_urdu}")
52
- print("ذرائع:")
53
- for item in result.evidence[:3]:
54
- print(f" - {item.title} ({item.url})")
55
- return 0
56
 
57
 
58
  if __name__ == "__main__":
59
- raise SystemExit(main())
 
 
1
+ """Haqeeqat Check — Gradio interface for Hugging Face Spaces.
2
+
3
+ Run locally: python app.py
4
+ """
5
+
6
  import os
7
+ import subprocess
8
  import sys
9
+ from pathlib import Path
10
 
11
+ # ---------------------------------------------------------------------------
12
+ # Ensure GROQ_API_KEY is loaded from Space secrets before any module import
13
+ # ---------------------------------------------------------------------------
14
+ if not os.environ.get("GROQ_API_KEY"):
15
+ pass # will be read at runtime by verification/config.py
16
 
17
+ import gradio as gr
18
+
19
+ try:
20
+ import spaces
21
+ _HAS_SPACES = True
22
+ except ImportError:
23
+ _HAS_SPACES = False
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # Model bootstrap — runs once at import time
27
+ # ---------------------------------------------------------------------------
28
+ _MODEL_FILES = ["best_norm_ED.pth", "yolov8m_UrduDoc.pt"]
29
+
30
+
31
+ def _ensure_models():
32
+ """Download OCR + Whisper models if not already present."""
33
+ root = Path(__file__).resolve().parent
34
+ models_dir = root / "models"
35
+ if os.environ.get("SPACE_ID"):
36
+ models_dir = Path("/home/user/app/models")
37
+ if all((models_dir / name).is_file() for name in _MODEL_FILES):
38
+ return
39
+ subprocess.run(
40
+ [sys.executable, str(root / "download_models.py")],
41
+ check=True,
42
+ )
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ _ensure_models()
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Lazy singletons — heavy imports deferred until first request
49
+ # ---------------------------------------------------------------------------
50
+ _ingestor = None
51
+ _agent = None
52
+
53
+
54
+ def _get_ingestor():
55
+ global _ingestor
56
+ if _ingestor is None:
57
  from ingestion.ingestor import HaqeeqatIngestor
58
+ _ingestor = HaqeeqatIngestor()
59
+ return _ingestor
60
+
61
+
62
+ def _get_agent():
63
+ global _agent
64
+ if _agent is None:
65
+ from verification.verdict_agent import VerdictAgent
66
+ _agent = VerdictAgent()
67
+ return _agent
68
+
69
+
70
+ # ---------------------------------------------------------------------------
71
+ # Labels
72
+ # ---------------------------------------------------------------------------
73
+ URDU_LABELS = {"sacha": "سچا", "jhoota": "جھوٹا", "mashkook": "مشکوک"}
74
+ ENGLISH_LABELS = {"sacha": "True", "jhoota": "False", "mashkook": "Unverified"}
75
+ VERDICT_ICONS = {"sacha": "✔", "jhoota": "✗", "mashkook": "?"}
76
+
77
+
78
+ # ---------------------------------------------------------------------------
79
+ # Core processing
80
+ # ---------------------------------------------------------------------------
81
+
82
+ if _HAS_SPACES:
83
+ @spaces.GPU
84
+ def _gpu_startup():
85
+ """Dummy function so Gradio 6.x detects a GPU-capable handler at startup."""
86
+ pass
87
+
88
+
89
+ def _resolve_path(file_data) -> str | None:
90
+ """Extract a filesystem path from a Gradio FileData object or plain string."""
91
+ if isinstance(file_data, str):
92
+ return file_data
93
+ # Gradio 6.x FileData: object with .path or dict-like access
94
+ if hasattr(file_data, "path"):
95
+ return file_data.path
96
+ if isinstance(file_data, dict):
97
+ return file_data.get("path")
98
+ return None
99
+
100
+
101
+ def _process_media_inner(file_data) -> tuple[str, str]:
102
+ """Ingest a media file, verify claims, return (verdict_box, reasoning_box)."""
103
+ if file_data is None:
104
+ return "کوئی فائل منتخب نہیں / No file selected.", ""
105
+
106
+ # Gradio 6.x passes a FileData object; extract the path string
107
+ file_path = _resolve_path(file_data)
108
+ if not file_path:
109
+ return "کوئی فائل منتخب نہیں / No file selected.", ""
110
+
111
+ ingestor = _get_ingestor()
112
+ agent = _get_agent()
113
+
114
+ report = ingestor.ingest(file_path)
115
+ text = report.get("combined_text", "")
116
+ if not text or not text.strip():
117
+ return "کوئی متن نکالا نہیں جا سکا / No text was extracted from the file.", ""
118
+
119
+ if report.get("metadata", {}).get("ocr_garbled"):
120
+ return (
121
+ "تصحیح OCR ناکام رہی / OCR failed to read this image properly.\n"
122
+ "براہ کرم واضح تصویر اپ لوڈ کریں / Please upload a clearer image."
123
+ ), f"استخراج شدہ متن:\n{text[:300]}"
124
 
125
+ result = agent.run(text)
126
+
127
+ if not result.is_checkworthy:
128
+ return "کوئی قابلِ تصدیق دعویٰ نہیں / No checkworthy claim found.", (
129
+ f"استخراج شدہ متن:\n{text[:500]}"
130
+ )
131
 
132
+ verdict_box = _format_verdict(result)
133
+ reasoning_box = _format_reasoning(result)
134
+ return verdict_box, reasoning_box
 
 
135
 
136
+
137
+ def _process_text(text: str) -> tuple[str, str]:
138
+ """Verify a pasted text claim, return (verdict_box, reasoning_box)."""
139
+ if not text or not text.strip():
140
+ return "براہ کرم متن لکھیں / Please enter some text.", ""
141
+
142
+ agent = _get_agent()
143
  result = agent.run(text)
144
+
 
 
 
 
 
 
 
 
145
  if not result.is_checkworthy:
146
+ return "کوئی قابلِ تصدیق دعویٰ نہیں / No checkworthy claim found.", ""
147
+
148
+ verdict_box = _format_verdict(result)
149
+ reasoning_box = _format_reasoning(result)
150
+ return verdict_box, reasoning_box
151
+
152
+
153
+ # Wrap _process_media_inner with @spaces.GPU on HF so UTRNet gets a GPU.
154
+ if _HAS_SPACES:
155
+ @spaces.GPU
156
+ def _process_media(file_data) -> tuple[str, str]:
157
+ return _process_media_inner(file_data)
158
+ else:
159
+ _process_media = _process_media_inner
160
+
161
+
162
+ def _format_verdict(result) -> str:
163
+ key = result.verdict.value
164
+ icon = VERDICT_ICONS[key]
165
+ urdu_label = URDU_LABELS[key]
166
+ eng_label = ENGLISH_LABELS[key]
167
+ lines = [
168
+ f"{icon} فیصلہ / Verdict: {urdu_label} ({eng_label})",
169
+ f" Confidence: {result.confidence:.0%}",
170
+ "",
171
+ f"دعویٰ / Claim:",
172
+ f" {result.claim_urdu}",
173
+ f" {result.claim_english}",
174
+ ]
175
+ return "\n".join(lines)
176
+
177
+
178
+ def _format_reasoning(result) -> str:
179
+ parts = [
180
+ "وجوہات / Reasoning:",
181
+ "",
182
+ result.reasoning_urdu,
183
+ "",
184
+ result.reasoning_english,
185
+ ]
186
+ if result.evidence:
187
+ parts.append("")
188
+ parts.append("شواہد / Sources:")
189
+ for item in result.evidence:
190
+ parts.append(f" [{item.source_domain}] {item.title}")
191
+ parts.append(f" {item.url}")
192
+ if item.snippet:
193
+ parts.append(f" {item.snippet[:200]}")
194
+ parts.append("")
195
+ return "\n".join(parts)
196
+
197
+
198
+ # ---------------------------------------------------------------------------
199
+ # Gradio UI
200
+ # ---------------------------------------------------------------------------
201
+ def build_ui() -> gr.Blocks:
202
+ with gr.Blocks(
203
+ title="Haqeeqat Check — Urdu Misinformation Detector",
204
+ ) as demo:
205
+ gr.Markdown(
206
+ "# Uraan Techathon 2.0\n"
207
+ "# Haqeeqat Check: Urdu Misinformation Detector\n"
208
+ "### حقیقت چیک: اردو غلط معلومات کی جانچ پڑتال"
209
+ )
210
+
211
+ with gr.Tabs():
212
+ with gr.Tab("Image"):
213
+ img_input = gr.Image(label="تصویر اپ لوڈ کریں / Upload Image", type="filepath")
214
+ img_btn = gr.Button("Check / چیک کریں", variant="primary")
215
+
216
+ with gr.Tab("Audio"):
217
+ aud_input = gr.Audio(label="آڈیو اپ لوڈ کریں / Upload Audio", type="filepath")
218
+ aud_btn = gr.Button("Check / چیک کریں", variant="primary")
219
+
220
+ with gr.Tab("Video"):
221
+ vid_input = gr.Video(label="ویڈیو اپ لوڈ کریں / Upload Video")
222
+ vid_btn = gr.Button("Check / چیک کریں", variant="primary")
223
+
224
+ with gr.Tab("Paste Text"):
225
+ txt_input = gr.Textbox(
226
+ label="اردو متن لکھیں یا پیسٹ کریں / Enter or paste Urdu text",
227
+ lines=5,
228
+ )
229
+ txt_btn = gr.Button("Check / چیک کریں", variant="primary")
230
+
231
+ gr.Markdown("---")
232
+ verdict_output = gr.Textbox(
233
+ label="فیصلہ / Verdict",
234
+ lines=8,
235
+ interactive=False,
236
+ )
237
+ reasoning_output = gr.Textbox(
238
+ label="وجوہات و شواہد / Reasoning & Sources",
239
+ lines=14,
240
+ interactive=False,
241
+ )
242
+
243
+ img_btn.click(fn=_process_media, inputs=img_input, outputs=[verdict_output, reasoning_output])
244
+ aud_btn.click(fn=_process_media, inputs=aud_input, outputs=[verdict_output, reasoning_output])
245
+ vid_btn.click(fn=_process_media, inputs=vid_input, outputs=[verdict_output, reasoning_output])
246
+ txt_btn.click(fn=_process_text, inputs=txt_input, outputs=[verdict_output, reasoning_output])
247
 
248
+ return demo
 
 
 
 
 
 
249
 
250
 
251
  if __name__ == "__main__":
252
+ demo = build_ui()
253
+ demo.launch(theme=gr.themes.Soft())