Spaces:
Runtime error
Runtime error
Cleanup code for better UX
Browse files- Dockerfile +6 -6
- app/admin/templates/admin_login.html +1 -1
- app/admin/templates/data_management.html +1 -1
- app/admin/templates/registration_success.html +1 -0
- app/admin/templates/user_registration.html +1 -1
- app/dependencies.py +8 -2
- app/main.py +1 -1
- app/utils/chat_rag.py +84 -84
- app/utils/db.py +0 -1
Dockerfile
CHANGED
|
@@ -23,9 +23,6 @@ ENV HOME=/home/user \
|
|
| 23 |
# Set the non-root user's home directory as the working directory
|
| 24 |
WORKDIR $HOME
|
| 25 |
|
| 26 |
-
# Create a symbolic link from /data to /home/user/data
|
| 27 |
-
RUN ln -s /data /home/user/data
|
| 28 |
-
|
| 29 |
# Change to the non-root user
|
| 30 |
USER user
|
| 31 |
|
|
@@ -44,6 +41,12 @@ WORKDIR $HOME/app
|
|
| 44 |
# Copy the rest of the application files into the container
|
| 45 |
COPY --chown=user:user ./app .
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
# Make port 7860 available to the world outside this container
|
| 48 |
EXPOSE 7860
|
| 49 |
|
|
@@ -56,8 +59,5 @@ RUN chmod +x /home/user/entrypoint.sh
|
|
| 56 |
# Update the ENTRYPOINT command to use the full path to entrypoint.sh
|
| 57 |
ENTRYPOINT ["/home/user/entrypoint.sh"]
|
| 58 |
|
| 59 |
-
# Set Python path just to make sure
|
| 60 |
-
ENV PYTHONPATH="/home/user/app:${PYTHONPATH}"
|
| 61 |
-
|
| 62 |
# Adjust the CMD to ensure it correctly references the FastAPI app
|
| 63 |
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
| 23 |
# Set the non-root user's home directory as the working directory
|
| 24 |
WORKDIR $HOME
|
| 25 |
|
|
|
|
|
|
|
|
|
|
| 26 |
# Change to the non-root user
|
| 27 |
USER user
|
| 28 |
|
|
|
|
| 41 |
# Copy the rest of the application files into the container
|
| 42 |
COPY --chown=user:user ./app .
|
| 43 |
|
| 44 |
+
# Create a symbolic link from /data to /home/user/data
|
| 45 |
+
RUN ln -s /data /home/user/data
|
| 46 |
+
|
| 47 |
+
# Set Python path just to make sure
|
| 48 |
+
ENV PYTHONPATH="/home/user/app:${PYTHONPATH}"
|
| 49 |
+
|
| 50 |
# Make port 7860 available to the world outside this container
|
| 51 |
EXPOSE 7860
|
| 52 |
|
|
|
|
| 59 |
# Update the ENTRYPOINT command to use the full path to entrypoint.sh
|
| 60 |
ENTRYPOINT ["/home/user/entrypoint.sh"]
|
| 61 |
|
|
|
|
|
|
|
|
|
|
| 62 |
# Adjust the CMD to ensure it correctly references the FastAPI app
|
| 63 |
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
|
app/admin/templates/admin_login.html
CHANGED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
<head>
|
| 3 |
<title>EduConnect Administration - login page</title>
|
| 4 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 5 |
-
<link href="static/css/mvp.css" rel="stylesheet" media="screen">
|
| 6 |
</head>
|
| 7 |
<body>
|
| 8 |
<div class="container">
|
|
|
|
| 2 |
<head>
|
| 3 |
<title>EduConnect Administration - login page</title>
|
| 4 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 5 |
+
<link href="/static/css/mvp.css" rel="stylesheet" media="screen">
|
| 6 |
</head>
|
| 7 |
<body>
|
| 8 |
<div class="container">
|
app/admin/templates/data_management.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
<head>
|
| 4 |
<title>Econnect Data Management</title>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<link href="static/css/mvp.css" rel="stylesheet" media="screen">
|
| 7 |
<!-- Bootstrap CSS -->
|
| 8 |
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
| 9 |
</head>
|
|
|
|
| 3 |
<head>
|
| 4 |
<title>Econnect Data Management</title>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<link href="/static/css/mvp.css" rel="stylesheet" media="screen">
|
| 7 |
<!-- Bootstrap CSS -->
|
| 8 |
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
| 9 |
</head>
|
app/admin/templates/registration_success.html
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
<html>
|
| 3 |
<head>
|
| 4 |
<title>Registration Success</title>
|
|
|
|
| 5 |
</head>
|
| 6 |
<body>
|
| 7 |
<h1>Registration Successful!</h1>
|
|
|
|
| 2 |
<html>
|
| 3 |
<head>
|
| 4 |
<title>Registration Success</title>
|
| 5 |
+
<link href="/static/css/mvp.css" rel="stylesheet" media="screen">
|
| 6 |
</head>
|
| 7 |
<body>
|
| 8 |
<h1>Registration Successful!</h1>
|
app/admin/templates/user_registration.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
<head>
|
| 4 |
<title>Econnect User Registration</title>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<link href="static/css/mvp.css" rel="stylesheet" media="screen">
|
| 7 |
</head>
|
| 8 |
<body>
|
| 9 |
<div class=""container">
|
|
|
|
| 3 |
<head>
|
| 4 |
<title>Econnect User Registration</title>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<link href="/static/css/mvp.css" rel="stylesheet" media="screen">
|
| 7 |
</head>
|
| 8 |
<body>
|
| 9 |
<div class=""container">
|
app/dependencies.py
CHANGED
|
@@ -13,6 +13,12 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
|
| 13 |
headers={"WWW-Authenticate": "Bearer"},
|
| 14 |
)
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
# Utilize the centralized JWT decoding and catch any JWT-related errors
|
| 17 |
try:
|
| 18 |
payload = decode_jwt(token)
|
|
@@ -23,9 +29,9 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
|
| 23 |
if user_id is None:
|
| 24 |
raise credentials_exception
|
| 25 |
|
| 26 |
-
# Verify if the token is stored and valid
|
| 27 |
if not tinydb_helper.query_token(user_id, token):
|
| 28 |
-
raise
|
| 29 |
|
| 30 |
# Payload is already obtained and validated, so just return it or its specific parts as needed
|
| 31 |
return {"user_id": user_id, "name": payload.get("name"), "role": payload.get("role")}
|
|
|
|
| 13 |
headers={"WWW-Authenticate": "Bearer"},
|
| 14 |
)
|
| 15 |
|
| 16 |
+
expiry_exception = HTTPException(
|
| 17 |
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
| 18 |
+
detail="No session found, please login again",
|
| 19 |
+
headers={"WWW-Authenticate": "Bearer"},
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
# Utilize the centralized JWT decoding and catch any JWT-related errors
|
| 23 |
try:
|
| 24 |
payload = decode_jwt(token)
|
|
|
|
| 29 |
if user_id is None:
|
| 30 |
raise credentials_exception
|
| 31 |
|
| 32 |
+
# Verify if the token is stored and valid as active session
|
| 33 |
if not tinydb_helper.query_token(user_id, token):
|
| 34 |
+
raise expiry_exception
|
| 35 |
|
| 36 |
# Payload is already obtained and validated, so just return it or its specific parts as needed
|
| 37 |
return {"user_id": user_id, "name": payload.get("name"), "role": payload.get("role")}
|
app/main.py
CHANGED
|
@@ -49,7 +49,7 @@ async def startup_event():
|
|
| 49 |
print(f"MODEL_PATH in main.py = {os.getenv('MODEL_PATH')} ")
|
| 50 |
|
| 51 |
# Mount static files
|
| 52 |
-
app.mount("/
|
| 53 |
|
| 54 |
# Setup Jinja2Templates to point to the templates directory
|
| 55 |
templates = Jinja2Templates(directory="admin/templates")
|
|
|
|
| 49 |
print(f"MODEL_PATH in main.py = {os.getenv('MODEL_PATH')} ")
|
| 50 |
|
| 51 |
# Mount static files
|
| 52 |
+
app.mount("/static", StaticFiles(directory="static"), name="static")
|
| 53 |
|
| 54 |
# Setup Jinja2Templates to point to the templates directory
|
| 55 |
templates = Jinja2Templates(directory="admin/templates")
|
app/utils/chat_rag.py
CHANGED
|
@@ -126,90 +126,90 @@ async def load_llm():
|
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
-
#step 5, to instantiate once to create default_chain,router_chain,destination_chains into chain and set vectordb. so will not re-create per prompt
|
| 130 |
-
async def default_chain(llm, user_collection_name):
|
| 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 |
# Adjust llm_infer to accept user_id and use it for user-specific processing
|
| 215 |
async def llm_infer(user_collection_name, prompt):
|
|
|
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
+
# #step 5, to instantiate once to create default_chain,router_chain,destination_chains into chain and set vectordb. so will not re-create per prompt
|
| 130 |
+
# async def default_chain(llm, user_collection_name):
|
| 131 |
+
# # Get Chromadb location
|
| 132 |
+
# CHROMADB_LOC = os.getenv('CHROMADB_LOC')
|
| 133 |
+
|
| 134 |
+
# vectordb = await get_vectordb_for_user_cached(user_collection_name) # Use the dynamic vectordb based on user_id
|
| 135 |
+
# sum_template = """
|
| 136 |
+
# As a machine learning education specialist, our expertise is pivotal in deepening the comprehension of complex machine learning concepts for both educators and students.
|
| 137 |
+
|
| 138 |
+
# our role entails:
|
| 139 |
+
|
| 140 |
+
# Providing Detailed Explanations: Deliver comprehensive answers to these questions, elucidating the underlying technical principles.
|
| 141 |
+
# Assisting in Exam Preparation: Support educators in formulating sophisticated exam and quiz questions, including MCQs, accompanied by thorough explanations.
|
| 142 |
+
# Summarizing Course Material: Distill key information from course materials, articulating complex ideas within the context of advanced machine learning practices.
|
| 143 |
+
|
| 144 |
+
# Objective: to summarize and explain the key points.
|
| 145 |
+
# Here the question:
|
| 146 |
+
# {input}"""
|
| 147 |
+
|
| 148 |
+
# mcq_template = """
|
| 149 |
+
# As a machine learning education specialist, our expertise is pivotal in deepening the comprehension of complex machine learning concepts for both educators and students.
|
| 150 |
+
|
| 151 |
+
# our role entails:
|
| 152 |
+
# Crafting Insightful Questions: Develop thought-provoking questions that explore the intricacies of machine learning topics.
|
| 153 |
+
# Generating MCQs: Create MCQs for each machine learning topic, comprising a question, four choices (A-D), and the correct answer, along with a rationale explaining the answer.
|
| 154 |
+
|
| 155 |
+
# Objective: to create multiple choice question in this format
|
| 156 |
+
# [question:
|
| 157 |
+
# options A:
|
| 158 |
+
# options B:
|
| 159 |
+
# options C:
|
| 160 |
+
# options D:
|
| 161 |
+
# correct_answer:
|
| 162 |
+
# explanation:]
|
| 163 |
+
|
| 164 |
+
# Here the question:
|
| 165 |
+
# {input}"""
|
| 166 |
+
|
| 167 |
+
# prompt_infos = [
|
| 168 |
+
# {
|
| 169 |
+
# "name": "SUMMARIZE",
|
| 170 |
+
# "description": "Good for summarizing and explaination ",
|
| 171 |
+
# "prompt_template": sum_template,
|
| 172 |
+
# },
|
| 173 |
+
# {
|
| 174 |
+
# "name": "MCQ",
|
| 175 |
+
# "description": "Good for creating multiple choices questions",
|
| 176 |
+
# "prompt_template": mcq_template,
|
| 177 |
+
# },
|
| 178 |
+
# ]
|
| 179 |
+
|
| 180 |
+
# destination_chains = {}
|
| 181 |
+
|
| 182 |
+
# for p_info in prompt_infos:
|
| 183 |
+
# name = p_info["name"]
|
| 184 |
+
# prompt_template = p_info["prompt_template"]
|
| 185 |
+
# #vectordb=p_info["vector"]
|
| 186 |
+
# prompt = PromptTemplate(template=prompt_template, input_variables=["input"])
|
| 187 |
+
# embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2') #new
|
| 188 |
+
# vectordb= await get_vectordb_for_user_cached(user_collection_name)
|
| 189 |
+
# retriever = vectordb.as_retriever()#new
|
| 190 |
+
# memory = VectorStoreRetrieverMemory(retriever=retriever) #new
|
| 191 |
+
|
| 192 |
+
# chain = LLMChain(llm=llm, prompt=prompt, verbose=True, memory=memory) #new memory=memory
|
| 193 |
+
# destination_chains[name] = chain
|
| 194 |
+
|
| 195 |
+
# #default_chain = ConversationChain(llm=llm, output_key="text")
|
| 196 |
+
# #memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
|
| 197 |
+
|
| 198 |
+
# default_chain = ConversationalRetrievalChain.from_llm(llm=llm,
|
| 199 |
+
# retriever=vectordb.as_retriever(search_kwargs={'k': 3}),
|
| 200 |
+
# verbose=True, output_key="text" )
|
| 201 |
+
|
| 202 |
+
# destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
|
| 203 |
+
# destinations_str = "\n".join(destinations)
|
| 204 |
+
# router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str)
|
| 205 |
+
# router_prompt = PromptTemplate(
|
| 206 |
+
# template=router_template,
|
| 207 |
+
# input_variables=["input"],
|
| 208 |
+
# output_parser=RouterOutputParser(),
|
| 209 |
+
# )
|
| 210 |
+
# router_chain = LLMRouterChain.from_llm(llm, router_prompt)
|
| 211 |
+
|
| 212 |
+
# return default_chain,router_chain,destination_chains
|
| 213 |
|
| 214 |
# Adjust llm_infer to accept user_id and use it for user-specific processing
|
| 215 |
async def llm_infer(user_collection_name, prompt):
|
app/utils/db.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
|
| 2 |
import os
|
| 3 |
from tinydb import TinyDB, Query, where
|
| 4 |
from tinydb.storages import MemoryStorage
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
from tinydb import TinyDB, Query, where
|
| 3 |
from tinydb.storages import MemoryStorage
|