Make a medical oncology discharge summary for supportive care for Indian patient cancer patients

Asking for Preferences
Reading File
Reading File
Running Command

mkdir -p /home/daytona/workspace/oncology-discharge && ls /home/daytona/workspac…

Writing File

~/oncology-discharge/generate_discharge.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame
from reportlab.lib.colors import HexColor

OUTPUT_PATH = "/home/daytona/workspace/oncology-discharge/Oncology_Discharge_Summary.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
DEEP_BLUE   = HexColor("#1A3A5C")   # headers / title bar
MID_BLUE    = HexColor("#2E6DA4")   # section headings
LIGHT_BLUE  = HexColor("#D6E8F7")   # table header row background
ORANGE      = HexColor("#E07B39")   # accent line under hospital name
LIGHT_GREY  = HexColor("#F5F5F5")   # alternating table row bg
RED_ALERT   = HexColor("#C0392B")   # allergy / alert text
WHITE       = colors.white
BLACK       = colors.black

W, H = A4

# ── Document setup ──────────────────────────────────────────────────────────
doc = BaseDocTemplate(
    OUTPUT_PATH,
    pagesize=A4,
    leftMargin=18*mm, rightMargin=18*mm,
    topMargin=22*mm, bottomMargin=20*mm,
    title="Medical Oncology Discharge Summary – Supportive Care",
    author="Tata Cancer Care Centre, Mumbai",
)

content_width = W - 36*mm   # usable width

frame = Frame(
    doc.leftMargin, doc.bottomMargin,
    content_width, H - doc.topMargin - doc.bottomMargin,
    id='normal'
)

def header_footer(canvas, doc_obj):
    canvas.saveState()
    # Top rule
    canvas.setStrokeColor(MID_BLUE)
    canvas.setLineWidth(0.8)
    canvas.line(18*mm, H - 14*mm, W - 18*mm, H - 14*mm)
    # Footer
    canvas.setFont("Helvetica", 7)
    canvas.setFillColor(colors.grey)
    canvas.drawString(18*mm, 12*mm, "CONFIDENTIAL – For treating physician use only")
    canvas.drawRightString(W - 18*mm, 12*mm, f"Page {doc_obj.page}")
    canvas.line(18*mm, 14*mm, W - 18*mm, 14*mm)
    canvas.restoreState()

doc.addPageTemplates([PageTemplate(id='main', frames=[frame], onPage=header_footer)])

# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()

def s(name, **kw):
    p = ParagraphStyle(name, parent=base['Normal'], **kw)
    return p

HOSPITAL = s("hospital", fontSize=16, fontName="Helvetica-Bold",
             textColor=WHITE, alignment=TA_CENTER, spaceAfter=0)
HOSP_SUB = s("hsub", fontSize=8.5, fontName="Helvetica",
             textColor=HexColor("#BDD9F2"), alignment=TA_CENTER, spaceAfter=0)
DOC_TITLE = s("docTitle", fontSize=13, fontName="Helvetica-Bold",
              textColor=DEEP_BLUE, alignment=TA_CENTER, spaceAfter=4)
SEC_HEAD  = s("secHead", fontSize=10, fontName="Helvetica-Bold",
              textColor=WHITE, alignment=TA_LEFT,
              leftIndent=4, spaceAfter=0, spaceBefore=8)
LABEL     = s("label", fontSize=8.5, fontName="Helvetica-Bold",
              textColor=DEEP_BLUE, spaceAfter=1)
VALUE     = s("value", fontSize=9, fontName="Helvetica",
              textColor=BLACK, spaceAfter=2)
SMALL     = s("small", fontSize=8, fontName="Helvetica",
              textColor=colors.grey)
ALERT     = s("alert", fontSize=9, fontName="Helvetica-Bold",
              textColor=RED_ALERT)
BODY      = s("body", fontSize=9, fontName="Helvetica",
              textColor=BLACK, leading=13, spaceAfter=3,
              alignment=TA_JUSTIFY)
BULLET    = s("bullet", fontSize=9, fontName="Helvetica",
              textColor=BLACK, leading=12, leftIndent=10, bulletIndent=0,
              spaceAfter=2)
SIG_STYLE = s("sig", fontSize=8.5, fontName="Helvetica",
              textColor=colors.grey, alignment=TA_CENTER)

def section_header(text):
    """Returns a full-width coloured banner for a section."""
    tbl = Table([[Paragraph(text, SEC_HEAD)]], colWidths=[content_width])
    tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), MID_BLUE),
        ('TOPPADDING',  (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING',  (0,0), (-1,-1), 6),
    ]))
    return tbl

