leilaghomashchi commited on
Commit
2823450
·
verified ·
1 Parent(s): b4aab80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -74
app.py CHANGED
@@ -14,8 +14,8 @@ class GroqConfig:
14
  """تنظیمات Groq API"""
15
  api_key: str
16
  base_url: str = "https://api.groq.com/openai/v1"
17
- model: str = "llama-3.1-8b-instant"
18
- max_tokens: int = 1500
19
  temperature: float = 0.1
20
 
21
  class GroqAnonymizer:
@@ -33,37 +33,23 @@ class GroqAnonymizer:
33
 
34
  def _create_system_prompt(self) -> str:
35
  """ایجاد دستورالعمل سیستمی برای Groq"""
36
- return """شما یک سیستم ناشناس‌سازی متن فارسی هستید. وظیفه شما تشخیص و جایگزینی موجودیت‌های حساس در متن است.
37
 
38
- قوانین ناشناس‌سازی:
39
- 1. نام شرکت‌ها را با company-01, company-02, ... جایگزین کنید
40
- 2. نام افراد را با person-01, person-02, ... جایگزین کنید
41
- 3. مبالغ و اعداد را با amount-01, amount-02, ... جایگزین کنید
42
- 4. درصدها را با percent-01, percent-02, ... جایگزین کنید
43
- 5. نام گروه‌ها را با group-01, group-02, ... جایگزین کنید
44
 
45
- نکات مهم:
46
- - اگر همان موجودیت تکرار شود، همان شماره را استفاده کنید
47
- - پیشوندهای افراد (دکتر، مهندس، آقا، خانم) را حفظ کنید
48
- - فقط موجودیت‌های حساس را تغییر دهید، بقیه متن دست نخورده باقی بماند
49
- - خروجی را فقط به صورت JSON با فیلدهای زیر ارائه دهید:
50
- {
51
- "anonymized_text": "متن ناشناس‌سازی شده",
52
- "entities": [
53
- {
54
- "original": "متن اصلی",
55
- "anonymized": "متن جایگزین",
56
- "type": "نوع موجودیت"
57
- }
58
- ],
59
- "statistics": {
60
- "company": تعداد,
61
- "person": تعداد,
62
- "amount": تعداد,
63
- "percent": تعداد,
64
- "group": تعداد
65
- }
66
- }"""
67
 
68
  def _make_api_request(self, text: str) -> Dict[str, Any]:
69
  """ارسال درخواست به Groq API"""
@@ -80,7 +66,7 @@ class GroqAnonymizer:
80
  },
81
  {
82
  "role": "user",
83
- "content": f"لطفاً متن زیر را ناشناس‌سازی کنید:\n\n{text}"
84
  }
85
  ],
86
  "model": self.config.model,
@@ -120,38 +106,53 @@ class GroqAnonymizer:
120
 
121
  content = response["choices"][0]["message"]["content"]
122
 
123
- try:
124
- # حذف markdown formatting
125
- if "```json" in content:
126
- content = content.split("```json")[1].split("```")[0]
127
- elif "```" in content:
128
- content = content.split("```")[1].split("```")[0]
129
-
130
- result = json.loads(content.strip())
131
-
132
- return {
133
- "success": True,
134
- "anonymized_text": result.get("anonymized_text", ""),
135
- "entities": result.get("entities", []),
136
- "statistics": result.get("statistics", {}),
137
- "usage": response.get("usage", {})
138
- }
139
-
140
- except json.JSONDecodeError:
141
- return {
142
- "success": True,
143
- "anonymized_text": content,
144
- "entities": [],
145
- "statistics": {},
146
- "usage": response.get("usage", {}),
147
- "note": "پاسخ به صورت JSON قابل پارس نبود"
148
- }
149
 
150
  except Exception as e:
