Spaces:
Runtime error
Runtime error
Chintan Donda
commited on
Commit
•
f0af1c3
1
Parent(s):
fafdacb
Adding support to get the Feedback on Answer shared by KCC-FTAs in Custom Query widget
Browse files- app.py +34 -0
- requirements.txt +1 -1
- src/constants.py +12 -2
- src/data_loader.py +1 -1
- src/kkms_kssw.py +1 -1
- src/langchain_utils.py +41 -3
- src/utils.py +1 -1
app.py
CHANGED
@@ -162,6 +162,21 @@ class DomState:
|
|
162 |
return self.kkms_kssw_obj.weather_utils_obj.get_weather_forecast(state, district)
|
163 |
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
def click_handler_for_get_kb_sources(
|
166 |
self
|
167 |
):
|
@@ -386,6 +401,25 @@ with gr.Blocks(title='KKMS-Smart-Search-Demo') as demo:
|
|
386 |
)
|
387 |
b_indic_lang_answer = gr.Button("Get answer in selected language").style(size='sm')
|
388 |
b_indic_lang_answer.click(fn=dom.click_handler_for_get_indic_translation, inputs=[answer, language], outputs=[indic_lang_answer])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
|
390 |
|
391 |
#############################################################################
|
|
|
162 |
return self.kkms_kssw_obj.weather_utils_obj.get_weather_forecast(state, district)
|
163 |
|
164 |
|
165 |
+
def click_handler_for_feedback(
|
166 |
+
self,
|
167 |
+
question_category,
|
168 |
+
question,
|
169 |
+
answer,
|
170 |
+
feedback
|
171 |
+
):
|
172 |
+
self.kkms_kssw_obj.langchain_utils_obj.save_answer_feeback(
|
173 |
+
question_category,
|
174 |
+
question,
|
175 |
+
answer,
|
176 |
+
feedback
|
177 |
+
)
|
178 |
+
|
179 |
+
|
180 |
def click_handler_for_get_kb_sources(
|
181 |
self
|
182 |
):
|
|
|
401 |
)
|
402 |
b_indic_lang_answer = gr.Button("Get answer in selected language").style(size='sm')
|
403 |
b_indic_lang_answer.click(fn=dom.click_handler_for_get_indic_translation, inputs=[answer, language], outputs=[indic_lang_answer])
|
404 |
+
|
405 |
+
with gr.Column(scale=1, min_width=600):
|
406 |
+
with gr.Tab(label='Feedback'):
|
407 |
+
# Submit feedback for the answer
|
408 |
+
feedback = gr.Radio(
|
409 |
+
[
|
410 |
+
"Correct",
|
411 |
+
"Incorrect",
|
412 |
+
"Partially Correct and contains irrelevant text",
|
413 |
+
"Correct but not complete",
|
414 |
+
],
|
415 |
+
label="Answer is",
|
416 |
+
value="Correct"
|
417 |
+
)
|
418 |
+
b_feedback = gr.Button("Submit Feedback").style(size='sm')
|
419 |
+
b_feedback.click(
|
420 |
+
fn=dom.click_handler_for_feedback,
|
421 |
+
inputs=[question_category, question, answer, feedback]
|
422 |
+
)
|
423 |
|
424 |
|
425 |
#############################################################################
|
requirements.txt
CHANGED
@@ -19,4 +19,4 @@ googletrans==3.1.0a0
|
|
19 |
BeautifulSoup4
|
20 |
pypdf
|
21 |
PyPDF2
|
22 |
-
html2text
|
|
|
19 |
BeautifulSoup4
|
20 |
pypdf
|
21 |
PyPDF2
|
22 |
+
html2text
|
src/constants.py
CHANGED
@@ -3,18 +3,28 @@ import src.web_crawler as web_crawler_utils
|
|
3 |
import src.weather as weather_utils
|
4 |
|
5 |
# Wheater to load the existing index store or create from scratch?
|
6 |
-
LOAD_FROM_EXISTING_INDEX_STORE =
|
7 |
INDEX_TYPE = 'FAISS'
|
8 |
|
9 |
# Path from where to load the data (from the local directory)
|
10 |
DATA_PATH = './data/'
|
11 |
|
|
|
|
|
|
|
12 |
# Path to store the index/vector db
|
13 |
-
OUTPUT_PATH = os.path.join(
|
14 |
# Create OUTPUT_PATH directory if not present
|
15 |
if not os.path.exists(OUTPUT_PATH):
|
16 |
os.makedirs(OUTPUT_PATH)
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
# Index categories (There would be an index for each category. On asking the query, App will search for the relevant docs/information only from the respective index category.)
|
19 |
INDEX_CATEGORY = [
|
20 |
'crops',
|
|
|
3 |
import src.weather as weather_utils
|
4 |
|
5 |
# Wheater to load the existing index store or create from scratch?
|
6 |
+
LOAD_FROM_EXISTING_INDEX_STORE = True
|
7 |
INDEX_TYPE = 'FAISS'
|
8 |
|
9 |
# Path from where to load the data (from the local directory)
|
10 |
DATA_PATH = './data/'
|
11 |
|
12 |
+
OUTPUT_DIR = './output/'
|
13 |
+
if not os.path.exists(OUTPUT_DIR):
|
14 |
+
os.makedirs(OUTPUT_DIR)
|
15 |
# Path to store the index/vector db
|
16 |
+
OUTPUT_PATH = os.path.join(OUTPUT_DIR, INDEX_TYPE)
|
17 |
# Create OUTPUT_PATH directory if not present
|
18 |
if not os.path.exists(OUTPUT_PATH):
|
19 |
os.makedirs(OUTPUT_PATH)
|
20 |
|
21 |
+
# Output path to store the feedback for the answers received by KCCs-FTAs
|
22 |
+
OUTPUT_PATH_ANSWER_FEEDBACK = os.path.join(OUTPUT_DIR, 'answers_feedback')
|
23 |
+
if not os.path.exists(OUTPUT_PATH_ANSWER_FEEDBACK):
|
24 |
+
os.makedirs(OUTPUT_PATH_ANSWER_FEEDBACK)
|
25 |
+
OUTPUT_PATH_ANSWER_FEEDBACK_FILE_PREFIX = 'answers_feedback'
|
26 |
+
OUTPUT_PATH_ANSWER_FEEDBACK_FILE_SAVE_SEPARATOR = '\t'
|
27 |
+
|
28 |
# Index categories (There would be an index for each category. On asking the query, App will search for the relevant docs/information only from the respective index category.)
|
29 |
INDEX_CATEGORY = [
|
30 |
'crops',
|
src/data_loader.py
CHANGED
@@ -14,10 +14,10 @@ from langchain.docstore.document import Document
|
|
14 |
import src.utils as utils
|
15 |
|
16 |
import logging
|
17 |
-
logger = logging.getLogger(__name__)
|
18 |
logging.basicConfig(
|
19 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
20 |
)
|
|
|
21 |
|
22 |
import warnings
|
23 |
warnings.filterwarnings('ignore')
|
|
|
14 |
import src.utils as utils
|
15 |
|
16 |
import logging
|
|
|
17 |
logging.basicConfig(
|
18 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
19 |
)
|
20 |
+
logger = logging.getLogger(__name__)
|
21 |
|
22 |
import warnings
|
23 |
warnings.filterwarnings('ignore')
|
src/kkms_kssw.py
CHANGED
@@ -8,10 +8,10 @@ import src.translator as translator_utils
|
|
8 |
import src.web_crawler as web_crawler_utils
|
9 |
|
10 |
import logging
|
11 |
-
logger = logging.getLogger(__name__)
|
12 |
logging.basicConfig(
|
13 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
14 |
)
|
|
|
15 |
|
16 |
import warnings
|
17 |
warnings.filterwarnings('ignore')
|
|
|
8 |
import src.web_crawler as web_crawler_utils
|
9 |
|
10 |
import logging
|
|
|
11 |
logging.basicConfig(
|
12 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
13 |
)
|
14 |
+
logger = logging.getLogger(__name__)
|
15 |
|
16 |
import warnings
|
17 |
warnings.filterwarnings('ignore')
|
src/langchain_utils.py
CHANGED
@@ -19,15 +19,18 @@ from langchain.vectorstores import FAISS
|
|
19 |
import pickle
|
20 |
import shutil
|
21 |
from typing import Dict, List, Optional
|
22 |
-
|
|
|
23 |
import os
|
24 |
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')
|
25 |
|
26 |
import logging
|
27 |
-
logger = logging.getLogger(__name__)
|
28 |
logging.basicConfig(
|
29 |
-
format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
|
|
|
|
|
30 |
)
|
|
|
31 |
|
32 |
import warnings
|
33 |
warnings.filterwarnings('ignore')
|
@@ -910,3 +913,38 @@ class LANGCHAIN_UTILS:
|
|
910 |
self.index_category_doc_type_wise_data_sources[index_category][dt].add(val.metadata['source'])
|
911 |
|
912 |
return self.index_category_doc_type_wise_data_sources
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
import pickle
|
20 |
import shutil
|
21 |
from typing import Dict, List, Optional
|
22 |
+
import pandas as pd
|
23 |
+
from datetime import datetime
|
24 |
import os
|
25 |
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')
|
26 |
|
27 |
import logging
|
|
|
28 |
logging.basicConfig(
|
29 |
+
format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
|
30 |
+
level=logging.INFO,
|
31 |
+
datefmt="%Y-%m-%d %H:%M:%S"
|
32 |
)
|
33 |
+
logger = logging.getLogger(__name__)
|
34 |
|
35 |
import warnings
|
36 |
warnings.filterwarnings('ignore')
|
|
|
913 |
self.index_category_doc_type_wise_data_sources[index_category][dt].add(val.metadata['source'])
|
914 |
|
915 |
return self.index_category_doc_type_wise_data_sources
|
916 |
+
|
917 |
+
|
918 |
+
def save_answer_feeback(
|
919 |
+
self,
|
920 |
+
question_category,
|
921 |
+
question,
|
922 |
+
answer,
|
923 |
+
feedback
|
924 |
+
):
|
925 |
+
logger.info(f'Question category: {question_category}')
|
926 |
+
logger.info(f'Question: {question}')
|
927 |
+
logger.info(f'Answer: {answer}')
|
928 |
+
logger.info(f'Answer feedback is: {feedback}')
|
929 |
+
|
930 |
+
feedback_filepath = os.path.join(
|
931 |
+
constants_utils.OUTPUT_PATH_ANSWER_FEEDBACK,
|
932 |
+
f'{constants_utils.OUTPUT_PATH_ANSWER_FEEDBACK_FILE_PREFIX}_{question_category}.tsv'
|
933 |
+
)
|
934 |
+
|
935 |
+
if os.path.exists(feedback_filepath):
|
936 |
+
df = pd.read_csv(feedback_filepath, sep=constants_utils.OUTPUT_PATH_ANSWER_FEEDBACK_FILE_SAVE_SEPARATOR)
|
937 |
+
else:
|
938 |
+
df = pd.DataFrame(columns=['question_category', 'question', 'answer', 'feedback', 'timestamp'])
|
939 |
+
|
940 |
+
# Append answer feedback to df
|
941 |
+
df.loc[len(df)] = {
|
942 |
+
'question_category': question_category,
|
943 |
+
'question': question,
|
944 |
+
'answer': answer,
|
945 |
+
'feedback': feedback,
|
946 |
+
'timestamp': datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')
|
947 |
+
}
|
948 |
+
|
949 |
+
# Save df into TSV format
|
950 |
+
df.to_csv(feedback_filepath, sep=constants_utils.OUTPUT_PATH_ANSWER_FEEDBACK_FILE_SAVE_SEPARATOR, index=False, header=True)
|
src/utils.py
CHANGED
@@ -4,10 +4,10 @@ import pandas as pd
|
|
4 |
from urllib.parse import urlparse
|
5 |
|
6 |
import logging
|
7 |
-
logger = logging.getLogger(__name__)
|
8 |
logging.basicConfig(
|
9 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
10 |
)
|
|
|
11 |
|
12 |
|
13 |
class UTILS:
|
|
|
4 |
from urllib.parse import urlparse
|
5 |
|
6 |
import logging
|
|
|
7 |
logging.basicConfig(
|
8 |
format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
|
9 |
)
|
10 |
+
logger = logging.getLogger(__name__)
|
11 |
|
12 |
|
13 |
class UTILS:
|