XshinzoX commited on
Commit
46f7fea
Β·
verified Β·
1 Parent(s): 9719f50

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +75 -87
src/streamlit_app.py CHANGED
@@ -775,24 +775,29 @@ def upload_page():
775
  uploaded_file = st.file_uploader(
776
  "Choose medical image",
777
  type=['png', 'jpg', 'jpeg', 'dcm'],
778
- help="Upload X-ray, CT, MRI, or other medical images (Max 10MB)"
 
779
  )
780
  st.markdown('</div>', unsafe_allow_html=True)
781
 
782
- # Display uploaded image with modern styling
783
  if uploaded_file is not None:
784
  try:
785
- # Validate file size
786
  file_size = uploaded_file.size
787
  if file_size > 10 * 1024 * 1024: # 10MB
788
  st.error("⚠️ File size too large. Please upload an image smaller than 10MB.")
789
  else:
790
- # Display file info
791
- st.info(f"πŸ“ File: {uploaded_file.name} ({file_size/1024:.1f} KB)")
 
792
 
793
- # Display image
794
- image = Image.open(uploaded_file)
795
- st.image(image, caption="Uploaded Medical Image", use_column_width=True)
 
 
 
796
 
797
  # Reset file pointer for later use
798
  uploaded_file.seek(0)
@@ -800,6 +805,8 @@ def upload_page():
800
  except Exception as e:
801
  st.error(f"❌ Error processing image: {str(e)}")
802
  st.info("πŸ’‘ Please ensure the file is a valid image format (PNG, JPG, JPEG, DCM)")
 
 
803
 
804
  submit_button = st.form_submit_button("πŸ” Generate Report", use_container_width=True)
805
 
