Spaces:
Build error
Build error
| """ | |
| وظائف مساعدة للتعامل مع APIs (Hugging Face و Supabase) | |
| """ | |
| import requests | |
| import json | |
| from typing import Dict, List, Optional | |
| import config | |
| def call_hf_api(prompt: str, max_tokens: int = 500, temperature: float = 0.7) -> Optional[str]: | |
| """ | |
| استدعاء Hugging Face Inference API | |
| Args: | |
| prompt: النص المُدخل للنموذج | |
| max_tokens: الحد الأقصى للـ tokens في الرد | |
| temperature: درجة العشوائية (0-1) | |
| Returns: | |
| النص المُولّد أو None في حالة الخطأ | |
| """ | |
| if not config.HF_API_TOKEN: | |
| return None | |
| headers = { | |
| "Authorization": f"Bearer {config.HF_API_TOKEN}", | |
| "Content-Type": "application/json" | |
| } | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": { | |
| "max_new_tokens": max_tokens, | |
| "temperature": temperature, | |
| "top_p": 0.9, | |
| "return_full_text": False | |
| } | |
| } | |
| try: | |
| response = requests.post( | |
| config.HF_API_URL, | |
| headers=headers, | |
| json=payload, | |
| timeout=30 | |
| ) | |
| if response.status_code == 200: | |
| result = response.json() | |
| if isinstance(result, list) and len(result) > 0: | |
| return result[0].get("generated_text", "") | |
| return result.get("generated_text", "") | |
| else: | |
| print(f"خطأ في API: {response.status_code} - {response.text}") | |
| return None | |
| except Exception as e: | |
| print(f"خطأ في استدعاء HF API: {str(e)}") | |
| return None | |
| def generate_curriculum(user_profile: Dict, hub_id: str) -> Optional[Dict]: | |
| """ | |
| توليد منهج مخصص بناءً على ملف المستخدم | |
| Args: | |
| user_profile: بيانات المستخدم | |
| hub_id: معرف المحور المختار | |
| Returns: | |
| المنهج المُولّد أو None | |
| """ | |
| hub = config.LEARNING_HUBS.get(hub_id, {}) | |
| prompt = f"""أنت مصمم مناهج تعليمية خبير. مهمتك توليد خطة تعلم لمدة {config.PLAN_DURATION_WEEKS} أسبوعاً. | |
| معلومات المستخدم: | |
| - الاسم: {user_profile.get('name', 'غير محدد')} | |
| - المستوى: {user_profile.get('level', 'مبتدئ')} | |
| - الوقت المتاح أسبوعياً: {user_profile.get('available_hours', 10)} ساعات | |
| - أسلوب التعلم المفضل: {user_profile.get('learning_style', 'مختلط')} | |
| المحور المطلوب: {hub.get('name', 'غير محدد')} | |
| ولّد خطة تعلم بصيغة JSON تحتوي على 12 وحدة أسبوعية. كل وحدة يجب أن تحتوي على: | |
| - week: رقم الأسبوع | |
| - unit_title: عنوان الوحدة | |
| - estimated_time_mins: الوقت المقدر بالدقائق | |
| - lessons: قائمة بالدروس (كل درس له: title, duration_mins, type, description) | |
| - experiment: تجربة عملية (title, description, deliverable) | |
| مثال على البنية: | |
| {{ | |
| "curriculum": [ | |
| {{ | |
| "week": 1, | |
| "unit_title": "...", | |
| "estimated_time_mins": 600, | |
| "lessons": [...], | |
| "experiment": {{...}} | |
| }} | |
| ] | |
| }} | |
| ردّ فقط بصيغة JSON بدون أي نص إضافي.""" | |
| # محاولة استدعاء API | |
| response = call_hf_api(prompt, max_tokens=2000, temperature=0.7) | |
| if response: | |
| try: | |
| # محاولة استخراج JSON من الرد | |
| json_start = response.find("{") | |
| json_end = response.rfind("}") + 1 | |
| if json_start != -1 and json_end > json_start: | |
| json_str = response[json_start:json_end] | |
| return json.loads(json_str) | |
| except: | |
| pass | |
| # في حالة الفشل، إرجاع منهج افتراضي | |
| return generate_default_curriculum(hub_id) | |
| def generate_default_curriculum(hub_id: str) -> Dict: | |
| """ | |
| توليد منهج افتراضي في حالة عدم توفر API | |
| """ | |
| hub = config.LEARNING_HUBS.get(hub_id, config.LEARNING_HUBS["ai_intro"]) | |
| curriculum = [] | |
| for week in range(1, 13): | |
| unit = { | |
| "week": week, | |
| "unit_title": f"الوحدة {week}: {hub['name']} - جزء {week}", | |
| "estimated_time_mins": 480, | |
| "lessons": [ | |
| { | |
| "title": f"درس {week}.1: المفاهيم الأساسية", | |
| "duration_mins": 120, | |
| "type": "concept", | |
| "description": f"شرح المفاهيم الأساسية في الأسبوع {week}" | |
| }, | |
| { | |
| "title": f"درس {week}.2: التطبيق العملي", | |
| "duration_mins": 180, | |
| "type": "practical", | |
| "description": f"تطبيق عملي على ما تم تعلمه" | |
| } | |
| ], | |
| "experiment": { | |
| "title": f"تجربة الأسبوع {week}", | |
| "description": f"مشروع تطبيقي لتعزيز الفهم", | |
| "deliverable": "ملف أو تقرير" | |
| } | |
| } | |
| curriculum.append(unit) | |
| return {"curriculum": curriculum} | |
| def generate_lesson_content(lesson_title: str, user_context: Dict) -> str: | |
| """ | |
| توليد محتوى درس مفصل | |
| """ | |
| prompt = f"""أنت مدرس متخصص. اكتب درساً تعليمياً قصيراً (5-10 دقائق قراءة) عن: | |
| {lesson_title} | |
| الدرس يجب أن يتضمن: | |
| 1. الفكرة المركزية (ملخص في سطرين) | |
| 2. شرح مبسط مع أمثلة واقعية | |
| 3. نقاط رئيسية (3-5 نقاط) | |
| 4. سؤال للتفكير | |
| 5. مصادر للمتابعة (اختياري) | |
| اكتب بأسلوب واضح ومشجع.""" | |
| response = call_hf_api(prompt, max_tokens=800) | |
| if response: | |
| return response | |
| # محتوى افتراضي | |
| return f"""# {lesson_title} | |
| ## الفكرة المركزية 💡 | |
| هذا درس تعليمي يهدف إلى تعريفك بالمفهوم الأساسي وتطبيقاته العملية. | |
| ## الشرح 📖 | |
| سنستكشف معاً هذا الموضوع المهم من خلال أمثلة واقعية وتطبيقات عملية تساعدك على الفهم العميق. | |
| ## النقاط الرئيسية ⭐ | |
| 1. المفهوم الأساسي وأهميته | |
| 2. التطبيقات العملية في الحياة اليومية | |
| 3. خطوات التنفيذ والممارسة | |
| 4. الأخطاء الشائعة وكيفية تجنبها | |
| 5. الخطوات التالية للتعمق | |
| ## سؤال للتفكير 🤔 | |
| كيف يمكنك تطبيق ما تعلمته اليوم في مشروعك الشخصي أو عملك؟ | |
| ## للمتابعة 📚 | |
| - ابحث عن أمثلة إضافية في مجالك | |
| - مارس التطبيق العملي بشكل يومي | |
| - شارك ما تعلمته مع الآخرين | |
| """ | |
| # دوال Supabase (اختيارية - يمكن استبدالها بملفات JSON محلية) | |
| def init_supabase(): | |
| """تهيئة اتصال Supabase""" | |
| if not config.USE_SUPABASE: | |
| return None | |
| try: | |
| from supabase import create_client | |
| return create_client(config.SUPABASE_URL, config.SUPABASE_KEY) | |
| except: | |
| return None | |
| def save_profile_to_supabase(profile: Dict) -> bool: | |
| """حفظ ملف تعريفي في Supabase""" | |
| client = init_supabase() | |
| if not client: | |
| return False | |
| try: | |
| client.table("profiles").insert(profile).execute() | |
| return True | |
| except: | |
| return False | |
| def get_profile_from_supabase(user_id: str) -> Optional[Dict]: | |
| """جلب ملف تعريفي من Supabase""" | |
| client = init_supabase() | |
| if not client: | |
| return None | |
| try: | |
| response = client.table("profiles").select("*").eq("user_id", user_id).execute() | |
| if response.data: | |
| return response.data[0] | |
| except: | |
| pass | |
| return None | |