Ali2206 commited on
Commit
e7f4852
·
verified ·
1 Parent(s): 558d9c8

Update api/routes.py

Browse files
Files changed (1) hide show
  1. api/routes.py +84 -57
api/routes.py CHANGED
@@ -579,75 +579,103 @@ async def generate_patient_pdf(patient_id: str, current_user: dict = Depends(get
579
  try:
580
  obj_id = ObjectId(patient_id)
581
  query = {"$or": [{"_id": obj_id}, {"fhir_id": patient_id}]}
582
- except Exception:
583
  query = {"fhir_id": patient_id}
584
 
585
  patient = await patients_collection.find_one(query)
586
-
587
  if not patient:
588
  raise HTTPException(status_code=404, detail="Patient not found")
589
 
590
- # Create temporary directory
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
591
  with tempfile.TemporaryDirectory() as tmpdir:
592
- tex_path = os.path.join(tmpdir, "patient.tex")
593
- pdf_path = os.path.join(tmpdir, "patient.pdf")
594
-
595
- latex = f"""
596
- \\documentclass[a4paper,12pt]{{article}}
597
- \\usepackage[utf8]{{inputenc}}
598
- \\usepackage[T1]{{fontenc}}
599
- \\usepackage{{geometry}}
600
- \\geometry{{margin=1in}}
601
- \\usepackage{{booktabs,longtable,fancyhdr}}
602
- \\pagestyle{{fancy}}
603
- \\fancyhf{{}}
604
- \\fancyhead[L]{{Patient Report}}
605
- \\fancyhead[R]{{Generated: \\today}}
606
- \\fancyfoot[C]{{\\thepage}}
607
-
608
- \\begin{{document}}
609
-
610
- \\begin{{center}}
611
- \\Large\\textbf{{Patient Medical Report}} \\\\
612
- \\vspace{{0.2cm}}
613
- \\textit{{Generated on {datetime.now().strftime('%A, %B %d, %Y at %I:%M %p')}}}
614
- \\end{{center}}
615
-
616
- \\section*{{Demographics}}
617
- \\begin{{itemize}}
618
- \\item \\textbf{{FHIR ID:}} {patient.get("fhir_id", "")}
619
- \\item \\textbf{{Full Name:}} {patient.get("full_name", "")}
620
- \\item \\textbf{{Gender:}} {patient.get("gender", "")}
621
- \\item \\textbf{{Date of Birth:}} {patient.get("date_of_birth", "")}
622
- \\item \\textbf{{Age:}} {calculate_age(patient.get("date_of_birth", ""))}
623
- \\item \\textbf{{Address:}} {patient.get("address", "")}, {patient.get("city", "")}, {patient.get("state", "")}, {patient.get("postal_code", "")}, {patient.get("country", "")}
624
- \\item \\textbf{{Marital Status:}} {patient.get("marital_status", "")}
625
- \\item \\textbf{{Language:}} {patient.get("language", "")}
626
- \\end{{itemize}}
627
-
628
- \\section*{{Clinical Notes}}
629
- \\begin{{longtable}}{{p{{3cm}}p{{3cm}}p{{7cm}}}}
630
- \\toprule
631
- \\textbf{{Date}} & \\textbf{{Type}} & \\textbf{{Text}} \\\\
632
- \\midrule
633
- \\endhead
634
- {" \\\\ \n".join([f"{n.get('date', '')} & {n.get('type', '')} & {n.get('text', '')}" for n in patient.get("notes", [])])}
635
- \\bottomrule
636
- \\end{{longtable}}
637
-
638
- \\end{{document}}
639
- """
640
-
641
- with open(tex_path, "w") as f:
642
  f.write(latex)
643
 
644
  try:
645
- subprocess.run(["latexmk", "-pdf", tex_path], check=True, cwd=tmpdir)
 
 
646
  with open(pdf_path, "rb") as f:
647
  pdf_bytes = f.read()
648
 
649
  response = Response(content=pdf_bytes, media_type="application/pdf")
650
- response.headers["Content-Disposition"] = f"attachment; filename=patient_{patient.get('fhir_id', 'unknown')}_record.pdf"
651
  return response
652
 
653
  except subprocess.CalledProcessError as e:
@@ -655,9 +683,8 @@ async def generate_patient_pdf(patient_id: str, current_user: dict = Depends(get
655
  raise HTTPException(status_code=500, detail="LaTeX compilation failed")
656
 
657
  except Exception as e:
658
- logger.error(f"PDF generation error: {e}")
659
  raise HTTPException(status_code=500, detail="Failed to generate PDF")
660
-
661
  @router.post("/signup", status_code=status.HTTP_201_CREATED)
662
  async def signup(data: SignupForm):
663
  logger.info(f"Signup attempt for email: {data.email}")
 
579
  try:
580
  obj_id = ObjectId(patient_id)
581
  query = {"$or": [{"_id": obj_id}, {"fhir_id": patient_id}]}
582
+ except InvalidId:
583
  query = {"fhir_id": patient_id}
584
 
585
  patient = await patients_collection.find_one(query)
 
586
  if not patient:
587
  raise HTTPException(status_code=404, detail="Patient not found")
588
 
589
+ # Prepare LaTeX template
590
+ latex_template = Template(r"""
591
+ \documentclass[a4paper,12pt]{article}
592
+ \usepackage[utf8]{inputenc}
593
+ \usepackage[T1]{fontenc}
594
+ \usepackage{geometry}
595
+ \geometry{margin=1in}
596
+ \usepackage{booktabs,longtable,fancyhdr}
597
+ \pagestyle{fancy}
598
+ \fancyhf{}
599
+ \fancyhead[L]{Patient Report}
600
+ \fancyhead[R]{Generated: \today}
601
+ \fancyfoot[C]{\thepage}
602
+
603
+ \begin{document}
604
+
605
+ \begin{center}
606
+ \Large\textbf{Patient Medical Report} \\
607
+ \vspace{0.2cm}
608
+ \textit{Generated on $date}
609
+ \end{center}
610
+
611
+ \section*{Demographics}
612
+ \begin{itemize}
613
+ \item \textbf{FHIR ID:} $fhir_id
614
+ \item \textbf{Full Name:} $full_name
615
+ \item \textbf{Gender:} $gender
616
+ \item \textbf{Date of Birth:} $dob
617
+ \item \textbf{Age:} $age
618
+ \item \textbf{Address:} $address
619
+ \item \textbf{Marital Status:} $marital_status
620
+ \item \textbf{Language:} $language
621
+ \end{itemize}
622
+
623
+ \section*{Clinical Notes}
624
+ \begin{longtable}{p{3cm}p{3cm}p{7cm}}
625
+ \toprule
626
+ \textbf{Date} & \textbf{Type} & \textbf{Text} \\
627
+ \midrule
628
+ \endhead
629
+ $notes
630
+ \bottomrule
631
+ \end{longtable}
632
+
633
+ \end{document}
634
+ """)
635
+
636
+ # Format notes
637
+ notes_rows = " \\\\\n".join(
638
+ f"{n.get('date', '')} & {n.get('type', '')} & {n.get('text', '').replace('&', '\\&')}"
639
+ for n in patient.get("notes", [])
640
+ )
641
+
642
+ # Fill in template
643
+ latex = latex_template.substitute(
644
+ date=datetime.now().strftime('%A, %B %d, %Y at %I:%M %p'),
645
+ fhir_id=patient.get("fhir_id", ""),
646
+ full_name=patient.get("full_name", ""),
647
+ gender=patient.get("gender", ""),
648
+ dob=patient.get("date_of_birth", ""),
649
+ age=calculate_age(patient.get("date_of_birth", "")),
650
+ address=", ".join(filter(None, [
651
+ patient.get("address", ""),
652
+ patient.get("city", ""),
653
+ patient.get("state", ""),
654
+ patient.get("postal_code", ""),
655
+ patient.get("country", "")
656
+ ])),
657
+ marital_status=patient.get("marital_status", ""),
658
+ language=patient.get("language", ""),
659
+ notes=notes_rows
660
+ )
661
+
662
+ # Save and compile PDF
663
  with tempfile.TemporaryDirectory() as tmpdir:
664
+ tex_path = os.path.join(tmpdir, "report.tex")
665
+ pdf_path = os.path.join(tmpdir, "report.pdf")
666
+
667
+ with open(tex_path, "w", encoding="utf-8") as f:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  f.write(latex)
669
 
670
  try:
671
+ subprocess.run(["latexmk", "-pdf", "-interaction=nonstopmode", tex_path],
672
+ check=True, cwd=tmpdir)
673
+
674
  with open(pdf_path, "rb") as f:
675
  pdf_bytes = f.read()
676
 
677
  response = Response(content=pdf_bytes, media_type="application/pdf")
678
+ response.headers["Content-Disposition"] = f"attachment; filename=patient_{patient.get('fhir_id', 'unknown')}_report.pdf"
679
  return response
680
 
681
  except subprocess.CalledProcessError as e:
 
683
  raise HTTPException(status_code=500, detail="LaTeX compilation failed")
684
 
685
  except Exception as e:
686
+ logger.exception("Unexpected error generating PDF")
687
  raise HTTPException(status_code=500, detail="Failed to generate PDF")
 
688
  @router.post("/signup", status_code=status.HTTP_201_CREATED)
689
  async def signup(data: SignupForm):
690
  logger.info(f"Signup attempt for email: {data.email}")