def kv_table(rows, col_ratios=(0.30, 0.70)):
    """Two-column label-value table."""
    cw = [content_width * r for r in col_ratios]
    data = [[Paragraph(lbl, LABEL), Paragraph(val, VALUE)] for lbl, val in rows]
    tbl = Table(data, colWidths=cw)
    tbl.setStyle(TableStyle([
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('LEFTPADDING', (0,0), (-1,-1), 4),
        ('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, LIGHT_GREY]),
        ('LINEBELOW', (0,-1), (-1,-1), 0.3, colors.lightgrey),
    ]))
    return tbl

def three_col_table(rows, headers, ratios=(0.35, 0.35, 0.30)):
    cw = [content_width * r for r in ratios]
    head_row = [Paragraph(f"<b>{h}</b>", s("th", fontSize=8.5, fontName="Helvetica-Bold",
                           textColor=DEEP_BLUE)) for h in headers]
    data = [head_row]
    for row in rows:
        data.append([Paragraph(cell, VALUE) for cell in row])
    tbl = Table(data, colWidths=cw)
    tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), LIGHT_BLUE),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_GREY]),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('LEFTPADDING', (0,0), (-1,-1), 4),
        ('GRID', (0,0), (-1,-1), 0.3, colors.lightgrey),
    ]))
    return tbl

def four_col_table(rows, headers, ratios=(0.22, 0.22, 0.28, 0.28)):
    cw = [content_width * r for r in ratios]
    head_row = [Paragraph(f"<b>{h}</b>", s("th4", fontSize=8.5, fontName="Helvetica-Bold",
                           textColor=DEEP_BLUE)) for h in headers]
    data = [head_row]
    for row in rows:
        data.append([Paragraph(cell, VALUE) for cell in row])
    tbl = Table(data, colWidths=cw)
    tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), LIGHT_BLUE),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LIGHT_GREY]),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('LEFTPADDING', (0,0), (-1,-1), 4),
        ('GRID', (0,0), (-1,-1), 0.3, colors.lightgrey),
    ]))
    return tbl

# ═══════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════════════════
story = []

# ── Hospital Header Banner ───────────────────────────────────────────────────
hosp_banner = Table(
    [[Paragraph("TATA CANCER CARE CENTRE", HOSPITAL)],
     [Paragraph("Department of Medical Oncology | Supportive & Palliative Care Unit", HOSP_SUB)],
     [Paragraph("Mumbai – 400 012, Maharashtra | Tel: 022-6750-0000 | www.tatacancercare.org", HOSP_SUB)]],
    colWidths=[content_width]
)
hosp_banner.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,-1), DEEP_BLUE),
    ('TOPPADDING',  (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,-1), (-1,-1), 8),
    ('LEFTPADDING',  (0,0), (-1,-1), 4),
]))
story.append(hosp_banner)
story.append(HRFlowable(width=content_width, thickness=3, color=ORANGE, spaceAfter=6))

# Document title
story.append(Paragraph("MEDICAL ONCOLOGY DISCHARGE SUMMARY", DOC_TITLE))
story.append(Paragraph("(Supportive Care Admission)", s("subT", fontSize=9.5,
             fontName="Helvetica-Oblique", textColor=MID_BLUE, alignment=TA_CENTER)))
story.append(Spacer(1, 6))

# ── SECTION 1: Patient Demographics ─────────────────────────────────────────
story.append(section_header("1.  PATIENT DEMOGRAPHICS"))
story.append(Spacer(1, 3))

# Top row: two side-by-side mini tables
left_kv = [
    ("Patient Name:", "Smt. Sunita Ramesh Patil"),
    ("Age / Sex / Blood Group:", "52 Years / Female / B+ve"),
    ("Date of Birth:", "14 March 1974"),
    ("Marital Status:", "Married"),
    ("Religion:", "Hindu"),
    ("Address:", "Flat No. 7, Shivaji Nagar, Pune – 411 005"),
    ("Contact Number:", "+91 98765 43210"),
    ("Guardian / Attendant:", "Shri Ramesh Patil (Husband) – +91 98765 43211"),
    ("Referred By:", "Dr. P. K. Nair, MBBS MD – Nair Hospital, Pune"),
    ("UHID / MRD No.:", "TATA-ONC-2026-04872"),
]
right_kv = [
    ("Admission Date:", "30 June 2026"),
    ("Discharge Date:", "09 July 2026"),
    ("Total Days Admitted:", "10 Days"),
    ("Ward / Bed:", "Oncology Ward – Bed No. 14B"),
    ("Treating Consultant:", "Dr. Anjali Mehta, MD DM Medical Oncology"),
    ("Co-consultant:", "Dr. Suresh Kadam, MD Palliative Medicine"),
    ("Resident / JR:", "Dr. Priya Soni (Junior Resident)"),
    ("Nursing In-charge:", "Nurse Kavita Joshi"),
    ("Insurance / Ayushman:", "Ayushman Bharat PMJAY – Policy No. 0045-2026"),
    ("ECOG Performance Status:", "2 (at admission) → 1 (at discharge)"),
]
demo_left  = kv_table(left_kv,  (0.40, 0.60))
demo_right = kv_table(right_kv, (0.44, 0.56))
demo_outer = Table([[demo_left, Spacer(4,1), demo_right]],
                   colWidths=[content_width*0.49, 4, content_width*0.49])
demo_outer.setStyle(TableStyle([('VALIGN', (0,0), (-1,-1), 'TOP')]))
story.append(demo_outer)
story.append(Spacer(1, 6))

