Skip to content

Commit 75b486c

Browse files
Kannav02luarss
andauthored
Design and add a MongoDB schema (Issue 75) - Revision (#101)
* (chore) added .DS_Store to .gitignore * (chore) added requirements.txt file for common folder * (feat): added the .env.example file for mongoDB * (feat) added the basic mongoDB functions to run * (feat) design for mongoDB schemas made and added * (chore) removed debug statements and added credentials.json to gitignore * (fix): fixed inconsistenicies in the code and removed debug statements * Update frontend/streamlit_app.py * fix checks --------- Signed-off-by: Kannav02 <[email protected]> Co-authored-by: Jack Luar <[email protected]>
1 parent 9af54cc commit 75b486c

File tree

7 files changed

+167
-6
lines changed

7 files changed

+167
-6
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ venv/
1414
.mypy_cache/
1515
.vscode/
1616
.venv
17+
.DS_Store
1718

1819
# docs
1920
documents.txt
21+
credentials.json
2022

2123
# virtualenv
2224
.venv

backend/src/agents/retriever_graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def route(self, state: AgentState) -> list[str]:
196196
return ["retrieve_general"]
197197

198198
if self.inbuit_tool_calling:
199-
tool_names = [tool["name"] for tool in tools if "name" in tool] # type: ignore
199+
tool_names = [tool["name"] for tool in tools if "name" in tool] # type: ignore
200200
return tool_names
201201
else:
202202
return tools

backend/src/api/main.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from fastapi import FastAPI
2-
32
from .routers import graphs, healthcheck
43

54
app = FastAPI()

common/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MONGO_DB_URI = YOUR_MONGO_DB_URI

common/mongoClient.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
from pymongo import MongoClient
2+
from pymongo.database import Database
3+
from dotenv import load_dotenv
4+
import os
5+
6+
load_dotenv()
7+
8+
# HARDCODED collection names
9+
feedback_collection_name = "feedback"
10+
context_collection_name = "context"
11+
12+
def get_mongo_db_client() -> Database:
13+
"""
14+
Get the MongoDB client.
15+
16+
Returns:
17+
- DatabaseClient: The Database client.
18+
19+
Note:
20+
MongoDB doesn't create a collection or a database until it gets content, so no need to check if the data already exists or not.
21+
"""
22+
23+
uri = os.getenv("MONGO_DB_URI")
24+
client = MongoClient(uri)
25+
# this is the database that is returned by the client
26+
return client["feedback_db"]
27+
28+
def submit_feedback():
29+
"""
30+
Submit feedback Record to the MongoDB database.
31+
32+
Args:
33+
- question (str): The question for which feedback is being submitted.
34+
- answer (str): The generated answer to the question.
35+
- sources (list[str]): Source data used for the answer.
36+
- context (list[str]): Additional context from the RAG.
37+
- issue (str): Details about the issue.
38+
- version (str): Version information.
39+
40+
Returns:
41+
- None
42+
"""
43+
44+
feedback_db_client = get_mongo_client()
45+
46+
try:
47+
if not check_collection_exists(feedback_collection_name,feedback_db_client,):
48+
create_collection(feedback_collection_name,feedback_db_client, validator={
49+
'$jsonSchema': {
50+
'bsonType': 'object',
51+
'required': ['question', 'answer', 'sources', 'context_ids', 'issue', 'version', 'timestamp'],
52+
'properties': {
53+
'question': {
54+
'bsonType': 'string',
55+
'description': 'must be a string and is required'
56+
},
57+
'answer': {
58+
'bsonType': 'string',
59+
'description': 'must be a string and is required'
60+
},
61+
'sources': {
62+
'bsonType': 'array',
63+
'items': {
64+
'bsonType': 'objectId'
65+
},
66+
'description': 'must be an array of ObjectIds referencing the sources and is required'
67+
},
68+
'context': {
69+
'bsonType': 'array',
70+
'items': {
71+
'bsonType': 'string'
72+
},
73+
'description': 'must be an array of strings and is required'
74+
},
75+
'issue': {
76+
'bsonType': 'string',
77+
'description': 'must be a string and is required'
78+
},
79+
'version': {
80+
'bsonType': 'string',
81+
'description': 'must be a string and is required'
82+
},
83+
'timestamp': {
84+
'bsonType': 'date',
85+
'description': 'must be a date and is required'
86+
},
87+
'status': {
88+
'enum': ['new', 'processing', 'resolved'],
89+
'description': 'can only be one of the enum values'
90+
}
91+
}
92+
}
93+
})
94+
if not check_collection_exists(context_collection_name,feedback_db_client):
95+
create_collection(context_collection_name,feedback_db_client,{
96+
'bsonType': 'object',
97+
'required': ['source', 'timestamp'],
98+
'properties': {
99+
'source': {
100+
'bsonType': 'string',
101+
'description': 'must be a string and is required'
102+
},
103+
'metadata': {
104+
'bsonType': 'object',
105+
'description': 'additional metadata for the context'
106+
},
107+
'timestamp': {
108+
'bsonType': 'date',
109+
'description': 'must be a date and is required'
110+
}
111+
}
112+
}
113+
)
114+
115+
except Exception as e:
116+
print(f"Failed to submit feedback: {e}")
117+
return None
118+
119+
def check_collection_exists(collection_name:str,client_database:Database)->bool:
120+
"""
121+
Check if the collection exists in the database.
122+
123+
Args:
124+
- collection_name (str): The name of the collection to check.
125+
- client_database (Database): The database to check.
126+
127+
Returns:
128+
- None
129+
"""
130+
return collection_name in client_database.list_collection_names()
131+
132+
def create_collection(collection_name:str,client_database:Database,validator:object)->None:
133+
"""
134+
Create a collection in the database.
135+
136+
Args:
137+
- collection_name (str): The name of the collection to create.
138+
- client_database (Database): The database to create the collection in.
139+
140+
Returns:
141+
- None
142+
"""
143+
try:
144+
client_database.create_collection(collection_name,validator=validator)
145+
print("Collection created successfully")
146+
except Exception as e:
147+
print(f"Failed to create collection: {e}")
148+
return None
149+
150+
if __name__ == "__main__":
151+
submit_feedback()

common/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pymongo==4.6.2
2+
python-dotenv==1.0.1

frontend/utils/feedback.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def submit_feedback_to_google_sheet(
9696
]
9797

9898
creds = Credentials.from_service_account_file(service_account_file, scopes=scope)
99+
# this is the place where the client is coming from, need to change this for mongoDB client
99100
client = gspread.authorize(creds)
100101

101102
sheet_id = os.getenv("FEEDBACK_SHEET_ID", "")
@@ -170,8 +171,13 @@ def show_feedback_form(
170171
feedback = st.sidebar.text_area("Please provide your feedback or report an issue:")
171172

172173
if selected_question:
173-
sources = [metadata[selected_question].get("sources", "N/A")]
174-
context = [metadata[selected_question].get("context", "N/A")]
174+
sources = metadata[selected_question].get("sources", ["N/A"])
175+
if isinstance(sources, str):
176+
sources = [sources]
177+
178+
context = metadata[selected_question].get("context", ["N/A"])
179+
if isinstance(context, str):
180+
context = [context]
175181

176182
if st.sidebar.button("Submit"):
177183
selected_index = questions[selected_question]
@@ -180,8 +186,8 @@ def show_feedback_form(
180186
submit_feedback_to_google_sheet(
181187
question=selected_question,
182188
answer=gen_ans,
183-
sources=sources,
184-
context=context,
189+
sources=sources, # Now passing as list
190+
context=context, # Now passing as list
185191
issue=feedback,
186192
version=os.getenv("RAG_VERSION", get_git_commit_hash()),
187193
)

0 commit comments

Comments
 (0)