QuangDinh2102 commited on
Commit
bd794f9
1 Parent(s): 5330c0f

phase3/quangdt: Tiny changes

Browse files
.gitignore CHANGED
@@ -5,3 +5,4 @@ credentials/
5
  data/CV
6
  data/JD
7
  data/QUESTION
 
 
5
  data/CV
6
  data/JD
7
  data/QUESTION
8
+ !.gitkeep
app/modules/__init__.py CHANGED
@@ -6,6 +6,7 @@ from app.modules.matching_cv import cvmatching_router
6
  from app.modules.crud_question_test import crud_question_tests_router
7
  from app.modules.crud_cvs import crud_cvs_router
8
  from app.modules.crud_jds import crud_jds_router
 
9
 
10
  modules_router = APIRouter(prefix="/modules", tags=["modules"])
11
  modules_router.include_router(qtretrieval_router)
@@ -13,6 +14,7 @@ modules_router.include_router(cvmatching_router)
13
  modules_router.include_router(crud_question_tests_router)
14
  modules_router.include_router(crud_cvs_router)
15
  modules_router.include_router(crud_jds_router)
 
16
 
17
  @modules_router.get("/")
18
  async def index():
 
6
  from app.modules.crud_question_test import crud_question_tests_router
7
  from app.modules.crud_cvs import crud_cvs_router
8
  from app.modules.crud_jds import crud_jds_router
9
+ from app.modules.question_rag import quiz_gen_router
10
 
11
  modules_router = APIRouter(prefix="/modules", tags=["modules"])
12
  modules_router.include_router(qtretrieval_router)
 
14
  modules_router.include_router(crud_question_tests_router)
15
  modules_router.include_router(crud_cvs_router)
16
  modules_router.include_router(crud_jds_router)
17
+ modules_router.include_router(quiz_gen_router)
18
 
19
  @modules_router.get("/")
20
  async def index():
