Skip to content

Commit 1a42a68

Browse files
Update cookbook code
1 parent cb997c4 commit 1a42a68

6 files changed

Lines changed: 132 additions & 117 deletions

cookbook/cds_discharge_summarizer_hf_chat.py

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,100 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Discharge Note Summarizer (LangChain + HuggingFace Chat)
4+
5+
CDS Hooks service that summarises discharge notes using a HuggingFace
6+
chat model via LangChain (DeepSeek R1 by default).
7+
8+
Requirements:
9+
pip install healthchain langchain-core langchain-huggingface python-dotenv
10+
# HUGGINGFACEHUB_API_TOKEN env var required
11+
12+
Run:
13+
python cookbook/cds_discharge_summarizer_hf_chat.py
14+
# POST /cds/cds-services/discharge-summarizer
15+
# Docs at: http://localhost:8000/docs
16+
"""
17+
118
import os
219
import getpass
320

4-
from healthchain.gateway import HealthChainAPI, CDSHooksService
5-
from healthchain.pipeline import SummarizationPipeline
6-
from healthchain.models import CDSRequest, CDSResponse
21+
from dotenv import load_dotenv
722

823
from langchain_huggingface.llms import HuggingFaceEndpoint
924
from langchain_huggingface import ChatHuggingFace
1025
from langchain_core.prompts import PromptTemplate
1126
from langchain_core.output_parsers import StrOutputParser
1227

13-
from dotenv import load_dotenv
28+
from healthchain.gateway import HealthChainAPI, CDSHooksService
29+
from healthchain.pipeline import SummarizationPipeline
30+
from healthchain.models import CDSRequest, CDSResponse
1431

1532
load_dotenv()
1633

1734

18-
if not os.getenv("HUGGINGFACEHUB_API_TOKEN"):
19-
os.environ["HUGGINGFACEHUB_API_TOKEN"] = getpass.getpass("Enter your token: ")
35+
def create_chain():
36+
if not os.getenv("HUGGINGFACEHUB_API_TOKEN"):
37+
os.environ["HUGGINGFACEHUB_API_TOKEN"] = getpass.getpass(
38+
"Enter your HuggingFace token: "
39+
)
2040

21-
22-
def create_summarization_chain():
2341
hf = HuggingFaceEndpoint(
2442
repo_id="deepseek-ai/DeepSeek-R1-0528",
2543
task="text-generation",
2644
max_new_tokens=512,
2745
do_sample=False,
2846
repetition_penalty=1.03,
2947
)
30-
3148
model = ChatHuggingFace(llm=hf)
32-
33-
template = """
34-
You are a discharge planning assistant for hospital operations.
35-
Provide a concise, objective summary focusing on actionable items
36-
for care coordination, including appointments, medications, and
37-
follow-up instructions. Format as bullet points with no preamble.\n'''{text}'''
38-
"""
39-
prompt = PromptTemplate.from_template(template)
40-
49+
prompt = PromptTemplate.from_template(
50+
"You are a discharge planning assistant for hospital operations. "
51+
"Provide a concise, objective summary focusing on actionable items "
52+
"for care coordination, including appointments, medications, and "
53+
"follow-up instructions. Format as bullet points with no preamble.\n'''{text}'''"
54+
)
4155
return prompt | model | StrOutputParser()
4256

4357

44-
# Create the healthcare application
45-
app = HealthChainAPI(
46-
title="Discharge Note Summarizer",
47-
description="AI-powered discharge note summarization service",
48-
)
49-
50-
chain = create_summarization_chain()
51-
pipeline = SummarizationPipeline.load(
52-
chain, source="langchain", template_path="templates/cds_card_template.json"
53-
)
54-
55-
# Create CDS Hooks service
56-
cds = CDSHooksService()
58+
def create_app() -> HealthChainAPI:
59+
chain = create_chain()
60+
pipeline = SummarizationPipeline.load(
61+
chain, source="langchain", template_path="templates/cds_card_template.json"
62+
)
63+
cds = CDSHooksService()
5764

65+
@cds.hook("encounter-discharge", id="discharge-summarizer")
66+
def discharge_summarizer(request: CDSRequest) -> CDSResponse:
67+
return pipeline.process_request(request)
5868

59-
@cds.hook("encounter-discharge", id="discharge-summarizer")
60-
def discharge_summarizer(request: CDSRequest) -> CDSResponse:
61-
result = pipeline.process_request(request)
62-
return result
69+
app = HealthChainAPI(
70+
title="Discharge Note Summarizer",
71+
description="AI-powered discharge note summarization service",
72+
port=8000,
73+
service_type="cds-hooks",
74+
)
75+
app.register_service(cds, path="/cds")
76+
return app
6377

6478

65-
# Register the CDS service
66-
app.register_service(cds, path="/cds")
79+
app = create_app()
6780

6881

6982
if __name__ == "__main__":
70-
import uvicorn
7183
import threading
72-
7384
from healthchain.sandbox import SandboxClient
7485

75-
# Start the API server in a separate thread
76-
def start_api():
77-
uvicorn.run(app, port=8000)
78-
79-
api_thread = threading.Thread(target=start_api, daemon=True)
86+
api_thread = threading.Thread(target=app.run, daemon=True)
8087
api_thread.start()
8188

82-
# Create sandbox client and load test data
8389
client = SandboxClient(
8490
url="http://localhost:8000/cds/cds-services/discharge-summarizer",
8591
workflow="encounter-discharge",
8692
)
87-
# Load discharge notes from CSV
8893
client.load_free_text(
8994
csv_path="data/discharge_notes.csv",
9095
column_name="text",
9196
)
92-
# Send requests and get responses
9397
responses = client.send_requests()
94-
95-
# Save results
9698
client.save_results("./output/")
9799

98100
try:

cookbook/cds_discharge_summarizer_hf_trf.py

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,79 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Discharge Note Summarizer (Transformer)
4+
5+
CDS Hooks service that summarises discharge notes using a fine-tuned
6+
HuggingFace transformer model (PEGASUS).
7+
8+
Requirements:
9+
pip install healthchain transformers torch python-dotenv
10+
# HUGGINGFACEHUB_API_TOKEN env var required
11+
12+
Run:
13+
python cookbook/cds_discharge_summarizer_hf_trf.py
14+
# POST /cds/cds-services/discharge-summarizer
15+
# Docs at: http://localhost:8000/docs
16+
"""
17+
118
import os
219
import getpass
320

