Roland Ding commited on
Commit
0d5eb6c
·
1 Parent(s): b426b8e

1.1.1.1 updated ui and corresponding features for the devices arrangement ui.

Browse files
Files changed (9) hide show
  1. app.py +4 -5
  2. application.py +14 -5
  3. cloud_db.py +61 -7
  4. features.py +82 -377
  5. test_cloud.py +0 -29
  6. ui_device.py +98 -51
  7. ui_studies.py +0 -38
  8. ui_study.py +0 -62
  9. utility.py +42 -1
app.py CHANGED
@@ -1,5 +1,3 @@
1
- # search_logic = gr.Interface(text_analysis,input="text",outputs="highlight",title="High light")
2
-
3
  # first layer extraction(text)
4
  # second layer extraction(first layer output)
5
  # third layer extraction(first layer outputs aggregated, second layer outputs aggregated)
@@ -10,6 +8,7 @@ import gradio as gr
10
  from cloud_db import *
11
  from supplier import *
12
  from utility import *
 
13
 
14
  from ui_device import *
15
  from ui_equivalent import *
@@ -21,11 +20,11 @@ examples = []
21
  demo = gr.TabbedInterface(
22
  [device_page,equivalent_page],
23
  ["Device","Equivalent Comparators"],
24
- [device_page,equivalent_page],
25
- ["Clinical Study","Studies"],
26
  theme = gr.themes.Soft(primary_hue="sky",secondary_hue="orange"),
 
27
  css = "footer {visibility: hidden}",
28
- title="AMRA AI Medi Reader")
 
29
 
30
  def refresh_data():
31
  return
 
 
 
1
  # first layer extraction(text)
2
  # second layer extraction(first layer output)
3
  # third layer extraction(first layer outputs aggregated, second layer outputs aggregated)
 
8
  from cloud_db import *
9
  from supplier import *
10
  from utility import *
11
+ from features import init_app_data
12
 
13
  from ui_device import *
14
  from ui_equivalent import *
 
20
  demo = gr.TabbedInterface(
21
  [device_page,equivalent_page],
22
  ["Device","Equivalent Comparators"],
 
 
23
  theme = gr.themes.Soft(primary_hue="sky",secondary_hue="orange"),
24
+ title="AMRA AI Medi Reader",
25
  css = "footer {visibility: hidden}",
26
+ )
27
+ # )
28
 
29
  def refresh_data():
30
  return
application.py CHANGED
@@ -79,6 +79,18 @@ data_structure = {
79
  "article",
80
  "outcomes"
81
  ]
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
  }
84
 
