Definition,Etiology / Causes,caused by Risk Factors,Pathophysiology(flow chart form ),Classification,Signs and Symptoms,Red Flag Signs,Differential Diagnosis,Diagnostic Tests( basic and specific) ,Diagnostic Criteria, treatment ( pharmacological , non pharmacological, surgery). Complications,Prevention,Emergency Management,Prognosis,Patient Counseling,Special Situations,Commonly Used Drugs in That Disease, lifestyle modification of ckd with simple pnemonics and make pdf of 2-3 page
ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace not found"
mkdir -p /home/daytona/workspace/ckd-notes && echo "created"
~/ckd-notes/generate_ckd_pdf.py
#!/usr/bin/env python3
"""Generate a comprehensive CKD clinical notes PDF using ReportLab."""
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, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
OUTPUT = "/home/daytona/workspace/ckd-notes/CKD_Clinical_Notes.pdf"
# ── colour palette ──────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3c6e")
MID_BLUE = colors.HexColor("#2563a8")
LIGHT_BLUE = colors.HexColor("#dbeafe")
ACCENT_RED = colors.HexColor("#dc2626")
ACCENT_AMBER= colors.HexColor("#d97706")
ACCENT_GREEN= colors.HexColor("#16a34a")
PALE_GREY = colors.HexColor("#f1f5f9")
MID_GREY = colors.HexColor("#64748b")
WHITE = colors.white
# ── styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
def S(name, parent="Normal", **kw):
s = ParagraphStyle(name, parent=base[parent], **kw)
return s
title_style = S("DocTitle", "Normal",
fontSize=22, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER,
spaceAfter=2)
subtitle_style= S("DocSub", "Normal",
fontSize=11, fontName="Helvetica",
textColor=colors.HexColor("#bfdbfe"), alignment=TA_CENTER,
spaceAfter=0)
h1 = S("H1", fontSize=13, fontName="Helvetica-Bold",
textColor=WHITE, spaceBefore=4, spaceAfter=2,
leftIndent=0, backColor=DARK_BLUE,
borderPadding=(4, 8, 4, 8))
h2 = S("H2", fontSize=10.5, fontName="Helvetica-Bold",
textColor=DARK_BLUE, spaceBefore=5, spaceAfter=2,
borderPadding=(0,0,0,0))
body = S("Body", fontSize=8.5, fontName="Helvetica",
leading=12, spaceAfter=3, alignment=TA_JUSTIFY)
bullet= S("Bullet", fontSize=8.5, fontName="Helvetica",
leading=12, leftIndent=14, firstLineIndent=-10,
spaceAfter=2)
mono = S("Mono", fontSize=8, fontName="Courier",
leading=11, leftIndent=6, textColor=DARK_BLUE, spaceAfter=2)
warn = S("Warn", fontSize=8.5, fontName="Helvetica-Bold",
textColor=ACCENT_RED, spaceAfter=3)
caption = S("Caption", fontSize=7.5, fontName="Helvetica-Oblique",
textColor=MID_GREY, spaceAfter=4, alignment=TA_CENTER)
mnemonic = S("Mnemonic", fontSize=9, fontName="Helvetica-Bold",
textColor=ACCENT_GREEN, leading=13, leftIndent=8, spaceAfter=2)
# ── helper functions ─────────────────────────────────────────────────────────
def HR():
return HRFlowable(width="100%", thickness=0.5, color=MID_BLUE, spaceAfter=4)
def section(title_text, content_items):
"""Return a KeepTogether block with header + content."""
bg = Table([[Paragraph(title_text, h1)]],
colWidths=["100%"])
bg.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING",(0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0),(-1,-1), 5),
("ROWHEIGHT", (0,0), (-1,-1), 20),
]))
return [Spacer(1, 4), bg] + content_items + [Spacer(1, 2)]
def sub(text):
return Paragraph(f"<b>{text}</b>", h2)
def bp(text):
return Paragraph(f"• {text}", bullet)
def bph(title, rest):
return Paragraph(f"• <b>{title}</b> {rest}", bullet)
def p(text):
return Paragraph(text, body)
def mn(text):
return Paragraph(text, mnemonic)
def wn(text):
return Paragraph(f"⚠ {text}", warn)
# ── two-column table helper ──────────────────────────────────────────────────
def two_col(rows, col1w=55*mm, col2w=120*mm):
t = Table(rows, colWidths=[col1w, col2w])
t.setStyle(TableStyle([
("FONTNAME", (0,0), (0,-1), "Helvetica-Bold"),
("FONTNAME", (1,0), (1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("LEADING", (0,0), (-1,-1), 11),
("BACKGROUND", (0,0), (0,-1), LIGHT_BLUE),
("GRID", (0,0), (-1,-1), 0.25, colors.HexColor("#93c5fd")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING", (0,0), (-1,-1), 5),
]))
return t
# ── KDIGO staging table ───────────────────────────────────────────────────────
def kdigo_table():
header = ["Stage", "GFR (mL/min/1.73m²)", "Description", "Albuminuria"]
rows = [
["G1", "≥90", "Normal or high", "A1: <30 mg/g A2: 30-300 A3: >300"],
["G2", "60-89", "Mildly decreased", ""],
["G3a", "45-59", "Mildly-moderately decreased", ""],
["G3b", "30-44", "Moderately-severely decreased", ""],
["G4", "15-29", "Severely decreased", ""],
["G5", "<15", "Kidney failure (ESKD)", ""],
]
stage_colors = {
"G1": colors.HexColor("#22c55e"),
"G2": colors.HexColor("#84cc16"),
"G3a": colors.HexColor("#eab308"),
"G3b": colors.HexColor("#f97316"),
"G4": colors.HexColor("#ef4444"),
"G5": colors.HexColor("#7f1d1d"),
}
data = [header] + rows
t = Table(data, colWidths=[18*mm, 42*mm, 64*mm, 51*mm])
style = [
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8),
("LEADING", (0,0), (-1,-1), 11),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
]
for i, row in enumerate(rows, start=1):
stage = row[0]
c = stage_colors.get(stage, PALE_GREY)
style.append(("BACKGROUND", (0,i), (0,i), c))
style.append(("TEXTCOLOR", (0,i), (0,i), WHITE))
style.append(("FONTNAME", (0,i), (0,i), "Helvetica-Bold"))
t.setStyle(TableStyle(style))
return t
# ── drug table ────────────────────────────────────────────────────────────────
def drug_table():
header = ["Drug Class", "Examples", "Indication / Notes"]
rows = [
["ACEi / ARB", "Ramipril, Losartan", "Proteinuria, HTN - renoprotective; monitor K⁺, Cr"],
["SGLT2i", "Empagliflozin, Dapagliflozin","eGFR ≥30; reno- + cardioprotective"],
["Loop Diuretic", "Furosemide, Torsemide", "Volume overload; works at low GFR"],
["Phosphate Binder", "Sevelamer, Ca-carbonate", "Hyperphosphatemia (CKD G3b+)"],
["Active Vit D", "Calcitriol, Paricalcitol", "Secondary hyperparathyroidism"],
["Calcimimetic", "Cinacalcet", "Dialysis patients - suppress PTH"],
["ESA", "Epoetin alfa, Darbepoetin", "Hb <10 g/dL; target Hb 10-11 g/dL"],
["IV Iron", "Iron sucrose, Ferric gluconate","TSAT ≤30%, ferritin <500; before ESA"],
["Statin (+ezetimibe)","Atorvastatin + Ezetimibe", "Age ≥50, eGFR <60 (KDIGO 2014)"],
["Oral Bicarbonate", "NaHCO₃ 650-1300 mg BD/TDS","Metabolic acidosis; keep HCO₃ ≥22"],
["GLP-1 RA", "Semaglutide, Liraglutide", "Diabetic CKD; wt loss + CV benefit"],
["Finerenone (MRA)", "Finerenone", "Diabetic CKD + proteinuria; K⁺ watch"],
]
data = [header] + rows
t = Table(data, colWidths=[40*mm, 50*mm, 85*mm])
style = [
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8),
("LEADING", (0,0), (-1,-1), 10),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[PALE_GREY, WHITE]),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING", (0,0), (-1,-1), 4),
]
t.setStyle(TableStyle(style))
return t
# ── differential diagnosis table ─────────────────────────────────────────────
def diff_diag_table():
rows = [
["AKI", "Sudden onset (<3 mo), reversible, no prior renal Hx"],
["AKI-on-CKD", "Acute decline superimposed on known CKD"],
["RPGN", "Rapid decline (weeks), crescentic GN on biopsy"],
["Nephrotic Syndrome","Massive proteinuria >3.5g/day, oedema, hypoalbuminaemia"],
["Renal artery stenosis","Sudden HTN, asymmetric kidneys on US, responds to revascularisation"],
["Multiple Myeloma","Light-chain nephropathy, SPEP, UPEP, Bence Jones proteins"],
["Obstructive Uropathy","Hydronephrosis on US, post-void residual elevated"],
]
data = [["Condition", "Distinguishing Features"]] + rows
t = Table(data, colWidths=[50*mm, 125*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 8),
("LEADING", (0,0), (-1,-1), 10),
("GRID", (0,0), (-1,-1), 0.4, MID_BLUE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("ROWBACKGROUNDS",(0,1),(-1,-1),[PALE_GREY, WHITE]),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING", (0,0), (-1,-1), 4),
]))
return t
# ── pathophysiology flow chart (text-based) ──────────────────────────────────
def patho_flow():
boxes = [
("Initiating Insult", "Diabetic nephropathy, HTN, glomerulonephritis,\nobstruction, toxins, genetic mutations"),
("Nephron Loss", "Reduction in functional nephron mass"),
("Compensatory Hyperfiltration", "Surviving nephrons hypertrophy; RAS activation;\n↑ intraglomerular pressure"),
("Maladaptive Changes", "Podocyte damage, glomerulosclerosis,\nproteinuria, tubulo-interstitial fibrosis"),
("Progressive GFR Decline", "Accelerated by proteinuria, HTN, poor glucose control,\nNSAIDs, contrast, nephrotoxins"),
("Metabolic Consequences", "↑Urea/Cr, ↑K⁺, ↓HCO₃, ↑PO₄, ↓Ca²⁺, ↓1,25-VitD,\n↑PTH, ↓EPO → anaemia"),
("End-Stage Renal Disease (ESKD)", "GFR <15 → Uremic syndrome → RRT required"),
]
rows = []
for i, (title, detail) in enumerate(boxes):
arrow = "▼" if i < len(boxes)-1 else ""
cell = Paragraph(f"<b>{title}</b><br/><font size=7.5>{detail}</font>", body)
rows.append([cell])
if arrow:
rows.append([Paragraph(f"<font color='#2563a8' size=12>{arrow}</font>",
S("arr", alignment=TA_CENTER, fontSize=12))])
t = Table([[r[0]] for r in rows], colWidths=[175*mm])
bg_list = []
for i in range(0, len(rows), 2):
if i == len(rows)-1:
bg_list.append(("BACKGROUND", (0,i), (0,i), DARK_BLUE))
bg_list.append(("TEXTCOLOR", (0,i), (0,i), WHITE))
else:
bg_list.append(("BACKGROUND", (0,i), (0,i), LIGHT_BLUE))
style = [
("GRID", (0,0), (-1,-1), 0, WHITE),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
] + bg_list
t.setStyle(TableStyle(style))
return t
# ── cover banner ──────────────────────────────────────────────────────────────
def cover_banner():
inner = Table([
[Paragraph("CHRONIC KIDNEY DISEASE (CKD)", title_style)],
[Paragraph("Complete Clinical Reference | Based on Harrison's 22E, Washington Manual, Brenner & Rector's", subtitle_style)],
[Paragraph("KDIGO Guidelines 2024 | NKF-KDOQI", subtitle_style)],
], colWidths=["100%"])
inner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return inner
# ── BUILD DOCUMENT ────────────────────────────────────────────────────────────
def build():
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=12*mm, bottomMargin=12*mm,
title="CKD Complete Clinical Notes",
author="Orris Medical AI",
)
story = []
# ---- COVER ---------------------------------------------------------------
story.append(cover_banner())
story.append(Spacer(1, 6))
# Quick index bar
idx_data = [["1. Definition & Etiology", "2. Pathophysiology", "3. Classification (KDIGO)",
"4. Signs & Symptoms", "5. Differentials"],
["6. Diagnostics", "7. Treatment", "8. Complications", "9. Prevention / Prognosis",
"10. Counseling & Lifestyle"]]
idx = Table(idx_data, colWidths=[37*mm]*5)
idx.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("FONTNAME", (0,0), (-1,-1), "Helvetica"),
("FONTSIZE", (0,0), (-1,-1), 7),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("GRID", (0,0), (-1,-1), 0.3, MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
]))
story.append(idx)
story.append(Spacer(1, 8))
# ── 1. DEFINITION & ETIOLOGY ──────────────────────────────────────────────
story += section("1. DEFINITION & ETIOLOGY / CAUSES", [
p("<b>Definition (KDIGO 2012):</b> Abnormalities of kidney structure or function present for "
"<b>>3 months</b>, with implications for health. Requires at least one of: GFR <60 mL/min/1.73m² "
"(GFR categories G3a-G5) OR markers of kidney damage (albuminuria ≥30 mg/g, urine sediment "
"abnormalities, tubular disorders, abnormal histology, abnormal imaging, kidney transplant history)."),
Spacer(1,3),
sub("Causes (Mnemonic: DIABETES-HG)"),
two_col([
["D - Diabetic nephropathy", "Most common cause (~40%); nodular glomerulosclerosis (Kimmelstiel-Wilson lesions)"],
["I - Immune (GN)", "IgA nephropathy, lupus nephritis, MPGN, membranous nephropathy"],
["A - Atheroembolism / RAS", "Renal artery stenosis, atheroembolism, renovascular disease"],
["B - BP (Hypertension)", "2nd most common; hypertensive nephrosclerosis"],
["E - Electrolyte/toxic", "NSAID, contrast, aminoglycosides, heavy metals, herbal"],
["T - Tubular (interstitial)", "Reflux nephropathy, analgesic nephropathy, myeloma cast nephropathy"],
["E - Endocrine / metabolic", "Hyperuricaemia, hypercalcaemia, oxalosis"],
["S - Structural / congenital", "ADPKD (most common hereditary), Alport syndrome, FSGS"],
["H - HIV / Hepatitis", "HIV-AN, HBV/HCV-associated membranous nephropathy"],
["G - Genetic (other)", "APOL1 variants (African ancestry, 7.5× ESKD risk), COL4A mutations"],
]),
Spacer(1,3),
sub("Risk Factors"),
two_col([
["Non-modifiable", "Age >60, male sex, African/Asian ancestry, low birth weight/prematurity, family Hx of CKD, prior AKI, APOL1 genotype"],
["Modifiable", "Diabetes, hypertension, obesity (BMI >30), dyslipidaemia, smoking, sedentary lifestyle, nephrotoxic drug use, recurrent UTI/stones"],
]),
])
# ── 2. PATHOPHYSIOLOGY ───────────────────────────────────────────────────
story += section("2. PATHOPHYSIOLOGY", [
patho_flow(),
Spacer(1,3),
p("<i>Key concept: RAAS activation drives both compensatory hyperfiltration and maladaptive "
"glomerulosclerosis. Proteinuria itself is directly tubulotoxic, amplifying interstitial "
"fibrosis. FGF-23 rises early (before PTH), and is a marker of early mineral bone disorder.</i>"),
])
# ── 3. CLASSIFICATION ────────────────────────────────────────────────────
story += section("3. CLASSIFICATION (KDIGO CGA Staging)", [
p("CKD is classified by: <b>C</b>ause + <b>G</b>FR category (G1-G5) + <b>A</b>lbuminuria category (A1-A3) — "
"collectively <b>'CGA Staging'</b>."),
Spacer(1,3),
kdigo_table(),
Spacer(1,3),
p("<b>Albuminuria:</b> A1 = normal to mildly increased (<30 mg/g); A2 = moderately increased "
"(30-300 mg/g); A3 = severely increased (>300 mg/g). Both GFR and albuminuria "
"independently predict risk of mortality, CV events, and CKD progression."),
p("<b>ESKD</b> = Stage G5 requiring dialysis or transplantation (kidney replacement therapy, KRT)."),
])
# ── 4. SIGNS & SYMPTOMS ──────────────────────────────────────────────────
story += section("4. SIGNS & SYMPTOMS + RED FLAG SIGNS ⚠", [
sub("By System (Mnemonic: UREMIA FANS)"),
two_col([
["U - Uraemia", "Nausea, vomiting, anorexia, metallic taste, uraemic frost (late)"],
["R - Renal", "Oliguria/anuria (late), nocturia (early - concentrating defect), haematuria"],
["E - Electrolytes", "Hyperkalaemia (palpitations, weakness), hyponatraemia, metabolic acidosis (Kussmaul breathing)"],
["M - Mineral", "Bone pain, fractures (renal osteodystrophy), pruritis (Ca²⁺-PO₄ deposition), periorbital calcification"],
["I - Immune", "Infections (↓immunity), impaired vaccine response"],
["A - Anaemia", "Fatigue, pallor, dyspnoea, ↓EPO production"],
["F - Fluid", "Oedema (peripheral, pulmonary), hypertension"],
["A - Autonomic/Neuro","Peripheral neuropathy, restless leg syndrome, encephalopathy (late)"],
["N - Nutrition", "Malnutrition, muscle wasting (sarcopaenia), hypoalbuminaemia"],
["S - Sexual/Skin", "Erectile dysfunction, amenorrhoea, uraemic pruritus, sallow skin, uraemic frost"],
]),
Spacer(1,3),
wn("RED FLAG SIGNS - Refer/Escalate Urgently"),
Table([
[Paragraph("• Rapid unexplained eGFR decline (>5 mL/min/year)", bullet),
Paragraph("• Nephrotic syndrome (proteinuria >3.5g/d + oedema)", bullet)],
[Paragraph("• Macroscopic haematuria (rule out malignancy)", bullet),
Paragraph("• Resistant / malignant hypertension", bullet)],
[Paragraph("• Hyperkalaemia >6.5 mEq/L or ECG changes", bullet),
Paragraph("• Signs of uraemia: pericarditis, encephalopathy", bullet)],
[Paragraph("• Bilateral hydronephrosis (obstruction)", bullet),
Paragraph("• Sudden anuria in known CKD patient", bullet)],
], colWidths=[90*mm, 85*mm]),
])
# ── PAGE BREAK ───────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(cover_banner())
story.append(Spacer(1,6))
# ── 5. DIFFERENTIAL DIAGNOSIS ────────────────────────────────────────────
story += section("5. DIFFERENTIAL DIAGNOSIS", [
diff_diag_table(),
Spacer(1,2),
p("<b>Key distinguishing feature:</b> CKD requires >3 months of impaired function. "
"Small echogenic kidneys on ultrasound strongly favour CKD over AKI (except in DM, amyloid, "
"ADPKD where kidneys may be large)."),
])
# ── 6. DIAGNOSTIC TESTS ──────────────────────────────────────────────────
story += section("6. DIAGNOSTIC TESTS & CRITERIA", [
sub("Basic (First-Line) Tests"),
two_col([
["Serum creatinine\n+ eGFR", "CKD-EPI equation (race-free 2021). eGFR <60 for >3 months = CKD"],
["Urine ACR", "Spot urine albumin:creatinine ratio; A1 <30, A2 30-300, A3 >300 mg/g"],
["Urinalysis + microscopy", "RBC casts → GN; WBC casts → pyelonephritis; waxy casts → advanced CKD"],
["Serum electrolytes", "Na, K, HCO₃, Cl - acidosis, hyperkalaemia"],
["Urea / BUN", "Uraemia marker; BUN:Cr ratio <20 in CKD"],
["CBC", "Normocytic, normochromic anaemia (EPO deficiency)"],
["Renal ultrasound", "Bilateral small echogenic kidneys (<9cm) = CKD; rule out obstruction, cysts, ADPKD"],
]),
Spacer(1,3),
sub("Specific / Advanced Tests"),
two_col([
["24h urine protein", "Gold standard for proteinuria quantification when ACR equivocal"],
["PTH (intact)", "↑ Secondary hyperparathyroidism from G3 onwards"],
["25-OH Vitamin D", "Deficiency common; drives ↑PTH if <30 ng/mL"],
["Serum phosphate & calcium", "Hyperphosphataemia + hypocalcaemia in G4-G5"],
["Serum albumin", "Nutritional marker; also nephrotic syndrome assessment"],
["Cystatin-C", "Alternative GFR marker unaffected by muscle mass; useful in elderly/amputees"],
["HbA1c", "Diabetic CKD monitoring; target <7%"],
["Fasting lipids", "CV risk assessment; statin therapy guidance"],
["Renal biopsy", "Indications: rapid decline, heavy proteinuria, atypical features, suspected GN/vasculitis"],
["ANCA, ANA, anti-GBM, C3/C4","Autoimmune GN screen in young patients or rapid progression"],
["SPEP / UPEP + FLC", "Rule out myeloma in elderly with unexplained CKD"],
["Renal Doppler USS", "Renal artery stenosis if resistant HTN or ACEi/ARB causes >30% Cr rise"],
]),
Spacer(1,3),
sub("Diagnostic Criteria (KDIGO 2012) — Mnemonic: '3-3-3 Rule'"),
Table([
[Paragraph("<b>Duration</b>: Abnormality present for >3 MONTHS", body),
Paragraph("<b>GFR</b>: <60 mL/min/1.73m² (categories G3a-G5)", body),
Paragraph("<b>OR Markers</b>: Proteinuria ≥30mg/g, abnormal sediment, imaging, histology, Hx of transplant", body)],
], colWidths=[58*mm, 58*mm, 59*mm]),
])
# ── 7. TREATMENT ─────────────────────────────────────────────────────────
story += section("7. TREATMENT", [
sub("A. Non-Pharmacological (Mnemonic: DASH-SPORT)"),
two_col([
["D - Diet: Na", "Sodium <2g/day for HTN/oedema; low-phosphate diet (avoid dark colas, nuts, processed meats)"],
["A - Avoid nephrotoxins","Stop NSAIDs, aminoglycosides, contrast (use pre-hydration/NAC if unavoidable)"],
["S - Sodium bicarb", "Oral NaHCO₃ 650-1300mg BD/TDS to keep HCO₃ ≥22 mEq/L (slows progression)"],
["H - Hydration", "Adequate hydration; restrict fluid only if dilutional hyponatraemia"],
["S - Smoking cessation","Tobacco accelerates CKD progression; cessation programmes mandatory"],
["P - Protein", "0.6-0.8 g/kg/day (moderate restriction); no benefit from severe restriction"],
["O - Obesity management","Weight loss to BMI <25; exercise ≥150 min/week moderate intensity"],
["R - RRT preparation", "AV fistula creation at G4; counsel on dialysis options at G4-G5"],
["T - Transplant", "Preferred RRT for eligible patients; pre-emptive transplant ideal"],
]),
Spacer(1,3),
sub("B. Pharmacological"),
drug_table(),
Spacer(1,3),
sub("C. Surgical / Procedural"),
bp("AV fistula creation (preferred haemodialysis access - start at G4)"),
bp("Peritoneal dialysis catheter insertion (alternative to HD)"),
bp("Renal transplantation (living/deceased donor; best survival outcomes)"),
bp("Parathyroidectomy (tertiary hyperparathyroidism unresponsive to medical therapy)"),
bp("Ureteric stenting/nephrostomy for obstructive uropathy"),
bp("Bilateral native nephrectomy (persistent nephrotic syndrome post-transplant, recurrent infection, massive polycystic kidneys)"),
])
# ── PAGE BREAK ───────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(cover_banner())
story.append(Spacer(1,6))
# ── 8. COMPLICATIONS ─────────────────────────────────────────────────────
story += section("8. COMPLICATIONS (Mnemonic: CHAMP-WAVE)", [
two_col([
["C - CV disease", "Leading cause of death in CKD; LVH, heart failure, accelerated atherosclerosis, arrhythmias"],
["H - Hypertension", "Both cause AND complication; resistant HTN common"],
["A - Anaemia", "Normocytic; ↓EPO, ↓iron absorption, chronic inflammation"],
["M - Mineral bone disease","Renal osteodystrophy: osteitis fibrosa cystica (↑PTH), adynamic bone disease, osteomalacia (Al toxicity)"],
["P - Protein-energy wasting","Malnutrition, muscle wasting, hypoalbuminaemia; worsens mortality"],
["W - Water/electrolytes", "Hyperkalaemia, metabolic acidosis, hyponatraemia, fluid overload"],
["A - Acidosis (metabolic)","Mixed high & normal anion-gap acidosis; worsens bone disease"],
["V - Vascular calcification","Ca-PO₄ deposition → vascular stiffness, medial calcification"],
["E - Encephalopathy", "Uraemic encephalopathy, peripheral neuropathy, restless legs syndrome"],
]),
])
# ── 9. PREVENTION ────────────────────────────────────────────────────────
story += section("9. PREVENTION, PROGNOSIS & EMERGENCY MANAGEMENT", [
sub("Prevention (Primary/Secondary)"),
bp("Control diabetes: HbA1c target <7%; SGLT2i have added nephroprotection"),
bp("Control BP: target <120 mmHg systolic (KDIGO 2021); use ACEi/ARB first-line if proteinuric"),
bp("Avoid nephrotoxins; NSAID restriction; adjust drug doses for eGFR"),
bp("Treat dyslipidaemia; smoking cessation; weight management"),
bp("Annual eGFR + ACR monitoring in high-risk patients (diabetes, HTN, family Hx)"),
bp("Hepatitis B vaccination (all adults with eGFR <30); pneumococcal vaccine at any CKD stage"),
Spacer(1,3),
sub("Prognosis"),
p("Prognosis is determined by GFR category + albuminuria category (heat map). Key points:"),
bp("Most G1-G2 patients without progressive proteinuria do NOT progress to ESKD"),
bp("Annual GFR decline >5 mL/min/year signals high-risk progression"),
bp("CKD-G3b A3 = 'Very High Risk' category; requires nephrologist co-management"),
bp("Leading cause of death: Cardiovascular disease (3-4× higher CV mortality than general population)"),
bp("With KRT (dialysis/transplant), 5-year survival ~40% on HD; transplant recipients 80-85% at 5 years"),
Spacer(1,3),
sub("Emergency Management"),
wn("Life-threatening emergencies in CKD:"),
two_col([
["Hyperkalaemia\n(K⁺ >6.5 or ECG changes)",
"1. IV Calcium gluconate 10% 10mL (membrane stabilisation)\n"
"2. Insulin 10U + Dextrose 50% 50mL IV (shift K⁺ intracellular)\n"
"3. Salbutamol 10-20mg nebulised\n"
"4. Kayexalate/Patiromer/Lokelma (elimination)\n"
"5. Emergency dialysis if refractory"],
["Pulmonary oedema\n(Volume overload)",
"1. Sit upright; high-flow O₂\n"
"2. IV Furosemide 40-80mg (escalate to 200mg bolus + drip)\n"
"3. IV/SL nitrates if BP allows\n"
"4. CPAP/BiPAP if respiratory failure\n"
"5. Emergent ultrafiltration/dialysis if refractory"],
["Uraemic pericarditis",
"Urgent haemodialysis; avoid anticoagulation (tamponade risk); pericardiocentesis if haemodynamic compromise"],
["Severe metabolic acidosis\n(pH <7.1)",
"IV sodium bicarbonate 8.4% cautiously; treat underlying cause; dialysis if refractory"],
["AKI-on-CKD",
"Identify & treat precipitant (dehydration, sepsis, obstruction, nephrotoxin withdrawal); IV fluids; early nephrology referral"],
]),
])
# ── 10. PATIENT COUNSELING, LIFESTYLE & SPECIAL SITUATIONS ──────────────
story += section("10. PATIENT COUNSELING, LIFESTYLE & SPECIAL SITUATIONS", [
sub("Patient Counseling (Mnemonic: KIDNEY)"),
mn("K - Know your numbers: eGFR and urine albumin checked regularly"),
mn("I - Inputs: Restrict salt (<2g Na), moderate protein (0.6-0.8g/kg), phosphate restriction"),
mn("D - Drugs: Never take NSAIDs/ibuprofen; careful with contrast dye; dose adjustments essential"),
mn("N - No smoking; No alcohol excess; exercise daily 30 min"),
mn("E - Emergency signs: breathlessness, chest pain, reduced urine - go to ER immediately"),
mn("Y - Yearly follow-up: blood test, urine test, BP check, eye check (if diabetic)"),
Spacer(1,3),
sub("Lifestyle Modifications (Mnemonic: STOP-SALT)"),
two_col([
["S - Smoking cessation", "Most impactful modifiable risk factor for progression"],
["T - Target BP <120 systolic","Home BP monitoring; take medications as prescribed"],
["O - Obesity: lose weight", "BMI target <25; caloric restriction + aerobic exercise"],
["P - Phosphate restriction","Avoid dairy excess, nuts, dark colas, processed foods"],
["S - Salt <2g/day", "No added salt; read food labels; avoid preserved/canned foods"],
["A - Alcohol: limit", "<2 units/day; alcohol raises BP and worsens fluid retention"],
["L - Low glycaemic diet", "Diabetic CKD: DASH diet, low sugar, complex carbs"],
["T - Twice-daily meds", "ACEi/ARB + SGLT2i twice daily; never skip doses"],
]),
Spacer(1,3),
sub("Special Situations"),
two_col([
["Diabetes + CKD", "SGLT2i first-line alongside ACEi/ARB; Finerenone if persisting proteinuria; "
"avoid Metformin if eGFR <30 (risk of lactic acidosis); GLP-1RA beneficial"],
["Pregnancy + CKD", "High risk of pre-eclampsia, preterm birth; ESKD → foetal loss risk; "
"ACEi/ARBs CONTRAINDICATED in pregnancy; refer to maternal-foetal medicine"],
["Elderly + CKD", "eGFR often low even with normal Cr; CKD-EPI preferred; conservative management "
"often appropriate; avoid aggressive protein restriction → sarcopaenia"],
["CKD + Contrast", "Pre-hydrate with NS 1 mL/kg/h 12h pre/post; minimize contrast dose; "
"hold metformin 48h post; use iso-osmolar contrast"],
["CKD + Surgery", "Pre-op: optimise volume, hold ACEi/ARB 24-48h pre-op; "
"avoid perioperative NSAIDs; careful with anaesthetic agents"],
["CKD + HIV", "APOL1 risk; TDF-containing ART nephrotoxic - prefer TAF; "
"monitor eGFR 3-monthly; consider renal biopsy for unexplained decline"],
["Vaccination", "Hepatitis B (anti-HBs ≥10 IU/L required, double dose); pneumococcal; "
"annual influenza; COVID-19 vaccine strongly recommended"],
]),
])
# footer note
story.append(HR())
story.append(Paragraph(
"<i>Sources: Harrison's Principles of Internal Medicine 22E (2025), The Washington Manual of Medical Therapeutics, "
"Brenner & Rector's The Kidney, National Kidney Foundation Primer 8E. KDIGO CKD Guidelines 2012/2024. "
"Compiled by Orris Medical AI — June 2026. For clinical use only; verify drug doses against local protocols.</i>",
caption))
doc.build(story)
print(f"PDF generated: {OUTPUT}")
if __name__ == "__main__":
build()
cd /home/daytona/workspace/ckd-notes && python3 generate_ckd_pdf.py 2>&1
ls -lh /home/daytona/workspace/ckd-notes/CKD_Clinical_Notes.pdf && python3 -c "from pypdf import PdfReader; r=PdfReader('/home/daytona/workspace/ckd-notes/CKD_Clinical_Notes.pdf'); print(f'Pages: {len(r.pages)}')"
CKD Clinical Notes
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Definition & Etiology | KDIGO 2012 definition; causes via mnemonic DIABETES-HG; modifiable/non-modifiable risk factors |
| 2. Pathophysiology | Visual flowchart: Insult → Nephron loss → Hyperfiltration → Glomerulosclerosis → ESKD |
| 3. Classification | Full KDIGO CGA staging table (G1-G5 × A1-A3), colour-coded by risk |
| 4. Signs & Symptoms + Red Flags | System-by-system via mnemonic UREMIA FANS; red flag table for urgent referral |
| 5. Differential Diagnosis | 7 key differentials with distinguishing features |
| 6. Diagnostics | Basic + specific tests; diagnostic criteria using 3-3-3 Rule mnemonic |
| 7. Treatment | Non-pharm (DASH-SPORT), pharmacological drug table (12 classes), surgical options |
| 8. Complications | Mnemonic CHAMP-WAVE covering all major complications |
| 9. Prevention + Prognosis + Emergency | Prevention bullets; prognosis pearls; step-by-step emergency protocols (hyperkalaemia, pulmonary oedema, uraemic pericarditis, acidosis) |
| 10. Counseling + Lifestyle + Special Situations | KIDNEY counseling mnemonic; STOP-SALT lifestyle mnemonic; 7 special scenarios (Diabetes, Pregnancy, Elderly, Contrast, Surgery, HIV, Vaccination) |
Give pdf
CKD Clinical Notes
PDF Document · PDF