@@ -823,7 +830,7 @@ def generate_report(name, date_of_birth, gender, medical_record_number,
823
  """Generate report by sending data to backend and displaying the result"""
824
  try:
825
  if uploaded_file is not None:
826
- with st.spinner("Processing image..."):
827
  # Validate file before sending
828
  if uploaded_file.size > 10 * 1024 * 1024: # 10MB limit
829
  st.error("⚠️ File size too large. Please upload an image smaller than 10MB.")
@@ -832,102 +839,83 @@ def generate_report(name, date_of_birth, gender, medical_record_number,
832
  # Reset file pointer to beginning
833
  uploaded_file.seek(0)
834
 
835
- # First get AI analysis from backend
836
- files = {"file": (uploaded_file.name, uploaded_file, uploaded_file.type)}
837
 
838
  try:
 
839
  analyze_response = requests.post(
840
- f"{FASTAPI_BASE_URL}/analyze/",
841
  files=files,
842
  timeout=60 # 60 second timeout
843
  )
844
 
845
- if analyze_response.status_code != 200:
846
- st.error(f"❌ Backend Error (Status {analyze_response.status_code}): {analyze_response.text}")
847
- return
848
-
849
- response_data = analyze_response.json()
850
-
851
- # Check for API errors
852
- if "error" in response_data:
853
- st.error(f"❌ Analysis Error: {response_data['error']}")
854
- return
855
-
856
- findings = response_data.get("findings", "No findings returned.")
857
- status = response_data.get("status", "unknown")
858
-
859
- if status == "error":
860
- st.error(f"❌ Analysis failed: {findings}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
861
  return
862
 
863
- if not findings or findings.strip() == "":
864
- st.warning("⚠️ No findings were generated. Please try again with a different image.")
865
- return
866
 
867
  except requests.exceptions.Timeout:
868
- st.error("❌ Request timed out. The analysis is taking too long. Please try again.")
869
  return
870
  except requests.exceptions.ConnectionError:
871
- st.error("❌ Cannot connect to backend service. Please ensure the backend is running on http://localhost:8001")
 
 
872
  return
873
  except requests.exceptions.RequestException as e:
874
  st.error(f"❌ Request failed: {str(e)}")
875
  return
876
 
877
- # Patient info for the report
878
- patient_info = {
879
- "name": name,
880
- "medical_record_number": medical_record_number,
881
- "referring_physician": referring_physician,
882
- "date_of_study": date_of_study
883
- }
884
-
885
- # Show findings and PDF link
886
- st.success("βœ… Analysis completed successfully!")
887
-
888
- # Separate thinking process from findings
889
- thinking_text = ""
890
- report_text = findings
891
-
892
- # Debug: Show raw findings
893
- # st.write("DEBUG - Raw findings:", findings[:200] + "..." if len(findings) > 200 else findings)
894
-
895
- # Check if findings contains "thinking:" section
896
- if "thinking:" in findings.lower():
897
- parts = findings.split("answer:", 1)
898
- if len(parts) == 2:
899
- # Extract thinking part (remove "thinking:" prefix)
900
- thinking_part = parts[0].strip()
901
- if thinking_part.lower().startswith("thinking:"):
902
- thinking_text = thinking_part[9:].strip() # Remove "thinking:" prefix
903
- else:
904
- thinking_text = thinking_part
905
-
906
- # Extract answer part
907
- report_text = parts[1].strip()
908
-
909
- # Debug: Show extracted parts
910
- # st.write("DEBUG - Thinking text:", thinking_text[:100] + "..." if len(thinking_text) > 100 else thinking_text)
911
- # st.write("DEBUG - Report text:", report_text[:100] + "..." if len(report_text) > 100 else report_text)
912
- else:
913
- # If no "answer:" found, use the whole thinking section
914
- thinking_text = findings
915
- report_text = "Analysis completed."
916
-
917
- stream_response(thinking_text, report_text, patient_info)
918
-
919
  # Generate PDF report
920
- with st.spinner("Generating PDF report..."):
921
  try:
922
  pdf_response = requests.post(
923
  f"{FASTAPI_BASE_URL}/generate-report/",
924
- params={
925
  "patient_name": name,
926
- "medical_record_number": medical_record_number,
927
  "date_of_birth": date_of_birth,
928
  "gender": gender,
929
  "referring_physician": referring_physician,
930
- "date_of_study": date_of_study,
931
  "findings": findings
932
  },
933
  timeout=30
@@ -936,7 +924,7 @@ def generate_report(name, date_of_birth, gender, medical_record_number,
936
  if pdf_response.status_code == 200:
937
  pdf_data = pdf_response.json()
938
  if pdf_data.get("success"):
939
- pdf_url = f"{FASTAPI_BASE_URL}/reports/{name}/pdf"
940
  st.markdown(f'''
941
  <div style="margin-top: 1rem; padding: 1rem; background: linear-gradient(135deg, #4caf50, #66bb6a); border-radius: 10px;">
942
  <p style="color: white; margin: 0; font-weight: 600;">βœ… PDF Report Generated Successfully!</p>
@@ -946,21 +934,21 @@ def generate_report(name, date_of_birth, gender, medical_record_number,
946
  </div>
947
  ''', unsafe_allow_html=True)
948
  else:
949
- st.error(f"❌ Failed to generate PDF: {pdf_data.get('error', 'Unknown error')}")
950
  else:
951
  st.error(f"❌ PDF generation failed with status {pdf_response.status_code}")
952
 
953
  except requests.exceptions.Timeout:
954
- st.error("❌ PDF generation timed out. Please try again.")
955
  except Exception as e:
956
  st.error(f"❌ Error generating PDF: {str(e)}")
957
 
958
  except Exception as e:
959
- st.error(f"❌ Unexpected error generating report: {str(e)}")
960
- st.info("πŸ’‘ Please check that:")
961
- st.info(" β€’ The backend service is running (http://localhost:8001)")
962
- st.info(" β€’ The uploaded file is a valid image")
963
- st.info(" β€’ Your internet connection is stable")
964
 
965
  def view_reports_page():
966
  st.markdown('<div class="section-header">πŸ“Š View Patient Reports - Search by MRN</div>', unsafe_allow_html=True)
 
775
  uploaded_file = st.file_uploader(
776
  "Choose medical image",
777
  type=['png', 'jpg', 'jpeg', 'dcm'],
778
+ help="Upload X-ray, CT, MRI, (Max 10MB)",
779
+ key="medical_image_upload"
780
  )
781
  st.markdown('</div>', unsafe_allow_html=True)
782
 
783
+ # Display uploaded image with modern styling (NO API CALLS)
784
  if uploaded_file is not None:
785
  try:
786
+ # Validate file size only (no API calls)
787
  file_size = uploaded_file.size
788
  if file_size > 10 * 1024 * 1024: # 10MB
789
  st.error("⚠️ File size too large. Please upload an image smaller than 10MB.")
790
  else:
791
+ # Display success message and file info
792
+ st.success(f"βœ… File uploaded successfully: {uploaded_file.name}")
793
+ st.info(f"πŸ“ File size: {file_size/1024:.1f} KB")
794
 
795
+ # Display image preview (local only, no backend calls)
796
+ if uploaded_file.type.startswith('image/'):
797
+ image = Image.open(uploaded_file)
798
+ st.image(image, caption="Uploaded Medical Image", use_column_width=True)
799
+ else:
800
+ st.info("πŸ“„ DICOM file uploaded successfully")
801
 
802
  # Reset file pointer for later use
803
  uploaded_file.seek(0)
 
805
  except Exception as e:
806
  st.error(f"❌ Error processing image: {str(e)}")
807
  st.info("πŸ’‘ Please ensure the file is a valid image format (PNG, JPG, JPEG, DCM)")
808
+ else:
809
+ st.info("πŸ‘† Please upload a medical image to begin analysis")
810
 
811
  submit_button = st.form_submit_button("πŸ” Generate Report", use_container_width=True)
812
 
 
830
  """Generate report by sending data to backend and displaying the result"""
831
  try:
832
  if uploaded_file is not None:
833
+ with st.spinner("πŸ”„ Analyzing medical image..."):
834
  # Validate file before sending
835
  if uploaded_file.size > 10 * 1024 * 1024: # 10MB limit
836
  st.error("⚠️ File size too large. Please upload an image smaller than 10MB.")
 
839
  # Reset file pointer to beginning
840
  uploaded_file.seek(0)
841
 
842
+ # Prepare file for upload
843
+ files = {"file": (uploaded_file.name, uploaded_file.getvalue(), uploaded_file.type)}
844
 
845
  try:
846
+ # Call analyze endpoint
847
  analyze_response = requests.post(
848
+ f"{FASTAPI_BASE_URL}/analyze",
849
  files=files,
850
  timeout=60 # 60 second timeout
851
  )
852
 
853
+ if analyze_response.status_code == 200:
854
+ response_data = analyze_response.json()
855
+
856
+ # Handle successful response
857
+ if response_data.get("success"):
858
+ findings = response_data.get("analysis", "Analysis completed")
859
+
860
+ # Parse thinking and answer sections
861
+ thinking_text = ""
862
+ report_text = findings
863
+
864
+ if "thinking:" in findings and "answer:" in findings:
865
+ parts = findings.split("answer:", 1)
866
+ thinking_text = parts[0].replace("thinking:", "").strip()
867
+ report_text = parts[1].strip()
868
+
869
+ st.success("βœ… Analysis completed successfully!")
870
+ stream_response(thinking_text, report_text, {
871
+ "name": name,
872
+ "medical_record_number": medical_record_number,
873
+ "referring_physician": referring_physician,
874
+ "date_of_study": date_of_study
875
+ })
876
+
877
+ else:
878
+ # Handle failed analysis with fallback
879
+ st.warning("⚠️ AI analysis encountered issues, using fallback analysis")
880
+ fallback_findings = response_data.get("analysis", "Medical image processed. Professional review recommended.")
881
+ stream_response("Fallback analysis used", fallback_findings, {
882
+ "name": name,
883
+ "medical_record_number": medical_record_number,
884
+ "referring_physician": referring_physician,
885
+ "date_of_study": date_of_study
886
+ })
887
+ findings = fallback_findings
888
+
889
+ else:
890
+ st.error(f"❌ Backend Error (Status {analyze_response.status_code})")
891
+ st.error(f"Response: {analyze_response.text}")
892
  return
893
 
 
 
 
894
 
895
  except requests.exceptions.Timeout:
896
+ st.error("⏱️ Request timed out. The analysis is taking too long. Please try again.")
897
  return
898
  except requests.exceptions.ConnectionError:
899
+ st.error("πŸ”Œ Cannot connect to backend service.")
900
+ st.error("Please ensure the backend is running at: http://localhost:8001")
901
+ st.info("πŸ’‘ To start the backend, run: `cd backend && python service.py`")
902
  return
903
  except requests.exceptions.RequestException as e:
904
  st.error(f"❌ Request failed: {str(e)}")
905
  return
906
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
907
  # Generate PDF report
908
+ with st.spinner("πŸ“„ Generating PDF report..."):
909
  try:
910
  pdf_response = requests.post(
911
  f"{FASTAPI_BASE_URL}/generate-report/",
912
+ data={
913
  "patient_name": name,
914
+ "medical_record_number": medical_record_number or "AUTO-GENERATED",
915
  "date_of_birth": date_of_birth,
916
  "gender": gender,
917
  "referring_physician": referring_physician,
918
+ "study_date": date_of_study,
919
  "findings": findings
920
  },
921
  timeout=30
 
924
  if pdf_response.status_code == 200:
925
  pdf_data = pdf_response.json()
926
  if pdf_data.get("success"):
927
+ pdf_url = f"{FASTAPI_BASE_URL}/reports/{name.replace(' ', '_')}/pdf"
928
  st.markdown(f'''
929
  <div style="margin-top: 1rem; padding: 1rem; background: linear-gradient(135deg, #4caf50, #66bb6a); border-radius: 10px;">
930
  <p style="color: white; margin: 0; font-weight: 600;">βœ… PDF Report Generated Successfully!</p>
 
934
  </div>
935
  ''', unsafe_allow_html=True)
936
  else:
937
+ st.error(f"❌ Failed to generate PDF: {pdf_data.get('message', 'Unknown error')}")
938
  else:
939
  st.error(f"❌ PDF generation failed with status {pdf_response.status_code}")
940
 
941
  except requests.exceptions.Timeout:
942
+ st.error("⏱️ PDF generation timed out. Please try again.")
943
  except Exception as e:
944
  st.error(f"❌ Error generating PDF: {str(e)}")
945
 
946
  except Exception as e:
947
+ st.error(f"❌ Unexpected error: {str(e)}")
948
+ st.info("πŸ’‘ Troubleshooting tips:")
949
+ st.info(" β€’ Ensure backend service is running on port 8001")
950
+ st.info(" β€’ Check that the uploaded file is a valid image")
951
+ st.info(" β€’ Try refreshing the page and uploading again")
952
 
953
  def view_reports_page():
954
  st.markdown('<div class="section-header">πŸ“Š View Patient Reports - Search by MRN</div>', unsafe_allow_html=True)