Abhaykumar04 commited on
Commit
de11922
Β·
verified Β·
1 Parent(s): 0e011c0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +286 -287
app.py CHANGED
@@ -1,287 +1,286 @@
1
- import yaml
2
- from together import Together
3
- from langchain.llms.together import Together as TogetherLLM
4
- from langchain.prompts import PromptTemplate
5
- from langchain.schema.runnable import RunnablePassthrough
6
- from langchain.schema.output_parser import StrOutputParser
7
- from pinecone import Pinecone
8
- import gradio as gr
9
- from dotenv import load_dotenv
10
- import os
11
-
12
- load_dotenv()
13
-
14
-
15
- API_FILE_PATH = r"C:\Users\abhay\Analytics Vidhya\API.yml"
16
- COURSES_FILE_PATH = r"C:\Users\abhay\Analytics Vidhya\courses.json"
17
-
18
- def load_api_keys(api_file_path):
19
- """Loads API keys from a YAML file."""
20
- with open(api_file_path, 'r') as f:
21
- api_keys = yaml.safe_load(f)
22
- return api_keys
23
-
24
- def generate_query_embedding(query, together_api_key):
25
- """Generates embedding for the user query."""
26
- client = Together(api_key=together_api_key)
27
- response = client.embeddings.create(
28
- model="WhereIsAI/UAE-Large-V1", input=query
29
- )
30
- return response.data[0].embedding
31
-
32
- def initialize_pinecone(pinecone_api_key):
33
- """Initializes Pinecone with API key."""
34
- return Pinecone(api_key=pinecone_api_key)
35
-
36
- def pinecone_similarity_search(pinecone_instance, index_name, query_embedding, top_k=5):
37
- """Performs a similarity search in Pinecone."""
38
- try:
39
- index = pinecone_instance.Index(index_name)
40
- results = index.query(vector=query_embedding, top_k=top_k, include_metadata=True)
41
- if not results.matches:
42
- return None
43
- return results
44
- except Exception as e:
45
- print(f"Error during similarity search: {e}")
46
- return None
47
-
48
- def create_prompt_template():
49
- """Creates a prompt template for LLM."""
50
- template = """You are a helpful AI course advisor. Based on the following context and query, suggest relevant courses.
51
- For each course, explain:
52
- 1. Why it's relevant to the query
53
- 2. What the student will learn
54
- 3. Who should take this course
55
-
56
- If no relevant courses are found, suggest alternative search terms.
57
-
58
- Context: {context}
59
- User Query: {query}
60
-
61
- Response: Let me help you find the perfect courses for your needs! πŸŽ“
62
- """
63
- return PromptTemplate(template=template, input_variables=["context", "query"])
64
-
65
- def initialize_llm(together_api_key):
66
- """Initializes Together LLM."""
67
- return TogetherLLM(
68
- model="mistralai/Mixtral-8x7B-Instruct-v0.1",
69
- together_api_key=together_api_key,
70
- temperature=0.3,
71
- max_tokens=500
72
- )
73
-
74
- def create_chain(llm, prompt):
75
- """Creates a chain using the RunnableSequence approach."""
76
- chain = (
77
- {"context": RunnablePassthrough(), "query": RunnablePassthrough()}
78
- | prompt
79
- | llm
80
- | StrOutputParser()
81
- )
82
- return chain
83
-
84
- def format_course_info(metadata):
85
- """Formats course information with emojis and styling."""
86
- return f"""
87
- πŸ“š **Course Title:** {metadata.get('title', 'No title')}
88
-
89
- πŸ“ **Description:** {metadata.get('text', 'No description')}
90
-
91
- πŸ”— **Course Link:** {metadata.get('course_link', 'No link')}
92
-
93
- πŸ‘¨β€πŸ« **Instructor:** {metadata.get('instructor', 'Not specified')}
94
-
95
- ⏱️ **Duration:** {metadata.get('duration', 'Not specified')}
96
-
97
- πŸ“Š **Level:** {metadata.get('difficulty_level', 'Not specified')}
98
-
99
- πŸ’° **Price:** {metadata.get('price', 'Not specified')}
100
- """
101
-
102
- def generate_llm_response(chain, query, retrieved_data):
103
- """Generates an LLM response with formatted course information."""
104
- try:
105
- if not retrieved_data or not retrieved_data.matches:
106
- return "πŸ” I couldn't find any relevant courses matching your query. Please try different search terms."
107
-
108
- context_parts = []
109
- formatted_courses = []
110
-
111
- for match in retrieved_data.matches:
112
- metadata = match.metadata
113
- if metadata:
114
- context_parts.append(
115
- f"Title: {metadata.get('title', 'No title')}\n"
116
- f"Description: {metadata.get('text', 'No description')}\n"
117
- f"Link: {metadata.get('course_link', 'No link')}"
118
- )
119
- formatted_courses.append(format_course_info(metadata))
120
-
121
- if not context_parts:
122
- return "⚠️ I found some matches but couldn't extract course information. Please try again."
123
-
124
- context = "\n\n".join(context_parts)
125
- llm_analysis = chain.invoke({"context": context, "query": query})
126
-
127
- separator = "=" * 50
128
- final_response = f"""
129
- {llm_analysis}
130
-
131
- 🎯 Here are the detailed course listings:
132
- {separator}
133
- {''.join(formatted_courses)}
134
- """
135
- return final_response
136
-
137
- except Exception as e:
138
- print(f"Error generating response: {e}")
139
- return "❌ I encountered an error while generating the response. Please try again."
140
-
141
- def create_gradio_interface(api_keys):
142
- """Creates a custom Gradio interface with improved styling."""
143
- # Initialize components
144
- pinecone_instance = initialize_pinecone(api_keys["pinecone_api_key"])
145
- llm = initialize_llm(api_keys["together_ai_api_key"])
146
- prompt = create_prompt_template()
147
- chain = create_chain(llm, prompt)
148
-
149
- def process_query(query):
150
- try:
151
- query_embedding = generate_query_embedding(query, api_keys["together_ai_api_key"])
152
- results = pinecone_similarity_search(
153
- pinecone_instance,
154
- api_keys["pinecone_index_name"],
155
- query_embedding
156
- )
157
- response = generate_llm_response(chain, query, results)
158
- return response
159
- except Exception as e:
160
- return f"❌ Error: {str(e)}"
161
-
162
- # Custom CSS for better styling
163
- custom_css = """
164
- .gradio-container {
165
- background-color: #f0f8ff;
166
- }
167
- .input-box {
168
- border: 2px solid #2e86de;
169
- border-radius: 10px;
170
- padding: 15px;
171
- margin: 10px 0;
172
- }
173
- .output-box {
174
- background-color: #ffffff;
175
- border: 2px solid #54a0ff;
176
- border-radius: 10px;
177
- padding: 20px;
178
- margin: 10px 0;
179
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
180
- }
181
- .heading {
182
- color: #2e86de;
183
- text-align: center;
184
- margin-bottom: 20px;
185
- }
186
- .submit-btn {
187
- background-color: #2e86de !important;
188
- color: white !important;
189
- border-radius: 8px !important;
190
- padding: 10px 20px !important;
191
- font-size: 16px !important;
192
- }
193
- .examples {
194
- margin-top: 20px;
195
- padding: 15px;
196
- background-color: #f8f9fa;
197
- border-radius: 10px;
198
- }
199
- """
200
-
201
- # Create Gradio interface with custom theme
202
- theme = gr.themes.Soft().set(
203
- body_background_fill="#f0f8ff",
204
- block_background_fill="#ffffff",
205
- block_border_width="2px",
206
- block_border_color="#2e86de",
207
- block_radius="10px",
208
- button_primary_background_fill="#2e86de",
209
- button_primary_text_color="white",
210
- input_background_fill="#ffffff",
211
- input_border_color="#2e86de",
212
- input_radius="8px",
213
- )
214
-
215
- with gr.Blocks(theme=theme, css=custom_css) as demo:
216
- gr.Markdown(
217
- """
218
- # πŸŽ“ Course Recommendation Assistant
219
-
220
- Welcome to your personalized course finder! Ask me about any topics you're interested in learning.
221
- I'll help you discover the perfect courses from Analytics Vidhya's collection.
222
-
223
- ## 🌟 Features:
224
- - πŸ“š Detailed course recommendations
225
- - 🎯 Learning path suggestions
226
- - πŸ“Š Course difficulty levels
227
- - πŸ’° Price information
228
- """,
229
- elem_classes=["heading"]
230
- )
231
-
232
- with gr.Row():
233
- with gr.Column():
234
- query_input = gr.Textbox(
235
- label="What would you like to learn? πŸ€”",
236
- placeholder="e.g., 'machine learning for beginners' or 'advanced python courses'",
237
- lines=3,
238
- elem_classes=["input-box"]
239
- )
240
- submit_btn = gr.Button(
241
- "πŸ” Find Courses",
242
- variant="primary",
243
- elem_classes=["submit-btn"]
244
- )
245
-
246
- with gr.Row():
247
- output = gr.Markdown(
248
- label="Recommendations πŸ“š",
249
- elem_classes=["output-box"]
250
- )
251
-
252
- with gr.Row(elem_classes=["examples"]):
253
- gr.Examples(
254
- examples=[
255
- ["I want to learn machine learning from scratch"],
256
- ["Advanced deep learning courses"],
257
- ["Data visualization tutorials"],
258
- ["Python programming for beginners"],
259
- ["Natural Language Processing courses"]
260
- ],
261
- inputs=query_input,
262
- label="πŸ“ Example Queries"
263
- )
264
-
265
- submit_btn.click(
266
- fn=process_query,
267
- inputs=query_input,
268
- outputs=output
269
- )
270
-
271
- return demo
272
-
273
- def main():
274
- try:
275
-
276
- api_keys = load_api_keys(API_FILE_PATH)
277
-
278
-
279
- demo = create_gradio_interface(api_keys)
280
- demo.launch(
281
- share=True)
282
-
283
- except Exception as e:
284
- print(f"An error occurred during initialization: {str(e)}")
285
-
286
- if __name__ == "__main__":
287
- main()
 
