Search code examples
packagecommand-line-interfacehl7-fhirhapi

HAPI FHIR: loading an entire package to server


I just read through the docs but can't seem to find a way to load an entire package to a HAPI-FHIR server. I was sure the hapi-fhir-cli client would have such an option but all I see is the ability to create a package.

I want to load a whole Core FHIR package (e.g., us-core, il-core etc.). I find it hard to believe I will have to load hundreds of files one by one every time a new version comes out. Been googling for a couple of hours but at some moment you have to accept that your wasting time.

Any help would be appreciated. Thanks!


Solution

  • After hours of searching I've come to understand that there is no such solution to date that allows one to keep the server up and running. So instead, let me offer the solution of loading all resources one by one live via a python script I wrote. It's probably not optimized, as I am only a very mediocre programmer (even that' s a bit of a stretch). Obviously, set your own endpoint and path. You will need the hapi-fhir-cli JAR file for this:

    import json
    import os
    import sys
    import requests
    
    path = 'C:/{path/to/folder/}'
    endpoint = {server_url}
    for filename in os.listdir(path):
        if filename.endswith('.json'):
            if filename.startswith("CodeSystem"):
                continue
            filepath = os.path.join(path, filename)
            with open(filepath, 'r', encoding='utf-8') as f:
                json_data = json.load(f)
                resource_type = json_data.get("resourceType", None)
                resource_id = json_data.get("id", None)
                if resource_type is not None and resource_id is not None and resource_type != "ImplementationGuide":
                    url = f"{end_point}/fhir/{resource_type}/{resource_id}"
                    headers = {'Content-type': 'application/fhir+json'}
                    r = requests.put(url, json=json_data, headers=headers)
                    if (r.status_code == 400):
                        print(filename, " ", resource_type)
                    print(r.status_code, " ", resource_type, " ", resource_id)
                else:
                    if resource_type is None:
                        print("resourceType not found in json")
                    if resource_id is None:
                        print("resource id not found in json")
    

    Uploading CodeSystems(CS) is messier and requires a CSV for each CS and a JSON, both being zipped in a specific format and specific naming. Wrote a separate program for that, though obviously I could combine the two. Take this only as a guide. Also, make sure python has permissions to write and delete files in the chosen folder.

    import json
    import csv
    import os
    import requests
    import zipfile
    
    rootdir = 'C:/path/to/folder/'
    endpoint = {server_url}
    
    for subdir, dirs, files in os.walk(rootdir):
        for file in files:
            if file.startswith("CodeSystem"):
                with open(os.path.join(subdir, file), 'r', encoding='utf-8-sig') as json_file:
                    data = json.load(json_file)
                    url = data["url"]
                    with open("CodeSystem.json", "w", encoding='utf-8-sig') as outfile:
                        json.dump(data, outfile)
                    with open("concepts.csv", "w", newline='', encoding='utf-8-sig') as f:
                        csv_writer = csv.writer(f)
                        csv_writer.writerow(["CODE", "DISPLAY"])
                        for concept in data["concept"]:
                            code = concept["code"]
                            display = concept["display"]
                            csv_writer.writerow([code, display])
                    with zipfile.ZipFile("resources.zip", 'w', zipfile.ZIP_DEFLATED) as myzip:
                        myzip.write("CodeSystem.json")
                        myzip.write("concepts.csv")
                    os.system(f'hapi-fhir-cli upload-terminology -d resources.zip -u {url} -t {end_point}/fhir -v r4')
                    os.remove("CodeSystem.json")
                    os.remove("concepts.csv")
                    os.remove("resources.zip")