Spaces:
Sleeping
Sleeping
| import os | |
| from flask import Flask, request, jsonify, render_template | |
| from flask_pymongo import PyMongo | |
| from flask_bcrypt import Bcrypt | |
| import secrets | |
| import google.generativeai as genai | |
| import markdown | |
| from PIL import Image | |
| import pytesseract # For OCR | |
| import fitz # PyMuPDF for reading PDFs | |
| import io | |
| # --- Basic Flask App Setup --- | |
| app = Flask(__name__) | |
| # --- Configurations --- | |
| app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') or secrets.token_hex(16) | |
| app.config['MONGO_URI'] = os.getenv('MONGODB_URI') or os.getenv('MONGO_URI') | |
| # --- Gemini API Configuration --- | |
| GOOGLE_API_KEY = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY') | |
| try: | |
| if GOOGLE_API_KEY: | |
| genai.configure(api_key=GOOGLE_API_KEY) | |
| else: | |
| print("Warning: GEMINI_API_KEY/GOOGLE_API_KEY not set; analysis will fail until configured.") | |
| except Exception as e: | |
| print(f"Error configuring Gemini API: {e}\nPlease make sure the GEMINI_API_KEY or GOOGLE_API_KEY environment variable is set.") | |
| # --- Initialize Extensions --- | |
| mongo = PyMongo(app) | |
| bcrypt = Bcrypt(app) | |
| # --- User Model for Flask-Login --- | |
| # Authentication removed: no user model or login manager | |
| # --- Helper function for Gemini Analysis --- | |
| def get_simplified_report(report_text): | |
| """Sends text to Gemini and returns a simplified, markdown-formatted report.""" | |
| if not report_text or not report_text.strip(): | |
| raise ValueError("Extracted text is empty.") | |
| model = genai.GenerativeModel('gemini-2.0-flash') | |
| prompt = f""" | |
| You are an expert medical assistant. Your task is to translate the following medical report into simple, clear, and easy-to-understand language for a patient with no medical background. | |
| Instructions: | |
| 1. Start with a one-sentence summary of the main finding. | |
| 2. Create a "Key Findings" section using bullet points. | |
| 3. For each technical term or measurement, first state the term from the report, then explain what it means in simple words and whether the result is normal, high, or low. | |
| 4. Maintain a reassuring and professional tone. | |
| 5. Conclude with a clear disclaimer: "This is a simplified summary and not a substitute for professional medical advice. Please discuss the full report with your doctor." | |
| 6. Format the entire output in Markdown. | |
| Medical Report to Analyze: | |
| --- | |
| {report_text} | |
| --- | |
| """ | |
| response = model.generate_content(prompt) | |
| return markdown.markdown(response.text) | |
| # --- Authentication routes removed; app is public --- | |
| # --- Main Application Routes --- | |
| def index(): | |
| # Publicly accessible page | |
| return render_template('report_analyzer.html') | |
| def analyze_report_text(): | |
| """Analyzes a report submitted as plain text.""" | |
| try: | |
| data = request.get_json() | |
| report_text = data.get('report_text') | |
| if not report_text or not report_text.strip(): | |
| return jsonify({'error': 'Report text cannot be empty.'}), 400 | |
| html_response = get_simplified_report(report_text) | |
| return jsonify({'simplified_report': html_response}) | |
| except Exception as e: | |
| print(f"Error during text report analysis: {e}") | |
| return jsonify({'error': 'An internal error occurred during report analysis.'}), 500 | |
| def analyze_report_file(): | |
| """Analyzes a report submitted as a PDF or Image file.""" | |
| try: | |
| if 'report_file' not in request.files: | |
| return jsonify({'error': 'No file part in the request.'}), 400 | |
| file = request.files['report_file'] | |
| if file.filename == '': | |
| return jsonify({'error': 'No file selected.'}), 400 | |
| report_text = "" | |
| # Check file extension | |
| if file.filename.lower().endswith('.pdf'): | |
| pdf_document = fitz.open(stream=file.read(), filetype="pdf") | |
| for page in pdf_document: | |
| report_text += page.get_text() | |
| pdf_document.close() | |
| elif file.filename.lower().endswith(('.png', '.jpg', '.jpeg')): | |
| image = Image.open(file.stream) | |
| report_text = pytesseract.image_to_string(image) | |
| else: | |
| return jsonify({'error': 'Unsupported file type. Please upload a PDF or an image.'}), 400 | |
| html_response = get_simplified_report(report_text) | |
| return jsonify({'simplified_report': html_response}) | |
| except Exception as e: | |
| print(f"Error during file report analysis: {e}") | |
| return jsonify({'error': 'An internal error occurred during file analysis.'}), 500 | |
| # --- Run the Application --- | |
| if __name__ == '__main__': | |
| app.run(port=5001, debug=True) | |