# ── SECTION 2: Oncological Diagnosis ────────────────────────────────────────
story.append(section_header("2.  ONCOLOGICAL DIAGNOSIS"))
story.append(Spacer(1, 3))
story.append(kv_table([
    ("Primary Diagnosis:", "Carcinoma Left Breast – Invasive Ductal Carcinoma (IDC), Grade III"),
    ("Stage:", "Stage IIIB (T4b N2 M0) – Locally Advanced Breast Cancer"),
    ("Receptor Status:", "ER +ve (80%), PR +ve (60%), HER2 2+ (FISH Non-amplified) – Luminal B (HER2-negative)"),
    ("Date of Histopathology:", "12 April 2026  |  Biopsy Lab Ref: TATA-PATH-2026-1122"),
    ("Ki-67 Index:", "35% (High Proliferative)"),
    ("Date of Initial Diagnosis:", "10 April 2026"),
    ("Comorbidities:", "Type 2 Diabetes Mellitus (on OHA), Hypertension (controlled), Iron-Deficiency Anaemia"),
    ("Known Allergies:", "<font color='#C0392B'><b>ALLERGIC TO PENICILLIN (Rash) – Documented on armband</b></font>"),
], (0.30, 0.70)))
story.append(Spacer(1, 6))

# ── SECTION 3: Current Admission – Reason ───────────────────────────────────
story.append(section_header("3.  REASON FOR THIS ADMISSION"))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "Patient was admitted with <b>Grade 3 febrile neutropaenia</b> following Cycle 3 of neoadjuvant "
    "chemotherapy (AC-T regimen: Doxorubicin + Cyclophosphamide). She presented with high-grade fever "
    "(39.8°C), rigors, oral mucositis (WHO Grade II), nausea/vomiting (CTCAE Grade 2), and significant "
    "fatigue. She also had worsening oral intake with body weight loss of 3 kg over 3 weeks, raising "
    "concern for nutritional compromise. Admission was also prompted by uncontrolled pain (NRS 7/10) "
    "from bone metastasis-related back pain.", BODY))
story.append(Spacer(1, 6))

# ── SECTION 4: Treatment Given During Admission ───────────────────────────────
story.append(section_header("4.  TREATMENT ADMINISTERED DURING ADMISSION"))
story.append(Spacer(1, 3))

story.append(Paragraph("<b>A. Anti-infective / Neutropaenia Management</b>", LABEL))
story.append(Spacer(1,2))
story.append(four_col_table([
    ["Inj. Piperacillin-Tazobactam 4.5 g IV Q8H", "30 Jun – 06 Jul 2026", "7 days", "Empiric broad-spectrum; de-escalated on culture sensitivity"],
    ["Inj. Amikacin 15 mg/kg IV OD", "30 Jun – 03 Jul 2026", "4 days", "Gram-negative cover; stopped on Day 4 (culture guided)"],
    ["Inj. Fluconazole 400 mg IV OD", "30 Jun – 05 Jul 2026", "6 days", "Antifungal prophylaxis; switched to oral on Day 6"],
    ["Inj. Filgrastim 300 mcg SC OD", "01 Jul – 06 Jul 2026", "6 days", "G-CSF – neutropaenia recovery"],
    ["Inj. Acyclovir 5 mg/kg IV Q8H", "01 Jul – 04 Jul 2026", "4 days", "HSV prophylaxis in immunocompromised state"],
], ["Drug / Dose / Route / Frequency", "Duration", "No. of Days", "Remarks"],
   ratios=(0.35, 0.22, 0.12, 0.31)))
story.append(Spacer(1, 4))

story.append(Paragraph("<b>B. Supportive Care – Antiemetics, Pain &amp; Nutrition</b>", LABEL))
story.append(Spacer(1,2))
story.append(four_col_table([
    ["Inj. Ondansetron 8 mg IV TID", "30 Jun – 08 Jul", "9 days", "5-HT3 antagonist; nausea control"],
    ["Tab. Metoclopramide 10 mg TID (PO) – after Day 5", "05 Jul – 08 Jul", "4 days", "Prokinetic; gastric stasis"],
    ["Inj. Pantoprazole 40 mg IV OD", "30 Jun – 09 Jul", "10 days", "Gastroprotection"],
    ["Tab. Pantoprazole 40 mg PO OD at discharge", "Discharge Rx", "Continue", "Step-down oral PPI"],
    ["Inj. Tramadol 50 mg IV Q8H (PRN)", "30 Jun – 03 Jul", "4 days", "Moderate-severe pain (NRS 7/10)"],
    ["Tab. Oxycodone CR 10 mg PO Q12H", "04 Jul onwards", "Continue", "Opioid rotation – better pain control"],
    ["Tab. Pregabalin 75 mg BD", "02 Jul onwards", "Continue", "Neuropathic component"],
    ["Tab. Paracetamol 500 mg TID (PRN)", "30 Jun onwards", "Continue", "Adjuvant analgesic / antipyretic"],
    ["Ryle's Tube feeding: Ensure Plus 200 mL Q4H", "01 Jul – 05 Jul", "5 days", "Enteral nutrition support – poor oral intake"],
    ["High-protein oral nutritional supplement (Protinex)", "06 Jul onwards", "Continue", "Oral sip feeds – 2 servings/day"],
    ["IV Fluids: NS 0.9% + KCl 20 mEq @ 80 mL/hr", "30 Jun – 04 Jul", "5 days", "Hydration, electrolyte correction"],
    ["Inj. Iron Sucrose 200 mg IV in 100 mL NS", "02, 04, 06 Jul", "3 doses", "Iron deficiency anaemia (Hb 7.8 on admission)"],
    ["PRBC transfusion 2 units", "03 July 2026", "1 session", "Hb 7.2 g/dL; symptomatic anaemia"],
], ["Drug / Intervention", "Duration", "Days", "Remarks"],
   ratios=(0.33, 0.17, 0.10, 0.40)))
