-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.py
More file actions
399 lines (314 loc) · 14.1 KB
/
index.py
File metadata and controls
399 lines (314 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
from flask import Flask, request, jsonify
from flask_cors import CORS
import requests
from openai import OpenAI
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
from dotenv import load_dotenv
import os
import json
import time
import threading
# loading our open ai api key
load_dotenv()
client = OpenAI( api_key = os.getenv('API_KEY') )
# loading our firebase keys
Firebase_KEY = credentials.Certificate(os.getenv('FIREBASE_KEY'))
firebase_admin.initialize_app(
Firebase_KEY,{
"databaseURL": os.getenv('DATABASE_URL')
})
app = Flask(__name__)
CORS(app)
# Shared storage for data between /medicalTalk and /response routes
shared_data = {"response": None}
# Lock to synchronize access to shared_data
data_lock = threading.Lock()
# open ai route
@app.route("/medicalTalk", methods=["POST"])
def openAi():
try:
# getting user text and user expectation
req = request.get_json()
data = req.get("data", "")
opinion = req.get("opinion", "0")
uid = req.get("user", "anonymose")
backend = req.get("backend", "")
print(data)
prompt = Prompt(data)
res = ""
# Handeling if we are going to call the openAi servers, or our LLM
if(backend == "HeReFaNmi LLM"):
# connecting to RAG server
RAGrequest(data)
# waiting for the response from the LLM server to be stored in shared_data
res = wait_for_response()
# terminate the connection and make a simple response so the app don't crash
if res == None :
res = """{
"medical": "True",
"news": "False",
"label": "Doubtful",
"reasoning": "We can't respond to your statment due to the waiting timeout for the LLM to respond, PLEASE TRY LATER!",
"sources": []
}"""
else :
# connecting to openAi server
res = backendHandler(backend, prompt)
print(res)
# getting the fields from the json
res_dict = json.loads(res)
medical_value = res_dict.get("medical", "True")
response_value = res_dict.get("reasoning", "")
label = res_dict.get("label", "Doubtful")
sources = res_dict.get("sources",[])
news = res_dict.get("news", "False")
#c learing the source list from the links that don't work before returning it
sources = ClearSources(sources)
# means that the data is not related to the medical field
if medical_value == "False" :
# saving data in firebase
reference = firebaseSave(uid, opinion, data, medical_value, news, response_value, label)
return jsonify(data = "Please try to ask something related to to medical field... !",
key = reference), 200
# saving data in firebase
reference = firebaseSave(uid, opinion, data, medical_value, news, response_value, label)
return jsonify(data = response_value, news = news, label = label, source = sources, key = reference), 200
except Exception as e:
print(str(e))
return jsonify({'error': str(e)}), 500
# Waiting timeout for the LLM response
def wait_for_response(timeout=30):
# Wait for the external server to respond, with a timeout.
start_time = time.time()
while time.time() - start_time < timeout:
with data_lock:
if shared_data["response"] is not None:
# Retrieve and clear the shared response we got from the /response route
response = shared_data["response"]
shared_data["response"] = None
return response
# Wait a short time before checking again
time.sleep(0.5)
# Return None if no response within the timeout period
return None
# Sending prompt to the RAG server
def RAGrequest(prompt):
# Connecting to walid's backend to send him the user prompt
url = "http://127.0.1:5000/find_similar_chunks"
# Prompt to send in the POST request
payload = {
"prompt": prompt,
"top_n": 3
}
try:
# Make a POST request to oualid's RAG server
response = requests.post(url, json=payload)
# Check if the request was successful
if response.status_code == 200:
print("Prompt sent successfully!")
else:
print("Failed to send the prompt to oualid's RAG server. Status code:", response.status_code)
except Exception as e:
print("Error during request:", e)
# getting the response from Hamdi's LLM server
@app.route("/response", methods=["POST"])
def LLMResponse():
try:
# getting the response from the LLM
data = request.get_json()
res = data.get("response", "")
print("################################")
print("dataaa from the server", res)
print("#################################")
# Store the LLM server response in shared_data
with data_lock:
shared_data["response"] = res
return "SUCCESS", 200
except Exception as e:
print(str(e))
return jsonify({'error': str(e)}), 500
def ClearSources(sources):
working_links = []
for link in sources:
try:
response = requests.head(link)
# Check if the response status code indicates success (2xx)
if response.status_code // 100 == 2:
working_links.append(link)
except requests.RequestException:
# If there's an exception (e.g., connection error), consider the link not working
working_links.append("{Web page is not working}")
pass
return working_links
def Prompt(data) :
return '''
<SYSTEM>
You are the most knowledgeable medical professional in history, you can effectively and accurately classify medical news articles as 'Trustworthy', 'Doubtful', or 'Fake'.
You can also provide reasoning and resources to back up your decision. Please include relevant details such as publication date, author, and any notable bias associated with the sources. Ensure a comprehensive analysis to assist in determining the credibility of the news report.
Here are some Examples for you to learn how you can response to my prompt :
--------------------------------------------------------------------
[
{
"input": "Groundbreaking Research Confirms New Treatment for Common Illness",
"output": {
"medical" : "True",
"news" : "True",
"reasoning": "A recent scientific study has discovered a revolutionary treatment for [common illness]. The research involved a large sample size and rigorous testing, providing hope for millions of patients worldwide.",
"label": "Trustworthy",
"sources": ["link from the internet to the reference that confirms it's trustworthy"]
}
},
{
"input": "Unverified Sources Claim Extra-terrestrial Contact in Remote Area",
"output": {
"medical" : "False",
"news" : "True",
"reasoning": "Reports from unidentified sources suggest that extra-terrestrial beings have made contact in a remote area. The lack of credible evidence and reliance on unverified testimonials makes this information highly doubtful.",
"label": "Doubtful",
"sources": [link from the internet for the reference that confirms it's doubtful]
}
},
{
"input": "World Leaders Announce Global Collaboration for Sustainable Energy",
"output": {
"medical" : "False",
"news" : "True",
"reasoning": "In a historic move, world leaders have come together to announce a comprehensive global collaboration aimed at achieving sustainable and clean energy solutions. The news is corroborated by official statements from multiple government representatives.",
"label": "Trustworthy",
"sources": ["https://official-government-statements.com"]
}
},
{
"input": "Giant Prehistoric Lizard Discovered in Urban Area",
"output": {
"medical" : "False",
"news" : "True",
"reasoning": "A team of archaeologists claims to have discovered a giant prehistoric lizard in the heart of a major city. The lack of credible sources, scientific backing, and the sensational nature of the news make it likely to be fake.",
"label": "Fake",
"sources": ["link from the internet to the reference that confirms it's fake"]
}
},
{
"input": "What is cancer?",
"output": {
"medical" : "True",
"news" : "False",
"reasoning": "Cancer is a group of diseases involving abnormal cell growth with the potential to invade or spread to other parts of the body. ",
"label": "trustworthy",
"sources": ["https://official-health-statements.com"]
}
},
]
--------------------------------------------------------------------
Instructions:
<instructions>
A - The response should always be only the output part of the JSON.
B - Responde by JSON contains the fields:
<json>
1 - "medical" : "True" (if the input has a relation with the medical field), or "False" (if the input doen't have a relation to the medical field).
2- "news" : "True" (if the input presents news, declarations, or information), or "Fake" (if the input presents a question, or is asking to provide information).
3 - "label" : "Fake" ( if the input is fake and presents false informations, unverified treatment , or information not aligned with medical research or regulated clinical practices), "Doubtful" (if the input presents trustworthy information contaminated by some fake information, or if the information presented is still experimental and is not completely validated by medical research and clinical practice ), or "Trustworthy"( if the input presents valid information verified by peer reviewed medical research and common clinical practice).
4 - "reasoning" : ( contains an explanation to the reason you chose the label ).
5 - "sources" : contains a list of web sites links, and research papers that have the reference to back up your decision for the label.
</json>
C - Don't add any other text besides the JSON response.
D - Respond to every following prompt by strictly adhering to the instruction provided above.
</instructions>
</SYSTEM>
<query>
Strictly following the information and direction provided to you as a system, evaluate this query :
<input>''' , data , ''' </input>
</query>" '''
# Choosing which openAi model we want to work with
def backendHandler(type, prompt):
Model = ""
# gpt 4 turbo ai request
if (type == "GPT4") :
Model = "gpt-4"
print("Working wih gpt 4 in the open ai ")
else :
Model = "gpt-3.5-turbo"
print("Working wih gpt 3 turbo in the open ai ")
# calling the openAi api
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": str(prompt),
}
],
model= Model,)
# getting response from open ai
res = chat_completion.choices[0].message.content
return res
# saving the user rating route
@app.route("/save", methods=["POST"])
def saveRating():
try:
# getting reference and rating
data = request.get_json()
ref = data.get("reference", "")
rating = data.get('rating', "")
uid = data.get('user', "anonymose")
ratingSaveReference(uid, ref, rating)
return "SUCCESS", 200
except Exception as e:
print(str(e))
return jsonify({'error': str(e)}), 500
# saving the user expectation, user prompt + the open ai response in the firebase
def firebaseSave(uid, opinion, data, med, news, res, label):
# puting user data in firebase
ref = db.reference(uid).push()
ref.set({
"Question": data,
"Opinion": opinion,
"Medical": med,
"News": news,
"label": label,
"Response": res,
"Rating" : "0"
})
# returning the key so we can use it to save the rating after
return str(ref.key)
# save rating in the firebase with the passed reference from the user
def ratingSaveReference(uid, reference, rating):
# puting user data in firebase
db.reference(uid).child(reference).child("Rating").set(rating)
# save the user first signup points in the firebase
@app.route("/pointsave", methods=["POST"])
def savePoints():
try:
# getting the user id from the request
data = request.get_json()
user = data.get("user", "")
points = data.get("points", "")
db.reference("users").child(user).child("points").set(points)
return "SUCCESS", 200
except Exception as e:
print(str(e))
return jsonify({'error': str(e)}), 500
# check if this is the user's first signup
@app.route("/pointcheck", methods=["POST"])
def checkPoints():
try:
# getting the user id from the request
data = request.get_json()
user = data.get("user", "")
points = db.reference("users").child(user).get("points")
# Extracting points from the tuple
if (points[0] != None):
points = points[0].get('points', 1)
print("Your point are ", points)
if points is not None:
# means that this user is not a new user
return jsonify(points = points), 200
# means this is a new user account
return jsonify(points = -1), 200
except Exception as e:
print(str(e))
return jsonify({'error': str(e)}), 500
if __name__ == "__main__":
app.run(host='0.0.0.0', port=10000)
# app.run(port=4000)