HuyDN commited on
Commit
0515d1d
2 Parent(s): d6ef950 308a9de

Merge branch 'main' into HuyDN

Browse files
app/modules/__init__.py CHANGED
@@ -7,6 +7,7 @@ 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.crud_rag_question_tests import crud_rag_question_tests_router
 
10
 
11
  modules_router = APIRouter(prefix="/modules", tags=["modules"])
12
  modules_router.include_router(qtretrieval_router)
@@ -15,6 +16,7 @@ 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(crud_rag_question_tests_router)
 
18
 
19
  @modules_router.get("/")
20
  async def index():
 
7
  from app.modules.crud_cvs import crud_cvs_router
8
  from app.modules.crud_jds import crud_jds_router
9
  from app.modules.crud_rag_question_tests import crud_rag_question_tests_router
10
+ from app.modules.question_rag import quiz_gen_router
11
 
12
  modules_router = APIRouter(prefix="/modules", tags=["modules"])
13
  modules_router.include_router(qtretrieval_router)
 
16
  modules_router.include_router(crud_cvs_router)
17
  modules_router.include_router(crud_jds_router)
18
  modules_router.include_router(crud_rag_question_tests_router)
19
+ modules_router.include_router(quiz_gen_router)
20
 
21
  @modules_router.get("/")
22
  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,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_google_genai import ChatGoogleGenerativeAI
2
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+ from langchain.chains.combine_documents import create_stuff_documents_chain
5
+ from langchain.chains import create_retrieval_chain
6
+ from langchain_core.output_parsers import JsonOutputParser
7
+
8
+ from langchain_community.vectorstores import Qdrant
9
+ import qdrant_client
10
+
11
+ import os
12
+ from dotenv import load_dotenv
13
+
14
+ # load the environment variables
15
+ load_dotenv()
16
+
17
+ # Define the google api key
18
+ os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY')
19
+ os.environ['QDRANT_API_KEY'] = os.getenv('QDRANT_API_KEY')
20
+ os.environ['QDRANT_URL'] = os.getenv('QDRANT_URL')
21
+
22
+ GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
23
+ QDRANT_API_KEY = os.environ.get("QDRANT_API_KEY")
24
+ QDRANT_URL = os.environ.get("QDRANT_URL")
25
+
26
+ def question_rag(jobtext: str):
27
+ llm = ChatGoogleGenerativeAI(model="gemini-pro", google_api_key=GOOGLE_API_KEY, request_timeout=120)
28
+
29
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
30
+
31
+ client = qdrant_client.QdrantClient(
32
+ url=QDRANT_URL,
33
+ api_key=QDRANT_API_KEY,
34
+ )
35
+
36
+ doc_store = Qdrant(
37
+ client=client,
38
+ collection_name="rag_documents_test",
39
+ embeddings=embeddings,
40
+ )
41
+
42
+ json_parser = JsonOutputParser()
43
+
44
+ prompt = ChatPromptTemplate.from_template("""
45
+ Answer the question based only on the following context:
46
+ <context>
47
+ {context}
48
+ </context>
49
+
50
+ Generate a 10 quiz suitable for the given job description "{input}". Do not include "All of the above" answers.
51
+ Output format is JSON:
52
+ ("__count__": 10, "data": ( "id": "", "question": "", "choices": [ "A. ", "B. ", "C.", "D. " ], "explanation": "", "answer": "", "level": "", "domain": "" )).
53
+ About level help me three levels: "Fresher, Junior, Senior".
54
+ """)
55
+
56
+ document_chain = create_stuff_documents_chain(llm, prompt, output_parser=json_parser)
57
+
58
+ retriever = doc_store.as_retriever()
59
+ retrieval_chain = create_retrieval_chain(retriever, document_chain)
60
+ response = retrieval_chain.invoke({"input": jobtext})
61
+
62
+ return response["answer"]
data/.gitkeep DELETED
File without changes
requirements.txt CHANGED
@@ -67,7 +67,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
 
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