SPECIAL / view_patient_reports.py
yougandar's picture
Update view_patient_reports.py
1a9fc4a verified
from flask import Flask, send_from_directory, render_template_string
import gradio as gr
import pandas as pd
import csv
import os
# Define the paths to the CSV files and the directory for reports
patients_file_path = "patients.csv"
reports_file_path = "reports.csv"
reports_folder_path = "reports"
# Create Flask app
app = Flask(__name__)
def get_patient_details(patient_id):
"""Retrieve the patient name based on Patient ID."""
if not os.path.exists(patients_file_path):
return "Patients file not found."
with open(patients_file_path, mode='r') as file:
reader = csv.DictReader(file)
for row in reader:
if row["Patient ID"].strip() == patient_id.strip():
return row["Patient Name"]
return "Patient ID not found."
def autofill_patient_name(patient_id):
"""Auto-fill the patient Name."""
return get_patient_details(patient_id)
def get_patient_reports(patient_id):
"""Retrieve patient reports based on Patient ID."""
if not os.path.exists(reports_file_path):
return pd.DataFrame(columns=["Report ID", "Report File"])
reports = []
try:
with open(reports_file_path, mode='r') as file:
reader = csv.DictReader(file)
headers = reader.fieldnames
if not headers or "Report ID" not in headers or "Patient ID" not in headers or "Report File" not in headers:
return pd.DataFrame(columns=["Report ID", "Report File"])
for row in reader:
# Trim whitespace from keys and values
row = {key.strip(): value.strip() for key, value in row.items()}
if row.get("Patient ID") == patient_id:
# Generate a clickable link for the report file
report_file_name = row.get("Report File")
report_link = f'<a href="/file/{report_file_name}" target="_blank">{report_file_name}</a>'
reports.append({
"Report ID": row.get("Report ID"),
"Report File": report_link
})
except Exception as e:
print(f"Error reading file: {e}")
return pd.DataFrame(reports) if reports else pd.DataFrame(columns=["Report ID", "Report File"])
def handle_file_upload(patient_id, file):
"""Handle file upload and save report details."""
patient_name = get_patient_details(patient_id)
if patient_name == "Patient ID not found":
return f"Error: {patient_name}"
if file is None:
return "Error: No file uploaded"
# Generate a file name with a unique identifier
file_extension = ".pdf" if file[:4] == b"%PDF" else ".jpg"
file_name = f"report_{patient_id}_{os.urandom(8).hex()}{file_extension}"
file_path = os.path.join(reports_folder_path, file_name)
os.makedirs(os.path.dirname(file_path), exist_ok=True)
# Write the binary content to the file
try:
with open(file_path, "wb") as f:
f.write(file)
except Exception as e:
return f"Error writing file: {e}"
# Load existing reports data
if os.path.exists(reports_file_path):
reports_df = pd.read_csv(reports_file_path)
else:
reports_df = pd.DataFrame(columns=["Report ID", "Patient ID", "Report File"])
# Generate a new Report ID
new_report_id = reports_df["Report ID"].max() + 1 if not reports_df.empty else 1
# Add new report details
new_report = pd.DataFrame({
"Report ID": [new_report_id],
"Patient ID": [patient_id],
"Report File": [file_name]
})
# Append new report details to existing data
reports_df = pd.concat([reports_df, new_report], ignore_index=True)
# Save updated reports data
try:
reports_df.to_csv(reports_file_path, index=False)
except Exception as e:
return f"Error saving CSV: {e}"
return f"Report uploaded successfully for {patient_name}."
def create_gradio_interface():
"""Create Gradio interface for viewing patient reports and uploading files."""
with gr.Blocks() as demo:
gr.Markdown("## View Patient Reports")
with gr.Row():
with gr.Column(scale=1): # Small column for the patient ID input
patient_id_view = gr.Textbox(label="Patient ID", placeholder="Enter Patient ID", max_lines=1)
with gr.Column(scale=3): # Larger column for the rest of the inputs and outputs
patient_name_view = gr.Textbox(label="Patient Name", placeholder="Patient name will auto-populate", interactive=False)
reports_output = gr.HTML()
fetch_button = gr.Button("Fetch Reports")
# Auto-populate patient name when Patient ID is entered
patient_id_view.change(
fn=autofill_patient_name,
inputs=patient_id_view,
outputs=patient_name_view
)
# Action to fetch and display reports
fetch_button.click(
fn=lambda patient_id: get_patient_reports(patient_id).drop(columns=["Patient ID"], errors="ignore").to_html(escape=False, index=False),
inputs=patient_id_view,
outputs=reports_output
)
with gr.Row():
with gr.Column(scale=1):
upload_patient_id = gr.Textbox(label="Patient ID", placeholder="Enter Patient ID for file upload", max_lines=1)
with gr.Column(scale=3):
file_upload = gr.File(label="Upload Report File")
upload_button = gr.Button("Upload Report")
# Action to handle file upload
upload_button.click(
fn=handle_file_upload,
inputs=[upload_patient_id, file_upload],
outputs=gr.Textbox() # Use Gradio Textbox for textual output
)
return demo
# Flask route to serve report files
@app.route("/file/<path:filename>")
def download_file(filename):
return send_from_directory(reports_folder_path, filename)
# Main route to serve Gradio interface
@app.route("/")
def home():
interface = create_gradio_interface()
return render_template_string("""
<div style="margin: 2rem;">
{{ interface }}
</div>
""", interface=interface)
# Make sure the reports folder exists
os.makedirs(reports_folder_path, exist_ok=True)
# Run the Flask app
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)