MuhammedSheded33 commited on
Commit
16f7f02
·
verified ·
1 Parent(s): 6729d84

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -0
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from langchain_pinecone import PineconeVectorStore
3
+ from langchain_openai import OpenAI, ChatOpenAI
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain_huggingface import HuggingFaceEmbeddings
7
+ from langchain.output_parsers import PydanticOutputParser
8
+ from dotenv import load_dotenv
9
+ import os
10
+ from pydantic import BaseModel, Field
11
+ from typing import List, Union
12
+ from typing_extensions import Literal
13
+
14
+
15
+ # Pydantic Schema
16
+ class Question(BaseModel):
17
+ question: str = Field(..., description="The question prompt that the user needs to answer.")
18
+ type: Literal['fill_missing', 'MCQ', 'short_answer'] = Field(..., description="The type of question: fill_missing, MCQ, or short_answer.")
19
+ options: Union[List[str], None] = Field(None, description="The options for the question, used only for MCQ type.")
20
+
21
+ class Questions(BaseModel):
22
+ no_of_questions: int = Field(..., description="The total number of questions generated.")
23
+ questions: List[Question] = Field(..., description="A list of Question objects.")
24
+
25
+
26
+ # Function to download Hugging Face embeddings
27
+ def download_hugging_face_embeddings():
28
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2')
29
+ return embeddings
30
+
31
+
32
+ # Load environment variables
33
+ def load_env_variables():
34
+ load_dotenv()
35
+ PINECONE_API_KEY = os.environ.get('PINECONE_API_KEY')
36
+ OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
37
+ GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
38
+
39
+ os.environ["PINECONE_API_KEY"] = PINECONE_API_KEY
40
+ os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
41
+ os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
42
+
43
+
44
+ # Function to initialize Pinecone vector store and retriever
45
+ def initialize_vector_store(embeddings):
46
+ index_name = "yolotest"
47
+ vector_store = PineconeVectorStore.from_existing_index(index_name=index_name, embedding=embeddings)
48
+ retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 5})
49
+ return retriever
50
+
51
+
52
+ # Function to initialize LLM
53
+ def initialize_llm():
54
+ llm = ChatOpenAI(api_key=os.environ.get("OPENAI_API_KEY"), temperature=0, model='gpt-3.5-turbo-0125')
55
+ llm_structured = llm.with_structured_output(Questions)
56
+ return llm_structured
57
+
58
+
59
+ # Function to initialize prompt template
60
+ def initialize_prompt_template(parser):
61
+ prompt_template = """
62
+ You are given some context below. Based on the context, generate questions with one of the following types: ['fill_missing', 'MCQ', 'short_answer'].
63
+
64
+ Context: {context}
65
+
66
+ Make sure to generate a variety of questions. The types should be distributed among 'fill_missing', 'MCQ', and 'short_answer'.
67
+
68
+ For MCQs, provide at least 3 options. For 'fill_missing', make sure to leave a gap that can be filled. For 'short_answer', make sure the answer is clear from the context.
69
+
70
+ Return a list of questions, with each question having the following structure:
71
+ - 'question': The question prompt.
72
+ - 'type': The type of question: 'fill_missing', 'MCQ', or 'short_answer'.
73
+ - 'options': For 'MCQ', a list of options. For other types, this field should be omitted.
74
+
75
+ The response should be with a format that matches the following structure:
76
+ {format_instructions}
77
+ """
78
+ return prompt_template
79
+
80
+
81
+ # Initialize components before user query
82
+ embeddings = download_hugging_face_embeddings()
83
+ load_env_variables()
84
+ retriever = initialize_vector_store(embeddings)
85
+ llm_structured = initialize_llm()
86
+ parser = PydanticOutputParser(pydantic_object=Questions)
87
+ prompt_template = initialize_prompt_template(parser)
88
+
89
+
90
+ # Function to generate questions from the context
91
+ def generate_questions_from_context(query: str, retriever, llm_structured, prompt_template, parser):
92
+ # Retrieve relevant documents from the vector store using the retriever
93
+ retrieved_docs = retriever.invoke(query)
94
+ retrieved_docs = [rec.page_content for rec in retrieved_docs]
95
+
96
+ # Combine the retrieved documents into a single context string
97
+ context = " ".join([doc for doc in retrieved_docs])
98
+
99
+ # Initialize prompt template
100
+ prompt = PromptTemplate(template=prompt_template, input_variables=["context"],
101
+ partial_variables={"format_instructions": parser.get_format_instructions()})
102
+
103
+ # Create chain and generate response
104
+ chain = prompt | llm_structured
105
+ response = chain.invoke({
106
+ "context": context, "format_instructions": parser.get_format_instructions()
107
+ })
108
+ return response
109
+
110
+
111
+ # Streamlit Interface
112
+ def main():
113
+ st.title("A Simple RAG App to Generate Questions in Specific Formats")
114
+
115
+ # Display user query input
116
+ query = st.chat_input("Say something: ")
117
+ if query:
118
+ with st.spinner('Generating questions...'):
119
+ st.write(f"Your query: {query}") # Display user query
120
+
121
+ # Generate questions
122
+ result = generate_questions_from_context(query, retriever, llm_structured, prompt_template, parser)
123
+ st.write(result)
124
+ # # Display the result in a more readable format
125
+ # st.subheader("Generated Questions")
126
+ # for i, question in enumerate(result.questions):
127
+ # st.markdown(f"### Question {i + 1}: {question.question}")
128
+ # st.markdown(f"**Type**: {question.type}")
129
+ # if question.type == "MCQ" and question.options:
130
+ # st.markdown("**Options**:")
131
+ # for option in question.options:
132
+ # st.markdown(f"- {option}")
133
+ # st.markdown("---")
134
+
135
+
136
+ # Run the app
137
+ if __name__ == "__main__":
138
+ main()