Spaces:
Sleeping
Sleeping
| import requests | |
| import json | |
| import gradio as gr | |
| from typing import Dict, Any | |
| import os | |
| from dataclasses import dataclass | |
| class GroqConfig: | |
| """تنظیمات Groq API""" | |
| api_key: str | |
| base_url: str = "https://api.groq.com/openai/v1" | |
| model: str = "llama-3.1-8b-instant" | |
| max_tokens: int = 1000 | |
| temperature: float = 0.1 | |
| class GroqAnonymizer: | |
| """سیستم ناشناسسازی با استفاده از Groq""" | |
| def __init__(self, api_key: str = None): | |
| if api_key is None: | |
| api_key = os.getenv("GROQ_API_KEY") | |
| if not api_key: | |
| raise ValueError("کلید API یافت نشد") | |
| self.config = GroqConfig(api_key=api_key) | |
| self.system_prompt = self._create_system_prompt() | |
| def _create_system_prompt(self) -> str: | |
| """ایجاد دستورالعمل سیستمی برای Groq""" | |
| return """Replace these in Persian text: | |
| - Company names with: company-01, company-02, etc. | |
| - Person names with: person-01, person-02, etc. | |
| - Numbers/amounts with: amount-01, amount-02, etc. | |
| - Percentages with: percent-01, percent-02, etc. | |
| Only return the anonymized text, nothing else.""" | |
| def _make_api_request(self, text: str) -> Dict[str, Any]: | |
| """ارسال درخواست به Groq API""" | |
| headers = { | |
| "Authorization": f"Bearer {self.config.api_key}", | |
| "Content-Type": "application/json" | |
| } | |
| payload = { | |
| "messages": [ | |
| { | |
| "role": "system", | |
| "content": self.system_prompt | |
| }, | |
| { | |
| "role": "user", | |
| "content": text | |
| } | |
| ], | |
| "model": self.config.model, | |
| "temperature": self.config.temperature, | |
| "max_tokens": self.config.max_tokens | |
| } | |
| try: | |
| response = requests.post( | |
| f"{self.config.base_url}/chat/completions", | |
| headers=headers, | |
| json=payload, | |
| timeout=30 | |
| ) | |
| response.raise_for_status() | |
| return response.json() | |
| except requests.exceptions.RequestException as e: | |
| raise Exception(f"خطا در ارتباط با Groq API: {str(e)}") | |
| def anonymize_text(self, text: str) -> Dict[str, Any]: | |
| """ناشناسسازی متن با استفاده از Groq""" | |
| if not text.strip(): | |
| return { | |
| "success": False, | |
| "error": "متن ورودی خالی است" | |
| } | |
| try: | |
| response = self._make_api_request(text) | |
| if "choices" not in response or not response["choices"]: | |
| return { | |
| "success": False, | |
| "error": "پاسخ نامعتبر از API" | |
| } | |
| content = response["choices"][0]["message"]["content"] | |
| # پاک کردن markdown اگر وجود دارد | |
| if "```" in content: | |
| lines = content.split('\n') | |
| clean_lines = [] | |
| skip = False | |
| for line in lines: | |
| if line.strip().startswith('```'): | |
| skip = not skip | |
| continue | |
| if not skip: | |
| clean_lines.append(line) | |
| content = '\n'.join(clean_lines) | |
| # حذف خطوط اضافی و فضاهای خالی | |
| content = content.strip() | |
| return { | |
| "success": True, | |
| "anonymized_text": content, | |
| "entities": [], # در حالت ساده entities نداریم | |
| "statistics": self._count_entities(content), | |
| "usage": response.get("usage", {}) | |
| } | |
| except Exception as e: | |
| return { | |
| "success": False, | |
| "error": f"خطا در پردازش: {str(e)}" | |
| } | |
| def _count_entities(self, text: str) -> Dict[str, int]: | |
| """شمارش موجودیتها در متن ناشناسسازی شده""" | |
| import re | |
| company_count = len(re.findall(r'company-\d+', text)) | |
| person_count = len(re.findall(r'person-\d+', text)) | |
| amount_count = len(re.findall(r'amount-\d+', text)) | |
| percent_count = len(re.findall(r'percent-\d+', text)) | |
| group_count = len(re.findall(r'group-\d+', text)) | |
| return { | |
| "company": company_count, | |
| "person": person_count, | |
| "amount": amount_count, | |
| "percent": percent_count, | |
| "group": group_count | |
| } | |
| def create_interface(): | |
| """ایجاد رابط کاربری""" | |
| # بررسی وجود کلید API | |
| api_key_available = bool(os.getenv("GROQ_API_KEY")) | |
| # CSS سفارشی | |
| custom_css = """ | |
| .gradio-container { | |
| font-family: 'Tahoma', 'Arial', sans-serif !important; | |
| direction: rtl; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| .result-box { | |
| background-color: #f0f8ff; | |
| border: 1px solid #ddd; | |
| border-radius: 8px; | |
| padding: 15px; | |
| } | |
| .warning-box { | |
| background-color: #fff3cd; | |
| border: 1px solid #ffeaa7; | |
| border-radius: 8px; | |
| padding: 10px; | |
| color: #856404; | |
| } | |
| .success-box { | |
| background-color: #d4edda; | |
| border: 1px solid #c3e6cb; | |
| border-radius: 8px; | |
| padding: 10px; | |
| color: #155724; | |
| } | |
| """ | |
| with gr.Blocks(css=custom_css, title="ناشناسسازی متن فارسی", theme=gr.themes.Soft()) as interface: | |
| # عنوان | |
| gr.Markdown(""" | |
| # 🔒 سیستم ناشناسسازی متن فارسی | |
| ### قدرتگرفته از Groq AI برای تشخیص و حفاظت از اطلاعات حساس | |
| """) | |
| # نمایش وضعیت API | |
| if api_key_available: | |
| gr.Markdown(""" | |
| <div class="success-box"> | |
| ✅ <strong>سیستم آماده است</strong> - کلید API تنظیم شده | |
| </div> | |
| """) | |
| api_key_input = gr.Textbox(visible=False, value="") | |
| else: | |
| gr.Markdown(""" | |
| <div class="warning-box"> | |
| ⚠️ <strong>کلید API تنظیم نشده</strong><br> | |
| لطفاً کلید Groq API خود را در زیر وارد کنید | |
| </div> | |
| """) | |
| api_key_input = gr.Textbox( | |
| label="🔑 کلید Groq API", | |
| placeholder="gsk_...", | |
| type="password", | |
| value="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" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| input_text = gr.Textbox( | |
| label="📝 متن ورودی", | |
| placeholder="متن خود را اینجا وارد کنید...", | |
| lines=10, | |
| max_lines=20 | |
| ) | |
| with gr.Row(): | |
| anonymize_btn = gr.Button( | |
| "🔒 ناشناسسازی متن", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| clear_btn = gr.Button( | |
| "🗑️ پاک کردن", | |
| variant="secondary" | |
| ) | |
| with gr.Column(scale=1): | |
| output_text = gr.Textbox( | |
| label="🎯 متن ناشناسسازی شده", | |
| lines=10, | |
| max_lines=20, | |
| elem_classes=["result-box"] | |
| ) | |
| # دکمه کپی | |
| copy_btn = gr.Button( | |
| "📋 کپی متن", | |
| variant="secondary", | |
| size="sm" | |
| ) | |
| # متن برای کپی | |
| copy_output = gr.Textbox( | |
| label="📋 متن برای کپی (Ctrl+A و Ctrl+C)", | |
| lines=3, | |
| max_lines=10, | |
| visible=False, | |
| interactive=True | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| statistics_output = gr.Markdown(label="📊 آمار تشخیص") | |
| with gr.Column(): | |
| usage_output = gr.Markdown(label="⚡ اطلاعات پردازش") | |
| entities_output = gr.Markdown(label="📋 جزئیات تغییرات") | |
| def process_text(text: str, api_key_manual: str = ""): | |
| """پردازش متن""" | |
| # حل مشکل NoneType | |
| if api_key_manual is None: | |
| api_key_manual = "" | |
| # تعیین کلید API | |
| final_api_key = "" | |
| if api_key_manual and api_key_manual.strip(): | |
| final_api_key = api_key_manual.strip() | |
| elif os.getenv("GROQ_API_KEY"): | |
| final_api_key = os.getenv("GROQ_API_KEY") | |
| if not final_api_key: | |
| return ( | |
| "", | |
| "❌ کلید API وارد نشده است", | |
| "", | |
| "" | |
| ) | |
| if not text or not text.strip(): | |
| return ( | |
| "", | |
| "❌ لطفاً متن ورودی را وارد کنید", | |
| "", | |
| "" | |
| ) | |
| try: | |
| anonymizer = GroqAnonymizer(api_key=final_api_key) | |
| result = anonymizer.anonymize_text(text) | |
| if not result["success"]: | |
| return ( | |
| "", | |
| f"❌ خطا: {result['error']}", | |
| "", | |
| "" | |
| ) | |
| # آمار | |
| stats = result.get("statistics", {}) | |
| stats_md = "📊 **آمار تشخیص:**\n\n" | |
| total = sum(stats.values()) if stats else 0 | |
| stats_md += f"🔢 **کل موارد:** {total}\n\n" | |
| type_names = { | |
| 'company': 'شرکتها', | |
| 'person': 'افراد', | |
| 'group': 'گروهها', | |
| 'amount': 'مبالغ', | |
| 'percent': 'درصدها' | |
| } | |
| if stats: | |
| for key, value in stats.items(): | |
| if value > 0: | |
| name = type_names.get(key, key) | |
| stats_md += f"• {name}: **{value}** مورد\n" | |
| # اطلاعات پردازش | |
| usage = result.get("usage", {}) | |
| usage_md = "⚡ **اطلاعات پردازش:**\n\n" | |
| if usage: | |
| usage_md += f"• مدل: Llama 3.1\n" | |
| usage_md += f"• Token های ورودی: {usage.get('prompt_tokens', 'نامشخص')}\n" | |
| usage_md += f"• Token های خروجی: {usage.get('completion_tokens', 'نامشخص')}\n" | |
| else: | |
| usage_md += "✅ پردازش با موفقیت انجام شد" | |
| # جزئیات موجودیتها | |
| entities_md = "📋 **جزئیات تغییرات:**\n\n" | |
| entities_md += "ناشناسسازی با موفقیت انجام شد" | |
| return ( | |
| result["anonymized_text"], | |
| stats_md, | |
| usage_md, | |
| entities_md | |
| ) | |
| except Exception as e: | |
| return ( | |
| "", | |
| f"❌ خطای غیرمنتظره: {str(e)}", | |
| "", | |
| "" | |
| ) | |
| def copy_text(text_to_copy): | |
| """تابع کپی متن""" | |
| if not text_to_copy or not text_to_copy.strip(): | |
| return gr.Textbox(visible=False), "⚠️ متنی برای کپی وجود ندارد" | |
| return gr.Textbox(value=text_to_copy, visible=True), "✅ متن در کادر زیر آماده کپی است" | |
| def clear_all(): | |
| """پاک کردن تمام فیلدها""" | |
| return "", "", "", "", "", gr.Textbox(visible=False) | |
| # اتصال رویدادها | |
| anonymize_btn.click( | |
| fn=process_text, | |
| inputs=[input_text, api_key_input], | |
| outputs=[output_text, statistics_output, usage_output, entities_output] | |
| ) | |
| copy_btn.click( | |
| fn=copy_text, | |
| inputs=[output_text], | |
| outputs=[copy_output, statistics_output] | |
| ) | |
| clear_btn.click( | |
| fn=clear_all, | |
| outputs=[input_text, output_text, statistics_output, usage_output, entities_output, copy_output] | |
| ) | |
| # مثالهای نمونه | |
| gr.Examples( | |
| examples=[ | |
| ["ایران خودرو در اسفندماه سال 1402 حدود 23 هزار و 296 میلیارد تومان درآمد کسب کرد که در مقایسه با بهمن 4.58 درصد افزایش داشت."], | |
| ["مهدی اخوان بهابادی، مدیرعامل همراه اول، اعلام کرد درآمد عملیاتی شرکت با رشد 37 درصدی به 70 هزار و 677 میلیارد تومان رسیده است."], | |
| ["بانک پاسارگاد با شناسایی سود خالص 155 هزار میلیارد ریالی در رده دوم سودآورترین بانکهای کشور قرار گرفت."] | |
| ], | |
| inputs=input_text, | |
| label="📚 مثالهای آزمایشی" | |
| ) | |
| # راهنمای استفاده | |
| gr.Markdown(""" | |
| --- | |
| ### 🎯 **ویژگیها:** | |
| - 🏢 تشخیص نام شرکتها و سازمانها | |
| - 👤 تشخیص نام افراد با پیشوندهای مختلف | |
| - 💰 تشخیص مبالغ مالی و اعداد | |
| - 📊 تشخیص درصدها با فرمتهای مختلف | |
| """) | |
| return interface | |
| # اجرای برنامه | |
| if __name__ == "__main__": | |
| interface = create_interface() | |
| interface.launch() | |