21+
from dotenv import load_dotenv
22+
423
from healthchain.gateway import HealthChainAPI, CDSHooksService
524
from healthchain.pipeline import SummarizationPipeline
625
from healthchain.models import CDSRequest, CDSResponse
726

8-
from dotenv import load_dotenv
9-
1027
load_dotenv()
1128

1229

13-
if not os.getenv("HUGGINGFACEHUB_API_TOKEN"):
14-
os.environ["HUGGINGFACEHUB_API_TOKEN"] = getpass.getpass("Enter your token: ")
15-
16-
17-
# Create the healthcare application
18-
app = HealthChainAPI(
19-
title="Discharge Note Summarizer",
20-
description="AI-powered discharge note summarization service",
21-
)
30+
def create_pipeline() -> SummarizationPipeline:
31+
if not os.getenv("HUGGINGFACEHUB_API_TOKEN"):
32+
os.environ["HUGGINGFACEHUB_API_TOKEN"] = getpass.getpass(
33+
"Enter your HuggingFace token: "
34+
)
35+
return SummarizationPipeline.from_model_id(
36+
"google/pegasus-xsum", source="huggingface", task="summarization"
37+
)
2238

23-
# Initialize pipeline
24-
pipeline = SummarizationPipeline.from_model_id(
25-
"google/pegasus-xsum", source="huggingface", task="summarization"
26-
)
2739

28-
# Create CDS Hooks service
29-
cds = CDSHooksService()
40+
def create_app() -> HealthChainAPI:
41+
pipeline = create_pipeline()
42+
cds = CDSHooksService()
3043

44+
@cds.hook("encounter-discharge", id="discharge-summarizer")
45+
def discharge_summarizer(request: CDSRequest) -> CDSResponse:
46+
return pipeline.process_request(request)
3147

32-
@cds.hook("encounter-discharge", id="discharge-summarizer")
33-
def discharge_summarizer(request: CDSRequest) -> CDSResponse:
34-
result = pipeline.process_request(request)
35-
return result
48+
app = HealthChainAPI(
49+
title="Discharge Note Summarizer",
50+
description="AI-powered discharge note summarization service",
51+
port=8000,
52+
service_type="cds-hooks",
53+
)
54+
app.register_service(cds, path="/cds")
55+
return app
3656

3757

38-
# Register the CDS service
39-
app.register_service(cds, path="/cds")
58+
app = create_app()
4059

4160

4261
if __name__ == "__main__":
43-
import uvicorn
4462
import threading
45-
4663
from healthchain.sandbox import SandboxClient
4764

48-
# Start the API server in a separate thread
49-
def start_api():
50-
uvicorn.run(app, port=8000)
51-
52-
api_thread = threading.Thread(target=start_api, daemon=True)
65+
api_thread = threading.Thread(target=app.run, daemon=True)
5366
api_thread.start()
5467

55-
# Create sandbox client and load test data
5668
client = SandboxClient(
5769
url="http://localhost:8000/cds/cds-services/discharge-summarizer",
5870
workflow="encounter-discharge",
5971
)
60-
# Load discharge notes from CSV
6172
client.load_free_text(
6273
csv_path="data/discharge_notes.csv",
6374
column_name="text",
6475
)
65-
# Send requests and get responses
6676
responses = client.send_requests()
67-
68-
# Save results
6977
client.save_results("./output/")
7078

7179
try:

cookbook/multi_ehr_data_aggregation.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
- Cerner Open Sandbox: No auth needed
1414
1515
Run:
16-
- python data_aggregation.py
16+
python cookbook/multi_ehr_data_aggregation.py
1717
"""
1818

1919
from typing import List
@@ -23,7 +23,7 @@
2323
from healthchain.fhir.r4b import Bundle, Condition, Annotation
2424

2525
from healthchain.gateway import FHIRGateway, HealthChainAPI
26-
from healthchain.gateway.clients.fhir.base import FHIRAuthConfig
26+
from healthchain.gateway.clients import FHIRAuthConfig
2727
from healthchain.pipeline import Pipeline
2828
from healthchain.io.containers import Document
2929
from healthchain.fhir import merge_bundles
@@ -100,15 +100,16 @@ def get_unified_patient(patient_id: str, sources: List[str]) -> Bundle:
100100

101101
return doc.fhir.bundle
102102

103-
app = HealthChainAPI()
104-
app.register_gateway(gateway)
103+
app = HealthChainAPI(
104+
title="Multi-EHR Data Aggregation",
105+
description="Aggregate patient data from multiple FHIR sources",
106+
port=8888,
107+
service_type="fhir-gateway",
108+
)
109+
app.register_gateway(gateway, path="/fhir")
105110

106111
return app
107112

108113

109114
if __name__ == "__main__":
110-
import uvicorn
111-
112-
app = create_app()
113-
uvicorn.run(app, port=8888)
114-
# Runs at: http://127.0.0.1:8888/
115+
create_app().run()

cookbook/notereader_clinical_coding_fhir.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44
Demonstrates FHIR-native pipelines, legacy system integration, and multi-source data handling.
55
66
Requirements:
7-
- pip install healthchain
8-
- pip install scispacy
9-
- pip install https://s3-us-west-2.amazonaws.com/ai2-s2-scispacy/releases/v0.5.4/en_core_sci_sm-0.5.4.tar.gz
10-
- pip install python-dotenv
7+
pip install healthchain scispacy python-dotenv
8+
pip install https://s3-us-west-2.amazonaws.com/ai2-s2-scispacy/releases/v0.5.4/en_core_sci_sm-0.5.4.tar.gz
119
1210
Run:
13-
- python notereader_clinical_coding_fhir.py # Demo and start server
11+
python cookbook/notereader_clinical_coding_fhir.py
1412
"""
1513

1614
import logging
@@ -21,7 +19,7 @@
2119
from healthchain.fhir import add_provenance_metadata
2220
from healthchain.gateway.api import HealthChainAPI
2321
from healthchain.gateway.fhir import FHIRGateway
24-
from healthchain.gateway.clients.fhir.base import FHIRAuthConfig
22+
from healthchain.gateway.clients import FHIRAuthConfig
2523
from healthchain.gateway.soap import NoteReaderService
2624
from healthchain.io import CdaAdapter, Document
2725
from healthchain.models import CdaRequest
@@ -104,7 +102,12 @@ def ai_coding_workflow(request: CdaRequest):
104102
return cda_response
105103

106104
# Register services
107-
app = HealthChainAPI(title="Epic CDI Service with FHIR integration")
105+
app = HealthChainAPI(
106+
title="Epic CDI Service",
107+
description="Clinical document intelligence with FHIR and NoteReader integration",
108+
port=8000,
109+
service_type="fhir-gateway",
110+
)
108111
app.register_gateway(fhir_gateway, path="/fhir")
109112
app.register_service(note_service, path="/notereader")
110113

@@ -117,18 +120,12 @@ def ai_coding_workflow(request: CdaRequest):
117120

118121
if __name__ == "__main__":
119122
import threading
120-
import uvicorn
121-
122123
from time import sleep
123124
from healthchain.sandbox import SandboxClient
124125

125-
# Start server
126-
def run_server():
127-
uvicorn.run(app, port=8000, log_level="warning")
128-
129-
server_thread = threading.Thread(target=run_server, daemon=True)
126+
server_thread = threading.Thread(target=app.run, daemon=True)
130127
server_thread.start()
131-
sleep(2) # Wait for startup
128+
sleep(2)
132129

133130
# Create sandbox client for testing
134131
client = SandboxClient(

cookbook/sepsis_cds_hooks.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,12 @@ def sepsis_alert(request: CDSRequest) -> CDSResponse:
115115

116116
return CDSResponse(cards=[])
117117

118-
app = HealthChainAPI(title="Sepsis CDS Hooks")
118+
app = HealthChainAPI(
119+
title="Sepsis CDS Hooks",
120+
description="Real-time sepsis risk alerts via CDS Hooks",
121+
port=8000,
122+
service_type="cds-hooks",
123+
)
119124
app.register_service(cds, path="/cds")
120125

121126
return app
@@ -126,15 +131,10 @@ def sepsis_alert(request: CDSRequest) -> CDSResponse:
126131

127132
if __name__ == "__main__":
128133
import threading
129-
import uvicorn
130134
from time import sleep
131135
from healthchain.sandbox import SandboxClient
132136

133-
# Start server
134-
def run_server():
135-
uvicorn.run(app, port=8000, log_level="warning")
136-
137-
server = threading.Thread(target=run_server, daemon=True)
137+
server = threading.Thread(target=app.run, daemon=True)
138138
server.start()
139139
sleep(2)
140140

0 commit comments

Comments
 (0)