story.append(Spacer(1, 4))

story.append(Paragraph("<b>C. Oral Care / Mucositis Management</b>", LABEL))
story.append(Spacer(1,2))
story.append(three_col_table([
    ["Magic Mouthwash (Lignocaine + Antacid + Diphenhydramine) 10 mL QID swish-spit", "07 days", "WHO Grade II Mucositis"],
    ["Benzydamine HCl 0.15% mouthwash TID", "07 days", "Anti-inflammatory rinse"],
    ["Clotrimazole oral lozenges 10 mg 5 x/day", "05 days", "Oral candidiasis prevention"],
    ["Soft / liquid diet; calorie-dense foods advised", "Ongoing", "Dietitian reviewed on Day 3"],
], ["Intervention", "Duration", "Reason / Notes"],
   ratios=(0.45, 0.15, 0.40)))
story.append(Spacer(1, 4))

story.append(Paragraph("<b>D. Psycho-Social &amp; Palliative Care Input</b>", LABEL))
story.append(Spacer(1,2))
story.append(three_col_table([
    ["Palliative care team review", "Day 2 &amp; Day 8", "Goals-of-care discussion; advance care planning initiated"],
    ["Psychiatric / Counselling referral", "Day 4", "Moderate anxiety-depression (PHQ-9 score 14); initiated Tab. Escitalopram 10 mg OD"],
    ["Social worker assessment", "Day 5", "Ayushman Bharat reimbursement facilitated; home nursing arranged"],
    ["Patient &amp; caregiver education (verbal + printed pamphlet in Marathi)", "Day 8 &amp; 9", "Chemotherapy side-effects, infection precautions, diet, pain diary"],
], ["Intervention", "Timing", "Details"],
   ratios=(0.28, 0.18, 0.54)))
story.append(Spacer(1, 6))

# ── SECTION 5: Investigations ────────────────────────────────────────────────
story.append(section_header("5.  KEY INVESTIGATIONS"))
story.append(Spacer(1, 3))

story.append(Paragraph("<b>Haematology &amp; Biochemistry (Admission vs Discharge)</b>", LABEL))
story.append(Spacer(1,2))
story.append(four_col_table([
    ["Haemoglobin (g/dL)",       "7.2",   "10.4",  "Post 2U PRBC transfusion + Iron sucrose"],
    ["Total WBC (cells/µL)",     "380",   "4,200", "Nadir on Day 1; recovery with G-CSF"],
    ["ANC (cells/µL)",           "80",    "2,800", "Severe neutropaenia → resolved"],
    ["Platelets (lakh/µL)",      "0.9",   "1.4",   "Mild thrombocytopenia; recovered spontaneously"],
    ["Serum Creatinine (mg/dL)", "1.1",   "0.9",   "Within normal limits"],
    ["Serum Sodium (mEq/L)",     "131",   "138",   "Mild hyponatraemia corrected"],
    ["Serum Potassium (mEq/L)",  "3.1",   "3.9",   "Hypokalaemia corrected with supplementation"],
    ["ALT / SGPT (U/L)",         "68",    "34",    "Mild transaminitis; resolved"],
    ["Serum Albumin (g/dL)",     "2.6",   "2.9",   "Improving with nutritional support"],
    ["Blood Sugar Fasting (mg/dL)","178", "112",   "Glycaemic control improved; OHA adjusted"],
    ["Blood Culture (Day 1)",    "E. coli (ESBL negative, sensitive to Pip-Taz)", "—", "Guided antibiotic therapy"],
    ["CXR (01 Jul 2026)",        "No consolidation; small left pleural effusion", "—", "Stable at discharge"],
    ["ECHO (03 Jul 2026)",       "EF 58%; no regional wall motion abnormality", "—", "Baseline pre-anthracycline"],
], ["Parameter", "At Admission", "At Discharge", "Remarks"],
   ratios=(0.30, 0.18, 0.18, 0.34)))
story.append(Spacer(1, 6))

# ── SECTION 6: Summary of Hospital Course ────────────────────────────────────
story.append(section_header("6.  SUMMARY OF HOSPITAL COURSE"))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "Patient was admitted with post-chemotherapy febrile neutropaenia (Grade 3) after Cycle 3 "
    "of AC chemotherapy. She was started promptly on empiric broad-spectrum IV antibiotics "
    "(Piperacillin-Tazobactam + Amikacin) as per institutional febrile neutropaenia protocol "
    "(MASCC Score 17 – Low Risk; admitted as per patient preference and logistic considerations). "
    "Blood culture grew E. coli, sensitive to the empiric regimen. Antibiotics were continued for a "
    "total of 7 days and successfully de-escalated. G-CSF (Filgrastim) was administered for 6 days; "
    "ANC recovered to &gt;2,000 by Day 7.", BODY))
