Hi all,
It's me again 😁. In the pervious article Writing a REST api service for exporting the generated FHIR bundle in JSON, we actually generated a resource DocumentReference, with the content data encoded in Base64
Question!! Is it possible to write a REST service for decoding it? Because I am very curious what is the message data talking about🤔🤔🤔
OK, Let's start!
1. Create a new utility class datagen.utli.decodefhirjson.cls for decoding the data inside the DocumentReference
Class datagen.utli.decodefhirjson Extends %RegisteredObject
{
}
2. Write a Python function decodebase64docref to
a. loop through the FHIR bundle
b. find out the resource DocumentReference
- get the 1st element in the content
- get the attachment from the content
- get the data from the attachment
c. decode the data by Base64
(this part I asked Chat-GPT to help me😂🤫)
Class datagen.utli.decodefhirjson Extends %RegisteredObject
{
ClassMethod decodebase64docref(fhirbundle = "") As %String [ Language = python ]
{
# w ##class(datagen.utli.decodefhirjson).decodebase64docref()
import base64
import json
def decode_discharge_summary(bundle_json):
"""
Extracts and decodes the Base64-encoded discharge summary note
from a FHIR Bundle containing a DocumentReference.
"""
for entry in bundle_json.get("entry", []):
resource = entry.get("resource", {})
if resource.get("resourceType") == "DocumentReference":
# Traverse to the attachment
content_list = resource.get("content", [])
if not content_list:
continue
attachment = content_list[0].get("attachment", {})
base64_data = attachment.get("data")
if base64_data:
decoded_text = base64.b64decode(base64_data).decode("utf-8")
return decoded_text
return None
# Example usage
# Load your FHIR Bundle JSON from a file or object
#with open("fhir_bundle.json", "r") as f:
# fhir_bundle = json.loads(f)
if fhirbundle=="":
rtstr=f"⚠️ No input found - JSON string is required."
jsstr={"operation_outcome" : rtstr}
return json.dumps(jsstr, indent=2)
fhir_bundle = json.loads(fhirbundle)
decoded_note = decode_discharge_summary(fhir_bundle)
if decoded_note:
#print("📝 Decoded Discharge Summary:\n")
#print(decoded_note)
rtstr=f"📝 Decoded Discharge Summary:\n {decoded_note}"
else:
#print("⚠️ No DocumentReference with Base64 note found.")
rtstr=f"⚠️ No DocumentReference with Base64 note found."
jsstr={"data" : rtstr}
return json.dumps(jsstr, indent=2)
}
}
For testing this function, I try do some trick, which is making use of the function genfhirbundle to generate FHIR bundle in JSON string, in the pervious article Writing a REST api service for exporting the generated FHIR bundle in JSON.
Let's generated a FHIR bundle and store into a variable jsonstr
set jsonstr=##class(datagen.utli.genfhirjson).genfhirbundle(1)
The test the decode function decodebase64docref with the jsonstr
w ##class(datagen.utli.decodefhirjson).decodebase64docref(jsonstr)
OK 😉 Looks good. Now I can read the decode message.
Now, go back the pervious and pervious article Writing a REST api service for exporting the generated patient data in .csv
We would like to add a new function and update the route for the datagen.restservice class.
1. Add a new function DecodeDocRef, which is expecting to handle the FHIR bundle attached in the body in JSON format.
i.e. In this case, we are expecting a POST.
the body content is packaged as %CSP.BinaryStream by default and stored in the variable %request.Content, so we can use the .Read() function from the class %CSP.BinaryStream to read the BinaryStream
ClassMethod DecodeDocRef() As %Status
{
// get body - json string
#dim bistream As %CSP.BinaryStream =""
set bistream=%request.Content
set jsstr=bistream.Read()
//decode the Document Reference data
w ##class(datagen.utli.decodefhirjson).decodebase64docref(jsstr)
return $$$OK
}
2. Then we add a route for the REST service and compile😀
<Route Url="/decode/docref" Method="POST" Call="DecodeDocRef" />
the updated datagen.restservice class will look like the following.
Great!! That's all we need to do!😁
Let's test in postman!!
POST the following path
localhost/irishealth/csp/mpapp/decode/docref
with the following body ( I simplified FHIR bundle, you may test the full one😀)
{
"resourceType": "Bundle",
"type": "transaction",
"id": "98bfce83-7eb1-4afe-bf2b-42916512244e",
"meta": {
"lastUpdated": "2025-10-13T05:49:07Z"
},
"entry": [
{
"fullUrl": "urn:uuid:5be1037d-a481-45ca-aea9-2034e27ebdcd",
"resource": {
"resourceType": "DocumentReference",
"id": "5be1037d-a481-45ca-aea9-2034e27ebdcd",
"status": "current",
"type": {
"coding": [
{
"system": "http://loinc.org",
"code": "18842-5",
"display": "Discharge summary"
}
]
},
"subject": {
"reference": "9e3a2636-4e87-4dee-b202-709d6f94ed18"
},
"author": [
{
"reference": "2aa54642-6743-4153-a171-7b8a8004ce5b"
}
],
"context": {
"encounter": [
{
"reference": "98cd848b-251f-4d0b-bf36-e35c9fe68956"
}
]
},
"content": [
{
"attachment": {
"contentType": "text/plain",
"language": "en",
"data": "RGlzY2hhcmdlIHN1bW1hcnkgZm9yIHBhdGllbnQgOWUzYTI2MzYtNGU4Ny00ZGVlLWIyMDItNzA5ZDZmOTRlZDE4LiBEaWFnbm9zaXM6IFN0YWJsZS4gRm9sbG93LXVwIGluIDIgd2Vla3Mu",
"title": "Discharge Summary Note"
}
}
]
},
"request": {
"method": "POST",
"url": "DocumentReference"
}
}
]
}
Works well!!!😆😉
Thank you very much for reading. 😘
Top comments (0)