app/modules/question_rag/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, UploadFile, File
2
+ from typing import Annotated
3
+
4
+ from app.modules.question_rag.models.question_rag_logic import question_rag
5
+ from app.modules.question_tests_retrieval.models.jd2text import jobdes2text
6
+
7
+ quiz_gen_router = APIRouter(prefix="/quiz_gen", tags=["quiz_gen"])
8
+
9
+ @quiz_gen_router.get("/")
10
+ async def index():
11
+ return {"message": "Welcome to quiz generator page"}
12
+
13
+ @quiz_gen_router.post("/quiz_gen")
14
+ # only upload .txt file
15
+ async def quiz_gen(txt_file: Annotated[UploadFile, File(..., description="The JD file (only .txt file)", media_type=["text/plain"])]):
16
+ try:
17
+ # read the txt file with format
18
+ jobdes = txt_file.file.read().decode("utf-8")
19
+ sumaryjd_text = jobdes2text(jobdes)
20
+ if question_rag(sumaryjd_text):
21
+ return {"message": "Generate quiz success",
22
+ "quiz": question_rag(sumaryjd_text)}
23
+ else:
24
+ return {"message": "Please upload only .txt file", "error": str(e)}
25
+ except Exception as e:
26
+ return {"message": "Please upload only .txt file", "error": str(e)}
app/modules/question_rag/models/question_rag_logic.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ Input : str of job description
3
+ Output : str of quiz
4
+ '''
5
+
6
+ from langchain_google_genai import ChatGoogleGenerativeAI
7
+ from langchain_community.document_loaders import Docx2txtLoader
8
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
9
+ from langchain_community.vectorstores import FAISS
10
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
11
+ from langchain_core.prompts import ChatPromptTemplate
12
+ from langchain.chains.combine_documents import create_stuff_documents_chain
13
+ from langchain.chains import create_retrieval_chain
14
+
15
+ import os
16
+ from dotenv import load_dotenv
17
+
18
+ # load the environment variables
19
+ load_dotenv()
20
+
21
+ # Define the google api key
22
+ os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY')
23
+ GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
24
+
25
+ # JOB_TEXT = "Job Title is Senior Python Software Engineer, Level is Senior, and Brief summary of required skills is 5+ years of professional Python development experience, Expertise in Python and its frameworks."
26
+
27
+ def question_rag(jobtext):
28
+ llm = ChatGoogleGenerativeAI(model="gemini-pro")
29
+
30
+ loader = Docx2txtLoader("data/w3school_data.docx")
31
+
32
+ docs = loader.load()
33
+
34
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
35
+
36
+ text_splitter = RecursiveCharacterTextSplitter()
37
+ documents = text_splitter.split_documents(docs)
38
+ vector = FAISS.from_documents(documents, embeddings)
39
+
40
+ prompt = ChatPromptTemplate.from_template("""Answer the question based only on the following context:
41
+ <context>
42
+ {context}
43
+ </context>
44
+
45
+ Generate a 10 quiz suitable for the given job description "{input}". Do not include "All of the above" answers.
46
+ Output format is JSON:
47
+ ("count": 10, "data": ( "id": "", "question": "", "choices": [ "A. ", "B. ", "C.", "D. " ], "explanation": "", "answer": "", "level": "", "domain": "" )).
48
+ About level help me three levels: "Fresher, Junior, Senior".
49
+ """)
50
+
51
+ document_chain = create_stuff_documents_chain(llm, prompt)
52
+
53
+ retriever = vector.as_retriever()
54
+ retrieval_chain = create_retrieval_chain(retriever, document_chain)
55
+ response = retrieval_chain.invoke({"input": jobtext})
56
+
57
+ return response["answer"]
app/modules/question_tests_retrieval/models/jd2text.py CHANGED
@@ -15,7 +15,7 @@ GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
15
  # define the parser object
16
  parser = JsonOutputParser()
17
 
18
- def jobdes2text(jobdes):
19
  # setup the gemini pro
20
  llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.3, convert_system_message_to_human=True, api_key=GOOGLE_API_KEY)
21
 
 
15
  # define the parser object
16
  parser = JsonOutputParser()
17
 
18
+ def jobdes2text(jobdes: str) -> str:
19
  # setup the gemini pro
20
  llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.3, convert_system_message_to_human=True, api_key=GOOGLE_API_KEY)
21
 
data/.gitkeep ADDED
File without changes
data/w3school_data.docx ADDED
Binary file (237 kB). View file
 
requirements.txt CHANGED
@@ -13,6 +13,7 @@ colorama==0.4.6
13
  cryptography==42.0.5
14
  dataclasses-json==0.6.4
15
  dnspython==2.6.1
 
16
  email_validator==2.1.1
17
  fastapi==0.110.0
18
  firebase-admin==6.4.0
@@ -67,7 +68,7 @@ protobuf==4.25.3
67
  pyasn1==0.5.1
68
  pyasn1-modules==0.3.0
69
  pycparser==2.21
70
- pydantic==2.6.3
71
  pydantic-extra-types==2.6.0
72
  pydantic-settings==2.2.1
73
  pydantic_core==2.16.3
@@ -76,6 +77,7 @@ pyparsing==3.1.2
76
  python-docx==1.1.0
77
  python-dotenv==1.0.1
78
  python-multipart==0.0.9
 
79
  PyYAML==6.0.1
80
  qdrant-client==1.8.0
81
  requests==2.31.0
 
13
  cryptography==42.0.5
14
  dataclasses-json==0.6.4
15
  dnspython==2.6.1
16
+ docx2txt==0.8
17
  email_validator==2.1.1
18
  fastapi==0.110.0
19
  firebase-admin==6.4.0
 
68
  pyasn1==0.5.1
69
  pyasn1-modules==0.3.0
70
  pycparser==2.21
71
+ pydantic==2.6.3
72
  pydantic-extra-types==2.6.0
73
  pydantic-settings==2.2.1
74
  pydantic_core==2.16.3
 
77
  python-docx==1.1.0
78
  python-dotenv==1.0.1
79
  python-multipart==0.0.9
80
+ pywin32==306
81
  PyYAML==6.0.1
82
  qdrant-client==1.8.0
83
  requests==2.31.0