story.append(Paragraph(
    "Symptomatic anaemia (Hb 7.2 g/dL) was managed with 2 units of packed red blood cells and "
    "3 doses of IV iron sucrose. Nutritional status was supported initially via nasogastric enteral feeds "
    "(5 days) and transitioned to oral sip feeds with dietitian supervision. Body weight improved by "
    "1.2 kg over the admission.", BODY))
story.append(Paragraph(
    "Pain was initially controlled with IV tramadol and was effectively rotated to oral sustained-release "
    "oxycodone with addition of pregabalin for the neuropathic component; NRS score improved from 7/10 "
    "to 2/10 at discharge. Oral mucositis healed to Grade I by Day 8. Electrolyte imbalances (hyponatraemia, "
    "hypokalaemia) were corrected. Blood sugar was stabilised with dose adjustment of oral hypoglycaemics. "
    "Palliative care and psychiatry teams were involved for goals-of-care planning and management of "
    "anxiety-depression. Patient and caregivers were educated in Marathi and English; home nursing "
    "services were arranged via the social worker.", BODY))
story.append(Spacer(1, 4))

# ── SECTION 7: Condition at Discharge ────────────────────────────────────────
story.append(section_header("7.  CONDITION AT DISCHARGE"))
story.append(Spacer(1, 3))
story.append(kv_table([
    ("General Condition:", "Stable, afebrile (Temp 37.1°C), ambulatory"),
    ("ECOG Performance Status:", "1 (improved from 2 at admission)"),
    ("Vital Signs at Discharge:", "BP 128/80 mmHg | PR 82/min, regular | SpO₂ 98% (RA) | RR 16/min"),
    ("Pain (NRS):", "2/10 – well-controlled on oral opioid regimen"),
    ("Oral Intake:", "Tolerating soft diet + high-protein sip feeds"),
    ("Emotional Status:", "Improved; less anxious; engaged with counselling"),
    ("Caregiver Status:", "Husband present; educated and capable of home care"),
], (0.28, 0.72)))
story.append(Spacer(1, 6))

# ── SECTION 8: Discharge Medications ─────────────────────────────────────────
story.append(section_header("8.  DISCHARGE MEDICATIONS (Rx)"))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "<font color='#C0392B'><b>ALLERGY: PENICILLIN</b></font>  –  ensure no beta-lactam penicillins are prescribed in the community.",
    ALERT))
story.append(Spacer(1, 3))
story.append(four_col_table([
    ["Tab. Oxycodone CR (OxyContin) 10 mg", "Twice daily (every 12 hrs)", "14 days", "Opioid – for persistent cancer pain; do NOT crush"],
    ["Tab. Paracetamol 500 mg", "Three times daily (TID)", "14 days", "Adjuvant analgesic / breakthrough pain"],
    ["Tab. Pregabalin 75 mg", "Twice daily (BD)", "14 days", "Neuropathic pain"],
    ["Tab. Pantoprazole 40 mg", "Once daily (before breakfast)", "30 days", "Gastroprotection with NSAIDs/steroids"],
    ["Tab. Ondansetron 4 mg", "Twice daily (PRN for nausea)", "10 days", "As-needed antiemetic"],
    ["Tab. Metoclopramide 10 mg", "Three times daily (before meals)", "10 days", "Prokinetic – nausea/gastric stasis"],
    ["Tab. Escitalopram 10 mg", "Once daily (morning)", "30 days", "Anxio-depressive symptoms; psychiatry follow-up"],
    ["Cap. Fluconazole 150 mg", "Once weekly", "4 weeks", "Antifungal maintenance; immunosuppressed state"],
    ["Tab. Acyclovir 400 mg", "Twice daily", "14 days", "HSV prophylaxis"],
    ["Tab. Cotrimoxazole DS", "Once daily (Mon/Wed/Fri)", "Until ANC &gt;500 sustained", "PCP prophylaxis (CD4 equivalent status)"],
    ["Tab. Metformin 500 mg + Glimepiride 1 mg", "Twice daily (with meals)", "Continue", "Diabetes management; BSFL 112 at discharge"],
    ["Tab. Amlodipine 5 mg", "Once daily (morning)", "Continue", "Antihypertensive"],
    ["Protinex (high-protein supplement) – 2 scoops", "Twice daily in warm milk/water", "Continue", "Nutritional support – target 1.5 g protein/kg/day"],
    ["Iron (Ferrous Ascorbate) 100 mg", "Twice daily (on empty stomach)", "30 days", "Iron deficiency anaemia – ongoing course"],
    ["Tab. Folic Acid 5 mg", "Once daily", "30 days", "Megaloblastic prevention with chemotherapy"],
], ["Drug / Formulation", "Dose / Frequency", "Duration", "Special Instructions"],
   ratios=(0.32, 0.22, 0.18, 0.28)))
