test-ai / app.py
Alhdrawi's picture
Update app.py
52d7042 verified
raw
history blame
5.22 kB
# app.py
# Gradio Hugging Face Space connected to Google Gemini (via google-genai)
# - Put your Gemini API key into Hugging Face Space secrets with name: GEMINI_API_KEY
# - Add requirements.txt with: gradio\ngoogle-genai
import os
import io
from google import genai
from google.genai import types
import gradio as gr
# Initialize client using secret from HF environment
CLIENT = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
MODEL = "gemini-2.5-flash" # or change to a model available in your project/region
# Fixed short reply for text-only chats
TEXT_ONLY_REPLY = "أنا R-RAY AI تم تدريبي على قواعد بيانات طبية ضخمة. كيف يمكنني مساعدتك اليوم؟"
# Strict radiology-report instruction (Arabic)
RADIology_PROMPT_TEMPLATE = '''أنت "R-RAY AI" — نموذج متخصص في تقارير الأشعة، تدربت على قواعد بيانات طبية ضخمة.
تعليمات صارمة:
1) عند استلام صور شعاعية (واحدة أو أكثر) — أجب **فقط** بتقرير طبي احترافي بصيغة تقارير الأشعة المستعملة سريريًا.
2) لا تضف جمل ترويجية أو اعتذارات أو نص خارج إطار التقرير.
3) إخراج التقرير يجب أن يحتوي على الأقسام التالية بالترتيب: عنوان الدراسة، تاريخ الاستلام (التاريخ اليومي تلقائيًا)، رقم المريض (إن وُرد)، التاريخ السريري/شكوى المريض (من نص المستخدم إن وُجد)، التقنية (نوع الصور: X-ray, CT, MRI + الإطارات/القطاعات المرفقة)، وصف تفصيلي للنتائج، خاتمة/تقرير تشخيصي موجز مع توصية واحدة على الأكثر.
4) إذا كان هناك أكثر من صورة — اذكر كل صورة مرقمة ووصف كل واحدة تحت قسم "الصور" ثم ادمج النتائج في قسم "النتائج".
5) اللغة: العربية الفصحى طبية. الطول: تقرير كامل ومحترف (لا يقل عن 6 جمل في الوصف ما لم تكن الصور طبيعية تمامًا).
البيانات المرسلة:
{clinical_text}
الصور المرسلة: {image_list}
أعد فقط التقرير الطبي بالصيغة المطلوبة. انتهى.
'''
def make_parts_from_images(image_files):
parts = []
for idx, img in enumerate(image_files, start=1):
img_bytes = img.read()
try:
part = types.Part.from_bytes(img_bytes)
except Exception:
try:
part = types.Part.from_image(img_bytes)
except Exception:
import base64
b64 = base64.b64encode(img_bytes).decode('utf-8')
part = types.Part.from_text(f"[BASE64_IMAGE_{idx}] {b64}")
parts.append(part)
return parts
def analyze(images, clinical_text):
clinical_text = (clinical_text or "").strip()
images = images or []
if len(images) == 0:
return TEXT_ONLY_REPLY
image_names = []
for i, f in enumerate(images, start=1):
name = getattr(f, "name", None) or f"image_{i}"
image_names.append(name)
image_list_text = ", ".join(image_names)
prompt_text = RADIology_PROMPT_TEMPLATE.format(
clinical_text=clinical_text if clinical_text else "(لا توجد معلومات سريرية إضافية)",
image_list=image_list_text,
)
parts = make_parts_from_images(images)
parts.append(types.Part.from_text(prompt_text))
contents = [
types.Content(
role="user",
parts=parts,
)
]
try:
response = CLIENT.models.generate_content(
model=MODEL,
contents=contents,
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(thinking_budget=-1),
),
)
return response.text
except Exception as e:
return f"خطأ أثناء الاتصال بنموذج Gemini: {e}"
with gr.Blocks() as demo:
gr.Markdown("# R-RAY AI — تقارير الأشعة\nارفع صور شعاعية (X-ray, CT, MRI) ويمكنك أيضًا ارفاق ملاحظات سريرية قصيرة.")
with gr.Row():
image_input = gr.File(label="تحميل صور (يمكن رفع أكثر من صورة)", file_types=[".png", ".jpg", ".jpeg", ".dcm"], file_types_description="Images", type="binary", file_count="multiple")
clinical_input = gr.Textbox(label="معلومات سريرية / تاريخ المريض (اختياري)", lines=4)
output = gr.Textbox(label="تقرير الأشعة (الناتج)", lines=20)
btn = gr.Button("تحليل وإصدار التقرير")
btn.click(fn=analyze, inputs=[image_input, clinical_input], outputs=[output])
gr.Markdown("**ملاحظة:** هذا النموذج للاختبار/التطوير فقط ولا يغني عن استشارة طبية حقيقية.")
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))