This repository has been archived by the owner on Jan 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into connectFormsToDatabase
- Loading branch information
Showing
12 changed files
with
482 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
/venv | ||
*.env | ||
*.pyc | ||
*.pyc | ||
__pycache__/ | ||
service.json | ||
settings.py | ||
.vscode | ||
.venv | ||
backend/settings.py | ||
.vscode | ||
__pycache__ |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from flask import Flask, request, jsonify, session, Blueprint | ||
from firebase_admin import firestore | ||
from .conversation import Conversation # Assuming your Conversation class is defined in 'conversation.py' | ||
from firebase_admin import firestore | ||
|
||
|
||
conversation_blueprint = Blueprint('conversation', __name__) | ||
|
||
db = firestore.client() | ||
users_ref = db.collection('practitioners') | ||
|
||
@conversation_blueprint.route('/send_message', methods=['POST']) | ||
def send_message(): | ||
practitioner = request.args.get('practitioner') | ||
patient = request.args.get('patient') | ||
|
||
user_doc_ref = users_ref.document(practitioner).collection("patients").document(patient) | ||
if 'conversation_id' not in session: | ||
conversation = Conversation(user_doc_ref=user_doc_ref) | ||
session['conversation_id'] = conversation.get_conversation_id() | ||
else: | ||
conversation_id = session['conversation_id'] | ||
conversation = Conversation(user_doc_ref=user_doc_ref, conversaton_id=conversation_id) | ||
|
||
# TODO: transcribe if it is audio | ||
message = request.json.get('message') | ||
|
||
# Generate a reply using the Conversation object | ||
reply = conversation.generate_reply(message) | ||
|
||
return jsonify({'reply': reply}), 200 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import whisper | ||
import datetime | ||
import os | ||
from openai import OpenAI | ||
|
||
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | ||
model = whisper.load_model("base") | ||
|
||
|
||
class Conversation: | ||
prompt = "You are a physiotherapist. You will now be connected to a patient (the user). You are to ask them about these following exercises one at a time to see how they are progressing. Please maintain a professional tone and keep your questions succint. Your goal is to quickly acquire all the required information from the patient. Use your professional knowledge to help inform your questions relative to each exercise. Here are the exercises:" | ||
|
||
def __init__(self, user_doc_ref, conversaton_id=None): | ||
if conversaton_id: | ||
self.conversation_ref = user_doc_ref.collection("conversations").document( | ||
conversaton_id | ||
) | ||
self.history = self.conversation_ref.get().get("history") | ||
else: | ||
self.history = [] | ||
_, self.conversation_ref = user_doc_ref.collection("conversations").add( | ||
{"date": datetime.datetime.now(), "history": self.history} | ||
) | ||
self.engineer_prompt(user_doc_ref) | ||
|
||
def get_conversation_id(self): | ||
return self.conversation_ref.id | ||
|
||
@staticmethod | ||
def transcribe(audio_file): | ||
return model.transcribe(audio_file, fp16=False).get("text") | ||
|
||
def request_reply(self): | ||
return client.chat.completions.create( | ||
model="gpt-3.5-turbo", messages=self.history, temperature=0.5 | ||
) | ||
|
||
def generate_reply(self, text): | ||
self.history.append({"role": "user", "content": text}) | ||
self.conversation_ref.update({"history": self.history}) | ||
response = self.request_reply() | ||
self.history.append( | ||
{ | ||
"role": "assistant", | ||
"content": response.choices[0].message.content.strip(), | ||
} | ||
) | ||
self.conversation_ref.update({"history": self.history}) | ||
return response.choices[0].message.content.strip() | ||
|
||
def generate_greeting(self): | ||
self.history.append({"role": "system", "content": self.prompt}) | ||
response = self.request_reply() | ||
self.history.append( | ||
{ | ||
"role": "assistant", | ||
"content": response.choices[0].message.content.strip(), | ||
} | ||
) | ||
self.conversation_ref.update({"history": self.history}) | ||
return response.choices[0].message.content.strip() | ||
|
||
def engineer_prompt(self, user_doc_ref): | ||
exercises = user_doc_ref.get().get("exercises") | ||
if exercises: | ||
for exercise in exercises: | ||
self.prompt += "\n" + exercise | ||
|
||
self.prompt += f". When necessary, please refer the patient to contact their physiotherapist who's name is: {user_doc_ref.parent.parent.get().get('name')}." | ||
|
||
def end_conversation(self): | ||
print(self.history) | ||
self.history.append( | ||
{ | ||
"role": "system", | ||
"content": "Summarize the entire conversation between the user and the assistant for a physiotherapist focus on the answers the user game. Give me only the summary, no other text.", | ||
} | ||
) | ||
response = client.chat.completions.create( | ||
model="gpt-3.5-turbo", messages=self.history, temperature=0.5 | ||
) | ||
self.summary = response.choices[0].message.content.strip() | ||
|
||
# Add the summary to the conversation collection | ||
self.conversation_ref.update({"summary": self.summary}) | ||
|
||
return self.summary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from flask import request, jsonify, Blueprint | ||
from firebase_admin import firestore | ||
from .conversation import ( | ||
Conversation, | ||
) | ||
from firebase_admin import firestore | ||
import tempfile | ||
import os | ||
|
||
conversation_blueprint = Blueprint("conversation", __name__) | ||
db = firestore.client() | ||
users_ref = db.collection("practitioners") | ||
|
||
session = {} | ||
|
||
|
||
@conversation_blueprint.route("/start") | ||
def start(): | ||
practitioner = request.args.get("practitioner") | ||
patient = request.args.get("patient") | ||
user_doc_ref = ( | ||
users_ref.document(practitioner).collection("patients").document(patient) | ||
) | ||
|
||
conversation = Conversation(user_doc_ref=user_doc_ref) | ||
greeting = conversation.generate_greeting() | ||
session["conversation_id"] = conversation.get_conversation_id() | ||
|
||
return jsonify({"reply": greeting}), 200 | ||
|
||
|
||
@conversation_blueprint.route("/send_message", methods=["POST"]) | ||
def send_message(): | ||
practitioner = request.args.get("practitioner") | ||
patient = request.args.get("patient") | ||
user_doc_ref = ( | ||
users_ref.document(practitioner).collection("patients").document(patient) | ||
) | ||
if "conversation_id" not in session: | ||
return jsonify({"reply": "Please start a conversation first"}), 400 | ||
|
||
conversation_id = session["conversation_id"] | ||
conversation = Conversation( | ||
user_doc_ref=user_doc_ref, conversaton_id=conversation_id | ||
) | ||
|
||
# Store audio in a temp file | ||
audio = request.files["audioFile"] | ||
temp_audio_path = os.path.join(tempfile.gettempdir(), "received_audio.wav") | ||
audio.save(temp_audio_path) | ||
|
||
# Transcribe the audio | ||
message = Conversation.transcribe(str(temp_audio_path)) | ||
os.remove(temp_audio_path) | ||
|
||
# Generate a reply using the Conversation object | ||
reply = conversation.generate_reply(message) | ||
return jsonify({"reply": reply}), 200 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
annotated-types==0.6.0 | ||
anyio==4.2.0 | ||
bidict==0.22.1 | ||
blinker==1.7.0 | ||
CacheControl==0.13.1 | ||
cachelib==0.10.2 | ||
cachetools==5.3.2 | ||
certifi==2023.11.17 | ||
cffi==1.16.0 | ||
charset-normalizer==3.3.2 | ||
click==8.1.7 | ||
cryptography==41.0.7 | ||
distro==1.9.0 | ||
exceptiongroup==1.2.0 | ||
filelock==3.13.1 | ||
firebase-admin==6.3.0 | ||
Flask==3.0.0 | ||
Flask-Cors==4.0.0 | ||
Flask-Mail==0.9.1 | ||
fsspec==2023.12.2 | ||
google-api-core==2.15.0 | ||
google-api-python-client==2.112.0 | ||
google-auth==2.26.1 | ||
google-auth-httplib2==0.2.0 | ||
google-cloud-core==2.4.1 | ||
google-cloud-firestore==2.14.0 | ||
google-cloud-storage==2.14.0 | ||
google-crc32c==1.5.0 | ||
google-resumable-media==2.7.0 | ||
googleapis-common-protos==1.62.0 | ||
grpcio==1.60.0 | ||
grpcio-status==1.60.0 | ||
h11==0.14.0 | ||
httpcore==1.0.2 | ||
httplib2==0.22.0 | ||
httpx==0.26.0 | ||
idna==3.6 | ||
itsdangerous==2.1.2 | ||
Jinja2==3.1.2 | ||
llvmlite==0.41.1 | ||
MarkupSafe==2.1.3 | ||
more-itertools==10.1.0 | ||
mpmath==1.3.0 | ||
msgpack==1.0.7 | ||
networkx==3.2.1 | ||
numba==0.58.1 | ||
numpy==1.26.3 | ||
nvidia-cublas-cu12==12.1.3.1 | ||
nvidia-cuda-cupti-cu12==12.1.105 | ||
nvidia-cuda-nvrtc-cu12==12.1.105 | ||
nvidia-cuda-runtime-cu12==12.1.105 | ||
nvidia-cudnn-cu12==8.9.2.26 | ||
nvidia-cufft-cu12==11.0.2.54 | ||
nvidia-curand-cu12==10.3.2.106 | ||
nvidia-cusolver-cu12==11.4.5.107 | ||
nvidia-cusparse-cu12==12.1.0.106 | ||
nvidia-nccl-cu12==2.18.1 | ||
nvidia-nvjitlink-cu12==12.3.101 | ||
nvidia-nvtx-cu12==12.1.105 | ||
openai==1.6.1 | ||
openai-whisper==20231117 | ||
proto-plus==1.23.0 | ||
protobuf==4.25.1 | ||
pyasn1==0.5.1 | ||
pyasn1-modules==0.3.0 | ||
pycparser==2.21 | ||
pydantic==2.5.3 | ||
pydantic_core==2.14.6 | ||
PyJWT==2.8.0 | ||
pyparsing==3.1.1 | ||
python-dotenv==1.0.0 | ||
python-engineio==4.8.2 | ||
python-socketio==5.10.0 | ||
regex==2023.12.25 | ||
requests==2.31.0 | ||
rsa==4.9 | ||
simple-websocket==1.0.0 | ||
sniffio==1.3.0 | ||
sympy==1.12 | ||
tiktoken==0.5.2 | ||
torch==2.1.2 | ||
tqdm==4.66.1 | ||
triton==2.1.0 | ||
typing_extensions==4.9.0 | ||
uritemplate==4.1.1 | ||
urllib3==2.1.0 | ||
Werkzeug==3.0.1 | ||
wsproto==1.2.0 |
Oops, something went wrong.