Written by

Sales Engineer at InterSystems
Article Kate Lau Β· Oct 9 6m read

Writing a REST api service for exporting the generated patient data in .csv

Hi,

It's me again😁, recently I am working on generating some fake patient data for testing purpose with the help of Chat-GPT by using Python. And, at the same time I would like to share my learning curve.πŸ˜‘

1st of all for building a custom REST api service is easy by extending the %CSP.REST

Creating a REST Service Manually

Let's Start !πŸ˜‚

1. Create a class datagen.restservice which extends  %CSP.REST 

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";
}

 

2. Add a function genpatientcsv() to generate the patient data, and package it into csv string

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";ClassMethod genpatientcsv() As%String [ Language = python ]
{
    # w##class(datagen.restservice).genpatientcsv()
    # python.exe -m pip install faker
    # python.exe -m pip install pandas

    from faker import Faker
    import random
    import pandas as pd
    from io import StringIO

    # Initialize Faker
    fake = Faker()

    def generate_patient(patient_id):
        return {
            "PatientID": patient_id,
            "Name": fake.name(),
            "Gender": random.choice(["Male", "Female"]),
            "DOB": fake.date_of_birth(minimum_age=0, maximum_age=100).strftime("%Y-%m-%d"),
            "City": fake.city(),
            "Phone": fake.phone_number(),
            "Email": fake.email(),
            "BloodType": random.choice(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]),
            "Diagnosis": random.choice(["Hypertension", "Diabetes", "Asthma", "Healthy", "Flu"]),
            "Height_cm": round(random.uniform(140, 200), 1),
            "Weight_kg": round(random.uniform(40, 120), 1),
        }

    # Generate 10 patients
    patients = [generate_patient(i) for i in range(1, 11)]

    # Convert to DataFrame
    df = pd.DataFrame(patients)

    # Convert to CSV string (without saving to file)
    csv_buffer = StringIO()
    df.to_csv(csv_buffer, index=False)
    csv_string = csv_buffer.getvalue()

    return csv_string
}
}

you may test the function in the terminal by typing

w##class(datagen.restservice).genpatientcsv()

3. Add a function GetMyDataCSV() in Python for populating the csv string as a csv file and then output through the REST api service. This can be achieve by,
   3.1. calling the patient data generate function to get the csv string
   3.2. set the %response.ContentType = "text/csv"
   3.3. set the header "Content-Disposition" value to "attachment; filename=mydata.csv"
   3.4.  write the generated csv string as output

remember to pip install the related libraries

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";ClassMethod GetMyDataCSV() As%Status
{
    // Build CSV stringSet tCSVString = ##class(datagen.restservice).genpatientcsv()

    //Set headers and output CSVSet%response.ContentType = "text/csv"Do%response.SetHeader("Content-Disposition","attachment; filename=mydata.csv")
    
    // Output the dataW tCSVString

    Quit$$$OK
}

ClassMethod genpatientcsv() As%String [ Language = python ]
{
    # w##class(datagen.restservice).genpatientcsv()
    # python.exe -m pip install faker
    # python.exe -m pip install pandas

    from faker import Faker
    import random
    import pandas as pd
    from io import StringIO

    # Initialize Faker
    fake = Faker()

    def generate_patient(patient_id):
        return {
            "PatientID": patient_id,
            "Name": fake.name(),
            "Gender": random.choice(["Male", "Female"]),
            "DOB": fake.date_of_birth(minimum_age=0, maximum_age=100).strftime("%Y-%m-%d"),
            "City": fake.city(),
            "Phone": fake.phone_number(),
            "Email": fake.email(),
            "BloodType": random.choice(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]),
            "Diagnosis": random.choice(["Hypertension", "Diabetes", "Asthma", "Healthy", "Flu"]),
            "Height_cm": round(random.uniform(140, 200), 1),
            "Weight_kg": round(random.uniform(40, 120), 1),
        }

    # Generate 10 patients
    patients = [generate_patient(i) for i in range(1, 11)]

    # Convert to DataFrame
    df = pd.DataFrame(patients)

    # Convert to CSV string (without saving to file)
    csv_buffer = StringIO()
    df.to_csv(csv_buffer, index=False)
    csv_string = csv_buffer.getvalue()

    return csv_string
}
}

4. Add the route to this function and compile the class

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";
XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
        <Route Url="/export/patientdata" Method="GET" Call="GetMyDataCSV"/>
</Routes>
}

ClassMethod GetMyDataCSV() As%Status
{
    // Build CSV stringSet tCSVString = ##class(datagen.restservice).genpatientcsv()

    //Set headers and output CSVSet%response.ContentType = "text/csv"Do%response.SetHeader("Content-Disposition","attachment; filename=mydata.csv")
    
    // Output the dataW tCSVString

    Quit$$$OK
}

ClassMethod genpatientcsv() As%String [ Language = python ]
{
    # w##class(datagen.restservice).genpatientcsv()
    # python.exe -m pip install faker
    # python.exe -m pip install pandas

    from faker import Faker
    import random
    import pandas as pd
    from io import StringIO

    # Initialize Faker
    fake = Faker()

    def generate_patient(patient_id):
        return {
            "PatientID": patient_id,
            "Name": fake.name(),
            "Gender": random.choice(["Male", "Female"]),
            "DOB": fake.date_of_birth(minimum_age=0, maximum_age=100).strftime("%Y-%m-%d"),
            "City": fake.city(),
            "Phone": fake.phone_number(),
            "Email": fake.email(),
            "BloodType": random.choice(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]),
            "Diagnosis": random.choice(["Hypertension", "Diabetes", "Asthma", "Healthy", "Flu"]),
            "Height_cm": round(random.uniform(140, 200), 1),
            "Weight_kg": round(random.uniform(40, 120), 1),
        }

    # Generate 10 patients
    patients = [generate_patient(i) for i in range(1, 11)]

    # Convert to DataFrame
    df = pd.DataFrame(patients)

    # Convert to CSV string (without saving to file)
    csv_buffer = StringIO()
    df.to_csv(csv_buffer, index=False)
    csv_string = csv_buffer.getvalue()

    return csv_string
}
}

 

OK, now our code is ready. πŸ˜ The next thing is to add the REST service to the web application

Input your Path, Namespace, and Rest service class name, and then Save

Assign the proper application role to this web application (because I am lazy, I just simply assign %All for testing 🀐)

OK everything is ready!!😁 Let's test the REST api!!!πŸ˜‚

Input the following path in a bowser

http://localhost/irishealth/csp/mpapp/export/patientdata

It trigger a file download, the file name is mydata.csvπŸ˜—

Let's check the file πŸ˜Š

Yeah!!! Work well!! πŸ˜πŸ˜

Thank you so much for the reading. πŸ˜‰

Comments

Vachan C Rannore Β· Oct 10

Hi Kate, I really enjoyed reading your article, it is beautifully written!

I’m curious to know: how and where did you install the dependencies like Faker, pandas, and random?

0
Kate Lau  Oct 10 to Vachan C Rannore

I think the 1st step is install python on the sever, where the IRIS instant on
Then, make sure the python runtime is properly config 
Use the Flexible Python Runtime Feature for IRIS on Windows Server

The  open a console or powershell of the server to install the python library

for example
python -m pip install faker
python -m pip install pandas
python -m pip install random

0
Vachan C Rannore  Oct 10 to Kate Lau

Great! That's another wonderful article written. Thanks! 

0