151
  return {
152
  "success": False,
153
  "error": f"خطا در پردازش: {str(e)}"
154
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
  def create_interface():
157
  """ایجاد رابط کاربری برای Hugging Face Spaces"""
@@ -201,19 +202,28 @@ def create_interface():
201
  این سیستم قادر است نام افراد، شرکت‌ها، مبالغ مالی و درصدها را به صورت هوشمند تشخیص و ناشناس‌سازی کند.
202
  """)
203
 
204
- # نمایش وضعیت API
205
- if api_key_available:
206
  gr.Markdown("""
207
- <div class="success-box">
208
- <strong>سیستم آماده است</strong> - کلید API تنظیم شده
 
209
  </div>
210
  """)
 
 
 
 
 
 
 
211
  else:
212
  gr.Markdown("""
213
- <div class="warning-box">
214
- ⚠️ <strong>کلید API تنظیم نشده</strong> - برای استفاده نیاز به تنظیم GROQ_API_KEY در متغیرهای محیطی
215
  </div>
216
  """)
 
217
 
218
  with gr.Row():
219
  with gr.Column(scale=1):
@@ -228,8 +238,7 @@ def create_interface():
228
  anonymize_btn = gr.Button(
229
  "🔒 ناشناس‌سازی متن",
230
  variant="primary",
231
- size="lg",
232
- interactive=api_key_available
233
  )
234
  clear_btn = gr.Button(
235
  "🗑️ پاک کردن",
@@ -243,6 +252,22 @@ def create_interface():
243
  max_lines=20,
244
  elem_classes=["result-box"]
245
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
  with gr.Row():
248
  with gr.Column():
@@ -252,12 +277,15 @@ def create_interface():
252
 
253
  entities_output = gr.Markdown(label="📋 جزئیات تغییرات")
254
 
255
- def process_text(text: str):
256
  """پردازش متن"""
257
- if not api_key_available:
 
 
 
258
  return (
259
  "",
260
- "❌ کلید API تنظیم نشده است",
261
  "",
262
  ""
263
  )
@@ -271,7 +299,7 @@ def create_interface():
271
  )
272
 
273
  try:
274
- anonymizer = GroqAnonymizer()
275
  result = anonymizer.anonymize_text(text)
276
 
277
  if not result["success"]:
@@ -310,7 +338,7 @@ def create_interface():
310
  usage_md += f"• Token های ورودی: {usage.get('prompt_tokens', 'نامشخص')}\n"
311
  usage_md += f"• Token های خروجی: {usage.get('completion_tokens', 'نامشخص')}\n"
312
  else:
313
- usage_md += "اطلاعات در دسترس نیست"
314
 
315
  # جزئیات موجودیت‌ها
316
  entities = result.get("entities", [])
@@ -339,20 +367,28 @@ def create_interface():
339
  ""
340
  )
341
 
 
 
 
 
 
 
 
 
342
  def clear_all():
343
  """پاک کردن تمام فیلدها"""
344
- return "", "", "", "", ""
345
 
346
  # اتصال رویدادها
347
  anonymize_btn.click(
348
  fn=process_text,
349
- inputs=[input_text],
350
  outputs=[output_text, statistics_output, usage_output, entities_output]
351
  )
352
 
353
  clear_btn.click(
354
  fn=clear_all,
355
- outputs=[input_text, output_text, statistics_output, usage_output, entities_output]
356
  )
357
 
358
  # مثال‌های نمونه
 
14
  """تنظیمات Groq API"""
15
  api_key: str
16
  base_url: str = "https://api.groq.com/openai/v1"
17
+ model: str = "llama-3.1-8b-instant"
18
+ max_tokens: int = 1000
19
  temperature: float = 0.1
20
 
21
  class GroqAnonymizer:
 
33
 
34
  def _create_system_prompt(self) -> str:
35
  """ایجاد دستورالعمل سیستمی برای Groq"""
36
+ return """شما یک سیستم ناشناس‌سازی متن فارسی هستید.
37
 
38
+ وظیفه: تشخیص و جایگزینی موجودیت‌های حساس:
 
 
 
 
 
39
 
40
+ 1. نام شرکت‌ها → company-01, company-02, ...
41
+ 2. نام افراد person-01, person-02, ...
42
+ 3. مبالغ و اعداد amount-01, amount-02, ...
43
+ 4. درصدها percent-01, percent-02, ...
44
+
45
+ نکات:
46
+ - همان موجودیت = همان شماره
47
+ - پیشوندها (دکتر، آقا) را حفظ کنید
48
+ - فقط متن ناشناس‌سازی شده را برگردانید، بدون JSON یا توضیح اضافی
49
+
50
+ مثال:
51
+ ورودی: احمد رضایی مدیرعامل شرکت پارس 100 میلیون تومان درآمد دارد
52
+ خروجی: person-01 مدیرعامل company-01 amount-01 درآمد دارد"""
 
 
 
 
 
 
 
 
 
53
 
54
  def _make_api_request(self, text: str) -> Dict[str, Any]:
55
  """ارسال درخواست به Groq API"""
 
66
  },
67
  {
68
  "role": "user",
69
+ "content": text
70
  }
71
  ],
72
  "model": self.config.model,
 
106
 
107
  content = response["choices"][0]["message"]["content"]
108
 
109
+ # پاک کردن markdown اگر وجود دارد
110
+ if "```" in content:
111
+ lines = content.split('\n')
112
+ clean_lines = []
113
+ skip = False
114
+ for line in lines:
115
+ if line.strip().startswith('```'):
116
+ skip = not skip
117
+ continue
118
+ if not skip:
119
+ clean_lines.append(line)
120
+ content = '\n'.join(clean_lines)
121
+
122
+ # ح��ف خطوط اضافی و فضاهای خالی
123
+ content = content.strip()
124
+
125
+ return {
126
+ "success": True,
127
+ "anonymized_text": content,
128
+ "entities": [], # در حالت ساده entities نداریم
129
+ "statistics": self._count_entities(content),
130
+ "usage": response.get("usage", {})
131
+ }
 
 
 
132
 
133
  except Exception as e:
134
  return {
135
  "success": False,
136
  "error": f"خطا در پردازش: {str(e)}"
137
  }
138
+
139
+ def _count_entities(self, text: str) -> Dict[str, int]:
140
+ """شمارش موجودیت‌ها در متن ناشناس‌سازی شده"""
141
+ import re
142
+
143
+ company_count = len(re.findall(r'company-\d+', text))
144
+ person_count = len(re.findall(r'person-\d+', text))
145
+ amount_count = len(re.findall(r'amount-\d+', text))
146
+ percent_count = len(re.findall(r'percent-\d+', text))
147
+ group_count = len(re.findall(r'group-\d+', text))
148
+
149
+ return {
150
+ "company": company_count,
151
+ "person": person_count,
152
+ "amount": amount_count,
153
+ "percent": percent_count,
154
+ "group": group_count
155
+ }
156
 
157
  def create_interface():
158
  """ایجاد رابط کاربری برای Hugging Face Spaces"""
 
202
  این سیستم قادر است نام افراد، شرکت‌ها، مبالغ مالی و درصدها را به صورت هوشمند تشخیص و ناشناس‌سازی کند.
203
  """)
