Spaces:
Sleeping
Sleeping
Download api_server.py from Youssef1F/MedAssist-AI: direct link, hf CLI and curl.
- Browser
- Download file 4.58 kB
-
https://huggingface.co/spaces/Youssef1F/MedAssist-AI/resolve/main/api_server.py
- Command line
-
hf download hf://spaces/Youssef1F/MedAssist-AI/api_server.py
-
curl -L -o api_server.py https://huggingface.co/spaces/Youssef1F/MedAssist-AI/resolve/main/api_server.py
4.58 kB
| import os | |
| import torch | |
| import torch.nn as nn | |
| from torchvision import models, transforms | |
| from fastapi import FastAPI, Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from PIL import Image | |
| import io | |
| import base64 | |
| import requests | |
| app = FastAPI() | |
| # تفعيل الـ CORS للربط مع Lovable | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- إعداد الموديل المحلي (DenseNet121) --- | |
| device = torch.device("cpu") | |
| def load_medical_model(): | |
| model = models.densenet121(weights=None) | |
| num_ftrs = model.classifier.in_features | |
| model.classifier = nn.Sequential( | |
| nn.Dropout(0.2), | |
| nn.Linear(num_ftrs, 14) | |
| ) | |
| if os.path.exists('best_densenet121.pth'): | |
| try: | |
| checkpoint = torch.load('best_densenet121.pth', map_location=device) | |
| model.load_state_dict(checkpoint) | |
| model.eval() | |
| print("✅ Medical Model Loaded!") | |
| return model | |
| except Exception as e: | |
| print(f"❌ Error loading .pth: {e}") | |
| return None | |
| return None | |
| medical_model = load_medical_model() | |
| transform = transforms.Compose([ | |
| transforms.Resize((224, 224)), | |
| transforms.ToTensor(), | |
| transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) | |
| ]) | |
| class_names = [ | |
| "Atelectasis", "Cardiomegaly", "Effusion", "Infiltration", "Mass", | |
| "Nodule", "Pneumonia", "Pneumothorax", "Consolidation", "Edema", | |
| "Emphysema", "Fibrosis", "Pleural_Thickening", "Hernia" | |
| ] | |
| # --- دالة الاتصال المباشر بجوجل (الحل القاطع للـ 404) --- | |
| def ask_gemini_direct(prompt, api_key): | |
| # استخدام v1beta لأنها النسخة المستقرة حالياً لموديل Flash | |
| url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={api_key}" | |
| payload = {"contents": [{"parts": [{"text": prompt}]}]} | |
| headers = {'Content-Type': 'application/json'} | |
| try: | |
| response = requests.post(url, json=payload, headers=headers, timeout=15) | |
| if response.status_code == 200: | |
| return response.json()['candidates'][0]['content']['parts'][0]['text'] | |
| else: | |
| return f"Error: {response.status_code} - {response.text}" | |
| except Exception as e: | |
| return f"Request Failed: {str(e)}" | |
| # --- Endpoints --- | |
| def home(): | |
| return {"status": "Healytics Backend is Ready", "model": medical_model is not None} | |
| async def chat_endpoint(request: Request): | |
| try: | |
| data = await request.json() | |
| api_key = os.getenv("GEMINI_API_KEY") | |
| if not api_key: | |
| return {"response": "❌ خطأ: لم يتم العثور على GEMINI_API_KEY في الـ Secrets."} | |
| # استقبال الرسالة من Lovable | |
| user_message = "" | |
| if "messages" in data and len(data["messages"]) > 0: | |
| user_message = data["messages"][-1].get("content", "") | |
| elif "message" in data: | |
| user_message = data["message"] | |
| image_data = data.get("image") | |
| # 1. تحليل الأشعة | |
| if image_data and medical_model: | |
| header, encoded = image_data.split(",", 1) if "," in image_data else (None, image_data) | |
| image = Image.open(io.BytesIO(base64.b64decode(encoded))).convert('RGB') | |
| input_tensor = transform(image).unsqueeze(0).to(device) | |
| with torch.no_grad(): | |
| outputs = medical_model(input_tensor) | |
| probs = torch.sigmoid(outputs) | |
| preds = (probs > 0.5).nonzero(as_tuple=True)[1] | |
| detected = [class_names[i] for i in preds] | |
| res_text = ", ".join(detected) if detected else "سليم" | |
| prompt = f"المريض رفع أشعة والذكاء الاصطناعي اكتشف: {res_text}. اشرح ده بالعربي بأسلوب طبي مطمئن." | |
| ai_res = ask_gemini_direct(prompt, api_key) | |
| return {"response": ai_res, "analysis": detected} | |
| # 2. دردشة نصية | |
| if user_message: | |
| ai_res = ask_gemini_direct(f"أنت مساعد طبي في نظام Healytics. رد بالعربي: {user_message}", api_key) | |
| return {"response": ai_res} | |
| return {"response": "أهلاً بك، أنا أسمعك جيداً."} | |
| except Exception as e: | |
| return {"response": f"❌ حدث خطأ: {str(e)}"} |