Écrit par

Associate professor at Igor Sikorsky Kyiv Polytechnic Institute
Article Iryna Mykhailova · Nov 5 6m read

Exemple d'API REST pour décoder les données Base64

Salut!

C'est encore moi 😁. Dans l'article précédent Comment écrire un service API REST pour exporter le paquet FHIR généré au format JSON, nous avons généré une ressource DocumentReference, dont le contenu était encodé en Base64

Question!! Est-il possible d'écrire un service REST pour le décoder? Je voudrais vraiment savoir ce que contiennent les données du message🤔🤔🤔

Bien, allons-y!

1. Créez une nouvelle classe utilitaire datagen.utli.decodefhirjson.cls pour décoder les données contenues dans DocumentReference
 

Class datagen.utli.decodefhirjson Extends%RegisteredObject
{
}

2. Écrivez une fonction Python decodebase64docref pour 
a. parcourir le paquet FHIR
b. découvrir la ressource DocumentReference
  - récupérer le premier élément dans le contenu
   - récupérer la pièce jointe à partir de  contenu
     - récupérer les données à partir de la pièce jointe
c. décoder les données par Base64
 (pour cette partie, j'ai demandé l'aide de Chat-GPT😂🤫) 

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):
    <span class="hljs-string">"""
    Extracts and decodes the Base64-encoded discharge summary note
    from a FHIR Bundle containing a DocumentReference.
    """</span>
    <span class="hljs-keyword">for</span> entry in bundle_json.get(<span class="hljs-string">"entry"</span>, []):
        resource = entry.get(<span class="hljs-string">"resource"</span>, {})
        <span class="hljs-keyword">if</span> resource.get(<span class="hljs-string">"resourceType"</span>) == <span class="hljs-string">"DocumentReference"</span>:
            # Traverse to the attachment
            content_list = resource.get(<span class="hljs-string">"content"</span>, [])
            <span class="hljs-keyword">if</span> not content_list:
                <span class="hljs-keyword">continue</span>
            attachment = content_list[<span class="hljs-number">0</span>].get(<span class="hljs-string">"attachment"</span>, {})
            base64_data = attachment.get(<span class="hljs-string">"data"</span>)
            <span class="hljs-keyword">if</span> base64_data:
                decoded_text = base64.b64decode(base64_data).decode(<span class="hljs-string">"utf-8"</span>)
                <span class="hljs-keyword">return</span> decoded_text
    <span class="hljs-keyword">return</span> None


# Example usage
# Load your FHIR Bundle JSON from a file or object
#with <span class="hljs-keyword">open</span>(<span class="hljs-string">"fhir_bundle.json"</span>, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> f:
#    fhir_bundle = json.loads(f)
<span class="hljs-keyword">if</span> fhirbundle==<span class="hljs-string">""</span>:
    rtstr=f<span class="hljs-string">"&#x26a0;&#xfe0f; No input found - JSON string is required."</span>
    jsstr={<span class="hljs-string">"operation_outcome"</span> : rtstr}
    <span class="hljs-keyword">return</span> json.dumps(jsstr, indent=<span class="hljs-number">2</span>)

fhir_bundle = json.loads(fhirbundle)
decoded_note = decode_discharge_summary(fhir_bundle)

<span class="hljs-keyword">if</span> decoded_note:
    #<span class="hljs-keyword">print</span>(<span class="hljs-string">"&#x1f4dd; Decoded Discharge Summary:\n"</span>)
    #<span class="hljs-keyword">print</span>(decoded_note)
    rtstr=f<span class="hljs-string">"&#x1f4dd; Decoded Discharge Summary:\n {decoded_note}"</span>
<span class="hljs-keyword">else</span>:
    #<span class="hljs-keyword">print</span>(<span class="hljs-string">"&#x26a0;&#xfe0f; No DocumentReference with Base64 note found."</span>)
    rtstr=f<span class="hljs-string">"&#x26a0;&#xfe0f; No DocumentReference with Base64 note found."</span>
jsstr={<span class="hljs-string">"data"</span> : rtstr}
<span class="hljs-keyword">return</span> json.dumps(jsstr, indent=<span class="hljs-number">2</span>)

}

}

Pour tester cette fonction, j' essaie une astuce qui consiste à utiliser la fonction genfhirbundle pour générer un paquet FHIR dans une chaîne JSON,  comme expliqué dans l'article précédent Comment écrire un service API REST pour exporter le paquet FHIR généré au format JSON 

Générons un paquet FHIR et stockons-le dans une variable jsonstr

set jsonstr=##class(datagen.utli.genfhirjson).genfhirbundle(1)

Testons la fonction de décodage decodebase64docref  avec jsonstr

w##class(datagen.utli.decodefhirjson).decodebase64docref(jsonstr)

Bien 😉 Ça semble correct. Je peux désormais lire le message décodé.


Maintenant,  revenez à l'article précédent Comment écrire un service API REST pour exporter les données patient générées au format .csv

Nous aimerions ajouter une nouvelle fonction et mettre à jour le chemin d'accès pour la classe datagen.restservice .

1. Ajoutez une nouvelle fonction DecodeDocRef, qui est censée traiter le paquet FHIR  joint dans le corps au format JSON.

Par exemple, dans ce cas, nous prévoyons un POST.

Le contenu du corps est packagé par défaut sous la forme %CSP.BinaryStream et stocké dans la variable %request.Content, nous pouvons donc utiliser la fonction .Read()  à partir de la classe %CSP.BinaryStream pour lire le BinaryStream

ClassMethod DecodeDocRef() As%Status
{
    // récupération du corps - chaîne json#dim bistream As%CSP.BinaryStream =""set bistream=%request.Contentset jsstr=bistream.Read()
<span class="hljs-comment">//décodage des données de référence du document</span>
<span class="hljs-keyword">w</span> <span class="hljs-keyword">##class</span>(datagen.utli.decodefhirjson).decodebase64docref(jsstr)
<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>

}

2. Ensuite, nous ajoutons un chemin d'accès pour le service REST et compilons😀

<Route Url="/decode/docref" Method="POST" Call="DecodeDocRef" />

La classe  datagen.restservice mise à jour se présentera comme suit.


Génial!! C'est tout ce qu'il y a à faire!😁

Nous allons vérifier cela dans Postman!!

COLLEZ le chemin d'accès  suivant

localhost/irishealth/csp/mpapp/decode/docref

avec le corps suivant (j'ai utilisé un paquet FHIR simplifié, vous pouvez tester le paquet complet😀)

{
    "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"
            }
        }
    ]
}

Ça marche parfaitement!!!😆😉

Merci infiniment à tous d'avoir pris le temps de lire cet article. 😘