How spinal anesthesia causes Nausia
spinal anesthesia nausea vomiting mechanism
| Mechanism | Pathway | Key Risk Factors |
|---|---|---|
| Hypotension | Cerebral hypoperfusion → vomiting center | Block ≥ T5, age ≥ 40, baseline BP low |
| Unopposed vagal tone | Gut hyperperistalsis → vagal afferents | High sympathetic block |
| Intrathecal opioids | Rostral CSF spread → CTZ + vomiting center | Morphine > fentanyl/sufentanil |
| Local anesthetic spread | Direct brainstem effect | High block, procaine use |
| Vasopressor additives | Autonomic stimulation | Phenylephrine, epinephrine in mix |
| High spinal | Medullary hypoperfusion | Excessive dose, obesity, pregnancy |
Find recent clinical guidelines on nausea/vomiting prevention in regional anesthesia
postoperative nausea vomiting prevention guidelines regional anesthesia
PONV prophylaxis consensus guidelines anesthesia
PMID: 32467512
PMID: 41672196
PMID: 33075160
PMID: 42194789
PONV guidelines 2024 2025 spinal anesthesia nausea vomiting prevention consensus
| Apfel Factor | Points |
|---|---|
| Female sex | +1 |
| Non-smoker | +1 |
| History of PONV or motion sickness | +1 |
| Postoperative opioid use expected | +1 |
| Score | PONV Risk |
|---|---|
| 0 | ~10% |
| 1 | ~21% |
| 2 | ~39% |
| 3 | ~61% |
| 4 | ~79% |
| Drug Class | Agent | Dose | Evidence Level |
|---|---|---|---|
| 5-HT3 antagonist | Ondansetron | 4 mg IV | High - most studied |
| 5-HT3 antagonist (2nd gen) | Palonosetron | 0.075 mg IV | High - longer-acting |
| Corticosteroid | Dexamethasone | 4-8 mg IV | High |
| NK1 antagonist | Aprepitant / fosaprepitant | 40-80 mg PO / 150 mg IV | High - especially high-risk |
| D2 antagonist | Droperidol | 0.625-1.25 mg IV | High |
| Antihistamine | Dimenhydrinate, promethazine | Variable | Moderate |
| Anticholinergic | Scopolamine patch | Transdermal | Moderate |
| Recommendation | Strength | Source |
|---|---|---|
| Use Apfel score for risk stratification | Strong | Gan et al. 2020 |
| Multimodal prophylaxis for Apfel ≥ 2 | Strong | Gan et al. 2020; Cochrane 2020 |
| Ondansetron 4 mg + dexamethasone 4-8 mg as baseline | Strong | Cochrane NMA 2020 |
| Add NK1 antagonist for high-risk patients | Moderate-Strong | Gan et al. 2020 |
| Prevent/treat hypotension in spinal anesthesia | Strong | Miller's Anesthesia 10e |
| Minimize intrathecal morphine dose (< 0.1 mg) | Moderate | Miller's Anesthesia 10e |
| Intrathecal mu-antagonist to prevent opioid PONV | Emerging (meta-analysis 2026) | PMID: 41672196 |
| Regional/neuraxial anesthesia preferred over GA in high PONV risk | Moderate | Gan et al. 2020 |
| Opioid-sparing ERAS approach | Strong | Dombrower et al. 2026 |
Create a printable PONV risk assessment & prophylaxis protocol (PDF)
mkdir -p /home/daytona/workspace/ponv-protocol && ls /home/daytona/workspace/ponv-protocol
~/ponv-protocol/create_ponv_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.colors import HexColor
import os
# ── Color palette ──────────────────────────────────────────
NAVY = HexColor("#1A3A5C")
TEAL = HexColor("#007C89")
LIGHT_TEAL = HexColor("#E0F4F6")
AMBER = HexColor("#F59E0B")
LIGHT_AMBER= HexColor("#FEF3C7")
RED = HexColor("#DC2626")
LIGHT_RED = HexColor("#FEE2E2")
GREEN = HexColor("#16A34A")
LIGHT_GREEN= HexColor("#DCFCE7")
GREY_BG = HexColor("#F1F5F9")
GREY_BORDER= HexColor("#CBD5E1")
WHITE = colors.white
BLACK = colors.black
DARK_GREY = HexColor("#374151")
MID_GREY = HexColor("#6B7280")
OUT_PATH = "/home/daytona/workspace/ponv-protocol/PONV_Protocol.pdf"
def build_pdf():
doc = SimpleDocTemplate(
OUT_PATH,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=15*mm, bottomMargin=18*mm,
title="PONV Risk Assessment & Prophylaxis Protocol",
author="Orris Clinical Tools",
subject="Perioperative PONV Management"
)
W = A4[0] - 30*mm # usable width
# ── Styles ─────────────────────────────────────────────
ss = getSampleStyleSheet()
def S(name, parent='Normal', **kw):
return ParagraphStyle(name, parent=ss[parent], **kw)
sTitle = S('sTitle', 'Title',
fontName='Helvetica-Bold', fontSize=20, leading=24,
textColor=WHITE, alignment=TA_CENTER)
sSubtitle = S('sSubtitle',
fontName='Helvetica', fontSize=9, leading=12,
textColor=HexColor("#B0C8E0"), alignment=TA_CENTER)
sH1 = S('sH1', fontName='Helvetica-Bold', fontSize=11,
textColor=WHITE, leading=14, alignment=TA_LEFT)
sH2 = S('sH2', fontName='Helvetica-Bold', fontSize=10,
textColor=NAVY, leading=13, spaceBefore=4)
sBody = S('sBody', fontName='Helvetica', fontSize=8.5,
textColor=DARK_GREY, leading=12, spaceBefore=2)
sBodySm = S('sBodySm', fontName='Helvetica', fontSize=8,
textColor=DARK_GREY, leading=11)
sBold = S('sBold', fontName='Helvetica-Bold', fontSize=8.5,
textColor=DARK_GREY, leading=12)
sCell = S('sCell', fontName='Helvetica', fontSize=8,
textColor=DARK_GREY, leading=11)
sCellBold = S('sCellBold', fontName='Helvetica-Bold', fontSize=8,
textColor=DARK_GREY, leading=11)
sCellHdr = S('sCellHdr', fontName='Helvetica-Bold', fontSize=8,
textColor=WHITE, leading=11, alignment=TA_CENTER)
sRef = S('sRef', fontName='Helvetica', fontSize=6.5,
textColor=MID_GREY, leading=9)
sFooter = S('sFooter', fontName='Helvetica', fontSize=7,
textColor=MID_GREY, alignment=TA_CENTER)
sWarning = S('sWarning', fontName='Helvetica-BoldOblique', fontSize=8,
textColor=RED, leading=11)
sGreen = S('sGreen', fontName='Helvetica-Bold', fontSize=8.5,
textColor=GREEN, leading=12)
sBox = S('sBox', fontName='Helvetica', fontSize=8,
textColor=DARK_GREY, leading=11, leftIndent=4)
story = []
# ══════════════════════════════════════════════════════
# HEADER BANNER
# ══════════════════════════════════════════════════════
header_data = [[
Paragraph("PONV RISK ASSESSMENT & PROPHYLAXIS PROTOCOL", sTitle),
]]
header_sub = [[
Paragraph(
"Postoperative Nausea & Vomiting | Perioperative Anesthesia Guidelines | "
"Based on: 4th Consensus Guidelines (Gan et al. 2020) & Cochrane NMA (Weibel et al. 2020)",
sSubtitle)
]]
banner = Table(header_data, colWidths=[W])
banner.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('ROWPADDING', (0,0), (-1,-1), 10),
('TOPPADDING', (0,0), (-1,-1), 12),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('ROUNDEDCORNERS', [6,6,0,0]),
]))
banner_sub = Table(header_sub, colWidths=[W])
banner_sub.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('ROWPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
]))
story.append(banner)
story.append(banner_sub)
story.append(Spacer(1, 5*mm))
# ══════════════════════════════════════════════════════
# SECTION 1 – APFEL SCORE
# ══════════════════════════════════════════════════════
def section_header(title):
t = Table([[Paragraph(title, sH1)]], colWidths=[W])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), TEAL),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
]))
return t
story.append(section_header("STEP 1 — APFEL SIMPLIFIED RISK SCORE"))
story.append(Spacer(1, 3*mm))
# Apfel factors table (left) + risk levels (right)
apfel_left = [
[Paragraph("<b>Risk Factor</b>", sCellHdr), Paragraph("<b>Points</b>", sCellHdr)],
[Paragraph("Female sex", sCell), Paragraph("+1", sCellBold)],
[Paragraph("Non-smoker", sCell), Paragraph("+1", sCellBold)],
[Paragraph("History of PONV or motion sickness", sCell), Paragraph("+1", sCellBold)],
[Paragraph("Expected postoperative opioid use", sCell), Paragraph("+1", sCellBold)],
]
apfel_right = [
[Paragraph("<b>Score</b>", sCellHdr), Paragraph("<b>PONV Risk</b>", sCellHdr), Paragraph("<b>Action</b>", sCellHdr)],
[Paragraph("0", sCellBold), Paragraph("~10%", sCell), Paragraph("Consider no prophylaxis", sCell)],
[Paragraph("1", sCellBold), Paragraph("~21%", sCell), Paragraph("1 antiemetic agent", sCell)],
[Paragraph("2", sCellBold), Paragraph("~39%", sCell), Paragraph("2 antiemetic agents", sCell)],
[Paragraph("3", sCellBold), Paragraph("~61%", sCell), Paragraph("3 antiemetic agents", sCell)],
[Paragraph("4", sCellBold), Paragraph("~79%", sCell), Paragraph("Multimodal + TIVA", sCell)],
]
lw = W * 0.42
rw = W * 0.54
col_pad = W * 0.04
tl = Table(apfel_left, colWidths=[lw*0.78, lw*0.22])
tl.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('BACKGROUND', (0,1), (-1,-1), WHITE),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.5, GREY_BORDER),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('ALIGN', (1,0), (1,-1), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
tr = Table(apfel_right, colWidths=[rw*0.18, rw*0.32, rw*0.50])
tr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.5, GREY_BORDER),
# color-code risk rows
('BACKGROUND', (0,1), (-1,1), LIGHT_GREEN),
('BACKGROUND', (0,2), (-1,2), LIGHT_GREEN),
('BACKGROUND', (0,3), (-1,3), LIGHT_AMBER),
('BACKGROUND', (0,4), (-1,4), LIGHT_RED),
('BACKGROUND', (0,5), (-1,5), LIGHT_RED),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('ALIGN', (0,0), (1,-1), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
combined = Table([[tl, Paragraph("", sBody), tr]], colWidths=[lw, col_pad, rw])
combined.setStyle(TableStyle([('VALIGN', (0,0), (-1,-1), 'TOP')]))
story.append(KeepTogether([combined]))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
"Additional risk factors: laparoscopic surgery, gynecological/ENT/breast surgery, "
"duration >60 min, volatile anesthetic use, nitrous oxide use, young age.",
sBodySm))
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 2 – BASELINE RISK REDUCTION
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 2 — REDUCE BASELINE RISK (ALL PATIENTS)"))
story.append(Spacer(1, 3*mm))
baseline_items = [
("Prefer regional/neuraxial anesthesia",
"Spinal or epidural significantly reduces PONV vs. general anesthesia"),
("Use TIVA (propofol-based) when GA required",
"Reduces PONV incidence by ~30% vs volatile agents; preferred in high-risk patients"),
("Minimize intraoperative and postoperative opioids",
"Use multimodal analgesia: NSAIDs, acetaminophen, regional blocks, dexmedetomidine"),
("Avoid nitrous oxide",
"Especially in surgeries >1 hour; independent PONV risk factor"),
("Minimize neostigmine dose",
"Use sugammadex when feasible for neuromuscular reversal"),
("Adequate IV hydration",
"Goal-directed fluid therapy; dehydration worsens PONV"),
("For spinal anesthesia: prevent hypotension",
"Phenylephrine infusion (obstetrics) or ephedrine; treat MAP drop >20% promptly"),
("Minimize intrathecal morphine",
"Use <0.1 mg; consider fentanyl/sufentanil for short procedures"),
]
brows = []
for i, (item, detail) in enumerate(baseline_items):
brows.append([
Paragraph(f"\u2713", sCellBold),
Paragraph(f"<b>{item}</b>", sCell),
Paragraph(detail, sCell)
])
bt = Table(brows, colWidths=[8*mm, W*0.35, W*0.58])
bt.setStyle(TableStyle([
('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.3, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TEXTCOLOR', (0,0), (0,-1), GREEN),
('ALIGN', (0,0), (0,-1), 'CENTER'),
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
]))
story.append(bt)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 3 – PROPHYLAXIS DRUG TABLE
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 3 — PHARMACOLOGICAL PROPHYLAXIS"))
story.append(Spacer(1, 3*mm))
drug_hdr = [
Paragraph("<b>Drug Class</b>", sCellHdr),
Paragraph("<b>Agent</b>", sCellHdr),
Paragraph("<b>Dose & Route</b>", sCellHdr),
Paragraph("<b>Timing</b>", sCellHdr),
Paragraph("<b>Notes / Cautions</b>", sCellHdr),
]
drug_rows = [
# class, agent, dose, timing, notes
("5-HT3 Antagonist\n(1st line)",
"Ondansetron",
"4 mg IV",
"End of surgery",
"Most studied; well tolerated. QTc prolongation risk at high doses."),
("5-HT3 Antagonist\n(1st line)",
"Palonosetron",
"0.075 mg IV",
"Induction",
"Longer-acting (T1/2 ~40h); superior for late PONV (2-24h)."),
("5-HT3 Antagonist\n(1st line)",
"Granisetron",
"1 mg IV",
"End of surgery",
"Alternative to ondansetron; similar efficacy."),
("Corticosteroid\n(1st line)",
"Dexamethasone",
"4-8 mg IV",
"After induction",
"Do not give at end of surgery. May raise glucose in diabetics. Most effective when given early."),
("NK1 Antagonist\n(add-on, high risk)",
"Aprepitant",
"40-80 mg PO",
"1-3h pre-op",
"Best for high-risk (Apfel 3-4) and opioid-heavy cases. Expensive."),
("NK1 Antagonist\n(add-on, high risk)",
"Fosaprepitant",
"150 mg IV",
"Before induction",
"IV formulation of aprepitant; equivalent efficacy."),
("D2 Antagonist",
"Droperidol",
"0.625-1.25 mg IV",
"End of surgery",
"Effective rescue and prophylaxis. FDA black box warning (QTc) -- use low doses only."),
("D2 Antagonist",
"Metoclopramide",
"10-25 mg IV",
"End of surgery",
"Weaker evidence than ondansetron. Extrapyramidal side effects possible."),
("D2 Antagonist",
"Haloperidol",
"0.5-2 mg IV/IM",
"Induction",
"Low-dose effective; monitor QTc. Off-label for PONV."),
("Antihistamine",
"Dimenhydrinate",
"1 mg/kg IV",
"End of surgery",
"Sedation side effect may be acceptable. Useful in motion-sickness phenotype."),
("Anticholinergic",
"Scopolamine",
"1.5 mg transdermal",
"Evening before or 2-4h pre-op",
"Effective for PONV; especially motion sickness history. May cause dry mouth, blurred vision."),
]
cw = [W*0.15, W*0.14, W*0.15, W*0.13, W*0.43]
drows = [drug_hdr]
for i, (cls, agent, dose, timing, notes) in enumerate(drug_rows):
drows.append([
Paragraph(cls, sCell),
Paragraph(f"<b>{agent}</b>", sCell),
Paragraph(dose, sCellBold),
Paragraph(timing, sCell),
Paragraph(notes, sCell),
])
dt = Table(drows, colWidths=cw, repeatRows=1)
dt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.4, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
# highlight 5HT3 rows
('BACKGROUND', (0,1), (-1,3), HexColor("#EFF8FF")),
# highlight steroid row
('BACKGROUND', (0,4), (-1,4), LIGHT_AMBER),
# highlight NK1 rows
('BACKGROUND', (0,5), (-1,6), HexColor("#F3E8FF")),
]))
story.append(dt)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 4 – COMBINATION STRATEGY
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 4 — COMBINATION STRATEGY BY RISK TIER"))
story.append(Spacer(1, 3*mm))
combo_hdr = [
Paragraph("<b>Apfel Score</b>", sCellHdr),
Paragraph("<b>Risk</b>", sCellHdr),
Paragraph("<b>Recommended Combination</b>", sCellHdr),
Paragraph("<b>Additional Options</b>", sCellHdr),
]
combo_rows = [
("0-1", "Low\n(10-21%)",
"No routine prophylaxis OR\nOndansetron 4 mg IV (if any risk factors)",
"Ensure adequate hydration; minimize opioids"),
("2", "Moderate\n(39%)",
"Ondansetron 4 mg IV\n+ Dexamethasone 4 mg IV",
"Consider scopolamine patch if motion-sickness history"),
("3", "High\n(61%)",
"Ondansetron 4 mg IV\n+ Dexamethasone 8 mg IV\n+ Droperidol 0.625 mg IV",
"NK1 antagonist (aprepitant); TIVA preferred; opioid-sparing regimen"),
("4", "Very High\n(79%)",
"Triple therapy (above) +\nAprepitant 40-80 mg PO pre-op\n+ TIVA with propofol",
"Regional anesthesia preferred; intrathecal opioid minimization;\nscopolamine patch;\nnon-pharmacologic adjuncts"),
]
cbg = [LIGHT_GREEN, LIGHT_GREEN, LIGHT_AMBER, LIGHT_RED, LIGHT_RED]
crows = [combo_hdr]
for i, (score, risk, combo, extra) in enumerate(combo_rows):
crows.append([
Paragraph(f"<b>{score}</b>", sCellBold),
Paragraph(risk, sCell),
Paragraph(combo, sCell),
Paragraph(extra, sCell),
])
ct = Table(crows, colWidths=[W*0.12, W*0.14, W*0.40, W*0.34])
ct.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('GRID', (0,0), (-1,-1), 0.4, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('ALIGN', (0,0), (1,-1), 'CENTER'),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
('BACKGROUND', (0,1), (-1,2), LIGHT_GREEN),
('BACKGROUND', (0,3), (-1,3), LIGHT_AMBER),
('BACKGROUND', (0,4), (-1,4), LIGHT_RED),
]))
story.append(ct)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 5 – SPINAL ANESTHESIA SPECIFIC
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 5 — SPINAL ANESTHESIA: SPECIAL CONSIDERATIONS"))
story.append(Spacer(1, 3*mm))
spinal_rows = [
[Paragraph("<b>Mechanism</b>", sCellHdr),
Paragraph("<b>Prevention Strategy</b>", sCellHdr),
Paragraph("<b>First-line Treatment</b>", sCellHdr)],
[Paragraph("Hypotension (most common cause)\nSympathetic blockade → vasodilation → cerebral hypoperfusion", sCell),
Paragraph("Phenylephrine infusion 25-50 mcg/min (obstetric) or ephedrine 5-10 mg bolus;\nIV co-loading with crystalloid;\nAvoid aortocaval compression (left tilt in pregnancy)", sCell),
Paragraph("IV phenylephrine bolus 50-100 mcg;\nEphedrine 5-10 mg IV;\nPlace supine, elevate legs;\nSupplement O2", sCell)],
[Paragraph("Unopposed vagal tone\nSympathetic block → gut hyperperistalsis", sCell),
Paragraph("Limit block height (use smallest effective dose);\nPrefer low intrathecal opioid doses;\nMaintain adequate sympathetic reserve", sCell),
Paragraph("Atropine 0.5-1 mg IV (if bradycardia accompanies);\nOndansetron 4 mg IV", sCell)],
[Paragraph("Intrathecal opioids\nRostral CSF spread to chemoreceptor trigger zone", sCell),
Paragraph("Use morphine <0.1 mg (lowest effective dose);\nPrefer fentanyl/sufentanil for short-term analgesia;\nCo-administer standard antiemetic prophylaxis", sCell),
Paragraph("Ondansetron 4 mg IV;\nNalbuphine 2-4 mg IV (for morphine-related PONV);\nDexamethasone 4-8 mg IV", sCell)],
[Paragraph("Vasopressor additives\n(epinephrine, phenylephrine in mix)", sCell),
Paragraph("Avoid epinephrine additives in spinal solution when not indicated;\nChoose plain local anesthetic when vasoconstrictor not needed", sCell),
Paragraph("Standard antiemetic therapy;\nOndansetron 4 mg IV", sCell)],
]
st2 = Table(spinal_rows, colWidths=[W*0.28, W*0.38, W*0.34], repeatRows=1)
st2.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.4, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 7.5),
]))
story.append(st2)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 6 – RESCUE TREATMENT
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 6 — RESCUE TREATMENT (PONV DESPITE PROPHYLAXIS)"))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"<b>Key principle:</b> Always use an agent from a DIFFERENT drug class than was given for prophylaxis.",
sBody))
story.append(Spacer(1, 2*mm))
rescue_hdr = [
Paragraph("<b>Prophylaxis Given</b>", sCellHdr),
Paragraph("<b>First Rescue Choice</b>", sCellHdr),
Paragraph("<b>Second Rescue Choice</b>", sCellHdr),
Paragraph("<b>Third-line</b>", sCellHdr),
]
rescue_rows = [
("5-HT3 antagonist only",
"Dexamethasone 4 mg IV\nor Droperidol 0.625 mg IV",
"Promethazine 6.25 mg IV\nor Haloperidol 0.5 mg IV",
"Aprepitant 40 mg PO"),
("Dexamethasone only",
"Ondansetron 4 mg IV\nor Granisetron 1 mg IV",
"Droperidol 0.625 mg IV",
"NK1 antagonist"),
("5-HT3 + Dexamethasone",
"Droperidol 0.625 mg IV\nor Haloperidol 0.5 mg IV",
"Promethazine 6.25-12.5 mg IV",
"Scopolamine patch + propofol 20 mg IV (sub-hypnotic)"),
("Triple therapy",
"Promethazine 6.25-12.5 mg IV",
"Sub-hypnotic propofol 20 mg IV bolus",
"Ensure hydration; correct hypotension; re-evaluate analgesia"),
]
rrows = [rescue_hdr]
for cls, r1, r2, r3 in rescue_rows:
rrows.append([Paragraph(cls, sCell), Paragraph(r1, sCell),
Paragraph(r2, sCell), Paragraph(r3, sCell)])
rt = Table(rrows, colWidths=[W*0.25, W*0.26, W*0.26, W*0.23])
rt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.4, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
]))
story.append(rt)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 7 – NON-PHARMACOLOGIC
# ══════════════════════════════════════════════════════
story.append(section_header("STEP 7 — NON-PHARMACOLOGIC ADJUNCTS"))
story.append(Spacer(1, 3*mm))
np_rows = [
("P6 Acupressure (Neiguan point)", "Wristband or needling; evidence supports modest reduction in PONV; no side effects"),
("Adequate IV hydration", "30 mL/kg crystalloid reduces PONV; goal-directed fluid therapy preferred"),
("Early oral intake (ERAS)", "Clear fluids up to 2h pre-op; early post-op oral intake accelerates GI recovery"),
("Avoid unnecessary opioids", "Maximize non-opioid analgesia (paracetamol, NSAIDs, regional blocks)"),
("Supplemental oxygen (intraoperative)", "30-80% FiO2 may reduce PONV in some settings; not universally endorsed"),
("Ginger (oral)", "1 g ginger root pre-op; limited but favorable evidence; safe adjunct"),
("Minimize movement post-op", "Sudden position changes worsen nausea; gentle transfers; semi-recumbent position"),
("Aromatherapy (isopropyl alcohol)", "Inhaled IPA wipes show modest rescue antiemetic effect in PACU"),
]
np_trows = []
for i, (item, detail) in enumerate(np_rows):
np_trows.append([Paragraph(f"\u25cf {item}", sCellBold), Paragraph(detail, sCell)])
npt = Table(np_trows, colWidths=[W*0.34, W*0.66])
npt.setStyle(TableStyle([
('ROWBACKGROUNDS', (0,0), (-1,-1), [WHITE, GREY_BG]),
('GRID', (0,0), (-1,-1), 0.3, GREY_BORDER),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,0), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,0), (-1,-1), 8),
]))
story.append(npt)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# SECTION 8 – INTRATHECAL MU ANTAGONIST (EMERGING)
# ══════════════════════════════════════════════════════
emerging_text = (
"<b>EMERGING EVIDENCE (2026):</b> Intrathecal mu-receptor antagonists (e.g., nalbuphine 0.8-1.6 mg "
"added to spinal local anesthetic + opioid) significantly reduce opioid-related PONV (OR 0.26, "
"p<0.00001) and pruritus (OR 0.15, p<0.00001) without compromising analgesia. "
"Consider in patients receiving intrathecal opioids for procedures under spinal anesthesia. "
"<i>Source: Huda et al. 2026. PMID: 41672196 [Systematic Review, 9 RCTs, n=653]</i>"
)
emerging_box = Table([[Paragraph(emerging_text, sBodySm)]], colWidths=[W])
emerging_box.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), HexColor("#EDE9FE")),
('BOX', (0,0), (-1,-1), 1.5, HexColor("#7C3AED")),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (-1,-1), 8),
]))
story.append(emerging_box)
story.append(Spacer(1, 4*mm))
# ══════════════════════════════════════════════════════
# REFERENCES
# ══════════════════════════════════════════════════════
story.append(HRFlowable(width=W, thickness=0.5, color=GREY_BORDER))
story.append(Spacer(1, 2*mm))
story.append(Paragraph("<b>Evidence Base</b>", S('sRefHdr', fontName='Helvetica-Bold',
fontSize=8, textColor=DARK_GREY)))
story.append(Spacer(1, 1*mm))
refs = [
"1. Gan TJ et al. Fourth Consensus Guidelines for the Management of Postoperative Nausea and Vomiting. "
"Anesth Analg. 2020;131(2):411-448. PMID: 32467512 (Erratum PMID: 33094991) — Endorsed by 23 professional societies.",
"2. Weibel S et al. Drugs for preventing postoperative nausea and vomiting in adults after general anaesthesia: "
"a network meta-analysis. Cochrane Database Syst Rev. 2020 Oct 19. PMID: 33075160 [585 RCTs, n=97,516]",
"3. Huda AU et al. Efficacy of intrathecal mu-receptor antagonist in preventing pruritus and PONV after spinal "
"anesthesia. Rev Esp Anestesiol Reanim. 2026. PMID: 41672196 [9 RCTs, n=653]",
"4. Dombrower R et al. Perioperative Anesthesia Strategies for PONV Prevention Within ERAS Pathways. "
"J Clin Med. 2026;15(10):3829. PMID: 42194789",
"5. Kienbaum P, Schaefer MS, Weibel S. Update on PONV. Anaesthesist. 2022;71(2):81-92. PMID: 34596699",
"6. Miller's Anesthesia, 10th Ed. (2023). Chapter: Complications of Neuraxial Anesthesia, pp. 6119-6124.",
"7. Apfel CC et al. A simplified risk score for predicting PONV. Anesthesiology. 1999;91(3):693-700.",
]
for ref in refs:
story.append(Paragraph(ref, sRef))
story.append(Spacer(1, 1*mm))
story.append(Spacer(1, 2*mm))
story.append(HRFlowable(width=W, thickness=0.5, color=GREY_BORDER))
story.append(Spacer(1, 1.5*mm))
story.append(Paragraph(
"PONV Risk Assessment & Prophylaxis Protocol | Generated June 2026 | "
"For clinical use, verify doses against current institutional formulary and patient-specific factors. | "
"This document does not replace clinical judgment.",
sFooter))
doc.build(story)
print(f"PDF created: {OUT_PATH}")
print(f"File size: {os.path.getsize(OUT_PATH):,} bytes")
if __name__ == "__main__":
build_pdf()
cd /home/daytona/workspace/ponv-protocol && python create_ponv_pdf.py 2>&1
cd /home/daytona/workspace/ponv-protocol && python -c " from pypdf import PdfReader r = PdfReader('PONV_Protocol.pdf') print(f'Pages: {len(r.pages)}') for i, page in enumerate(r.pages): txt = page.extract_text() print(f'--- Page {i+1} ({len(txt)} chars) ---') print(txt[:300]) print('...') "
PONV Protocol
PDF Document · PDF
| Section | Content |
|---|---|
| Step 1 | Apfel Risk Score table with color-coded risk tiers (green/amber/red) |
| Step 2 | Baseline risk reduction checklist (8 interventions, spinal-specific tips included) |
| Step 3 | Full pharmacological prophylaxis drug table - all agents, doses, timing, cautions |
| Step 4 | Combination strategy matrix by Apfel score (0-1 / 2 / 3 / 4) |
| Step 5 | Spinal anesthesia-specific table: mechanism, prevention, treatment for each cause |
| Step 6 | Rescue therapy guide - matched to what prophylaxis was given |
| Step 7 | Non-pharmacologic adjuncts (P6 acupressure, hydration, IPA aromatherapy, etc.) |
| Emerging | 2026 intrathecal mu-antagonist evidence (PMID: 41672196) highlighted in purple box |
| References | 7 citations including Gan 2020, Cochrane NMA 2020, and 2026 data |