story.append(Spacer(1, 4))
story.append(Paragraph(
    "<b>Note:</b> All opioid prescriptions have been issued with Schedule X narcotic prescription slips "
    "(as per NDPS Act India). Caregiver has been counselled on safe opioid storage, "
    "constipation prophylaxis, and signs of opioid toxicity.", SMALL))
story.append(Spacer(1, 6))

# ── SECTION 9: Dietary & Lifestyle Advice ─────────────────────────────────────
story.append(section_header("9.  DIETARY &amp; LIFESTYLE ADVICE (Advised by Dietitian Ms. Rekha More)"))
story.append(Spacer(1, 3))
bullets = [
    "Target caloric intake: <b>2,000–2,200 kcal/day</b>; protein target: <b>75–80 g/day</b> (1.5 g/kg/day).",
    "Foods encouraged: Soft-cooked lentils (dal), curd/yoghurt, mashed potato, soft idli/upma, boiled eggs, fish curry, ragi porridge, banana, papaya, seasonal fruits (washed thoroughly).",
    "Foods to <b>AVOID</b> during chemotherapy: Raw salads, uncooked sprouts, street food (chaat, pani puri), unpasteurised milk/cheese (paneer from street vendors), high-fibre raw vegetables, alcohol, tobacco products.",
    "Maintain oral hygiene: Rinse after every meal with warm saline or prescribed mouthwash.",
    "Adequate hydration: Minimum <b>2–2.5 litres/day</b> of boiled/filtered water.",
    "Light physical activity as tolerated: 15–20-minute walks twice daily (if ANC &gt;1,000).",
    "Avoid crowded places, religious gatherings, sick contacts – infection precautions during neutropaenia phase.",
    "Report any fever ≥38°C immediately to oncology emergency (do not wait – come directly to casualty).",
]
for b in bullets:
    story.append(Paragraph(f"• {b}", BULLET))
story.append(Spacer(1, 6))

# ── SECTION 10: Follow-up Plan ────────────────────────────────────────────────
story.append(section_header("10.  FOLLOW-UP PLAN"))
story.append(Spacer(1, 3))
story.append(three_col_table([
    ["<b>CBC + Blood Sugar + LFT + KFT</b>", "14 July 2026 (Day 5 post-discharge)", "Community lab OR TATA OPD Lab; report to bring on follow-up"],
    ["<b>Medical Oncology OPD – Dr. Anjali Mehta</b>", "16 July 2026 – 10:00 AM (OPD No. 14)", "Pre-Cycle 4 evaluation; dose modification if needed"],
    ["<b>Palliative Medicine – Dr. Suresh Kadam</b>", "18 July 2026", "Pain assessment; opioid dose titration"],
    ["<b>Psychiatry OPD</b>", "20 July 2026", "Escitalopram response evaluation; counselling continuation"],
    ["<b>Dietitian Review</b>", "23 July 2026 (telephonic)", "Nutritional status, weight trend, sip feed compliance"],
    ["<b>Cycle 4 Chemotherapy (Paclitaxel 175 mg/m²)</b>", "28 July 2026 (tentative)", "Subject to ANC &gt;1,500, Hb &gt;9, Platelets &gt;1,00,000"],
], ["Appointment", "Date / Time", "Details"],
   ratios=(0.32, 0.28, 0.40)))
story.append(Spacer(1, 6))

# ── SECTION 11: Emergency Instructions ───────────────────────────────────────
story.append(section_header("11.  EMERGENCY INSTRUCTIONS – WHEN TO COME TO HOSPITAL IMMEDIATELY"))
story.append(Spacer(1, 3))
alert_items = [
    "Fever ≥38°C or chills/rigors at any time (do <b>NOT</b> give paracetamol and wait – come directly)",
    "Bleeding from any site (gums, nose, urine, stool, skin bruising)",
    "Sudden breathlessness, chest pain, or palpitations",
    "Severe pain (NRS &gt;6) not responding to prescribed medications",
    "Inability to take oral medications or severe vomiting for &gt;12 hours",
    "Confusion, altered sensorium, fits or severe headache",
    "Swelling, redness, or pus at the IV cannula site or PICC line",
    "Signs of opioid overdose: excessive drowsiness, slow breathing (&lt;8/min), pinpoint pupils",
]
for item in alert_items:
    story.append(Paragraph(f"⚠  {item}", s("alertBullet", fontSize=9, fontName="Helvetica",
                 textColor=HexColor("#7B2D00"), leading=13, leftIndent=8, spaceAfter=2)))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "<b>Oncology Emergency Helpline (24×7):</b>  022-6750-0911  |  "
    "<b>Oncology Casualty:</b>  Ground Floor, Block C, TATA Cancer Care Centre, Mumbai",
    s("emHelpline", fontSize=9, fontName="Helvetica-Bold", textColor=DEEP_BLUE)))
story.append(Spacer(1, 6))

# ── SECTION 12: Signatures ────────────────────────────────────────────────────
story.append(section_header("12.  SIGNATURES &amp; CERTIFICATION"))
story.append(Spacer(1, 6))