1
+ import yaml
2
+ from together import Together
3
+ from langchain.prompts import PromptTemplate
4
+ from langchain.schema.runnable import RunnablePassthrough
5
+ from langchain.schema.output_parser import StrOutputParser
6
+ from pinecone import Pinecone
7
+ import gradio as gr
8
+ from dotenv import load_dotenv
9
+ import os
10
+
11
+ load_dotenv()
12
+
13
+
14
+ API_FILE_PATH = r"C:\Users\abhay\Analytics Vidhya\API.yml"
15
+ COURSES_FILE_PATH = r"C:\Users\abhay\Analytics Vidhya\courses.json"
16
+
17
+ def load_api_keys(api_file_path):
18
+ """Loads API keys from a YAML file."""
19
+ with open(api_file_path, 'r') as f:
20
+ api_keys = yaml.safe_load(f)
21
+ return api_keys
22
+
23
+ def generate_query_embedding(query, together_api_key):
24
+ """Generates embedding for the user query."""
25
+ client = Together(api_key=together_api_key)
26
+ response = client.embeddings.create(
27
+ model="WhereIsAI/UAE-Large-V1", input=query
28
+ )
29
+ return response.data[0].embedding
30
+
31
+ def initialize_pinecone(pinecone_api_key):
32
+ """Initializes Pinecone with API key."""
33
+ return Pinecone(api_key=pinecone_api_key)
34
+
35
+ def pinecone_similarity_search(pinecone_instance, index_name, query_embedding, top_k=5):
36
+ """Performs a similarity search in Pinecone."""
37
+ try:
38
+ index = pinecone_instance.Index(index_name)
39
+ results = index.query(vector=query_embedding, top_k=top_k, include_metadata=True)
40
+ if not results.matches:
41
+ return None
42
+ return results
43
+ except Exception as e:
44
+ print(f"Error during similarity search: {e}")
45
+ return None
46
+
47
+ def create_prompt_template():
48
+ """Creates a prompt template for LLM."""
49
+ template = """You are a helpful AI course advisor. Based on the following context and query, suggest relevant courses.
50
+ For each course, explain:
51
+ 1. Why it's relevant to the query
52
+ 2. What the student will learn
53
+ 3. Who should take this course
54
+
55
+ If no relevant courses are found, suggest alternative search terms.
56
+
57
+ Context: {context}
58
+ User Query: {query}
59
+
60
+ Response: Let me help you find the perfect courses for your needs! πŸŽ“
61
+ """
62
+ return PromptTemplate(template=template, input_variables=["context", "query"])
63
+
64
+ def initialize_llm(together_api_key):
65
+ """Initializes Together LLM."""
66
+ return TogetherLLM(
67
+ model="mistralai/Mixtral-8x7B-Instruct-v0.1",
68
+ together_api_key=together_api_key,
69
+ temperature=0.3,
70
+ max_tokens=500
71
+ )
72
+
73
+ def create_chain(llm, prompt):
74
+ """Creates a chain using the RunnableSequence approach."""
75
+ chain = (
76
+ {"context": RunnablePassthrough(), "query": RunnablePassthrough()}
77
+ | prompt
78
+ | llm
79
+ | StrOutputParser()
80
+ )
81
+ return chain
82
+
83
+ def format_course_info(metadata):
84
+ """Formats course information with emojis and styling."""
85
+ return f"""
86
+ πŸ“š **Course Title:** {metadata.get('title', 'No title')}
87
+
88
+ πŸ“ **Description:** {metadata.get('text', 'No description')}
89
+
90
+ πŸ”— **Course Link:** {metadata.get('course_link', 'No link')}
91
+
92
+ πŸ‘¨β€πŸ« **Instructor:** {metadata.get('instructor', 'Not specified')}
93
+
94
+ ⏱️ **Duration:** {metadata.get('duration', 'Not specified')}
95
+
96
+ πŸ“Š **Level:** {metadata.get('difficulty_level', 'Not specified')}
97
+
98
+ πŸ’° **Price:** {metadata.get('price', 'Not specified')}
99
+ """
100
+
101
+ def generate_llm_response(chain, query, retrieved_data):
102
+ """Generates an LLM response with formatted course information."""
103
+ try:
104
+ if not retrieved_data or not retrieved_data.matches:
105
+ return "πŸ” I couldn't find any relevant courses matching your query. Please try different search terms."
106
+
107
+ context_parts = []
108
+ formatted_courses = []
109
+
110
+ for match in retrieved_data.matches:
111
+ metadata = match.metadata
112
+ if metadata:
113
+ context_parts.append(
114
+ f"Title: {metadata.get('title', 'No title')}\n"
115
+ f"Description: {metadata.get('text', 'No description')}\n"
116
+ f"Link: {metadata.get('course_link', 'No link')}"
117
+ )
118
+ formatted_courses.append(format_course_info(metadata))
119
+
120
+ if not context_parts:
121
+ return "⚠️ I found some matches but couldn't extract course information. Please try again."
122
+
123
+ context = "\n\n".join(context_parts)
124
+ llm_analysis = chain.invoke({"context": context, "query": query})
125
+
126
+ separator = "=" * 50
127
+ final_response = f"""
128
+ {llm_analysis}
129
+
130
+ 🎯 Here are the detailed course listings:
131
+ {separator}
132
+ {''.join(formatted_courses)}
133
+ """
134
+ return final_response
135
+
136
+ except Exception as e:
137
+ print(f"Error generating response: {e}")
138
+ return "❌ I encountered an error while generating the response. Please try again."
139
+
140
+ def create_gradio_interface(api_keys):
141
+ """Creates a custom Gradio interface with improved styling."""
142
+ # Initialize components
143
+ pinecone_instance = initialize_pinecone(api_keys["pinecone_api_key"])
144
+ llm = initialize_llm(api_keys["together_ai_api_key"])
145
+ prompt = create_prompt_template()
146
+ chain = create_chain(llm, prompt)
147
+
148
+ def process_query(query):
149
+ try:
150
+ query_embedding = generate_query_embedding(query, api_keys["together_ai_api_key"])
151
+ results = pinecone_similarity_search(
152
+ pinecone_instance,
153
+ api_keys["pinecone_index_name"],
154
+ query_embedding
155
+ )
156
+ response = generate_llm_response(chain, query, results)
157
+ return response
158
+ except Exception as e:
159
+ return f"❌ Error: {str(e)}"
160
+
161
+ # Custom CSS for better styling
162
+ custom_css = """
163
+ .gradio-container {
164
+ background-color: #f0f8ff;
165
+ }
166
+ .input-box {
167
+ border: 2px solid #2e86de;
168
+ border-radius: 10px;
169
+ padding: 15px;
170
+ margin: 10px 0;
171
+ }
172
+ .output-box {
173
+ background-color: #ffffff;
174
+ border: 2px solid #54a0ff;
175
+ border-radius: 10px;
176
+ padding: 20px;
177
+ margin: 10px 0;
178
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
179
+ }
180
+ .heading {
181
+ color: #2e86de;
182
+ text-align: center;
183
+ margin-bottom: 20px;
184
+ }
185
+ .submit-btn {
186
+ background-color: #2e86de !important;
187
+ color: white !important;
188
+ border-radius: 8px !important;
189
+ padding: 10px 20px !important;
190
+ font-size: 16px !important;
191
+ }
192
+ .examples {
193
+ margin-top: 20px;
194
+ padding: 15px;
195
+ background-color: #f8f9fa;
196
+ border-radius: 10px;
197
+ }
198
+ """
199
+
200
+ # Create Gradio interface with custom theme
201
+ theme = gr.themes.Soft().set(
202
+ body_background_fill="#f0f8ff",
203
+ block_background_fill="#ffffff",
204
+ block_border_width="2px",
205
+ block_border_color="#2e86de",
206
+ block_radius="10px",
207
+ button_primary_background_fill="#2e86de",
208
+ button_primary_text_color="white",
209
+ input_background_fill="#ffffff",
210
+ input_border_color="#2e86de",
211
+ input_radius="8px",
212
+ )
213
+
214
+ with gr.Blocks(theme=theme, css=custom_css) as demo:
215
+ gr.Markdown(
216
+ """
217
+ # πŸŽ“ Course Recommendation Assistant
218
+
219
+ Welcome to your personalized course finder! Ask me about any topics you're interested in learning.
220
+ I'll help you discover the perfect courses from Analytics Vidhya's collection.
221
+
222
+ ## 🌟 Features:
223
+ - πŸ“š Detailed course recommendations
224
+ - 🎯 Learning path suggestions
225
+ - πŸ“Š Course difficulty levels
226
+ - πŸ’° Price information
227
+ """,
228
+ elem_classes=["heading"]
229
+ )
230
+
231
+ with gr.Row():
232
+ with gr.Column():
233
+ query_input = gr.Textbox(
234
+ label="What would you like to learn? πŸ€”",
235
+ placeholder="e.g., 'machine learning for beginners' or 'advanced python courses'",
236
+ lines=3,
237
+ elem_classes=["input-box"]
238
+ )
239
+ submit_btn = gr.Button(
240
+ "πŸ” Find Courses",
241
+ variant="primary",
242
+ elem_classes=["submit-btn"]
243
+ )
244
+
245
+ with gr.Row():
246
+ output = gr.Markdown(
247
+ label="Recommendations πŸ“š",
248
+ elem_classes=["output-box"]
249
+ )
250
+
251
+ with gr.Row(elem_classes=["examples"]):
252
+ gr.Examples(
253
+ examples=[
254
+ ["I want to learn machine learning from scratch"],
255
+ ["Advanced deep learning courses"],
256
+ ["Data visualization tutorials"],
257
+ ["Python programming for beginners"],
258
+ ["Natural Language Processing courses"]
259
+ ],
260
+ inputs=query_input,
261
+ label="πŸ“ Example Queries"
262
+ )
263
+
264
+ submit_btn.click(
265
+ fn=process_query,
266
+ inputs=query_input,
267
+ outputs=output
268
+ )
269
+
270
+ return demo
271
+
272
+ def main():
273
+ try:
274
+
275
+ api_keys = load_api_keys(API_FILE_PATH)
276
+
277
+
278
+ demo = create_gradio_interface(api_keys)
279
+ demo.launch(
280
+ share=True)
281
+
282
+ except Exception as e:
283
+ print(f"An error occurred during initialization: {str(e)}")
284
+
285
+ if __name__ == "__main__":
286
+ main()