@@ -86,9 +98,6 @@ data_structure = {
86
  application default data
87
  '''
88
  app_data = {
89
- "current_article":{},
90
- "articles":[],
91
- "terms":[],
92
- "prompts":[],
93
- "outputs":[]
94
  }
 
79
  "article",
80
  "outcomes"
81
  ]
82
+ },
83
+ "devices":{
84
+ "key":[
85
+ "device_name"
86
+ ],
87
+ "fields":[
88
+ "device_name",
89
+ "device_type",
90
+ "intended_use",
91
+ "indications",
92
+ "contraindications"
93
+ ]
94
  }
95
  }
96
 
 
98
  application default data
99
  '''
100
  app_data = {
101
+ "current_device":{},
102
+ "devices":[],
 
 
 
103
  }
cloud_db.py CHANGED
@@ -14,13 +14,31 @@ db_client = boto3.client(
14
  dynamodb data operations
15
  '''
16
 
17
- # get the list of articles from articles table in dynamodb
18
  def get_table(table_name:str):
 
 
 
 
 
 
 
 
 
19
  result = db_client.scan(TableName = table_name,AttributesToGet = data_structure[table_name]["fields"])
20
  return [db_map_to_py_dict(r) for r in result["Items"]]
21
 
22
- # add a new article to table articles in dynamodb, return error if failed
23
  def post_item(table_name:str,item:dict):
 
 
 
 
 
 
 
 
 
24
  try:
25
  res = db_client.put_item(
26
  TableName = table_name,
@@ -30,8 +48,18 @@ def post_item(table_name:str,item:dict):
30
  return {"Error":e}
31
  return res
32
 
33
- # update an article in table articles in dynamodb, return error if failed
34
  def put_item(table_name:str,item:dict):
 
 
 
 
 
 
 
 
 
 
35
  try:
36
  res = db_client.put_item(
37
  TableName = table_name,
@@ -41,8 +69,18 @@ def put_item(table_name:str,item:dict):
41
  return {"Error":e}
42
  return res
43
 
44
- # delete an article in table articles in dynamodb, return error if not found.
45
  def delete_item(table_name:str,key:dict):
 
 
 
 
 
 
 
 
 
 
46
  try:
47
  res = db_client.delete_item(
48
  TableName = table_name,
@@ -52,10 +90,17 @@ def delete_item(table_name:str,key:dict):
52
  return {"Error":e}
53
  return res
54
 
55
-
56
- '''
57
- '''
58
  def get_item(table_name:str,key:dict):
 
 
 
 
 
 
 
 
 
 
59
  try:
60
  res = db_client.get_item(
61
  TableName = table_name,
@@ -69,5 +114,14 @@ def get_item(table_name:str,key:dict):
69
  dynamodb structure management
70
  '''
71
  def get_structure(table_name:str):
 
 
 
 
 
 
 
 
 
72
  result = db_client.describe_table(TableName = table_name)
73
  return result["Table"]["AttributeDefinitions"]
 
14
  dynamodb data operations
15
  '''
16
 
17
+ # get the list of items from a table in dynamodb
18
  def get_table(table_name:str):
19
+ '''
20
+ get the list of items from table in dynamodb
21
+
22
+ Args:
23
+ table_name (str): the name of the table in dynamodb
24
+
25
+ Returns:
26
+ list: a list of items in the table
27
+ '''
28
  result = db_client.scan(TableName = table_name,AttributesToGet = data_structure[table_name]["fields"])
29
  return [db_map_to_py_dict(r) for r in result["Items"]]
30
 
31
+ # add a new item to a table in dynamodb, return error if failed
32
  def post_item(table_name:str,item:dict):
33
+ '''
34
+ add a new item to table in dynamodb, return error if failed
35
+
36
+ Args:
37
+ table_name (str): the name of the table in dynamodb
38
+ item (dict): the item to be added to the table
39
+
40
+ Returns:
41
+ dict: the result of the operation'''
42
  try:
43
  res = db_client.put_item(
44
  TableName = table_name,
 
48
  return {"Error":e}
49
  return res
50
 
51
+ # update an item in a table in dynamodb, return error if failed
52
  def put_item(table_name:str,item:dict):
53
+ '''
54
+ update an item in table in dynamodb, return error if failed
55
+
56
+ Args:
57
+ table_name (str): the name of the table in dynamodb
58
+ item (dict): the item to be updated to the table
59
+
60
+ Returns:
61
+ dict: the result of the operation
62
+ '''
63
  try:
64
  res = db_client.put_item(
65
  TableName = table_name,
 
69
  return {"Error":e}
70
  return res
71
 
72
+ # delete an item in a table in dynamodb, return error if not found.
73
  def delete_item(table_name:str,key:dict):
74
+ '''
75
+ delete an item in table in dynamodb, return error if not found.
76
+
77
+ Args:
78
+ table_name (str): the name of the table in dynamodb
79
+ key (dict): the key of the item to be deleted
80
+
81
+ Returns:
82
+ dict: the result of the operation
83
+ '''
84
  try:
85
  res = db_client.delete_item(
86
  TableName = table_name,
 
90
  return {"Error":e}
91
  return res
92
 
 
 
 
93
  def get_item(table_name:str,key:dict):
94
+ '''
95
+ get an item in table in dynamodb, return error if not found.
96
+
97
+ Args:
98
+ table_name (str): the name of the table in dynamodb
99
+ key (dict): the key of the item to be deleted
100
+
101
+ Returns:
102
+ dict: the result of the operation
103
+ '''
104
  try:
105
  res = db_client.get_item(
106
  TableName = table_name,
 
114
  dynamodb structure management
115
  '''
116
  def get_structure(table_name:str):
117
+ '''
118
+ get the structure of a table in dynamodb
119
+
120
+ Args:
121
+ table_name (str): the name of the table in dynamodb
122
+
123
+ Returns:
124
+ dict: the structure of the table
125
+ '''
126
  result = db_client.describe_table(TableName = table_name)
127
  return result["Table"]["AttributeDefinitions"]
features.py CHANGED
@@ -1,417 +1,122 @@
1
  # language default packages
2
- from datetime import datetime
3
- from collections import defaultdict
4
 
5
  # external packages
6
  import gradio as gr
7
- import tiktoken
8
 
9
  # internal packages
10
  from cloud_db import *
11
  from cloud_storage import *
12
  from supplier import *
13
 
14
- encoding = tiktoken.get_encoding("cl100k_base")
15
-
16
  # get prompts, terms, outputs from the cloud
17
  def init_app_data():
18
  '''
19
  a function to initialize the application data from the cloud backend
20
  '''
21
- app_data["prompts"] = get_table("prompts")
22
- app_data["terms"] = get_table("terms")
23
- app_data["outputs"] = get_table("outputs")
24
- app_data["articles"] = get_table("articles")
25
-
26
- def process_study(
27
- study_file_obj,
28
- study_content,
29
- device=default_device
30
- ):
31
-
32
- if study_file_obj:
33
- article = add_article(device,study_file_obj)
34
- elif study_content:
35
- article = add_article(device,study_content,file_object=False)
36
- else:
37
- return "No file or content provided","No file or content provided","No file or content provided"
38
-
39
- app_data["current_article"] = article
40
- selected_prompts = select_prompts(article["content"],terms=app_data["terms"],prompts=app_data["prompts"])
41
-
42
- res = process_prompts(article["content"],selected_prompts)
43
- output = {
44
- "domain":article["domain"],
45
- "article":article["name"],
46
- "outcomes":res
47
- }
48
-
49
- add_output(output)
50
- views = create_views(res)
51
-
52
- return views
53
- # return ""
54
-
55
- def refresh():
56
- '''
57
- this function refresh the application data from the cloud backend
58
- '''
59
- init_app_data()
60
 
61
- article = app_data["current_article"]
62
- if not article:
63
- return "No file or content provided"
64
- selected_prompts = select_prompts(article["content"],terms=app_data["terms"],prompts=app_data["prompts"])
65
-
66
- res = process_prompts(article["content"],selected_prompts)
67
-
68
- output = {
69
- "domain":article["domain"],
70
- "article":article["name"],
71
- "outcomes":res
72
- }
73
- views = create_views(res)
74
- add_output(output)
75
-
76
- return views
77
-
78
- def create_views(output):
79
  md_text = ""
80
 
81
- overview = [v for _,v in output.items() if v["assessment"] == "overview"][0]
82
- safety = [v for _,v in output.items() if v["assessment"] == "safety"][0]
83
  # add overview
84
- md_text += f"<details><summary><b>Overivew</b></summary>\n\n"
85
- md_text += overview["content"] + "\n</details>\n\n"
86
-
87
- # add performance
88
- md_text += f"<details><summary><b>Performance</b></summary>\n\n"
89
- for title,content in output.items():
90
- if content["assessment"] not in ["overview","safety"]:
91
- md_text += f"#### {content['assessment']} - {title}\n\n"
92
- md_text += content["content"] + "\n\n"
93
- md_text += "</details>\n\n"
94
-
95
- # add safety
96
- md_text += f"<details><summary><b>Safety</b></summary>\n\n"
97
- md_text += safety["content"] + "\n\n" + "</details>\n\n"
98
-
99
- return gr.update(value=md_text)
100
 
101
- def extract_key_content(text,start,end,before = None,case_sensitive=False):
102
- '''
103
- this function extract the content between start and end
104
- and return the content in between. The function will find
105
- all the start and keep the last one showing up in the text,
106
- and find all the end and keep the last one showing up in the
107
- text. If no start or end is found, the function will return
108
- the no text.
109
 
110
- Parameters
111
- ----------
112
- text : str
113
- text of the article
114
- start : list
115
- list of start substrings
116
- end : list
117
- list of end substrings
118
 
119
- Returns
120
- -------
121
- str
122
- content between start and end
123
- '''
124
- origin = text
125
- if not case_sensitive:
126
- text = text.lower()
127
- start = [s.lower() for s in start]
128
- end = [e.lower() for e in end]
129
-
130
- start_index = 0
131
- for s in start:
132
- start_index = max(start_index,text.find(s))
133
-
134
- if start_index ==-1: start_index = 0
135
 
136
- end_index = 0
137
- for e in end:
138
- end_index = max(end_index,text[start_index:].find(e))
139
-
140
- if before:
141
- for b in before:
142
- before_index = text[start_index:start_index+end_index].find(b)
143
- end_index = min(end_index,before_index) if before_index != -1 and before_index >=800 else end_index # 800 is a magic number for the length of the abstract
144
 
145
- content = origin[start_index:start_index+end_index]
146
- return content, start_index, start_index+end_index
147
-
148
- def get_articles(update_local=True):
149
- '''
150
- this function return the list of articles
151
-
152
- Parameters
153
- ----------
154
- update_local : bool, optional
155
- update the local memory, by default True
156
-
157
- Returns
158
- -------
159
- list
160
- list of articles
161
- '''
162
- articles = get_table("articles")
163
- if update_local:
164
- app_data["articles"] = articles
165
-
166
- return articles
167
-
168
- def get_article(domain,name):
169
- '''
170
- this function return the article object
171
-
172
- Parameters
173
- ----------
174
- domain : str
175
- subject domain of the article
176
- name : str
177
- name of the article
178
-
179
- Returns
180
- -------
181
- dict
182
- article object
183
- '''
184
- article = get_item("articles",{"domain":domain,"name":name})
185
-
186
- return article
187
-
188
- def add_article(domain,file,add_to_s3=True, add_to_local=True, file_object=True):
189
- '''
190
- this function receive the domain name and file obj
191
- and add the article to the cloud, s3 and local memory
192
 
193
- Parameters
194
- ----------
195
- domain : str
196
- subject domain of the article
197
- file_obj : file object
198
- file object of the article
199
- add_to_s3 : bool, optional
200
- add article to s3 bucket, by default True
201
- add_to_local : bool, optional
202
- add article to local memory, by default True
203
-
204
- Returns
205
- -------
206
- dict
207
- article object
208
- '''
209
- if file_object:
210
- content, _ = read_pdf(file)
211
- filename = file.name.split("\\")[-1]
212
- # name = filename.split(".")[0]
213
- else:
214
- content = file
215
- # filename = file.name
216
- filename = f"temp_{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
217
-
218
- article ={
219
- "domain":domain,
220
- "name":filename,
221
- "content":content,
222
- "upload_time":datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
223
  }
224
 
225
- if add_to_s3 and file_object:
226
- upload_fileobj(file,domain,filename)
227
-
228
- if add_to_local:
229
- app_data["articles"].append(article)
230
-
231
- res = post_item("articles",article)
232
- if "Error" in res:
233
- print(res["Error"])
234
- return res
235
-
236
- return article
237
-
238
- def remove_article(domain,name,remove_from_s3=True, remove_from_local=True):
239
- '''
240
- this function remove the article from the cloud, s3 and local memory
241
-
242
- Parameters
243
- ----------
244
- domain : str
245
- subject domain of the article
246
- name : str
247
- name of the article
248
- remove_from_s3 : bool, optional
249
- remove article from s3 bucket, by default True
250
- remove_from_local : bool, optional
251
- remove article from local memory, by default True
252
-
253
- Returns
254
- -------
255
- dict
256
- article object
257
- '''
258
- delete_item("articles",{"domain":domain,"name":name})
259
- if remove_from_s3:
260
- delete_file(domain,name)
261
- if remove_from_local:
262
- # app_data["articles"].remove(article)
263
- pass
264
- delete_item("articles",{"domain":domain,"name":name})
265
-
266
- return True
267
 
268
- def update_article(article,file_obj=None,update_local=True):
269
- '''
270
- this function receive the article object and update the article
271
- to the cloud, s3 and local memory
272
-
273
- Parameters
274
- ----------
275
- article : dict
276
- article object
277
- file_obj : file object, optional
278
- file object of the article, by default None
279
- update_local : bool, optional
280
- update article to local memory, by default True
281
 
282
- Returns
283
- -------
284
- dict
285
- article object
286
- '''
287
- if file_obj:
288
- upload_fileobj(file_obj,article["domain"],article["name"])
289
-
290
- if update_local:
291
- app_data["articles"].append(article)
292
 
293
- post_item("articles",article)
294
-
295
- return article
296
-
297
- def add_output(output):
298
- '''
299
- this function add the output to the cloud
300
-
301
- Parameters
302
- ----------
303
- output : dict
304
- output object
305
-
306
- Returns
307
- -------
308
- bool
309
- True if success
310
- '''
311
- res = post_item("outputs",output)
312
-
313
- if "Error" in res:
314
- print(res)
315
- return False
316
- return res
317
-
318
- def get_output(domain,name):
319
- res = output = get_item("outputs",{"domain":domain,"name":name})
320
- if "Error" in res:
321
- print(res)
322
- return False
323
- return output
324
 
325
- def remove_output(domain,name):
326
- res = delete_item("outputs",{"domain":domain,"name":name})
327
- if "Error" in res:
328
- print(res)
329
- return False
330
- return True
331
 
332
- def update_output(output):
333
- res = put_item("outputs",output)
334
- if "Error" in res:
335
- print(res)
336
- return False
337
- return True
338
 
339
- def add_device(*args):
340
- pass
341
 
342
- def get_device():
343
- pass
 
 
 
 
344
 
345
- def remove_device():
346
- pass
 
 
 
347
 
348
- def update_device():
349
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
 
351
- # identify article state
352
- def identify_logic(text):
353
- article_logic = [
354
- "groups",
355
- "levels",
356
- "preoperatives"
357
  ]
 
 
358
 
359
- return {l:l in text.lower() for l in article_logic}
360
-
361
- def select_prompts(text,terms,prompts):
362
- selected_templates = set()
363
- for t in terms:
364
- if all([term in text for term in t["terms"]]):
365
- selected_templates.update(t["template_name"])
366
-
367
- logic = identify_logic(text)
368
-
369
- selected_prompts = [p for p in prompts if p["template_name"] in selected_templates]
370
- overview_prompts = [p for p in prompts if p["assessment_step"] == "overview"]
371
- for p in overview_prompts:
372
- if all([p[l]==v for l,v in logic.items() if v]):
373
- selected_prompts.append(p)
374
-
375
- return selected_prompts
376
-
377
- def keyword_search(keywords,full_text):
378
- keywords_result = {}
379
- for k in keywords:
380
- if type(k) is tuple:
381
- keywords_result[k]=list_or([keyword_search(kw,full_text) for kw in k])
382
- else:
383
- keywords_result[k]=keyword_search(k,full_text)
384
- return keywords_result
385
-
386
- def process_prompts(text,prompts):
387
- '''
388
- process_prompts function receive the text and prompts and return the instruction stream
389
-
390
- Parameters
391
- ----------
392
- text : str
393
- text of the article
394
- prompts : list
395
- list of prompts
396
-
397
- Returns
398
- -------
399
- dict
400
- processed extraction results from openai api
401
- '''
402
- res = {}
403
- for p in prompts:
404
- inst = [
405
- p["prompt"]+", ".join(p["fields"]),
406
- p["reformat_inst"]
407
- ]
408
- inst_stream = create_inst(text,inst)
409
- extraction = send_inst(inst_stream)
410
-
411
- res[p["template_name"]] = {
412
- "template_name":p["template_name"],
413
- "assessment":p["assessment_step"],
414
- "content":extraction
415
- }
416
 
417
- return res
 
 
 
 
 
 
1
  # language default packages
2
+ from application import *
 
3
 
4
  # external packages
5
  import gradio as gr
 
6
 
7
  # internal packages
8
  from cloud_db import *
9
  from cloud_storage import *
10
  from supplier import *
11
 
 
 
12
  # get prompts, terms, outputs from the cloud
13
  def init_app_data():
14
  '''
15
  a function to initialize the application data from the cloud backend
16
  '''
17
+ app_data["devices"] = get_table("devices")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ def create_view(device):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  md_text = ""
21
 
 
 
22
  # add overview
23
+ md_text += f"<details><summary><b>Intended Use</b></summary>\n\n"
24
+ md_text += device["intended_use"] + "\n</details>\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ md_text += f"<details><summary><b>Indications</b></summary>\n\n"
27
+ md_text += device["indications"] + "\n</details>\n\n"
 
 
 
 
 
 
28
 
29
+ md_text += f"<details><summary><b>Contraindications</b></summary>\n\n"
30
+ md_text += device["contraindications"] + "\n</details>\n\n"
 
 
 
 
 
 
31
 
32
+ return gr.update(value=md_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ def add_device(
35
+ device_name,
36
+ device_type,
37
+ upload_instruction,
38
+ intended_use,
39
+ indications,
40
+ contraindications
41
+ ):
42
 
43
+ if device_name in [d["device_name"] for d in app_data["devices"]]:
44
+ return gr.update(value="Device already exists!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ device = {
47
+ "device_name":device_name,
48
+ "device_type":device_type,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
 
51
+ if upload_instruction:
52
+ content, _ = read_pdf(upload_instruction)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
+ device["intended_use"] = get_intended_use(content)
55
+ device["indications"] = get_indications(content)
56
+ device["contraindications"] = get_contraindications(content)
 
 
 
 
 
 
 
 
 
 
57
 
58
+ filename = upload_instruction.name.split("/")[-1] if "/" in upload_instruction.name else upload_instruction.name.split("\\")[-1]
 
 
 
 
 
 
 
 
 
59
 
60
+ upload_fileobj(upload_instruction,"instructions",filename)
61
+ else:
62
+ device["intended_use"] = intended_use
63
+ device["indications"] = indications
64
+ device["contraindications"] = contraindications
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ res = post_item("devices",device)
67
+ app_data["current_device"] = device
 
 
 
 
68
 
69
+ init_app_data()
 
 
 
 
 
70
 
71
+ return create_view(device)
 
72
 
73
+ def get_device(
74
+ device_name
75
+ ):
76
+ item = get_item("devices",{"device_name":device_name})["Item"]
77
+ device = db_map_to_py_dict(item)
78
+ return device["device_name"], device["device_type"], device["intended_use"], device["indications"], device["contraindications"], create_view(device)
79
 
80
+ def remove_device(
81
+ device_name
82
+ ):
83
+ res = delete_item("devices",{"device_name":device_name})
84
+ return res
85
 
86
+ def update_device(
87
+ device_name,
88
+ device_type,
89
+ intended_use,
90
+ indications,
91
+ contraindications
92
+ ):
93
+ device = {
94
+ "device_name":device_name,
95
+ "device_type":device_type,
96
+ "intended_use":intended_use,
97
+ "indications":indications,
98
+ "contraindications":contraindications
99
+ }
100
+ res = put_item("devices",device)
101
+ return res
102
 
103
+ def get_intended_use(content):
104
+ instructions = [
105
+ "what is the intended use of this device?"
 
 
 
106
  ]
107
+ result = send_inst(create_inst(content,instructions))
108
+ return result
109
 
110
+ def get_indications(content):
111
+ instructions = [
112
+ "what are the indications for use outllined for this device?"
113
+ ]
114
+ result = send_inst(create_inst(content,instructions))
115
+ return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ def get_contraindications(content):
118
+ instructions = [
119
+ "what are the contraindications for use outllined for this device?"
120
+ ]
121
+ result = send_inst(create_inst(content,instructions))
122
+ return result
test_cloud.py DELETED
@@ -1,29 +0,0 @@
1
- from cloud_db import *
2
- from cloud_storage import *
3
- from utility import default_domain
4
-
5
- import unittest
6
-
7
- tables = ["articles","prompts","terms","outputs"]
8
- samples_dir = "../.samples/input/"
9
-
10
- files = []
11
- for file in os.listdir(samples_dir):
12
- if file.endswith(".pdf"):
13
- files.append(os.path.join(samples_dir, file))
14
-
15
- class TestCloud(unittest.TestCase):
16
- # a function to test the cloud db get article function
17
- def test_cloud_db(self):
18
- pass
19
-
20
- # a function to test the cloud storage upload file function
21
- def test_cloud_storage(self):
22
- # upload a file to the cloud storage
23
- for f in files:
24
- # filename = os.path.basename(f)
25
- assert upload_file(f,default_domain) == True
26
- # assert res == True
27
-
28
- if __name__ == '__main__':
29
- unittest.main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui_device.py CHANGED
@@ -2,14 +2,7 @@ import gradio as gr
2
 
3
  from utility import *
4
  from application import *
5
- from features import init_app_data, add_device
6
- # from ui_list import render_list
7
-
8
- def refresh_ui_device():
9
- # init_app_data()
10
- # render_list()
11
-
12
- return ()
13
 
14
  def reset():
15
  return (
@@ -18,59 +11,113 @@ def reset():
18
  gr.File.update(value=None),
19
  gr.TextArea.update(value=""),
20
  gr.TextArea.update(value=""),
21
- gr.TextArea.update(value="")
 
22
  )
23
 
 
 
 
 
 
 
 
 
24
  with gr.Blocks() as device_page:
25
-
26
- with gr.Column():
27
- gr.Markdown("## Devices")
28
- gr.HTML("<hr>")
29
- device_name = gr.Textbox(lines=1, label="Subject Device Name")
 
 
 
 
 
 
 
 
 
30
 
31
- upload_instruction = gr.File(label="Upload IFU(Instruction For Use)")
32
 
33
- intented_use = gr.TextArea(lines=5, label="Intended Use")
34
- indications = gr.TextArea(lines=5, label="Indication")
35
- contraindications = gr.TextArea(lines=5, label="Contraindication")
36
 
37
- with gr.Row():
38
- btn_reset = gr.Button("Reset",variant="stop")
39
- btn_add = gr.Button("Add",variant="primary")
 
40
 
41
- btn_reset.click(
42
- fn=reset,
43
- outputs=[
44
- device_name,
45
- upload_instruction,
46
- intented_use,
47
- indications,
48
- contraindications
49
- ])
50
 
51
- btn_add.click(
52
- fn=add_device,
53
- inputs=[
54
- device_name,
55
- upload_instruction,
56
- intented_use,
57
- indications,
58
- contraindications
59
- ])
 
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- # show the list of devices in the database
63
- with gr.Column() as device_list:
64
- gr.HTML("<hr>")
65
- gr.Markdown("## Device List")
66
- gr.HTML("<hr>")
67
- # gr.Label("Select a device to view the details")
68
- # devices_list = render_list(app_data["devices"],title="Device List")
 
 
 
 
 
69
 
70
- btn_refresh = gr.Button("Refresh")
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- btn_refresh.click(
73
- fn=refresh_ui_device
74
- )
 
 
75
 
76
-
 
 
 
 
 
 
 
 
 
2
 
3
  from utility import *
4
  from application import *
5
+ from features import init_app_data, add_device, remove_device, get_device
 
 
 
 
 
 
 
6
 
7
  def reset():
8
  return (
 
11
  gr.File.update(value=None),
12
  gr.TextArea.update(value=""),
13
  gr.TextArea.update(value=""),
14
+ gr.TextArea.update(value=""),
15
+ gr.Markdown.update(value="")
16
  )
17
 
18
+ def refresh():
19
+ init_app_data()
20
+ '''
21
+ refresh the literature report.
22
+ '''
23
+ print([d["device_name"] for d in app_data["devices"]])
24
+ return create_md_tables(app_data["devices"]), gr.Dropdown.update(choices=[d["device_name"] for d in app_data["devices"]])
25
+
26
  with gr.Blocks() as device_page:
27
+ with gr.Row():
28
+ with gr.Column():
29
+ gr.Markdown("## Devices")
30
+ gr.HTML("<hr>")
31
+ select_device = gr.Dropdown(
32
+ choices=[d["device_name"] for d in app_data["devices"]],
33
+ # choices=["chiken","duck","goose"],
34
+ value=None,
35
+ label="Select Device",
36
+ interactive=True
37
+ )
38
+ gr.HTML("<hr>")
39
+ device_name = gr.Textbox(lines=1, label="Subject Device Name")
40
+ device_type = gr.Textbox(lines=1, label="Subject Device Type")
41
 
42
+ upload_instruction = gr.File(label="Upload IFU(Instruction For Use)")
43
 
44
+ intended_use = gr.TextArea(lines=5, label="Intended Use")
45
+ indications = gr.TextArea(lines=5, label="Indication")
46
+ contraindications = gr.TextArea(lines=5, label="Contraindication")
47
 
48
+ with gr.Row():
49
+ btn_get = gr.Button("Get",variant="primary")
50
+ btn_add = gr.Button("Add",variant="primary")
51
+ btn_reset = gr.Button("Reset",variant="stop")
52
 
53
+ gr.Markdown("## Device Details")
54
+ details = gr.Markdown("")
 
 
 
 
 
 
 
55
 
56
+ btn_reset.click(
57
+ fn=reset,
58
+ outputs=[
59
+ device_name,
60
+ device_type,
61
+ upload_instruction,
62
+ intended_use,
63
+ indications,
64
+ contraindications,
65
+ details
66
+ ])
67
 
68
+ btn_add.click(
69
+ fn=add_device,
70
+ inputs=[
71
+ device_name,
72
+ device_type,
73
+ upload_instruction,
74
+ intended_use,
75
+ indications,
76
+ contraindications
77
+ ],
78
+ outputs=[
79
+ details
80
+ ]
81
+ )
82
 
83
+ btn_get.click(
84
+ fn=get_device,
85
+ inputs=[select_device],
86
+ outputs=[
87
+ device_name,
88
+ device_type,
89
+ intended_use,
90
+ indications,
91
+ contraindications,
92
+ details
93
+ ]
94
+ )
95
 
96
+ # select_device.change(
97
+ # fn=get_device,
98
+ # inputs=[select_device],
99
+ # outputs=[
100
+ # device_name,
101
+ # device_type,
102
+ # intended_use,
103
+ # indications,
104
+ # contraindications,
105
+ # details
106
+ # ]
107
+ # )
108
 
109
+ # show the list of devices in the database
110
+ with gr.Column(scale=2):
111
+ gr.Markdown("## Devices List")
112
+ btn_refresh = gr.Button(value="Refresh",variant="primary")
113
+ gr.HTML("<hr>")
114
 
115
+ device_list = gr.Markdown("")
116
+
117
+ btn_refresh.click(
118
+ fn=refresh,
119
+ outputs=[
120
+ device_list,
121
+ select_device
122
+ ]
123
+ )
ui_studies.py DELETED
@@ -1,38 +0,0 @@
1
- import gradio as gr
2
-
3
- from application import *
4
- from features import init_app_data
5
-
6
- def refresh():
7
- init_app_data()
8
- '''
9
- refresh the literature report.
10
- '''
11
- return create_md_tables(app_data["articles"])
12
-
13
-
14
- def create_md_tables(articles):
15
- '''
16
- create markdown tables for the articles.
17
- '''
18
- md_text = ""
19
- md_text += "| Domain | File Name | Upload Time | Device |\n| --- | --- | --- | --- |\n"
20
-
21
- for article in articles:
22
- md_table = f"| {article['domain']} | {article['name']} | {article['upload_time']} | {default_device} |\n"
23
- md_text += md_table
24
-
25
- return md_text
26
-
27
- with gr.Blocks() as studies_page:
28
- with gr.Row():
29
- gr.Markdown("## Article Lists")
30
- btn_refresh = gr.Button(value="Refresh",variant="primary")
31
- gr.HTML("<hr>")
32
-
33
- article_list = gr.Markdown("")
34
-
35
- btn_refresh.click(
36
- fn=refresh,
37
- outputs=[article_list]
38
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui_study.py DELETED
@@ -1,62 +0,0 @@
1
- import gradio as gr
2
-
3
- from utility import *
4
- from application import *
5
- from features import *
6
-
7
- def reset():
8
- '''
9
- reset gradio input and output features in this page.
10
- '''
11
- return (
12
- gr.Files.update(value=None),
13
- gr.TextArea.update(value=""),
14
- gr.Markdown.update(value="")
15
- )
16
-
17
- with gr.Blocks() as study_page:
18
- with gr.Row():
19
- with gr.Column():
20
- gr.Markdown("## Studies")
21
- gr.HTML("<hr>")
22
-
23
- upload_study = gr.File(label="Upload a clinical study report",type="file")
24
-
25
- input_study = gr.TextArea(label="Or paste a clinical study report content",placeholder="Paste content here...",lines=5)
26
-
27
- with gr.Row():
28
- btn_reset = gr.Button(value="Reset",variant="stop")
29
- btn_add_study = gr.Button(value="Add",variant="primary")
30
-
31
- with gr.Column():
32
- with gr.Row():
33
- gr.Markdown("## Literature Report")
34
- btn_refresh = gr.Button(value="Refresh",variant="primary")
35
- views = gr.Markdown("")
36
-
37
- btn_reset.click(
38
- reset,
39
- outputs=[
40
- upload_study,
41
- input_study,
42
- views,
43
- ]
44
- )
45
-
46
- btn_add_study.click(
47
- process_study,
48
- inputs=[
49
- upload_study,
50
- input_study,
51
- ],
52
- outputs=[
53
- views,
54
- ],
55
- )
56
-
57
- btn_refresh.click(
58
- refresh,
59
- outputs=[
60
- views,
61
- ],
62
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
utility.py CHANGED
@@ -1,10 +1,30 @@
1
  import json
2
 
3
  from application import *
 
 
4
  from pdfminer.high_level import extract_text
5
  from pdfminer.pdfparser import PDFParser
6
  from pdfminer.pdfdocument import PDFDocument
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  '''
10
  following functions are for file manipulation
@@ -191,6 +211,27 @@ following functions are used for business logic. (to be moved to business logic
191
  '''
192
 
193
  # function to calculate the estimated cost of the translation
194
- def est_cost(n_tokens,rate):
195
  return round(rate*n_tokens/1000,4)
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import json
2
 
3
  from application import *
4
+
5
+ import tiktoken
6
  from pdfminer.high_level import extract_text
7
  from pdfminer.pdfparser import PDFParser
8
  from pdfminer.pdfdocument import PDFDocument
9
 
10
+ token_encoder = tiktoken.get_encoding("cl100k_base")
11
+
12
+ def count_tokens(text):
13
+ '''
14
+ this function count the number of tokens in the text
15
+
16
+ Parameters
17
+ ----------
18
+ text: str
19
+ text to be counted
20
+
21
+ Returns
22
+ -------
23
+ n_tokens: int
24
+ number of tokens in the text
25
+ '''
26
+
27
+ return len(token_encoder.encode(text))
28
 
29
  '''
30
  following functions are for file manipulation
 
211
  '''
212
 
213
  # function to calculate the estimated cost of the translation
214
+ def est_cost(n_tokens,rate:float=0.004):
215
  return round(rate*n_tokens/1000,4)
216
 
217
+ def create_md_tables(devices):
218
+ '''
219
+ create markdown tables for the articles.
220
+
221
+ Parameters
222
+ ----------
223
+ devices: list
224
+ list of devices
225
+
226
+ Returns
227
+ -------
228
+ md_text: str
229
+ '''
230
+ md_text = ""
231
+ md_text += "| Device name | Device Type | Intended Use | \n| --- | --- | --- | \n"
232
+
233
+ for device in devices:
234
+ md_table = f"| {device['device_name']} | {device['device_type']} | {device['intended_use']} | \n"
235
+ md_text += md_table
236
+
237
+ return md_text