sig_data = [
    [
        Paragraph("<b>Dr. Anjali Mehta</b><br/>MD, DM Medical Oncology<br/>"
                  "Reg. No.: MCI-2003-DM-04891<br/>Date: 09 July 2026", SIG_STYLE),
        Paragraph("<b>Dr. Suresh Kadam</b><br/>MD Palliative Medicine<br/>"
                  "Reg. No.: MCI-2007-MD-11223<br/>Date: 09 July 2026", SIG_STYLE),
        Paragraph("<b>Dr. Priya Soni</b><br/>MBBS, Junior Resident<br/>"
                  "Reg. No.: MMC-2022-01567<br/>Date: 09 July 2026", SIG_STYLE),
        Paragraph("<b>Nurse Kavita Joshi</b><br/>B.Sc Nursing, Oncology Certified<br/>"
                  "Staff ID: TATA-NRS-442<br/>Date: 09 July 2026", SIG_STYLE),
    ]
]
sig_labels = [
    Paragraph("____________________________", SIG_STYLE),
    Paragraph("____________________________", SIG_STYLE),
    Paragraph("____________________________", SIG_STYLE),
    Paragraph("____________________________", SIG_STYLE),
]

sig_tbl = Table(
    [sig_labels, sig_data[0]],
    colWidths=[content_width/4]*4
)
sig_tbl.setStyle(TableStyle([
    ('VALIGN', (0,0), (-1,-1), 'BOTTOM'),
    ('TOPPADDING', (0,0), (-1,-1), 2),
    ('BOTTOMPADDING', (0,0), (-1,-1), 2),
    ('ALIGN', (0,0), (-1,-1), 'CENTER'),
]))
story.append(sig_tbl)
story.append(Spacer(1, 8))