204
 
205
+ # ورود کلید API اگر در secrets موجود نباشد
206
+ if not api_key_available:
207
  gr.Markdown("""
208
+ <div class="warning-box">
209
+ ⚠️ <strong>کلید API در متغیرهای محیطی یافت نشد</strong><br>
210
+ لطفاً کلید Groq API خود را در زیر وارد کنید یا در Settings > Secrets تنظیم کنید
211
  </div>
212
  """)
213
+
214
+ api_key_input = gr.Textbox(
215
+ label="🔑 کلید Groq API",
216
+ placeholder="gsk_...",
217
+ type="password",
218
+ value=""
219
+ )
220
  else:
221
  gr.Markdown("""
222
+ <div class="success-box">
223
+ <strong>سیستم آماده است</strong> - کلید API تنظیم شده
224
  </div>
225
  """)
226
+ api_key_input = gr.Textbox(visible=False)
227
 
228
  with gr.Row():
229
  with gr.Column(scale=1):
 
238
  anonymize_btn = gr.Button(
239
  "🔒 ناشناس‌سازی متن",
240
  variant="primary",
241
+ size="lg"
 
242
  )
243
  clear_btn = gr.Button(
244
  "🗑️ پاک کردن",
 
252
  max_lines=20,
253
  elem_classes=["result-box"]
254
  )
255
+
256
+ # دکمه کپی
257
+ copy_btn = gr.Button(
258
+ "📋 کپی متن",
259
+ variant="secondary",
260
+ size="sm"
261
+ )
262
+
263
+ # متن برای کپی
264
+ copy_output = gr.Textbox(
265
+ label="📋 متن برای کپی (Ctrl+A و Ctrl+C)",
266
+ lines=3,
267
+ max_lines=10,
268
+ visible=False,
269
+ interactive=True
270
+ )
271
 
272
  with gr.Row():
273
  with gr.Column():
 
277
 
278
  entities_output = gr.Markdown(label="📋 جزئیات تغییرات")
279
 
280
+ def process_text(text: str, api_key_manual: str = ""):
281
  """پردازش متن"""
282
+ # تعیین کلید API - اولویت با manual input
283
+ final_api_key = api_key_manual.strip() if api_key_manual.strip() else os.getenv("GROQ_API_KEY")
284
+
285
+ if not final_api_key:
286
  return (
287
  "",
288
+ "❌ کلید API وارد نشده است. لطفاً در فیلد بالا وارد کنید یا در Settings تنظیم کنید.",
289
  "",
290
  ""
291
  )
 
299
  )
300
 
301
  try:
302
+ anonymizer = GroqAnonymizer(api_key=final_api_key)
303
  result = anonymizer.anonymize_text(text)
304
 
305
  if not result["success"]:
 
338
  usage_md += f"• Token های ورودی: {usage.get('prompt_tokens', 'نامشخص')}\n"
339
  usage_md += f"• Token های خروجی: {usage.get('completion_tokens', 'نامشخص')}\n"
340
  else:
341
+ usage_md += " پردازش با موفقیت انجام شد"
342
 
343
  # جزئیات موجودیت‌ها
344
  entities = result.get("entities", [])
 
367
  ""
368
  )
369
 
370
+ def copy_text(text_to_copy):
371
+ """تابع کپی متن"""
372
+ if not text_to_copy.strip():
373
+ return gr.Textbox(visible=False), "⚠️ متنی برای کپی وجود ندارد"
374
+
375
+ # نمایش textbox با محتوای قابل کپی
376
+ return gr.Textbox(value=text_to_copy, visible=True), "✅ متن در کادر زیر آماده کپی است (Ctrl+A سپس Ctrl+C)"
377
+
378
  def clear_all():
379
  """پاک کردن تمام فیلدها"""
380
+ return "", "", "", "", "", gr.Textbox(visible=False)
381
 
382
  # اتصال رویدادها
383
  anonymize_btn.click(
384
  fn=process_text,
385
+ inputs=[input_text, api_key_input],
386
  outputs=[output_text, statistics_output, usage_output, entities_output]
387
  )
388
 
389
  clear_btn.click(
390
  fn=clear_all,
391
+ outputs=[input_text, output_text, statistics_output, usage_output, entities_output, copy_output]
392
  )
393
 
394
  # مثال‌های نمونه