Tonic commited on
Commit
5372c12
·
unverified ·
1 Parent(s): 161443d

add callback manager , model app

Browse files
README.md CHANGED
@@ -5,7 +5,7 @@ colorFrom: gray
5
  colorTo: pink
6
  sdk: gradio
7
  sdk_version: 5.19.0
8
- app_file: app.py
9
  pinned: false
10
  license: mit
11
  short_description: Provides guardrails and discharge summaries with compliance
 
5
  colorTo: pink
6
  sdk: gradio
7
  sdk_version: 5.19.0
8
+ app_file: callbackmanager.py
9
  pinned: false
10
  license: mit
11
  short_description: Provides guardrails and discharge summaries with compliance
__pycache__/meldrx.cpython-312.pyc ADDED
Binary file (12.6 kB). View file
 
callbackmanager.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from meldrx import MeldRxAPI
3
+ import json
4
+
5
+ # CallbackManager class to handle OAuth callbacks
6
+ class CallbackManager:
7
+ def __init__(self, client_id: str, redirect_uri: str, workspace_id: str, client_secret: str = None):
8
+ """
9
+ Initialize the CallbackManager with MeldRx API credentials.
10
+
11
+ Args:
12
+ client_id (str): The client ID from MeldRx Developer Portal.
13
+ redirect_uri (str): The redirect URI for the Gradio app (e.g., Space URL + /callback).
14
+ workspace_id (str): The workspace slug/ID.
15
+ client_secret (str, optional): The client secret (for confidential clients).
16
+ """
17
+ self.api = MeldRxAPI(client_id, redirect_uri, workspace_id, client_secret)
18
+ self.auth_code = None
19
+ self.access_token = None
20
+
21
+ def get_auth_url(self) -> str:
22
+ """Generate and return the SMART on FHIR authorization URL."""
23
+ return self.api.get_authorization_url()
24
+
25
+ def set_auth_code(self, code: str) -> str:
26
+ """Set the authorization code and attempt to get an access token."""
27
+ self.auth_code = code
28
+ if self.api.authenticate_with_code(code):
29
+ self.access_token = self.api.access_token
30
+ return f"Authentication successful! Access Token: {self.access_token[:10]}... (truncated)"
31
+ return "Authentication failed. Please check the code."
32
+
33
+ def get_patient_data(self) -> str:
34
+ """Retrieve patient data using the access token."""
35
+ if not self.access_token:
36
+ return "Not authenticated. Please provide a valid authorization code first."
37
+ patients = self.api.get_patients()
38
+ if patients is not None:
39
+ return json.dumps(patients, indent=2) if patients else "No patient data returned."
40
+ return "Failed to retrieve patient data."
41
+
42
+ # Discharge form display function
43
+ def display_form(
44
+ first_name, last_name, middle_initial, dob, age, sex, address, city, state, zip_code,
45
+ doctor_first_name, doctor_last_name, doctor_middle_initial, hospital_name, doctor_address,
46
+ doctor_city, doctor_state, doctor_zip,
47
+ admission_date, referral_source, admission_method, discharge_date, discharge_reason, date_of_death,
48
+ diagnosis, procedures, medications, preparer_name, preparer_job_title
49
+ ):
50
+ form = f"""
51
+ **Patient Discharge Form**
52
+
53
+ **Patient Details:**
54
+ - Name: {first_name} {middle_initial} {last_name}
55
+ - Date of Birth: {dob}, Age: {age}, Sex: {sex}
56
+ - Address: {address}, {city}, {state}, {zip_code}
57
+
58
+ **Primary Healthcare Professional Details:**
59
+ - Name: {doctor_first_name} {doctor_middle_initial} {doctor_last_name}
60
+ - Hospital/Clinic: {hospital_name}
61
+ - Address: {doctor_address}, {doctor_city}, {doctor_state}, {doctor_zip}
62
+
63
+ **Admission and Discharge Details:**
64
+ - Date of Admission: {admission_date}
65
+ - Source of Referral: {referral_source}
66
+ - Method of Admission: {admission_method}
67
+ - Date of Discharge: {discharge_date}
68
+ - Discharge Reason: {discharge_reason}
69
+ - Date of Death (if applicable): {date_of_death}
70
+
71
+ **Diagnosis & Procedures:**
72
+ - Diagnosis: {diagnosis}
73
+ - Procedures: {procedures}
74
+
75
+ **Medication Details:**
76
+ - Medications on Discharge: {medications}
77
+
78
+ **Prepared By:**
79
+ - Name: {preparer_name}, Job Title: {preparer_job_title}
80
+ """
81
+ return form
82
+
83
+ # Initialize CallbackManager with your credentials
84
+ CALLBACK_MANAGER = CallbackManager(
85
+ client_id="your_client_id", # Replace with actual client ID
86
+ redirect_uri="https://multitransformer-discharge-guard.hf.space/callback",
87
+ workspace_id="your_workspace_id", # Replace with actual workspace ID
88
+ client_secret=None # Replace with actual secret if using a confidential client
89
+ )
90
+
91
+ # Gradio interface
92
+ with gr.Blocks() as demo:
93
+ gr.Markdown("# Patient Discharge Form with MeldRx Integration")
94
+
95
+ # Authentication Section
96
+ with gr.Tab("Authenticate with MeldRx"):
97
+ gr.Markdown("## SMART on FHIR Authentication")
98
+ auth_url_output = gr.Textbox(label="Authorization URL", value=CALLBACK_MANAGER.get_auth_url(), interactive=False)
99
+ gr.Markdown("Copy the URL above, open it in a browser, log in, and paste the 'code' from the redirect URL below.")
100
+ auth_code_input = gr.Textbox(label="Authorization Code")
101
+ auth_submit = gr.Button("Submit Code")
102
+ auth_result = gr.Textbox(label="Authentication Result")
103
+ patient_data_button = gr.Button("Fetch Patient Data")
104
+ patient_data_output = gr.Textbox(label="Patient Data")
105
+
106
+ auth_submit.click(
107
+ fn=CALLBACK_MANAGER.set_auth_code,
108
+ inputs=auth_code_input,
109
+ outputs=auth_result
110
+ )
111
+ patient_data_button.click(
112
+ fn=CALLBACK_MANAGER.get_patient_data,
113
+ inputs=None,
114
+ outputs=patient_data_output
115
+ )
116
+
117
+ # Discharge Form Section
118
+ with gr.Tab("Discharge Form"):
119
+ gr.Markdown("## Patient Details")
120
+ with gr.Row():
121
+ first_name = gr.Textbox(label="First Name")
122
+ last_name = gr.Textbox(label="Last Name")
123
+ middle_initial = gr.Textbox(label="Middle Initial")
124
+
125
+ with gr.Row():
126
+ dob = gr.Textbox(label="Date of Birth")
127
+ age = gr.Textbox(label="Age")
128
+ sex = gr.Textbox(label="Sex")
129
+
130
+ address = gr.Textbox(label="Address")
131
+ with gr.Row():
132
+ city = gr.Textbox(label="City")
133
+ state = gr.Textbox(label="State")
134
+ zip_code = gr.Textbox(label="Zip Code")
135
+
136
+ gr.Markdown("## Primary Healthcare Professional Details")
137
+ with gr.Row():
138
+ doctor_first_name = gr.Textbox(label="Doctor's First Name")
139
+ doctor_last_name = gr.Textbox(label="Doctor's Last Name")
140
+ doctor_middle_initial = gr.Textbox(label="Middle Initial")
141
+
142
+ hospital_name = gr.Textbox(label="Hospital/Clinic Name")
143
+ doctor_address = gr.Textbox(label="Address")
144
+ with gr.Row():
145
+ doctor_city = gr.Textbox(label="City")
146
+ doctor_state = gr.Textbox(label="State")
147
+ doctor_zip = gr.Textbox(label="Zip Code")
148
+
149
+ gr.Markdown("## Admission and Discharge Details")
150
+ with gr.Row():
151
+ admission_date = gr.Textbox(label="Date of Admission")
152
+ referral_source = gr.Textbox(label="Source of Referral")
153
+
154
+ admission_method = gr.Textbox(label="Method of Admission")
155
+ with gr.Row():
156
+ discharge_date = gr.Textbox(label="Date of Discharge")
157
+ discharge_reason = gr.Radio(["Treated", "Transferred", "Discharge Against Advice", "Patient Died"], label="Discharge Reason")
158
+
159
+ date_of_death = gr.Textbox(label="Date of Death (if applicable)")
160
+
161
+ gr.Markdown("## Diagnosis & Procedures")
162
+ diagnosis = gr.Textbox(label="Diagnosis")
163
+ procedures = gr.Textbox(label="Operation & Procedures")
164
+
165
+ gr.Markdown("## Medication Details")
166
+ medications = gr.Textbox(label="Medication on Discharge")
167
+
168
+ gr.Markdown("## Prepared By")
169
+ with gr.Row():
170
+ preparer_name = gr.Textbox(label="Name")
171
+ preparer_job_title = gr.Textbox(label="Job Title")
172
+
173
+ submit = gr.Button("Generate Form")
174
+ output = gr.Markdown()
175
+
176
+ submit.click(
177
+ display_form,
178
+ inputs=[
179
+ first_name, last_name, middle_initial, dob, age, sex, address, city, state, zip_code,
180
+ doctor_first_name, doctor_last_name, doctor_middle_initial, hospital_name, doctor_address,
181
+ doctor_city, doctor_state, doctor_zip,
182
+ admission_date, referral_source, admission_method, discharge_date, discharge_reason, date_of_death,
183
+ diagnosis, procedures, medications, preparer_name, preparer_job_title
184
+ ],
185
+ outputs=output
186
+ )
187
+
188
+ demo.launch()
commandr.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import InferenceClient
2
+
3
+ client = InferenceClient(api_key="YOUR_HF_TOKEN")
4
+
5
+ messages = [
6
+ { "role": "user", "content": "you are a senior expert medical health practitioner known for their abilities to decide on clinical discharge . you will recieve a clinical case study for a fictional patient. you should respond with the following model { \"response\" : { \"discharge\" : True/False } } if the patient should be discharged or not. produce only your final answer:\n\nPatient Name: Patient 2 \nGender: Female \nAge: 72 years \n\n### Presentation and Diagnosis: \nThe patient presented to the emergency department in October 2024 with complaints of progressive shortness of breath, fatigue, and bilateral lower extremity edema persisting for three weeks. Initial evaluation revealed tachycardia, hypoxia (SpO2 88% on room air), and elevated blood pressure (168/94 mmHg). Laboratory findings demonstrated elevated brain natriuretic peptide (BNP) at 1,200 pg/mL, creatinine of 2.1 mg/dL (baseline 1.0 mg/dL), and a troponin I of 0.08 ng/mL. Chest X-ray showed bilateral pleural effusions and pulmonary congestion. An echocardiogram revealed a left ventricular ejection fraction (LVEF) of 25%, severe mitral regurgitation, and elevated pulmonary artery pressure (55 mmHg). Electrocardiogram (ECG) indicated sinus rhythm with left bundle branch block. The patient was diagnosed with acute decompensated heart failure (ADHF) secondary to ischemic cardiomyopathy, with concurrent stage IIIb chronic kidney disease (CKD) identified based on estimated glomerular filtration rate (eGFR) of 35 mL/min/1.73m². Coronary angiography performed subsequently confirmed triple-vessel coronary artery disease (CAD) with no immediate indication for revascularization due to high procedural risk.\n\n### Hospital Course: \nThe patient was admitted to the cardiac care unit (CCU) and initiated on intravenous furosemide (40 mg IV twice daily) and supplemental oxygen via nasal cannula. Nitroglycerin infusion was started for preload reduction but was discontinued after 24 hours due to hypotension (systolic BP dropping to 85 mmHg). She was transitioned to oral guideline-directed medical therapy (GDMT), including carvedilol (3.125 mg twice daily), sacubitril/valsartan (24/26 mg twice daily), and spironolactone (25 mg daily), with doses titrated cautiously due to renal impairment and borderline blood pressure. Despite initial improvement in dyspnea and reduction in edema, the patient developed worsening renal function (creatinine peaked at 2.8 mg/dL, eGFR 25 mL/min/1.73m²) by hospital day 5, prompting a temporary hold on diuretics and angiotensin receptor-neprilysin inhibitor (ARNI) therapy. Nephrology was consulted, and ultrafiltration was initiated for volume overload management, achieving a net fluid removal of 4 liters over 72 hours. \n\nBy hospital day 10, the patient stabilized hemodynamically (BP 110/70 mmHg, SpO2 94% on 2L oxygen), but attempts to wean oxygen supplementation resulted in recurrent hypoxia. Repeat echocardiography showed persistent LVEF of 25% with no improvement in mitral regurgitation. A multidisciplinary team discussion concluded that the patient’s advanced heart failure, compounded by CKD and frailty (Clinical Frailty Scale score of 6), precluded discharge to home. She was deemed high-risk for outpatient management due to recurrent decompensation risk, frequent monitoring needs, and inability to tolerate optimal GDMT dosing. A trial of inotropic support with dobutamine (2.5 mcg/kg/min) was initiated on hospital day 14 to improve cardiac output, with partial symptomatic relief but no significant change in LVEF or renal function. \n\nOn hospital day 20, the patient developed a hospital-acquired pneumonia, confirmed by chest X-ray (right lower lobe consolidation) and sputum culture positive for *Klebsiella pneumoniae*. She was started on piperacillin-tazobactam (adjusted for renal function), but her respiratory status deteriorated, requiring escalation to high-flow nasal cannula (HFNC) at 40 L/min with FiO2 of 60%. Infectious disease and pulmonology consultations recommended a 10-day antibiotic course and supportive care, but the patient’s frailty and poor cardiac reserve limited recovery. By hospital day 30, she remained oxygen-dependent, with persistent volume overload and worsening renal function (creatinine 3.2 mg/dL, eGFR 20 mL/min/1.73m²), necessitating ongoing ultrafiltration and inotropic support.\n\n### Current Status: \nAs of February 28, 2025, the patient remains hospitalized in a step-down unit, unable to be discharged due to chronic dependence on inotropic therapy (dobutamine 2.5 mcg/kg/min) and supplemental oxygen (HFNC at 30 L/min, FiO2 50%). Her advanced heart failure, compounded by recurrent infections, severe CKD, and poor functional status, renders her ineligible for home care or transfer to a lower-acuity facility. Palliative care has been engaged to discuss goals of care, but the patient and family have declined hospice transition, opting for continued aggressive management. She experiences intermittent dyspnea at rest, fatigue, and fluctuating mental status (likely due to hypoperfusion and medication effects), requiring constant nursing supervision. Long-term plans include evaluation for potential left ventricular assist device (LVAD) candidacy, though her comorbidities and frailty pose significant barriers." },
7
+ # { "role": "assistant", "content": "{\n \"response\": {\n \"discharge\": false\n }\n}" }
8
+ ]
9
+
10
+ stream = client.chat.completions.create(
11
+ model="CohereForAI/c4ai-command-r-plus-08-2024",
12
+ messages=messages,
13
+ temperature=0.4,
14
+ max_tokens=1280,
15
+ top_p=0.7,
16
+ stream=True
17
+ )
18
+
19
+ for chunk in stream:
20
+ print(chunk.choices[0].delta.content)
hospital.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ def display_form(
4
+ first_name, last_name, middle_initial, dob, age, sex, address, city, state, zip_code,
5
+ doctor_first_name, doctor_last_name, doctor_middle_initial, hospital_name, doctor_address,
6
+ doctor_city, doctor_state, doctor_zip,
7
+ admission_date, referral_source, admission_method, discharge_date, discharge_reason, date_of_death,
8
+ diagnosis, procedures, medications, preparer_name, preparer_job_title
9
+ ):
10
+ form = f"""
11
+ **Patient Discharge Form**
12
+
13
+ **Patient Details:**
14
+ - Name: {first_name} {middle_initial} {last_name}
15
+ - Date of Birth: {dob}, Age: {age}, Sex: {sex}
16
+ - Address: {address}, {city}, {state}, {zip_code}
17
+
18
+ **Primary Healthcare Professional Details:**
19
+ - Name: {doctor_first_name} {doctor_middle_initial} {doctor_last_name}
20
+ - Hospital/Clinic: {hospital_name}
21
+ - Address: {doctor_address}, {doctor_city}, {doctor_state}, {doctor_zip}
22
+
23
+ **Admission and Discharge Details:**
24
+ - Date of Admission: {admission_date}
25
+ - Source of Referral: {referral_source}
26
+ - Method of Admission: {admission_method}
27
+ - Date of Discharge: {discharge_date}
28
+ - Discharge Reason: {discharge_reason}
29
+ - Date of Death (if applicable): {date_of_death}
30
+
31
+ **Diagnosis & Procedures:**
32
+ - Diagnosis: {diagnosis}
33
+ - Procedures: {procedures}
34
+
35
+ **Medication Details:**
36
+ - Medications on Discharge: {medications}
37
+
38
+ **Prepared By:**
39
+ - Name: {preparer_name}, Job Title: {preparer_job_title}
40
+ """
41
+ return form
42
+
43
+ with gr.Blocks() as demo:
44
+ gr.Markdown("# Patient Discharge Form")
45
+
46
+ with gr.Row():
47
+ first_name = gr.Textbox(label="First Name")
48
+ last_name = gr.Textbox(label="Last Name")
49
+ middle_initial = gr.Textbox(label="Middle Initial")
50
+
51
+ with gr.Row():
52
+ dob = gr.Textbox(label="Date of Birth")
53
+ age = gr.Textbox(label="Age")
54
+ sex = gr.Textbox(label="Sex")
55
+
56
+ address = gr.Textbox(label="Address")
57
+
58
+ with gr.Row():
59
+ city = gr.Textbox(label="City")
60
+ state = gr.Textbox(label="State")
61
+ zip_code = gr.Textbox(label="Zip Code")
62
+
63
+ gr.Markdown("## Primary Healthcare Professional Details")
64
+
65
+ with gr.Row():
66
+ doctor_first_name = gr.Textbox(label="Doctor's First Name")
67
+ doctor_last_name = gr.Textbox(label="Doctor's Last Name")
68
+ doctor_middle_initial = gr.Textbox(label="Middle Initial")
69
+
70
+ hospital_name = gr.Textbox(label="Hospital/Clinic Name")
71
+ doctor_address = gr.Textbox(label="Address")
72
+
73
+ with gr.Row():
74
+ doctor_city = gr.Textbox(label="City")
75
+ doctor_state = gr.Textbox(label="State")
76
+ doctor_zip = gr.Textbox(label="Zip Code")
77
+
78
+ gr.Markdown("## Admission and Discharge Details")
79
+
80
+ with gr.Row():
81
+ admission_date = gr.Textbox(label="Date of Admission")
82
+ referral_source = gr.Textbox(label="Source of Referral")
83
+
84
+ admission_method = gr.Textbox(label="Method of Admission")
85
+
86
+ with gr.Row():
87
+ discharge_date = gr.Textbox(label="Date of Discharge")
88
+ discharge_reason = gr.Radio(["Treated", "Transferred", "Discharge Against Advice", "Patient Died"], label="Discharge Reason")
89
+
90
+ date_of_death = gr.Textbox(label="Date of Death (if applicable)")
91
+
92
+ gr.Markdown("## Diagnosis & Procedures")
93
+ diagnosis = gr.Textbox(label="Diagnosis")
94
+ procedures = gr.Textbox(label="Operation & Procedures")
95
+
96
+ gr.Markdown("## Medication Details")
97
+ medications = gr.Textbox(label="Medication on Discharge")
98
+
99
+ gr.Markdown("## Prepared By")
100
+
101
+ with gr.Row():
102
+ preparer_name = gr.Textbox(label="Name")
103
+ preparer_job_title = gr.Textbox(label="Job Title")
104
+
105
+ submit = gr.Button("Generate Form")
106
+ output = gr.Markdown()
107
+
108
+ submit.click(
109
+ display_form,
110
+ inputs=[
111
+ first_name, last_name, middle_initial, dob, age, sex, address, city, state, zip_code,
112
+ doctor_first_name, doctor_last_name, doctor_middle_initial, hospital_name, doctor_address,
113
+ doctor_city, doctor_state, doctor_zip,
114
+ admission_date, referral_source, admission_method, discharge_date, discharge_reason, date_of_death,
115
+ diagnosis, procedures, medications, preparer_name, preparer_job_title
116
+ ],
117
+ outputs=output
118
+ )
119
+
120
+ demo.launch()
interfacehospital.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ def display_discharge_form(
4
+ patient_first, patient_last, patient_middle, dob, age, sex, address, city, state, zip_code,
5
+ doctor_first, doctor_last, doctor_middle, hospital, doctor_address, doctor_city, doctor_state, doctor_zip,
6
+ admission_date, referral_source, admission_method, discharge_date, discharge_reason, death_date,
7
+ diagnosis, procedures, medications, preparer_name, job_title, signature
8
+ ):
9
+
10
+ form = f"""
11
+ **Patient Details:**
12
+ - **Name:** {patient_first} {patient_middle} {patient_last}
13
+ - **Date of Birth:** {dob}, **Age:** {age}, **Sex:** {sex}
14
+ - **Address:** {address}, {city}, {state} {zip_code}
15
+
16
+ **Primary Healthcare Professional Details:**
17
+ - **Name:** {doctor_first} {doctor_middle} {doctor_last}
18
+ - **Hospital/Clinic:** {hospital}
19
+ - **Address:** {doctor_address}, {doctor_city}, {doctor_state} {doctor_zip}
20
+
21
+ **Admission and Discharge Details:**
22
+ - **Date of Admission:** {admission_date}
23
+ - **Source of Referral:** {referral_source}
24
+ - **Method of Admission:** {admission_method}
25
+ - **Date of Discharge:** {discharge_date}
26
+ - **Discharge Reason:** {discharge_reason}
27
+ - **Date of Death:** {death_date if discharge_reason == 'Patient Died' else 'N/A'}
28
+
29
+ **Diagnosis & Procedures:**
30
+ - **Diagnosis:** {diagnosis}
31
+ - **Operations & Procedures:** {procedures}
32
+
33
+ **Medication Details:**
34
+ - **Medication on Discharge:** {medications}
35
+
36
+ **Prepared By:**
37
+ - **Name:** {preparer_name}, **Job Title:** {job_title}
38
+ - **Signature:** {signature}
39
+ """
40
+ return form
41
+
42
+ discharge_interface = gr.Interface(
43
+ fn=display_discharge_form,
44
+ inputs=[
45
+ gr.Textbox(label="Patient First Name"), gr.Textbox(label="Patient Last Name"), gr.Textbox(label="Patient Middle Initial"),
46
+ gr.Textbox(label="Date of Birth"), gr.Textbox(label="Age"), gr.Textbox(label="Sex"),
47
+ gr.Textbox(label="Address"), gr.Textbox(label="City"), gr.Textbox(label="State"), gr.Textbox(label="Zip Code"),
48
+ gr.Textbox(label="Doctor First Name"), gr.Textbox(label="Doctor Last Name"), gr.Textbox(label="Doctor Middle Initial"),
49
+ gr.Textbox(label="Hospital/Clinic Name"), gr.Textbox(label="Doctor Address"),
50
+ gr.Textbox(label="Doctor City"), gr.Textbox(label="Doctor State"), gr.Textbox(label="Doctor Zip Code"),
51
+ gr.Textbox(label="Date of Admission"), gr.Textbox(label="Source of Referral"), gr.Textbox(label="Method of Admission"),
52
+ gr.Textbox(label="Date of Discharge"), gr.Radio(["Treated", "Transferred", "Discharge Against Advice", "Patient Died"], label="Discharge Reason"),
53
+ gr.Textbox(label="Date of Death (if applicable)"),
54
+ gr.Textbox(label="Diagnosis"), gr.Textbox(label="Operations & Procedures"),
55
+ gr.Textbox(label="Medication on Discharge"),
56
+ gr.Textbox(label="Prepared By (Name)"), gr.Textbox(label="Job Title"), gr.Textbox(label="Signature"),
57
+ ],
58
+ outputs=gr.Markdown(),
59
+ title="Patient Discharge Form",
60
+ description="Fill in the required fields to generate a complete patient discharge summary."
61
+ )
62
+
63
+ discharge_interface.launch()
llamaprompt.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import InferenceClient
2
+
3
+ client = InferenceClient(api_key="YOUR_HF_TOKEN")
4
+
5
+ messages = [
6
+ { "role": "user", "content": "" },
7
+ { "role": "assistant", "content": "you are a senior expert medical health practitioner known for their abilities to produce discharge papers. you will recieve patient information and treatment cursus. Produce a complete discharge summary based on the information provided. produce complete discharge summary." },
8
+ { "role": "user", "content": "Patient Name: Patient 1\nGender: Male\nAge: 65 years\n\nPresentation and Diagnosis:\nThe patient was diagnosed with acute myeloid leukemia (AML) in January 2020 based on leukocytosis, thrombocytopenia and anemia. Bone marrow aspiration revealed a hypercellular bone marrow with 50% blasts. The patient was further assessed using flow cytometry and cytogenetics, and molecular panel testing showed aberrations in ASXL1, CEBPA, JAK2, and RUNX1. AML with adverse risk was diagnosed according to genetic risk stratification.\n\nHospital Course:\nAfter one course of induction treatment with the IA regimen, the patient achieved complete remission with low minimal residual disease. Genetic analyses showed negative gene mutations, and the patient received consolidation therapies with the IA regimen and high-dose Ara-c (HiDAC) regimen. However, remission duration only lasted for 11 months, and in November 2020, relapsed BM morphology was detected, indicating relapsed AML with concurrent molecular aberration recurrence. The patient underwent several treatment regimens, including venetoclax combined with azacitidine and chidamide with venetoclax and azacitidine regimen. He achieved complete remission after one course of the chidamide combined regimen.\n\nOutcome:\nThe patient passed away due to disease progression three months after the completion of therapy." },
9
+ # { "role": "assistant", "content": "**DISCHARGE SUMMARY**\n\n**Patient Name:** Patient 1\n**Gender:** Male\n**Age:** 65 years\n**Medical Record Number:** [Insert MRN]\n**Date of Admission:** [Insert Date]\n**Date of Discharge:** [Insert Date]\n**Discharge Diagnosis:**\n1. Acute Myeloid Leukemia (AML) with adverse risk\n2. Relapsed AML with molecular aberration recurrence\n\n**History of Present Illness:**\nThe patient was initially diagnosed with Acute Myeloid Leukemia (AML) in January 2020, characterized by leukocytosis, thrombocytopenia, and anemia. Bone marrow aspiration revealed a hypercellular bone marrow with 50% blasts. Further genetic and molecular testing identified aberrations in ASXL1, CEBPA, JAK2, and RUNX1, categorizing the AML as high risk.\n\n**Treatment Course:**\n- The patient underwent induction therapy with the IA regimen, achieving complete remission with minimal residual disease.\n- Consolidation therapies included the IA regimen and high-dose Ara-c (HiDAC) regimen.\n- Despite initial remission, the patient relapsed 11 months later, with detection of relapsed BM morphology and concurrent molecular aberration recurrence.\n- Subsequent treatments included venetoclax combined with azacitidine and a regimen of chidamide with venetoclax and azacitidine, with the latter resulting in complete remission.\n\n**Outcome:**\nUnfortunately, the patient's disease progressed, and he passed away three months after completing the last therapy regimen.\n\n**Discharge Condition:**\nThe patient was discharged in a terminal condition due to disease progression.\n\n**Medications at Discharge:**\n[Insert list of medications the patient was on at the time of discharge, including dosages and frequencies]\n\n**Follow-Up Care:**\nGiven the patient's demise, follow-up care was not applicable. However, the family was counseled regarding the disease progression and the options for bereavement support.\n\n**Instructions to Patient/Family:**\nAt the time of discharge, the patient and family were informed about the terminal nature of the disease and the focus was shifted to palliative care. They were provided with information on hospice care services and bereavement counseling.\n\n**Condition at Time of Discharge:**\nThe patient's condition at discharge was terminal, with evidence of disease progression despite aggressive treatment.\n\n**Certification:**\nI, [Your Name], hereby certify that the information contained in this discharge summary is accurate and complete to the best of my knowledge. I can be reached at [Your Contact Information] for any further questions or clarifications.\n\n**Signature:** [Your Signature]\n**Date:** [Current Date]\n**Title:** Senior Expert Medical Health Practitioner" }
10
+ ]
11
+
12
+ stream = client.chat.completions.create(
13
+ model="meta-llama/Llama-3.3-70B-Instruct",
14
+ messages=messages,
15
+ temperature=0.4,
16
+ max_tokens=3584,
17
+ top_p=0.7,
18
+ stream=True
19
+ )
20
+
21
+ for chunk in stream:
22
+ print(chunk.choices[0].delta.content)
meldrx.py ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ from typing import Optional, Dict, Any
4
+
5
+ class MeldRxAPI:
6
+ """
7
+ A Python class to interact with the MeldRx API, including the MIPS API.
8
+ Provides methods to authenticate, retrieve/update patients, create virtual workspaces,
9
+ and interact with encounter data.
10
+ """
11
+
12
+ def __init__(self, client_id: str, client_secret: str, workspace_id: str):
13
+ """
14
+ Initialize the MeldRxAPI class with client credentials and workspace ID.
15
+
16
+ Args:
17
+ client_id (str): The client ID (App ID) obtained from MeldRx Developer Portal.
18
+ client_secret (str): The client secret for authentication.
19
+ workspace_id (str): The workspace slug/ID to interact with.
20
+ """
21
+ self.base_url = "https://app.meldrx.com"
22
+ self.api_base_url = f"{self.base_url}/api"
23
+ self.fhir_base_url = f"{self.api_base_url}/fhir/{workspace_id}"
24
+ self.mips_base_url = f"{self.base_url}/mms-api" # MIPS API base URL
25
+ self.token_url = f"{self.base_url}/connect/token"
26
+ self.client_id = client_id
27
+ self.client_secret = client_secret
28
+ self.workspace_id = workspace_id
29
+ self.access_token = None
30
+ self.session = requests.Session()
31
+
32
+ def authenticate(self) -> bool:
33
+ """
34
+ Authenticate with the MeldRx API to obtain an access token.
35
+
36
+ Returns:
37
+ bool: True if authentication is successful, False otherwise.
38
+ """
39
+ payload = {
40
+ "grant_type": "client_credentials",
41
+ "client_id": self.client_id,
42
+ "client_secret": self.client_secret
43
+ }
44
+ headers = {"Content-Type": "application/x-www-form-urlencoded"}
45
+
46
+ try:
47
+ response = self.session.post(self.token_url, data=payload, headers=headers)
48
+ response.raise_for_status()
49
+ token_data = response.json()
50
+ self.access_token = token_data.get("access_token")
51
+ if not self.access_token:
52
+ raise ValueError("No access token received from the server.")
53
+ return True
54
+ except requests.RequestException as e:
55
+ print(f"Authentication failed: {e}")
56
+ return False
57
+ except ValueError as e:
58
+ print(f"Authentication error: {e}")
59
+ return False
60
+
61
+ def _get_headers(self) -> Dict[str, str]:
62
+ """
63
+ Generate headers with the Bearer token for authenticated requests.
64
+
65
+ Returns:
66
+ Dict[str, str]: Headers dictionary with Authorization token if available.
67
+ """
68
+ headers = {"Content-Type": "application/json"}
69
+ if self.access_token:
70
+ headers["Authorization"] = f"Bearer {self.access_token}"
71
+ return headers
72
+
73
+ def get_patients(self) -> Optional[Dict[str, Any]]:
74
+ """
75
+ Retrieve a list of patients from the specified workspace (FHIR API).
76
+
77
+ Returns:
78
+ Optional[Dict[str, Any]]: Patient data as a dictionary if successful, None otherwise.
79
+ """
80
+ url = f"{self.fhir_base_url}/Patient"
81
+
82
+ if not self.access_token and not self.authenticate():
83
+ print("Cannot proceed without authentication.")
84
+ return None
85
+
86
+ try:
87
+ response = self.session.get(url, headers=self._get_headers())
88
+ response.raise_for_status()
89
+ return response.json() if response.text else {}
90
+ except requests.RequestException as e:
91
+ print(f"Failed to retrieve patients: {e}")
92
+ return None
93
+
94
+ def get_authorization_url(self, scope: str = "patient/*.read openid profile", state: str = "random_state") -> str:
95
+ """
96
+ Generate the SMART on FHIR authorization URL for patient login.
97
+
98
+ Args:
99
+ scope (str): The requested scopes (default: patient/*.read openid profile).
100
+ state (str): A random state string for security (default: random_state).
101
+
102
+ Returns:
103
+ str: The authorization URL to open in a browser.
104
+ """
105
+ params = {
106
+ "response_type": "code",
107
+ "client_id": self.client_id,
108
+ "redirect_uri": self.redirect_uri,
109
+ "scope": scope,
110
+ "state": state,
111
+ "aud": self.fhir_base_url
112
+ }
113
+ query_string = "&".join(f"{k}={v}" for k, v in params.items())
114
+ return f"{self.authorize_url}?{query_string}"
115
+
116
+ def authenticate_with_code(self, auth_code: str) -> bool:
117
+ """
118
+ Exchange an authorization code for an access token.
119
+
120
+ Args:
121
+ auth_code (str): The authorization code from the redirect URI.
122
+
123
+ Returns:
124
+ bool: True if authentication is successful, False otherwise.
125
+ """
126
+ payload = {
127
+ "grant_type": "authorization_code",
128
+ "code": auth_code,
129
+ "redirect_uri": self.redirect_uri,
130
+ "client_id": self.client_id
131
+ }
132
+ if self.client_secret:
133
+ payload["client_secret"] = self.client_secret
134
+ headers = {"Content-Type": "application/x-www-form-urlencoded"}
135
+
136
+ try:
137
+ response = self.session.post(self.token_url, data=payload, headers=headers)
138
+ response.raise_for_status()
139
+ token_data = response.json()
140
+ self.access_token = token_data.get("access_token")
141
+ if not self.access_token:
142
+ raise ValueError("No access token received from the server.")
143
+ return True
144
+ except requests.RequestException as e:
145
+ print(f"Authentication failed: {e}")
146
+ return False
147
+ except ValueError as e:
148
+ print(f"Authentication error: {e}")
149
+ return False
150
+ def create_virtual_workspace(self, snapshot: str = "patient-prefetch",
151
+ patient_id: str = "AutoPopulatedIfNotManuallySet",
152
+ hook: str = "patient-view") -> bool:
153
+ """
154
+ Create a virtual workspace in the specified workspace (FHIR API).
155
+
156
+ Args:
157
+ snapshot (str): The snapshot type (default: "patient-prefetch").
158
+ patient_id (str): The patient ID (default: "AutoPopulatedIfNotManuallySet").
159
+ hook (str): The hook type (default: "patient-view").
160
+
161
+ Returns:
162
+ bool: True if the virtual workspace is created successfully, False otherwise.
163
+ """
164
+ url = f"{self.fhir_base_url}/$virtual-workspace"
165
+
166
+ if not self.access_token and not self.authenticate():
167
+ print("Cannot proceed without authentication.")
168
+ return False
169
+
170
+ payload = {"snapshot": snapshot, "patientId": patient_id, "hook": hook}
171
+
172
+ try:
173
+ response = self.session.post(url, data=json.dumps(payload), headers=self._get_headers())
174
+ response.raise_for_status()
175
+ return True
176
+ except requests.RequestException as e:
177
+ print(f"Failed to create virtual workspace: {e}")
178
+ return False
179
+
180
+ def get_mips_patients(self) -> Optional[Dict[str, Any]]:
181
+ """
182
+ Retrieve a list of patients from the MIPS API.
183
+
184
+ Returns:
185
+ Optional[Dict[str, Any]]: Patient data as a dictionary if successful, None otherwise.
186
+ """
187
+ url = f"{self.mips_base_url}/Patient"
188
+
189
+ if not self.access_token and not self.authenticate():
190
+ print("Cannot proceed without authentication.")
191
+ return None
192
+
193
+ try:
194
+ response = self.session.get(url, headers=self._get_headers())
195
+ response.raise_for_status()
196
+ return response.json() if response.text else {}
197
+ except requests.RequestException as e:
198
+ print(f"Failed to retrieve MIPS patients: {e}")
199
+ return None
200
+
201
+ def get_mips_patient_by_id(self, patient_id: str) -> Optional[Dict[str, Any]]:
202
+ """
203
+ Retrieve patient information by ID from the MIPS API.
204
+
205
+ Args:
206
+ patient_id (str): The ID of the patient to retrieve.
207
+
208
+ Returns:
209
+ Optional[Dict[str, Any]]: Patient data as a dictionary if successful, None otherwise.
210
+ """
211
+ url = f"{self.mips_base_url}/Patient/{patient_id}"
212
+
213
+ if not self.access_token and not self.authenticate():
214
+ print("Cannot proceed without authentication.")
215
+ return None
216
+
217
+ try:
218
+ response = self.session.get(url, headers=self._get_headers())
219
+ response.raise_for_status()
220
+ return response.json() if response.text else {}
221
+ except requests.RequestException as e:
222
+ print(f"Failed to retrieve patient {patient_id}: {e}")
223
+ return None
224
+
225
+ def get_mips_encounters(self, patient_id: str = None) -> Optional[Dict[str, Any]]:
226
+ """
227
+ Retrieve encounters from the MIPS API, optionally filtered by patient ID.
228
+
229
+ Args:
230
+ patient_id (str, optional): The ID of the patient to filter encounters by.
231
+
232
+ Returns:
233
+ Optional[Dict[str, Any]]: Encounter data as a dictionary if successful, None otherwise.
234
+ """
235
+ url = f"{self.mips_base_url}/Encounter"
236
+ if patient_id:
237
+ url += f"?patient={patient_id}"
238
+
239
+ if not self.access_token and not self.authenticate():
240
+ print("Cannot proceed without authentication.")
241
+ return None
242
+
243
+ try:
244
+ response = self.session.get(url, headers=self._get_headers())
245
+ response.raise_for_status()
246
+ return response.json() if response.text else {}
247
+ except requests.RequestException as e:
248
+ print(f"Failed to retrieve encounters: {e}")
249
+ return None
250
+
251
+ def update_fhir_patient(self, patient_id: str, patient_data: Dict[str, Any]) -> bool:
252
+ """
253
+ Update patient data in the FHIR API using a PUT request.
254
+
255
+ Args:
256
+ patient_id (str): The ID of the patient to update.
257
+ patient_data (Dict[str, Any]): The updated patient data in FHIR JSON format.
258
+
259
+ Returns:
260
+ bool: True if the patient is updated successfully, False otherwise.
261
+ """
262
+ url = f"{self.fhir_base_url}/Patient/{patient_id}"
263
+
264
+ if not self.access_token and not self.authenticate():
265
+ print("Cannot proceed without authentication.")
266
+ return False
267
+
268
+ try:
269
+ response = self.session.put(url, data=json.dumps(patient_data), headers=self._get_headers())
270
+ response.raise_for_status()
271
+ return True
272
+ except requests.RequestException as e:
273
+ print(f"Failed to update FHIR patient {patient_id}: {e}")
274
+ return False
275
+
276
+ def update_mips_patient(self, patient_id: str, patient_data: Dict[str, Any]) -> bool:
277
+ """
278
+ Update patient data in the MIPS API using a PUT request.
279
+
280
+ Args:
281
+ patient_id (str): The ID of the patient to update.
282
+ patient_data (Dict[str, Any]): The updated patient data in FHIR JSON format.
283
+
284
+ Returns:
285
+ bool: True if the patient is updated successfully, False otherwise.
286
+ """
287
+ url = f"{self.mips_base_url}/Patient/{patient_id}"
288
+
289
+ if not self.access_token and not self.authenticate():
290
+ print("Cannot proceed without authentication.")
291
+ return False
292
+
293
+ try:
294
+ response = self.session.put(url, data=json.dumps(patient_data), headers=self._get_headers())
295
+ response.raise_for_status()
296
+ return True
297
+ except requests.RequestException as e:
298
+ print(f"Failed to update MIPS patient {patient_id}: {e}")
299
+ return False
300
+
301
+ def close(self):
302
+ """Close the session to free up resources."""
303
+ self.session.close()
304
+
305
+ def __enter__(self):
306
+ """Support for context manager entry."""
307
+ return self
308
+
309
+ def __exit__(self, exc_type, exc_val, exc_tb):
310
+ """Support for context manager exit, ensuring session is closed."""
311
+ self.close()
312
+
313
+
314
+ # # Example usage with patient update functionality
315
+ # if __name__ == "__main__":
316
+ # # Replace these with your actual credentials and workspace ID
317
+ # CLIENT_ID = "your_client_id"
318
+ # CLIENT_SECRET = "your_client_secret"
319
+ # WORKSPACE_ID = "your_workspace_id"
320
+ # PATIENT_ID = "example_patient_id" # Replace with an actual patient ID
321
+
322
+ # with MeldRxAPI(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, workspace_id=WORKSPACE_ID) as meldrx:
323
+ # # Authenticate
324
+ # if meldrx.authenticate():
325
+ # print("Authentication successful!")
326
+
327
+ # # Retrieve specific patient information from MIPS API
328
+ # patient_info = meldrx.get_mips_patient_by_id(PATIENT_ID)
329
+ # if patient_info is not None:
330
+ # print(f"Original Patient {PATIENT_ID} Info:", json.dumps(patient_info, indent=2))
331
+
332
+ # # Example patient data to update (FHIR Patient resource format)
333
+ # updated_patient_data = {
334
+ # "resourceType": "Patient",
335
+ # "id": PATIENT_ID,
336
+ # "name": [{
337
+ # "family": "Doe",
338
+ # "given": ["John", "Updated"]
339
+ # }],
340
+ # "gender": "male",
341
+ # "birthDate": "1980-01-01"
342
+ # }
343
+
344
+ # # Update patient in FHIR API
345
+ # if meldrx.update_fhir_patient(PATIENT_ID, updated_patient_data):
346
+ # print(f"Successfully updated patient {PATIENT_ID} in FHIR API")
347
+ # updated_info = meldrx.get_mips_patient_by_id(PATIENT_ID)
348
+ # if updated_info:
349
+ # print(f"Updated Patient {PATIENT_ID} Info (FHIR):", json.dumps(updated_info, indent=2))
350
+
351
+ # # Update patient in MIPS API
352
+ # if meldrx.update_mips_patient(PATIENT_ID, updated_patient_data):
353
+ # print(f"Successfully updated patient {PATIENT_ID} in MIPS API")
354
+ # updated_info = meldrx.get_mips_patient_by_id(PATIENT_ID)
355
+ # if updated_info:
356
+ # print(f"Updated Patient {PATIENT_ID} Info (MIPS):", json.dumps(updated_info, indent=2))
357
+
358
+ # # Retrieve encounters for the patient from MIPS API
359
+ # encounters = meldrx.get_mips_encounters(patient_id=PATIENT_ID)
360
+ # if encounters is not None:
361
+ # print(f"Encounters for Patient {PATIENT_ID}:", json.dumps(encounters, indent=2))
meldrxtester.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ from typing import Optional, Dict, Any
4
+ from meldrx import MeldRxAPI
5
+
6
+ # Testing class
7
+ class MeldRxAPITest:
8
+ """A class to test the functionality of the MeldRxAPI class."""
9
+
10
+ def __init__(self):
11
+ # Placeholder variables (replace with real values for live testing)
12
+ self.client_id = "04bdc9f9a23d488a868b93d594ee5a4a"
13
+ self.client_secret = "test_client_secret"
14
+ self.workspace_id = "09ed4f76-b5ac-42bf-92d5-496933203dbe"
15
+ self.test_patient_id = "05f7c0c2-ebee-44db-ab71-2113e7a70acb"
16
+ self.api = MeldRxAPI(self.client_id, self.client_secret, self.workspace_id)
17
+
18
+ def test_authenticate(self):
19
+ """Test the authentication method."""
20
+ print("\n=== Testing Authentication ===")
21
+ result = self.api.authenticate()
22
+ print(f"Authentication Result: {result}")
23
+ if result:
24
+ print(f"Access Token: {self.api.access_token[:10]}... (truncated for brevity)")
25
+ else:
26
+ print("Authentication failed. Subsequent tests may not work as expected.")
27
+
28
+ def test_get_patients(self):
29
+ """Test retrieving patients from the FHIR API."""
30
+ print("\n=== Testing Get Patients (FHIR) ===")
31
+ patients = self.api.get_patients()
32
+ if patients is not None:
33
+ print("Patients Retrieved Successfully:")
34
+ print(json.dumps(patients, indent=2) if patients else "No data returned (expected per docs)")
35
+ else:
36
+ print("Failed to retrieve patients.")
37
+
38
+ def test_create_virtual_workspace(self):
39
+ """Test creating a virtual workspace."""
40
+ print("\n=== Testing Create Virtual Workspace ===")
41
+ success = self.api.create_virtual_workspace(
42
+ snapshot="patient-prefetch",
43
+ patient_id=self.test_patient_id,
44
+ hook="patient-view"
45
+ )
46
+ print(f"Virtual Workspace Creation Result: {success}")
47
+ if success:
48
+ print("Virtual workspace created successfully (no response body expected).")
49
+ else:
50
+ print("Failed to create virtual workspace.")
51
+
52
+ def test_get_mips_patients(self):
53
+ """Test retrieving patients from the MIPS API."""
54
+ print("\n=== Testing Get MIPS Patients ===")
55
+ patients = self.api.get_mips_patients()
56
+ if patients is not None:
57
+ print("MIPS Patients Retrieved Successfully:")
58
+ print(json.dumps(patients, indent=2) if patients else "No data returned")
59
+ else:
60
+ print("Failed to retrieve MIPS patients.")
61
+
62
+ def test_get_mips_patient_by_id(self):
63
+ """Test retrieving a specific patient by ID from the MIPS API."""
64
+ print("\n=== Testing Get MIPS Patient by ID ===")
65
+ patient = self.api.get_mips_patient_by_id(self.test_patient_id)
66
+ if patient is not None:
67
+ print(f"Patient {self.test_patient_id} Retrieved Successfully:")
68
+ print(json.dumps(patient, indent=2) if patient else "No data returned")
69
+ else:
70
+ print(f"Failed to retrieve patient {self.test_patient_id}.")
71
+
72
+ def test_get_mips_encounters(self):
73
+ """Test retrieving encounters from the MIPS API (with and without patient filter)."""
74
+ print("\n=== Testing Get MIPS Encounters (All) ===")
75
+ encounters = self.api.get_mips_encounters()
76
+ if encounters is not None:
77
+ print("All Encounters Retrieved Successfully:")
78
+ print(json.dumps(encounters, indent=2) if encounters else "No data returned")
79
+ else:
80
+ print("Failed to retrieve all encounters.")
81
+
82
+ print("\n=== Testing Get MIPS Encounters (Filtered by Patient) ===")
83
+ encounters_filtered = self.api.get_mips_encounters(self.test_patient_id)
84
+ if encounters_filtered is not None:
85
+ print(f"Encounters for Patient {self.test_patient_id} Retrieved Successfully:")
86
+ print(json.dumps(encounters_filtered, indent=2) if encounters_filtered else "No data returned")
87
+ else:
88
+ print(f"Failed to retrieve encounters for patient {self.test_patient_id}.")
89
+
90
+ def run_all_tests(self):
91
+ """Run all test methods in sequence."""
92
+ print("Starting MeldRx API Tests...\n")
93
+ self.test_authenticate()
94
+ self.test_get_patients()
95
+ self.test_create_virtual_workspace()
96
+ self.test_get_mips_patients()
97
+ self.test_get_mips_patient_by_id()
98
+ self.test_get_mips_encounters()
99
+ print("\nAll tests completed.")
100
+ self.api.close()
101
+
102
+
103
+ # Run the tests
104
+ if __name__ == "__main__":
105
+ tester = MeldRxAPITest()
106
+ tester.run_all_tests()
meldrxtester2.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ from typing import Optional, Dict, Any
4
+ from meldrx import MeldRxAPI # Assuming meldrx.py contains the updated MeldRxAPI with SMART on FHIR
5
+
6
+ class MeldRxAPITest:
7
+ """A class to test the functionality of the MeldRxAPI class with SMART on FHIR and Gradio callback."""
8
+
9
+ def __init__(self):
10
+ # Placeholder variables (replace with real values for live testing)
11
+ self.client_id = "04bdc9f9a23d488a868b93d594ee5a4a" # Replace with your actual client ID
12
+ self.redirect_uri = "https://multitransformer-discharge-guard.hf.space/callback" # Gradio Space callback URL
13
+ self.workspace_id = "09ed4f76-b5ac-42bf-92d5-496933203dbe" # Replace with your workspace ID
14
+ self.test_patient_id = "05f7c0c2-ebee-44db-ab71-2113e7a70acb" # Replace with a valid patient ID
15
+ self.client_secret = None # Optional; set if using a confidential client
16
+ self.api = MeldRxAPI(self.client_id, self.redirect_uri, self.workspace_id, self.client_secret)
17
+ self.auth_code = None
18
+ self.access_token = None
19
+
20
+ def _print_section(self, title: str):
21
+ """Helper method to print section headers."""
22
+ print(f"\n{'=' * 10} {title} {'=' * 10}")
23
+
24
+ def test_get_auth_url(self):
25
+ """Test generating the SMART on FHIR authorization URL."""
26
+ self._print_section("Testing Get Authorization URL")
27
+ auth_url = self.api.get_authorization_url()
28
+ print(f"Generated Authorization URL:\n{auth_url}")
29
+ print("Action: Open this URL in a browser, log in, and copy the 'code' from the redirect URL.")
30
+
31
+ def test_authenticate_with_code(self):
32
+ """Test authentication using an authorization code (simulating Gradio callback)."""
33
+ self._print_section("Testing Authenticate with Code")
34
+ self.auth_code = input("Enter the authorization code from the redirect URL (or press Enter to skip): ").strip()
35
+ if not self.auth_code:
36
+ print("No code provided. Skipping authentication test.")
37
+ return
38
+ result = self.api.authenticate_with_code(self.auth_code)
39
+ print(f"Authentication Result: {result}")
40
+ if result:
41
+ self.access_token = self.api.access_token
42
+ print(f"Access Token: {self.access_token[:10]}... (truncated for brevity)")
43
+ else:
44
+ print("Authentication failed. Subsequent tests may not work as expected.")
45
+
46
+ def test_get_patients(self):
47
+ """Test retrieving patients from the FHIR API."""
48
+ self._print_section("Testing Get Patients (FHIR)")
49
+ if not self.access_token:
50
+ print("Not authenticated. Run test_authenticate_with_code first.")
51
+ return
52
+ patients = self.api.get_patients()
53
+ if patients is not None:
54
+ print("Patients Retrieved Successfully:")
55
+ print(json.dumps(patients, indent=2) if patients else "No data returned (expected per docs)")
56
+ else:
57
+ print("Failed to retrieve patients.")
58
+
59
+ def test_create_virtual_workspace(self):
60
+ """Test creating a virtual workspace."""
61
+ self._print_section("Testing Create Virtual Workspace")
62
+ if not self.access_token:
63
+ print("Not authenticated. Run test_authenticate_with_code first.")
64
+ return
65
+ success = self.api.create_virtual_workspace(
66
+ snapshot="patient-prefetch",
67
+ patient_id=self.test_patient_id,
68
+ hook="patient-view"
69
+ )
70
+ print(f"Virtual Workspace Creation Result: {success}")
71
+ if success:
72
+ print("Virtual workspace created successfully (no response body expected).")
73
+ else:
74
+ print("Failed to create virtual workspace.")
75
+
76
+ def test_get_mips_patients(self):
77
+ """Test retrieving patients from the MIPS API."""
78
+ self._print_section("Testing Get MIPS Patients")
79
+ if not self.access_token:
80
+ print("Not authenticated. Run test_authenticate_with_code first.")
81
+ return
82
+ patients = self.api.get_mips_patients()
83
+ if patients is not None:
84
+ print("MIPS Patients Retrieved Successfully:")
85
+ print(json.dumps(patients, indent=2) if patients else "No data returned")
86
+ else:
87
+ print("Failed to retrieve MIPS patients.")
88
+
89
+ def test_get_mips_patient_by_id(self):
90
+ """Test retrieving a specific patient by ID from the MIPS API."""
91
+ self._print_section("Testing Get MIPS Patient by ID")
92
+ if not self.access_token:
93
+ print("Not authenticated. Run test_authenticate_with_code first.")
94
+ return
95
+ patient = self.api.get_mips_patient_by_id(self.test_patient_id)
96
+ if patient is not None:
97
+ print(f"Patient {self.test_patient_id} Retrieved Successfully:")
98
+ print(json.dumps(patient, indent=2) if patient else "No data returned")
99
+ else:
100
+ print(f"Failed to retrieve patient {self.test_patient_id}.")
101
+
102
+ def test_get_mips_encounters(self):
103
+ """Test retrieving encounters from the MIPS API (with and without patient filter)."""
104
+ self._print_section("Testing Get MIPS Encounters (All)")
105
+ if not self.access_token:
106
+ print("Not authenticated. Run test_authenticate_with_code first.")
107
+ return
108
+ encounters = self.api.get_mips_encounters()
109
+ if encounters is not None:
110
+ print("All Encounters Retrieved Successfully:")
111
+ print(json.dumps(encounters, indent=2) if encounters else "No data returned")
112
+ else:
113
+ print("Failed to retrieve all encounters.")
114
+
115
+ self._print_section("Testing Get MIPS Encounters (Filtered by Patient)")
116
+ encounters_filtered = self.api.get_mips_encounters(self.test_patient_id)
117
+ if encounters_filtered is not None:
118
+ print(f"Encounters for Patient {self.test_patient_id} Retrieved Successfully:")
119
+ print(json.dumps(encounters_filtered, indent=2) if encounters_filtered else "No data returned")
120
+ else:
121
+ print(f"Failed to retrieve encounters for patient {self.test_patient_id}.")
122
+
123
+ def run_all_tests(self):
124
+ """Run all test methods in sequence."""
125
+ print("Starting MeldRx API Tests with Gradio Callback Simulation...\n")
126
+ self.test_get_auth_url()
127
+ self.test_authenticate_with_code()
128
+ self.test_get_patients()
129
+ self.test_create_virtual_workspace()
130
+ self.test_get_mips_patients()
131
+ self.test_get_mips_patient_by_id()
132
+ self.test_get_mips_encounters()
133
+ print("\nAll tests completed.")
134
+ self.api.close()
135
+
136
+
137
+ # Run the tests
138
+ if __name__ == "__main__":
139
+ tester = MeldRxAPITest()
140
+ tester.run_all_tests()
qwenprompt.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import InferenceClient
2
+
3
+ client = InferenceClient(api_key="YOUR_HF_TOKEN")
4
+
5
+ messages = [
6
+ { "role": "user", "content": "" },
7
+ { "role": "assistant", "content": "you are a senior expert medical health practitioner known for their abilities to produce discharge papers. you will recieve patient information and treatment cursus. Produce a complete discharge summary based on the information provided. produce complete discharge summary." },
8
+ { "role": "user", "content": "Patient Name: Patient 1\nGender: Male\nAge: 65 years\n\nPresentation and Diagnosis:\nThe patient was diagnosed with acute myeloid leukemia (AML) in January 2020 based on leukocytosis, thrombocytopenia and anemia. Bone marrow aspiration revealed a hypercellular bone marrow with 50% blasts. The patient was further assessed using flow cytometry and cytogenetics, and molecular panel testing showed aberrations in ASXL1, CEBPA, JAK2, and RUNX1. AML with adverse risk was diagnosed according to genetic risk stratification.\n\nHospital Course:\nAfter one course of induction treatment with the IA regimen, the patient achieved complete remission with low minimal residual disease. Genetic analyses showed negative gene mutations, and the patient received consolidation therapies with the IA regimen and high-dose Ara-c (HiDAC) regimen. However, remission duration only lasted for 11 months, and in November 2020, relapsed BM morphology was detected, indicating relapsed AML with concurrent molecular aberration recurrence. The patient underwent several treatment regimens, including venetoclax combined with azacitidine and chidamide with venetoclax and azacitidine regimen. He achieved complete remission after one course of the chidamide combined regimen.\n\nOutcome:\nThe patient passed away due to disease progression three months after the completion of therapy." },
9
+ # { "role": "assistant", "content": "### Discharge Summary\n\n**Patient Name:** Patient 1 \n**Gender:** Male \n**Age:** 65 years \n**Date of Admission:** January 2020 \n**Date of Discharge:** April 2021 \n**Attending Physician:** Dr. [Attending Physician's Name] \n**Discharge Diagnosis:** Acute Myeloid Leukemia (AML) with Adverse Risk\n\n#### Presentation and Diagnosis:\nThe patient, a 65-year-old male, was diagnosed with acute myeloid leukemia (AML) in January 2020. The initial presentation included leukocytosis, thrombocytopenia, and anemia. A bone marrow aspiration revealed a hypercellular bone marrow with 50% blasts. Further evaluation using flow cytometry, cytogenetics, and molecular panel testing identified aberrations in ASXL1, CEBPA, JAK2, and RUNX1. Based on these findings, the patient was diagnosed with AML with adverse risk according to genetic risk stratification.\n\n#### Hospital Course:\n- **Initial Treatment:**\n - The patient underwent one course of induction treatment with the IA (idarubicin and cytarabine) regimen.\n - After the induction treatment, the patient achieved complete remission with low minimal residual disease (MRD). Genetic analyses confirmed the absence of gene mutations.\n - The patient then received consolidation therapies, including additional courses of the IA regimen and a high-dose Ara-C (HiDAC) regimen.\n\n- **Relapse:**\n - Despite the initial success, the patient's remission lasted only 11 months. In November 2020, a bone marrow biopsy revealed relapsed AML with concurrent molecular aberration recurrence.\n - The patient was subsequently treated with several regimens, including venetoclax combined with azacitidine and a chidamide with venetoclax and azacitidine regimen.\n - After one course of the chidamide combined regimen, the patient achieved complete remission again.\n\n- **Disease Progression:**\n - Despite achieving remission, the patient's condition began to deteriorate three months after the completion of therapy.\n - The patient developed progressive disease, and despite supportive care and palliative measures, he passed away due to disease progression.\n\n#### Outcome:\nThe patient passed away on [Date of Death] due to disease progression and complications associated with relapsed AML. The family was provided with appropriate bereavement support and counseling.\n\n#### Discharge Instructions:\n- **Follow-Up:**\n - The patient's family was advised to follow up with the oncology team for any further questions or support.\n - The family was also provided with resources for grief counseling and support groups.\n\n- **Medications:**\n - The patient was not discharged on any medications due to the terminal nature of his condition.\n\n- **Diet and Activity:**\n - The patient was on a regular diet and was encouraged to maintain a comfortable level of activity as tolerated.\n\n- **Advance Directives:**\n - The patient had previously completed an advance directive, and his wishes were respected throughout his care.\n\n#### Summary:\nPatient 1, a 65-year-old male with AML with adverse risk, underwent multiple treatment regimens, including induction and consolidation therapies, and achieved remission twice. However, the disease ultimately progressed, leading to his passing. The family was provided with comprehensive support and resources to navigate this difficult time.\n\n**Signed:**\nDr. [Attending Physician's Name] \n[Contact Information] \n[Date]" }
10
+ ]
11
+
12
+ stream = client.chat.completions.create(
13
+ model="Qwen/Qwen2.5-72B-Instruct",
14
+ messages=messages,
15
+ temperature=0.6,
16
+ max_tokens=4096,
17
+ top_p=0.7,
18
+ stream=True
19
+ )
20
+
21
+ for chunk in stream:
22
+ print(chunk.choices[0].delta.content)
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ openai
test_meldrx.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import unittest
2
+ from unittest.mock import patch, Mock
3
+ import json
4
+ from io import StringIO
5
+ from contextlib import redirect_stdout
6
+ from meldrx import MeldRxAPI # Import the class from meldrx.py
7
+
8
+ class TestMeldRxAPI(unittest.TestCase):
9
+ def setUp(self):
10
+ """Set up test fixtures before each test."""
11
+ self.client_id = "test_client_id"
12
+ self.client_secret = "test_client_secret"
13
+ self.workspace_id = "test_workspace_id"
14
+ self.patient_id = "test_patient_id"
15
+ self.api = MeldRxAPI(self.client_id, self.client_secret, self.workspace_id)
16
+
17
+ def tearDown(self):
18
+ """Clean up after each test."""
19
+ self.api.close()
20
+
21
+ @patch('meldrx.requests.Session.post')
22
+ def test_authenticate_success(self, mock_post):
23
+ """Test successful authentication."""
24
+ mock_response = Mock()
25
+ mock_response.status_code = 200
26
+ mock_response.json.return_value = {"access_token": "test_token"}
27
+ mock_post.return_value = mock_response
28
+
29
+ result = self.api.authenticate()
30
+ self.assertTrue(result)
31
+ self.assertEqual(self.api.access_token, "test_token")
32
+
33
+ @patch('meldrx.requests.Session.post')
34
+ def test_authenticate_failure(self, mock_post):
35
+ """Test authentication failure."""
36
+ mock_response = Mock()
37
+ mock_response.status_code = 401
38
+ mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError("Unauthorized")
39
+ mock_post.return_value = mock_response
40
+
41
+ with redirect_stdout(StringIO()) as output:
42
+ result = self.api.authenticate()
43
+ self.assertFalse(result)
44
+ self.assertIsNone(self.api.access_token)
45
+ self.assertIn("Authentication failed: Unauthorized", output.getvalue())
46
+
47
+ @patch('meldrx.requests.Session.get')
48
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
49
+ def test_get_patients_success(self, mock_auth, mock_get):
50
+ """Test successful retrieval of patients from FHIR API."""
51
+ mock_response = Mock()
52
+ mock_response.status_code = 200
53
+ mock_response.text = json.dumps({"resourceType": "Bundle", "entry": [{"resource": {"id": self.patient_id}}]})
54
+ mock_response.json.return_value = json.loads(mock_response.text)
55
+ mock_get.return_value = mock_response
56
+
57
+ result = self.api.get_patients()
58
+ self.assertIsNotNone(result)
59
+ self.assertEqual(result["entry"][0]["resource"]["id"], self.patient_id)
60
+
61
+ @patch('meldrx.requests.Session.get')
62
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=False)
63
+ def test_get_patients_auth_failure(self, mock_auth, mock_get):
64
+ """Test patient retrieval fails due to authentication."""
65
+ with redirect_stdout(StringIO()) as output:
66
+ result = self.api.get_patients()
67
+ self.assertIsNone(result)
68
+ mock_get.assert_not_called()
69
+ self.assertIn("Cannot proceed without authentication", output.getvalue())
70
+
71
+ @patch('meldrx.requests.Session.post')
72
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
73
+ def test_create_virtual_workspace_success(self, mock_auth, mock_post):
74
+ """Test successful creation of a virtual workspace."""
75
+ mock_response = Mock()
76
+ mock_response.status_code = 201
77
+ mock_post.return_value = mock_response
78
+
79
+ result = self.api.create_virtual_workspace()
80
+ self.assertTrue(result)
81
+
82
+ @patch('meldrx.requests.Session.get')
83
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
84
+ def test_get_mips_patients_success(self, mock_auth, mock_get):
85
+ """Test successful retrieval of patients from MIPS API."""
86
+ mock_response = Mock()
87
+ mock_response.status_code = 200
88
+ mock_response.text = json.dumps({"resourceType": "Bundle", "entry": [{"resource": {"id": self.patient_id}}]})
89
+ mock_response.json.return_value = json.loads(mock_response.text)
90
+ mock_get.return_value = mock_response
91
+
92
+ result = self.api.get_mips_patients()
93
+ self.assertIsNotNone(result)
94
+ self.assertEqual(result["entry"][0]["resource"]["id"], self.patient_id)
95
+
96
+ @patch('meldrx.requests.Session.get')
97
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
98
+ def test_get_mips_patient_by_id_success(self, mock_auth, mock_get):
99
+ """Test successful retrieval of a patient by ID from MIPS API."""
100
+ mock_response = Mock()
101
+ mock_response.status_code = 200
102
+ mock_response.text = json.dumps({"resourceType": "Patient", "id": self.patient_id})
103
+ mock_response.json.return_value = json.loads(mock_response.text)
104
+ mock_get.return_value = mock_response
105
+
106
+ result = self.api.get_mips_patient_by_id(self.patient_id)
107
+ self.assertIsNotNone(result)
108
+ self.assertEqual(result["id"], self.patient_id)
109
+
110
+ @patch('meldrx.requests.Session.get')
111
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
112
+ def test_get_mips_encounters_success(self, mock_auth, mock_get):
113
+ """Test successful retrieval of encounters from MIPS API."""
114
+ mock_response = Mock()
115
+ mock_response.status_code = 200
116
+ mock_response.text = json.dumps({"resourceType": "Bundle", "entry": [{"resource": {"id": "enc1"}}]})
117
+ mock_response.json.return_value = json.loads(mock_response.text)
118
+ mock_get.return_value = mock_response
119
+
120
+ result = self.api.get_mips_encounters(self.patient_id)
121
+ self.assertIsNotNone(result)
122
+ self.assertEqual(result["entry"][0]["resource"]["id"], "enc1")
123
+
124
+ @patch('meldrx.requests.Session.put')
125
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
126
+ def test_update_fhir_patient_success(self, mock_auth, mock_put):
127
+ """Test successful update of patient data in FHIR API."""
128
+ mock_response = Mock()
129
+ mock_response.status_code = 200
130
+ mock_put.return_value = mock_response
131
+
132
+ patient_data = {"resourceType": "Patient", "id": self.patient_id, "name": [{"family": "Doe"}]}
133
+ result = self.api.update_fhir_patient(self.patient_id, patient_data)
134
+ self.assertTrue(result)
135
+
136
+ @patch('meldrx.requests.Session.put')
137
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=True)
138
+ def test_update_mips_patient_success(self, mock_auth, mock_put):
139
+ """Test successful update of patient data in MIPS API."""
140
+ mock_response = Mock()
141
+ mock_response.status_code = 200
142
+ mock_put.return_value = mock_response
143
+
144
+ patient_data = {"resourceType": "Patient", "id": self.patient_id, "name": [{"family": "Doe"}]}
145
+ result = self.api.update_mips_patient(self.patient_id, patient_data)
146
+ self.assertTrue(result)
147
+
148
+ @patch('meldrx.requests.Session.put')
149
+ @patch('meldrx.MeldRxAPI.authenticate', return_value=False)
150
+ def test_update_fhir_patient_auth_failure(self, mock_auth, mock_put):
151
+ """Test patient update fails due to authentication in FHIR API."""
152
+ patient_data = {"resourceType": "Patient", "id": self.patient_id}
153
+ with redirect_stdout(StringIO()) as output:
154
+ result = self.api.update_fhir_patient(self.patient_id, patient_data)
155
+ self.assertFalse(result)
156
+ mock_put.assert_not_called()
157
+ self.assertIn("Cannot proceed without authentication", output.getvalue())
158
+
159
+ if __name__ == "__main__":
160
+ unittest.main(verbosity=2) # Increased verbosity for detailed output
wound.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ def submit_form(
4
+ patient_name, dob, ssn, goal_met, goal_reason,
5
+ discharge_date, wound1_location, wound1_status, wound1_measure_date, wound1_length, wound1_width, wound1_depth,
6
+ wound2_location, wound2_status, wound2_measure_date, wound2_length, wound2_width, wound2_depth,
7
+ provider_name, provider_phone, info_date
8
+ ):
9
+ result = f"""
10
+ Patient Information:
11
+ Name: {patient_name}
12
+ DOB: {dob}
13
+ SSN: {ssn}
14
+
15
+ Physician's Goal Met: {'Yes' if goal_met else 'No'}
16
+ Reason (if no): {goal_reason}
17
+
18
+ Discharge Date: {discharge_date}
19
+
20
+ Wound #1:
21
+ Location: {wound1_location}
22
+ Status: {', '.join(wound1_status)}
23
+ Measurement Date: {wound1_measure_date}
24
+ Length: {wound1_length} cm, Width: {wound1_width} cm, Depth: {wound1_depth} cm
25
+
26
+ Wound #2:
27
+ Location: {wound2_location}
28
+ Status: {', '.join(wound2_status)}
29
+ Measurement Date: {wound2_measure_date}
30
+ Length: {wound2_length} cm, Width: {wound2_width} cm, Depth: {wound2_depth} cm
31
+
32
+ Provider Information:
33
+ Name: {provider_name}
34
+ Phone: {provider_phone}
35
+ Information Date: {info_date}
36
+ """
37
+ return result
38
+
39
+ with gr.Blocks() as app:
40
+ gr.Markdown("### Discharge Form")
41
+ with gr.Row():
42
+ patient_name = gr.Textbox(label="Patient's Name (Last, First, MI)")
43
+ dob = gr.Textbox(label="Date of Birth (MM/DD/YYYY)")
44
+ ssn = gr.Textbox(label="Social Security Number (XXX-XX-XXXX)")
45
+
46
+ goal_met = gr.Checkbox(label="Was the Physician’s Goal Met?")
47
+ goal_reason = gr.Textbox(label="If No, Explain Why")
48
+ discharge_date = gr.Textbox(label="Therapy Discharge Date (MM/DD/YYYY)")
49
+
50
+ gr.Markdown("### Wound #1")
51
+ with gr.Row():
52
+ wound1_location = gr.Textbox(label="Wound Location")
53
+ wound1_status = gr.CheckboxGroup(["Adequate granulation", "Patient in hospital", "Wound unresponsive", "Pain", "Wound healed", "Delayed primary closure", "Patient non-compliant", "Patient expired", "Wound sutured closed", "Tunnel dimensions decreased or closed", "Undermining improved or resolved", "4 months of treatment completed", "Other"], label="Wound Status")
54
+ wound1_measure_date = gr.Textbox(label="Final Measurement Date (MM/DD/YYYY)")
55
+ with gr.Row():
56
+ wound1_length = gr.Number(label="Length (cm)")
57
+ wound1_width = gr.Number(label="Width (cm)")
58
+ wound1_depth = gr.Number(label="Depth (cm)")
59
+
60
+ gr.Markdown("### Wound #2 (if applicable)")
61
+ with gr.Row():
62
+ wound2_location = gr.Textbox(label="Wound Location")
63
+ wound2_status = gr.CheckboxGroup(["Adequate granulation", "Patient in hospital", "Wound unresponsive", "Pain", "Wound healed", "Delayed primary closure", "Patient non-compliant", "Patient expired", "Wound sutured closed", "Tunnel dimensions decreased or closed", "Undermining improved or resolved", "4 months of treatment completed", "Other"], label="Wound Status")
64
+ wound2_measure_date = gr.Textbox(label="Final Measurement Date (MM/DD/YYYY)")
65
+ with gr.Row():
66
+ wound2_length = gr.Number(label="Length (cm)")
67
+ wound2_width = gr.Number(label="Width (cm)")
68
+ wound2_depth = gr.Number(label="Depth (cm)")
69
+
70
+ gr.Markdown("### Provider Information")
71
+ provider_name = gr.Textbox(label="Print Name, Title, Employer")
72
+ provider_phone = gr.Textbox(label="Phone Number")
73
+ info_date = gr.Textbox(label="Information Date (MM/DD/YYYY)")
74
+
75
+ submit = gr.Button("Submit")
76
+ output = gr.Textbox(label="Form Output", interactive=False)
77
+ submit.click(submit_form, inputs=[
78
+ patient_name, dob, ssn, goal_met, goal_reason,
79
+ discharge_date, wound1_location, wound1_status, wound1_measure_date, wound1_length, wound1_width, wound1_depth,
80
+ wound2_location, wound2_status, wound2_measure_date, wound2_length, wound2_width, wound2_depth,
81
+ provider_name, provider_phone, info_date
82
+ ], outputs=output)
83
+
84
+ app.launch()