# Patient acknowledgement
ack_tbl = Table([[
    Paragraph(
        "Patient / Guardian Acknowledgement:<br/>"
        "I, <u>Shri Ramesh Patil</u>, have received and understood the discharge instructions, "
        "medication list, and follow-up plan in <b>Marathi and English</b>.<br/><br/>"
        "Signature: ____________________________  &nbsp;&nbsp;&nbsp;"
        "Date: 09 July 2026 &nbsp;&nbsp;&nbsp; Relation to Patient: Husband",
        s("ack", fontSize=8.5, fontName="Helvetica", textColor=BLACK, leading=13))
]], colWidths=[content_width])
ack_tbl.setStyle(TableStyle([
    ('BOX', (0,0), (-1,-1), 0.8, MID_BLUE),
    ('BACKGROUND', (0,0), (-1,-1), LIGHT_BLUE),
    ('TOPPADDING', (0,0), (-1,-1), 6),
    ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(ack_tbl)
story.append(Spacer(1, 6))

# ── Footer disclaimer ─────────────────────────────────────────────────────────
story.append(HRFlowable(width=content_width, thickness=0.5, color=colors.grey))
story.append(Spacer(1, 3))
story.append(Paragraph(
    "This discharge summary is generated for clinical and documentation purposes. "
    "Details are fictitious and created for demonstration / training. "
    "All drug dosages and regimens should be verified against current institutional guidelines "
    "and the prescribing physician's clinical judgment. "
    "Orris Medical AI – July 2026.",
    s("disclaimer", fontSize=7, fontName="Helvetica-Oblique",
      textColor=colors.grey, alignment=TA_CENTER)))

# ═══════════════════════════════════════════════════════════════════════════
# BUILD
# ═══════════════════════════════════════════════════════════════════════════
doc.build(story)
print(f"PDF saved to: {OUTPUT_PATH}")
Running Command

cd /home/daytona/workspace/oncology-discharge && python generate_discharge.py 2>…

Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Running Command

cd /home/daytona/workspace/oncology-discharge && python generate_discharge.py 2>…

Running Command

cd /home/daytona/workspace/oncology-discharge && python -c " from reportlab.lib.…

Running Command

cd /home/daytona/workspace/oncology-discharge && python -c " import traceback ex…

Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Editing File

~/oncology-discharge/generate_discharge.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/oncology-discharge/generate_discharge.py'
Running Command

cd /home/daytona/workspace/oncology-discharge && python generate_discharge.py 2>…

Model call limits exceeded: run limit (20/20)

Find latest ASCO guidelines on palliative care in cancer

Searching PubMed

ASCO guideline palliative care cancer

Searching the Web

ASCO 2024 2025 palliative care oncology guideline update

Reading Article

PMID: 38748941

Reading Article

PMID: 36469839

Reading Article

PMID: 36122322

Reading Web Page

https://ascopubs.org/doi/10.1200/JCO.24.00542

Reading Article

PMID: 40029420

Here is a comprehensive summary of the latest ASCO guidelines on palliative care in cancer.

ASCO Guidelines on Palliative Care in Cancer - Latest Evidence (2022-2025)


1. PRIMARY GUIDELINE: Palliative Care for Patients With Cancer: ASCO Guideline Update (2024)

Citation: Sanders JJ, Temin S, Ghoshal A, et al. J Clin Oncol. 2024;42(19):2336-2357. Published online May 15, 2024. PMID: 38748941 | DOI: 10.1200/JCO.24.00542
This is the most current and comprehensive ASCO palliative care guideline, updating the previous 2016 version. It reviewed 52 studies (systematic reviews, meta-analyses, RCTs) published 2015-2023.

Core Recommendations

Who should receive specialist palliative care referral:
  • All patients with advanced solid tumors and hematologic malignancies should be referred to specialized interdisciplinary palliative care teams
  • Referral should begin early in the disease course, alongside active cancer treatment - not reserved for end of life
  • Patients on Phase I cancer clinical trials with solid tumors may also be referred to specialist palliative care
  • Patients with uncontrolled symptoms, QOL concerns, psychosocial or spiritual distress should receive early palliative care involvement
Where and how care is delivered:
  • Teams should provide both outpatient and inpatient palliative care
  • Cancer care programs should maintain dedicated specialist palliative care services complementing existing supportive care interventions (nurse navigation, geriatric oncology, psycho-oncology, pain services, telehealth)
  • Telehealth-based palliative care delivery is recognised as an emerging modality
Family caregivers:
  • Oncology clinicians may refer family caregivers and care partners (including chosen family and friends) to palliative care teams for additional support - this is a new explicit recommendation vs. the 2016 guideline
Equity and language:
  • This update explicitly addresses linguistic, geographic, ethical, and contextual factors affecting equitable access to palliative care - particularly relevant for diverse populations including India

What Changed From 2016 to 2024?

Domain2016 Guideline2024 Update
Patient populationAdvanced cancer, early integrationExtended to hematologic malignancies explicitly
Caregiver supportMentionedNow an explicit recommendation
Phase I trialsNot addressedNow included
Equity/languageNot addressedExplicitly addressed
TelehealthNot addressedRecognised as modality
Evidence base2009-2015 literature2015-2023 (52 studies)

2. ASCO Guideline: Use of Opioids for Cancer Pain (2023)

Citation: Paice JA, Bohlke K, Barton D, et al. J Clin Oncol. 2023;41(4):914-930. PMID: 36469839 | DOI: 10.1200/JCO.22.02198
Key recommendations:
  • Opioids should be offered to all patients with moderate-to-severe cancer pain unless contraindicated
  • Initiate PRN at the lowest effective dose, with early assessment and frequent titration
  • For patients with substance use disorder, collaborate with palliative care/pain/addiction specialists
  • Monitor and proactively manage opioid adverse effects (constipation, nausea, sedation)

3. SIO-ASCO Guideline: Integrative Medicine for Pain in Oncology (2022)

Citation: Mao JJ, Ismaila N, Bao T, et al. J Clin Oncol. 2022;40(34):3998-4024. PMID: 36122322 | DOI: 10.1200/JCO.22.01357
Key recommendations (evidence-based, moderate strength):
  • Acupuncture: Recommended for aromatase inhibitor-related joint pain; may be used for general cancer pain
  • Acupressure/Reflexology: May be offered for general cancer or musculoskeletal pain
  • Hypnosis: May be used for procedural pain
  • Massage: Recommended for pain during palliative or hospice care

4. MASCC-ASCO Multi-Society Guideline: Opioid Conversion in Cancer (2025)

Citation: Davis MP, Davies A, McPherson ML, et al. Support Care Cancer. 2025 Mar 3. PMID: 40029420 | DOI: 10.1007/s00520-025-09286-z
This multi-society 2025 guideline (MASCC + ASCO + AAHPM + HPNA + NICSO) addresses practical opioid rotation/conversion:
  • Based on 208 studies + modified Delphi consensus (58/84 statements reached 75% agreement)
  • Covers pre-conversion assessment, conversion strategies, and post-conversion monitoring
  • Goal: reduce risk of overdosing or under-dosing during opioid-to-opioid rotation or route switching
  • Highlights variability in conversion ratios, especially for methadone

5. Companion Commentary on the "Reality Gap" (2025)

Citation: Crowley F, Smith CB, Arnold RM, Afezolli D. Cancer. 2025;131(1):e35656. PMID: 39560401
This 2025 commentary from Mount Sinai highlights the implementation gap - despite strong evidence and guideline recommendations, most cancer patients worldwide (including in LMICs like India) still do not receive early specialist palliative care. Key barriers identified: workforce shortages, poor reimbursement, cultural stigma around "palliative = giving up," and access in rural/semi-urban settings.

Summary Table: ASCO Palliative Care Guidelines at a Glance

GuidelineYearJournalPMIDFocus
Palliative Care Integration2024J Clin Oncol38748941Core - early integration, all advanced cancer
Opioids for Cancer Pain2023J Clin Oncol36469839Opioid initiation & titration
Integrative Medicine (SIO-ASCO)2022J Clin Oncol36122322Acupuncture, massage, hypnosis
Opioid Conversion (MASCC-ASCO)2025Support Care Cancer40029420Opioid rotation/switching

Key Takeaway for Indian Oncology Practice

The 2024 ASCO guideline specifically recognises geographic and equity barriers to palliative care delivery - directly relevant to India. The recommendation for early integration starting from the time of diagnosis of advanced cancer (not at end-of-life) aligns with AIIMS and NMHC national palliative care policy directions. The endorsement of telehealth and generalist oncologist-delivered supportive care as complements to specialist teams is especially actionable in resource-limited settings.
This is a shared conversation. Sign in to Orris to start your own chat.