Minimum gv for doing upper GI endoscopy
minimum hemoglobin platelet count upper GI endoscopy safe threshold guidelines
| Context | Threshold |
|---|---|
| Elective / stable patient | No strict minimum Hb; transfuse if Hb < 7 g/dL before proceeding |
| Coronary artery disease / cardiac patient | Transfuse if Hb < 8 g/dL before proceeding |
| Active UGIB (emergency) | Endoscopy proceeds regardless; transfuse to target Hb ≥ 7 g/dL (restrictive strategy) |
| Procedure | ASGE Minimum Threshold |
|---|---|
| Diagnostic upper endoscopy (EGD) only | ≥ 20,000/mm³ |
| EGD + biopsy | ≥ 50,000/mm³ |
| Variceal banding / therapeutic procedures | ≥ 50,000/mm³ |
| Active UGIB (emergency EGD) | Aim for > 50,000/mm³ if possible, but endoscopy can be performed at lower counts in life-threatening bleeds |
| INR | Recommendation |
|---|---|
| INR 1.5 - 2.5 | Do not delay endoscopy - correction not required |
| INR > 2.5 | Correct before elective endoscopy |
| Active anticoagulation (DOAC/warfarin) with bleeding | Proceed to endoscopy before correcting (per Goldman-Cecil guidelines) |
| Parameter | Minimum for Diagnostic EGD | Minimum for Therapeutic EGD |
|---|---|---|
| Hemoglobin | Transfuse if < 7 g/dL (< 8 with CAD) | Same |
| Platelets | ≥ 20,000/mm³ | ≥ 50,000/mm³ |
| INR | ≤ 2.5 for elective | Correct if > 2.5 |
Create a pre-endoscopy checklist PDF with lab value requirements
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "workspace ready"
mkdir -p /tmp/workspace/endoscopy-checklist && python3 << 'EOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm, cm from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, HRFlowable from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT from reportlab.platypus import KeepTogether output_path = "/tmp/workspace/endoscopy-checklist/Pre_Endoscopy_Checklist.pdf" doc = SimpleDocTemplate( output_path, pagesize=A4, rightMargin=15*mm, leftMargin=15*mm, topMargin=12*mm, bottomMargin=12*mm ) styles = getSampleStyleSheet() # --- Custom styles --- title_style = ParagraphStyle( 'Title', parent=styles['Title'], fontSize=18, textColor=colors.HexColor('#1a3a5c'), spaceAfter=2*mm, alignment=TA_CENTER, fontName='Helvetica-Bold' ) subtitle_style = ParagraphStyle( 'Subtitle', parent=styles['Normal'], fontSize=10, textColor=colors.HexColor('#4a6fa5'), spaceAfter=6*mm, alignment=TA_CENTER, fontName='Helvetica' ) section_style = ParagraphStyle( 'Section', parent=styles['Normal'], fontSize=11, textColor=colors.white, fontName='Helvetica-Bold', alignment=TA_LEFT ) body_style = ParagraphStyle( 'Body', parent=styles['Normal'], fontSize=9, textColor=colors.HexColor('#222222'), fontName='Helvetica', leading=13 ) note_style = ParagraphStyle( 'Note', parent=styles['Normal'], fontSize=8, textColor=colors.HexColor('#555555'), fontName='Helvetica-Oblique', leading=11 ) footer_style = ParagraphStyle( 'Footer', parent=styles['Normal'], fontSize=7.5, textColor=colors.HexColor('#888888'), fontName='Helvetica', alignment=TA_CENTER ) label_style = ParagraphStyle( 'Label', parent=styles['Normal'], fontSize=9, textColor=colors.HexColor('#1a3a5c'), fontName='Helvetica-Bold' ) value_style = ParagraphStyle( 'Value', parent=styles['Normal'], fontSize=9, textColor=colors.HexColor('#333333'), fontName='Helvetica' ) warn_style = ParagraphStyle( 'Warn', parent=styles['Normal'], fontSize=8.5, textColor=colors.HexColor('#b22222'), fontName='Helvetica-Bold' ) BLUE_DARK = colors.HexColor('#1a3a5c') BLUE_MID = colors.HexColor('#2e6da4') BLUE_LIGHT = colors.HexColor('#dce9f7') GREEN_LIGHT = colors.HexColor('#e8f5e9') RED_LIGHT = colors.HexColor('#fdecea') ORANGE_LIGHT= colors.HexColor('#fff3e0') GREY_LINE = colors.HexColor('#cccccc') WHITE = colors.white TICK_BOX = u'\u25a1' # empty checkbox story = [] # ── HEADER ────────────────────────────────────────────────────────────────── story.append(Paragraph("PRE-ENDOSCOPY ASSESSMENT CHECKLIST", title_style)) story.append(Paragraph("Upper Gastrointestinal Endoscopy (EGD) | ASGE / ACG / AGA Guidelines", subtitle_style)) story.append(HRFlowable(width="100%", thickness=2, color=BLUE_DARK, spaceAfter=4*mm)) # ── PATIENT INFO ───────────────────────────────────────────────────────────── pt_data = [ [Paragraph("Patient Name:", label_style), Paragraph("_________________________________", value_style), Paragraph("Date:", label_style), Paragraph("__________________", value_style)], [Paragraph("MRN / ID:", label_style), Paragraph("_________________________________", value_style), Paragraph("Endoscopist:", label_style), Paragraph("__________________", value_style)], [Paragraph("DOB / Age:", label_style), Paragraph("_________________________________", value_style), Paragraph("Indication:", label_style), Paragraph("__________________", value_style)], ] pt_table = Table(pt_data, colWidths=[28*mm, 65*mm, 22*mm, 55*mm]) pt_table.setStyle(TableStyle([ ('BACKGROUND', (0,0),(-1,-1), BLUE_LIGHT), ('ROWBACKGROUNDS', (0,0), (-1,-1), [BLUE_LIGHT, WHITE]), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ])) story.append(pt_table) story.append(Spacer(1, 5*mm)) # ── HELPER: section header ──────────────────────────────────────────────────── def section_header(text, bg=BLUE_DARK): t = Table([[Paragraph(f" {text}", section_style)]], colWidths=[180*mm]) t.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), bg), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ])) return t def checkbox_row(label, threshold, result_field="Result: ________", note=""): note_para = Paragraph(note, note_style) if note else Paragraph("", note_style) row = [ Paragraph(TICK_BOX, body_style), Paragraph(f"<b>{label}</b>", body_style), Paragraph(threshold, body_style), Paragraph(result_field, body_style), note_para, ] return row # ── SECTION 1: LAB VALUES ──────────────────────────────────────────────────── story.append(section_header("SECTION 1 — LABORATORY VALUES (Required Before EGD)")) story.append(Spacer(1, 2*mm)) lab_header = [ Paragraph("", body_style), Paragraph("<b>Test</b>", label_style), Paragraph("<b>Minimum / Target</b>", label_style), Paragraph("<b>Patient Result</b>", label_style), Paragraph("<b>Notes</b>", label_style), ] lab_rows = [ lab_header, checkbox_row("Hemoglobin (Hb)", "≥ 7 g/dL (elective)\n≥ 8 g/dL (CAD/cardiac)", "Result: _______ g/dL", "Transfuse if below threshold before elective EGD"), checkbox_row("Hematocrit (Hct)", "≥ 21% (elective)\n≥ 24% (cardiac)", "Result: _______ %", "Correlates with Hb; may lag in acute hemorrhage"), checkbox_row("Platelet Count", "≥ 20,000/mm³ (diagnostic)\n≥ 50,000/mm³ (biopsy/therapeutic)", "Result: _______/mm³", "Transfuse platelets if below threshold for planned procedure"), checkbox_row("INR / PT", "INR ≤ 2.5 (elective)\nDo NOT delay for INR 1.5–2.5", "INR: _______", "Correct INR > 2.5 before elective EGD; FFP/Vit K as indicated"), checkbox_row("aPTT", "< 1.5× upper limit of normal", "Result: _______ sec", "Relevant in heparin therapy or coagulopathy"), checkbox_row("Serum Creatinine / eGFR", "Document baseline", "Cr: _______ eGFR: _______", "CKD may affect platelet function; contrast nephropathy risk"), checkbox_row("Serum Electrolytes", "Na, K, Cl, HCO₃ within range", "Na:___ K:___ Cl:___", "Correct severe hypokalemia before sedation"), checkbox_row("Blood Group & Screen", "Required if active/major bleeding", "Group: _______ Screen: ___", "Type & crossmatch if transfusion anticipated"), checkbox_row("Liver Function Tests", "Bilirubin, AST, ALT, Albumin", "ALT:___ Alb:___", "Cirrhosis alters coagulation & sedation metabolism"), ] lab_col_widths = [8*mm, 42*mm, 48*mm, 40*mm, 50*mm] lab_table = Table(lab_rows, colWidths=lab_col_widths, repeatRows=1) lab_table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), BLUE_MID), ('TEXTCOLOR', (0,0), (-1,0), WHITE), ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, BLUE_LIGHT]), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 4), ])) story.append(lab_table) story.append(Spacer(1, 5*mm)) # ── QUICK REFERENCE THRESHOLDS BOX ──────────────────────────────────────────── ref_title = [ [Paragraph(" QUICK REFERENCE — LAB VALUE THRESHOLDS AT A GLANCE", ParagraphStyle( 'RefTitle', parent=styles['Normal'], fontSize=9.5, textColor=WHITE, fontName='Helvetica-Bold')) ] ] ref_title_tbl = Table(ref_title, colWidths=[180*mm]) ref_title_tbl.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), BLUE_MID), ('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ])) ref_data = [ [Paragraph("<b>Parameter</b>", label_style), Paragraph("<b>Diagnostic EGD</b>", label_style), Paragraph("<b>EGD + Biopsy</b>", label_style), Paragraph("<b>Therapeutic EGD</b>", label_style), Paragraph("<b>Emergency EGD</b>", label_style)], [Paragraph("Hemoglobin", body_style), Paragraph("≥ 7 g/dL*", body_style), Paragraph("≥ 7 g/dL*", body_style), Paragraph("≥ 7 g/dL*", body_style), Paragraph("Proceed; transfuse simultaneously", body_style)], [Paragraph("Platelets", body_style), Paragraph("≥ 20,000/mm³", body_style), Paragraph("≥ 50,000/mm³", body_style), Paragraph("≥ 50,000/mm³", body_style), Paragraph("Target > 50,000 if possible", body_style)], [Paragraph("INR", body_style), Paragraph("≤ 2.5", body_style), Paragraph("≤ 1.5 preferred", body_style), Paragraph("≤ 1.5 preferred", body_style), Paragraph("Do not delay for anticoagulants", body_style)], [Paragraph("aPTT", body_style), Paragraph("< 1.5× ULN", body_style), Paragraph("< 1.5× ULN", body_style), Paragraph("< 1.5× ULN", body_style), Paragraph("Correct if feasible", body_style)], ] ref_table = Table(ref_data, colWidths=[32*mm, 34*mm, 34*mm, 34*mm, 44*mm], repeatRows=1) ref_table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#4a6fa5')), ('TEXTCOLOR', (0,0), (-1,0), WHITE), ('ROWBACKGROUNDS', (0,1), (-1,-1), [GREEN_LIGHT, WHITE]), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 3), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('LEFTPADDING', (0,0), (-1,-1), 4), ])) story.append(KeepTogether([ref_title_tbl, ref_table])) story.append(Paragraph(" * ≥ 8 g/dL for patients with coronary artery disease, recent cardiac surgery, or hematologic malignancy (AAFP 2020).", note_style)) story.append(Spacer(1, 5*mm)) # ── SECTION 2: CLINICAL ASSESSMENT ─────────────────────────────────────────── story.append(section_header("SECTION 2 — CLINICAL ASSESSMENT")) story.append(Spacer(1, 2*mm)) clinical_rows = [ [Paragraph("<b>Item</b>", label_style), Paragraph("<b>Detail / Finding</b>", label_style), Paragraph("<b>Cleared?</b>", label_style)], [Paragraph(f"{TICK_BOX} ASA / Allergy History", body_style), Paragraph("NSAIDs, antiplatelet, anticoagulant medications listed: ________________________", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Fasting Status", body_style), Paragraph("NPO solids ≥ 6 h, NPO clear liquids ≥ 2 h confirmed", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} IV Access", body_style), Paragraph("Large-bore IV (≥ 18G) secured: site _______________", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Vital Signs", body_style), Paragraph("BP: ___/___ HR: ___ SpO₂: ___ RR: ___ Temp: ___", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Hemodynamic Stability", body_style), Paragraph("Systolic BP ≥ 90 mmHg (if unstable → urgent endoscopy, ongoing resuscitation)", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Airway Assessment", body_style), Paragraph("Mallampati class: ___ Neck mobility: ___ Anticipated difficult airway? ___", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Cardiorespiratory History", body_style), Paragraph("IHD / CCF / COPD / OSA: ________________________________", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Sedation Consent", body_style), Paragraph("Informed consent obtained, risks explained, escort arranged", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Anticoagulant Management", body_style), Paragraph("Warfarin held ≥ 5 days / DOAC held per protocol / Bridging if required", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Antiplatelet Management", body_style), Paragraph("Aspirin: continue / hold Clopidogrel: continue / hold (per procedure risk)", body_style), Paragraph("Yes / No", body_style)], [Paragraph(f"{TICK_BOX} Infection Precautions", body_style), Paragraph("High-risk procedure + ANC < 500/mm³ → antibiotic prophylaxis considered", body_style), Paragraph("Yes / No", body_style)], ] clinical_table = Table(clinical_rows, colWidths=[52*mm, 102*mm, 24*mm], repeatRows=1) clinical_table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), BLUE_MID), ('TEXTCOLOR', (0,0), (-1,0), WHITE), ('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, BLUE_LIGHT]), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 4), ])) story.append(clinical_table) story.append(Spacer(1, 5*mm)) # ── SECTION 3: PROCEDURE RISK STRATIFICATION ───────────────────────────────── story.append(section_header("SECTION 3 — PROCEDURE RISK STRATIFICATION (ASGE)")) story.append(Spacer(1, 2*mm)) risk_rows = [ [Paragraph("<b>Risk Category</b>", label_style), Paragraph("<b>Procedure Type</b>", label_style), Paragraph("<b>Hold Antithrombotic?</b>", label_style)], [Paragraph("LOW RISK", ParagraphStyle('LowRisk', parent=styles['Normal'], fontSize=9, fontName='Helvetica-Bold', textColor=colors.HexColor('#1b7e1b'))), Paragraph("Diagnostic EGD ± biopsy, Capsule endoscopy, ERCP without sphincterotomy, EUS without FNA", body_style), Paragraph("Usually NOT required", body_style)], [Paragraph("HIGH RISK", ParagraphStyle('HighRisk', parent=styles['Normal'], fontSize=9, fontName='Helvetica-Bold', textColor=colors.HexColor('#b22222'))), Paragraph("Variceal banding, Polypectomy (>1 cm), EMR/ESD, Sphincterotomy, Dilation, PEG insertion, EUS-FNA", body_style), Paragraph("HOLD antithrombotics; confirm platelet ≥ 50,000; INR ≤ 1.5 preferred", body_style)], ] risk_table = Table(risk_rows, colWidths=[28*mm, 98*mm, 52*mm], repeatRows=1) risk_table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,0), BLUE_MID), ('TEXTCOLOR', (0,0), (-1,0), WHITE), ('BACKGROUND', (0,1), (-1,1), GREEN_LIGHT), ('BACKGROUND', (0,2), (-1,2), RED_LIGHT), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('TOPPADDING', (0,0), (-1,-1), 5), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('LEFTPADDING', (0,0), (-1,-1), 5), ])) story.append(risk_table) story.append(Spacer(1, 5*mm)) # ── SECTION 4: EMERGENCY UGIB PATHWAY ──────────────────────────────────────── story.append(section_header("SECTION 4 — EMERGENCY UGIB PATHWAY", bg=colors.HexColor('#8b0000'))) story.append(Spacer(1, 2*mm)) emerg_data = [ [Paragraph(f"{TICK_BOX} Resuscitate simultaneously — do NOT delay endoscopy for lab correction alone", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} Transfuse pRBC if Hb < 7 g/dL (< 8 g/dL if CAD/cardiac). Use restrictive strategy.", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} Platelet transfusion if < 50,000/mm³ (target > 50,000 before hemostasis attempts)", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} FFP/Vit K if INR > 2.5 and time permits; do NOT delay for anticoagulant patients", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} IV PPI bolus (e.g., Pantoprazole 80 mg IV) then infusion initiated", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} Terlipressin / Octreotide if variceal bleed suspected", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} Endoscopy within 24 h (within 12 h if hemodynamically unstable / high-risk Blatchford)", body_style), Paragraph("Done / N/A", body_style)], [Paragraph(f"{TICK_BOX} Glasgow-Blatchford Score calculated: Score = _______ (≥ 1 warrants inpatient EGD)", body_style), Paragraph("Done / N/A", body_style)], ] emerg_table = Table(emerg_data, colWidths=[156*mm, 22*mm]) emerg_table.setStyle(TableStyle([ ('ROWBACKGROUNDS', (0,0), (-1,-1), [RED_LIGHT, ORANGE_LIGHT]), ('BOX', (0,0), (-1,-1), 0.5, GREY_LINE), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('TOPPADDING', (0,0), (-1,-1), 4), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('LEFTPADDING', (0,0), (-1,-1), 5), ])) story.append(emerg_table) story.append(Spacer(1, 5*mm)) # ── SECTION 5: CLEARANCE SIGN-OFF ──────────────────────────────────────────── story.append(section_header("SECTION 5 — CLEARANCE & SIGN-OFF")) story.append(Spacer(1, 2*mm)) signoff_data = [ [Paragraph("<b>All lab criteria met?</b>", label_style), Paragraph("YES / NO / DEFERRED (emergency)", body_style), Paragraph("<b>Procedure cleared?</b>", label_style), Paragraph("YES / NO", body_style)], [Paragraph("<b>Pending action(s):</b>", label_style), Paragraph("_________________________________________________", body_style), Paragraph("", body_style), Paragraph("", body_style)], [Paragraph("<b>Reviewing Clinician:</b>", label_style), Paragraph("___________________________ Signature: _____________", body_style), Paragraph("<b>Time:</b>", label_style), Paragraph("_______ hrs", body_style)], ] signoff_table = Table(signoff_data, colWidths=[38*mm, 62*mm, 32*mm, 46*mm]) signoff_table.setStyle(TableStyle([ ('BACKGROUND', (0,0), (-1,-1), BLUE_LIGHT), ('BOX', (0,0), (-1,-1), 0.7, BLUE_DARK), ('INNERGRID', (0,0), (-1,-1), 0.3, GREY_LINE), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TOPPADDING', (0,0), (-1,-1), 5), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('LEFTPADDING', (0,0), (-1,-1), 5), ])) story.append(signoff_table) story.append(Spacer(1, 4*mm)) # ── FOOTER ──────────────────────────────────────────────────────────────────── story.append(HRFlowable(width="100%", thickness=1, color=BLUE_MID, spaceBefore=2*mm, spaceAfter=2*mm)) story.append(Paragraph( "References: ASGE Guidelines 2012 | AGA Guidelines 2019 | ACG Guidelines 2021 | AAFP 2020 (AFP 101:294) | " "Villanueva et al. NEJM 2013 | Tintinalli Emergency Medicine | Harrison's Principles 22E | Yamada's Gastroenterology 7E", footer_style )) story.append(Paragraph( "This checklist is a clinical aide-memoire. Final decisions must be made by the responsible endoscopist. " "Generated: August 14, 2026", footer_style )) doc.build(story) print(f"PDF created: {output_path}") EOF
Pre Endoscopy Checklist
PDF Document · PDF