| from fastapi import FastAPI, HTTPException |
| from fastapi.middleware.cors import CORSMiddleware |
| from sentence_transformers import SentenceTransformer |
| import fitz |
| import faiss |
| import os |
| import numpy as np |
| import requests |
| import gradio as gr |
|
|
| |
| GEMINI_API_KEY = "AIzaSyArbgg_p_HlmpgrcjVYemdSJeMCP9OTj3E" |
| GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent" |
|
|
| |
| EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2" |
| model = SentenceTransformer(EMBEDDING_MODEL) |
| INDEX_PATH = "medical_faiss_index" |
| documents = [] |
|
|
| |
| if os.path.exists(INDEX_PATH): |
| index = faiss.read_index(INDEX_PATH) |
| print("Index FAISS chargé avec succès.") |
| else: |
| index = faiss.IndexFlatL2(model.get_sentence_embedding_dimension()) |
| print("Nouvel index FAISS créé.") |
|
|
| |
| def extract_text_from_pdf(file_content: bytes): |
| pdf = fitz.open(stream=file_content, filetype="pdf") |
| paragraphs = [] |
| for page in pdf: |
| text = page.get_text() |
| if text.strip(): |
| paragraphs.extend([p.strip() for p in text.split("\n\n") if p.strip()]) |
| return paragraphs |
|
|
| |
| def add_medical_reference(file_content: bytes): |
| global index, documents |
| paragraphs = extract_text_from_pdf(file_content) |
| embeddings = model.encode(paragraphs) |
| index.add(np.array(embeddings, dtype="float32")) |
| documents.extend(paragraphs) |
| faiss.write_index(index, INDEX_PATH) |
|
|
| |
| def search_faiss(query, k=5): |
| query_embedding = model.encode([query]) |
| distances, indices = index.search(np.array(query_embedding, dtype="float32"), k) |
| results = [documents[i] for i in indices[0] if i < len(documents)] |
| return results |
|
|
| |
| def call_gemini_api(prompt): |
| headers = {"Content-Type": "application/json"} |
| payload = { |
| "contents": [ |
| { |
| "parts": [ |
| {"text": prompt} |
| ] |
| } |
| ] |
| } |
| try: |
| response = requests.post(f"{GEMINI_API_URL}?key={GEMINI_API_KEY}", json=payload, headers=headers) |
| response.raise_for_status() |
| response_json = response.json() |
| candidates = response_json.get("candidates", []) |
| if candidates: |
| return candidates[0]["content"]["parts"][0]["text"] |
| return "Pas de réponse disponible depuis Gemini." |
| except requests.exceptions.RequestException as e: |
| return f"Erreur API Gemini : {str(e)}" |
|
|
| |
| def upload_reference(file): |
| try: |
| |
| with open(file.name, "rb") as f: |
| file_content = f.read() |
| add_medical_reference(file_content) |
| return "Référence médicale ajoutée avec succès." |
| except Exception as e: |
| return f"Erreur : {str(e)}" |
|
|
|
|
| |
| def analyze_blood_test(file): |
| try: |
| |
| with open(file.name, "rb") as f: |
| file_content = f.read() |
| |
| |
| test_results = extract_text_from_pdf(file_content) |
|
|
| if not test_results: |
| return "Aucun texte valide extrait du fichier d'analyse." |
|
|
| |
| query = "\n".join(test_results) |
|
|
| |
| relevant_docs = search_faiss(query, k=5) |
| context = "\n".join(relevant_docs) |
|
|
| |
| enriched_prompt = f"Voici les résultats d'analyse :\n{query}\n\nContexte pertinent :\n{context}" |
| gemini_response = call_gemini_api(enriched_prompt) |
|
|
| return { |
| "Réponse générée": gemini_response, |
| "Documents pertinents": relevant_docs |
| } |
| except Exception as e: |
| return f"Erreur : {str(e)}" |
|
|
|
|
| |
| def gradio_upload_reference(file): |
| return upload_reference(file) |
|
|
| def gradio_analyze_blood_test(file): |
| response = analyze_blood_test(file) |
| if isinstance(response, dict): |
| return f"Réponse générée :\n{response['Réponse générée']}\n\nDocuments pertinents :\n{response['Documents pertinents']}" |
| return response |
|
|
| |
| with gr.Blocks() as demo: |
| gr.Markdown("## Analyse Médicale avec RAG et Gemini") |
| |
| with gr.Tab("Ajouter Références Médicales"): |
| ref_file = gr.File(label="Téléchargez un fichier PDF de référence médicale") |
| ref_output = gr.Textbox(label="Résultat") |
| ref_button = gr.Button("Ajouter") |
| ref_button.click(gradio_upload_reference, inputs=ref_file, outputs=ref_output) |
| |
| with gr.Tab("Analyser un Résultat d'Analyse"): |
| test_file = gr.File(label="Téléchargez un fichier PDF d'analyse de sang") |
| analysis_output = gr.Textbox(label="Résultat") |
| analyze_button = gr.Button("Analyser") |
| analyze_button.click(gradio_analyze_blood_test, inputs=test_file, outputs=analysis_output) |
|
|
| demo.launch() |
|
|