Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,19 +1,24 @@
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
-
from streamlit_option_menu import option_menu
|
3 |
-
from langchain_groq import ChatGroq
|
4 |
-
import fitz # PyMuPDF
|
5 |
import requests
|
6 |
-
from
|
|
|
7 |
import plotly.express as px
|
8 |
-
import re
|
9 |
import pandas as pd
|
10 |
import sqlite3
|
11 |
from datetime import datetime, timedelta
|
12 |
-
|
13 |
import os
|
14 |
|
|
|
|
|
|
|
|
|
|
|
15 |
GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
|
16 |
RAPIDAPI_KEY = st.secrets["RAPIDAPI_KEY"]
|
|
|
17 |
|
18 |
llm = ChatGroq(
|
19 |
temperature=0,
|
@@ -21,6 +26,10 @@ llm = ChatGroq(
|
|
21 |
model_name="llama-3.1-70b-versatile"
|
22 |
)
|
23 |
|
|
|
|
|
|
|
|
|
24 |
@st.cache_data(ttl=3600)
|
25 |
def extract_text_from_pdf(pdf_file):
|
26 |
"""
|
@@ -313,9 +322,56 @@ def parse_duration(duration_str):
|
|
313 |
except:
|
314 |
return 0
|
315 |
|
316 |
-
|
317 |
-
#
|
318 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
|
320 |
def init_db():
|
321 |
"""
|
@@ -422,10 +478,6 @@ def generate_learning_path(career_goal, current_skills):
|
|
422 |
st.error(f"Error generating learning path: {e}")
|
423 |
return ""
|
424 |
|
425 |
-
# -------------------------------
|
426 |
-
# Page Functions
|
427 |
-
# -------------------------------
|
428 |
-
|
429 |
def email_generator_page():
|
430 |
st.header("Automated Email Generator")
|
431 |
|
@@ -722,7 +774,7 @@ def interview_preparation_module():
|
|
722 |
st.header("Interview Preparation")
|
723 |
|
724 |
st.write("""
|
725 |
-
Prepare for your interviews with tailored mock questions and
|
726 |
""")
|
727 |
|
728 |
# Create two columns for input fields
|
@@ -737,32 +789,27 @@ def interview_preparation_module():
|
|
737 |
st.error("Please enter both job title and company name.")
|
738 |
return
|
739 |
with st.spinner("Generating questions..."):
|
|
|
740 |
prompt = f"""
|
741 |
-
Generate a list of
|
742 |
"""
|
743 |
try:
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
try:
|
759 |
-
sample_answers = llm.invoke(sample_prompt).content.strip()
|
760 |
-
st.subheader("Sample Answers:")
|
761 |
-
st.write(sample_answers)
|
762 |
-
except Exception as e:
|
763 |
-
st.error(f"Error generating sample answers: {e}")
|
764 |
except Exception as e:
|
765 |
-
st.error(f"Error generating interview
|
766 |
|
767 |
def personalized_learning_paths_module():
|
768 |
st.header("Personalized Learning Paths")
|
@@ -1079,9 +1126,6 @@ def chatbot_support_page():
|
|
1079 |
else:
|
1080 |
message(chat['message'], is_user=False, avatar_style="bottts")
|
1081 |
|
1082 |
-
# -------------------------------
|
1083 |
-
# Main App Function
|
1084 |
-
# -------------------------------
|
1085 |
|
1086 |
def main_app():
|
1087 |
# Apply a consistent theme or style
|
@@ -1102,15 +1146,11 @@ def main_app():
|
|
1102 |
|
1103 |
# Sidebar Navigation
|
1104 |
with st.sidebar:
|
1105 |
-
selected =
|
1106 |
"Main Menu",
|
1107 |
["Email Generator", "Cover Letter Generator", "Resume Analysis", "Application Tracking",
|
1108 |
"Interview Preparation", "Personalized Learning Paths", "Networking Opportunities",
|
1109 |
-
"Salary Estimation", "Feedback", "Gamification", "Resource Library", "Success Stories", "Chatbot Support", "Help"]
|
1110 |
-
icons=["envelope", "file-earmark-text", "file-person", "briefcase", "gear",
|
1111 |
-
"book", "people", "currency-dollar", "chat-left-text", "trophy", "collection", "star", "chat", "question-circle"],
|
1112 |
-
menu_icon="cast",
|
1113 |
-
default_index=0,
|
1114 |
)
|
1115 |
|
1116 |
# Route to the selected page
|
@@ -1143,5 +1183,6 @@ def main_app():
|
|
1143 |
elif selected == "Help":
|
1144 |
help_page()
|
1145 |
|
|
|
1146 |
if __name__ == "__main__":
|
1147 |
main_app()
|
|
|
1 |
+
# app.py
|
2 |
+
|
3 |
import streamlit as st
|
|
|
|
|
|
|
4 |
import requests
|
5 |
+
from langchain_groq import ChatGroq
|
6 |
+
from streamlit_chat import message
|
7 |
import plotly.express as px
|
|
|
8 |
import pandas as pd
|
9 |
import sqlite3
|
10 |
from datetime import datetime, timedelta
|
11 |
+
import re
|
12 |
import os
|
13 |
|
14 |
+
# -------------------------------
|
15 |
+
# Initialize the LLM with Groq API Key
|
16 |
+
# -------------------------------
|
17 |
+
|
18 |
+
# Ensure API keys are stored securely using secrets.toml
|
19 |
GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
|
20 |
RAPIDAPI_KEY = st.secrets["RAPIDAPI_KEY"]
|
21 |
+
YOUTUBE_API_KEY = st.secrets["YOUTUBE_API_KEY"]
|
22 |
|
23 |
llm = ChatGroq(
|
24 |
temperature=0,
|
|
|
26 |
model_name="llama-3.1-70b-versatile"
|
27 |
)
|
28 |
|
29 |
+
# -------------------------------
|
30 |
+
# Helper Functions with Caching
|
31 |
+
# -------------------------------
|
32 |
+
|
33 |
@st.cache_data(ttl=3600)
|
34 |
def extract_text_from_pdf(pdf_file):
|
35 |
"""
|
|
|
322 |
except:
|
323 |
return 0
|
324 |
|
325 |
+
|
326 |
+
@st.cache_data(ttl=86400) # Cache results for 1 day
|
327 |
+
def search_youtube_videos(query, max_results=3, video_duration="short", order="relevance"):
|
328 |
+
"""
|
329 |
+
Searches YouTube for videos related to the query with additional filters.
|
330 |
+
|
331 |
+
Args:
|
332 |
+
query (str): The search query/topic.
|
333 |
+
max_results (int): The maximum number of videos to retrieve.
|
334 |
+
video_duration (str): Duration filter ('any', 'short', 'medium', 'long').
|
335 |
+
order (str): Order of results ('date', 'rating', 'relevance', 'title', 'videoCount', 'viewCount').
|
336 |
+
|
337 |
+
Returns:
|
338 |
+
list: A list of YouTube video URLs.
|
339 |
+
"""
|
340 |
+
api_key = YOUTUBE_API_KEY
|
341 |
+
search_url = "https://www.googleapis.com/youtube/v3/search"
|
342 |
+
|
343 |
+
params = {
|
344 |
+
"part": "snippet",
|
345 |
+
"q": query,
|
346 |
+
"type": "video",
|
347 |
+
"maxResults": max_results,
|
348 |
+
"videoDuration": video_duration,
|
349 |
+
"order": order,
|
350 |
+
"key": api_key
|
351 |
+
}
|
352 |
+
|
353 |
+
try:
|
354 |
+
response = requests.get(search_url, params=params)
|
355 |
+
response.raise_for_status()
|
356 |
+
results = response.json().get("items", [])
|
357 |
+
video_urls = [f"https://www.youtube.com/watch?v={item['id']['videoId']}" for item in results]
|
358 |
+
return video_urls
|
359 |
+
except requests.exceptions.RequestException as e:
|
360 |
+
st.error(f"Error fetching YouTube videos: {e}")
|
361 |
+
return []
|
362 |
+
|
363 |
+
def embed_youtube_videos(video_urls, topic):
|
364 |
+
"""
|
365 |
+
Embeds YouTube videos under a specific topic within an expander.
|
366 |
+
|
367 |
+
Args:
|
368 |
+
video_urls (list): List of YouTube video URLs.
|
369 |
+
topic (str): The interview topic.
|
370 |
+
"""
|
371 |
+
with st.expander(f"Videos for {topic}"):
|
372 |
+
for url in video_urls:
|
373 |
+
st.video(url)
|
374 |
+
|
375 |
|
376 |
def init_db():
|
377 |
"""
|
|
|
478 |
st.error(f"Error generating learning path: {e}")
|
479 |
return ""
|
480 |
|
|
|
|
|
|
|
|
|
481 |
def email_generator_page():
|
482 |
st.header("Automated Email Generator")
|
483 |
|
|
|
774 |
st.header("Interview Preparation")
|
775 |
|
776 |
st.write("""
|
777 |
+
Prepare for your interviews with tailored mock questions, expert tips, and curated video resources.
|
778 |
""")
|
779 |
|
780 |
# Create two columns for input fields
|
|
|
789 |
st.error("Please enter both job title and company name.")
|
790 |
return
|
791 |
with st.spinner("Generating questions..."):
|
792 |
+
# Example prompt to generate interview topics using LLM
|
793 |
prompt = f"""
|
794 |
+
Generate a list of 5 key topics that a candidate should prepare for an interview for the position of {job_title} at {company}. Each topic should be a concise phrase.
|
795 |
"""
|
796 |
try:
|
797 |
+
# Invoke the LLM to get topics
|
798 |
+
topics = llm.invoke(prompt).content.strip().split('\n')
|
799 |
+
topics = [topic.strip('- ').strip() for topic in topics if topic.strip()]
|
800 |
+
st.subheader("Key Interview Topics:")
|
801 |
+
for idx, topic in enumerate(topics, 1):
|
802 |
+
st.markdown(f"{idx}. {topic}")
|
803 |
+
|
804 |
+
st.subheader("Recommended YouTube Videos:")
|
805 |
+
for topic in topics:
|
806 |
+
video_urls = search_youtube_videos(query=topic, max_results=2)
|
807 |
+
if video_urls:
|
808 |
+
embed_youtube_videos(video_urls, topic)
|
809 |
+
else:
|
810 |
+
st.write(f"No videos found for **{topic}**.")
|
|
|
|
|
|
|
|
|
|
|
|
|
811 |
except Exception as e:
|
812 |
+
st.error(f"Error generating interview topics: {e}")
|
813 |
|
814 |
def personalized_learning_paths_module():
|
815 |
st.header("Personalized Learning Paths")
|
|
|
1126 |
else:
|
1127 |
message(chat['message'], is_user=False, avatar_style="bottts")
|
1128 |
|
|
|
|
|
|
|
1129 |
|
1130 |
def main_app():
|
1131 |
# Apply a consistent theme or style
|
|
|
1146 |
|
1147 |
# Sidebar Navigation
|
1148 |
with st.sidebar:
|
1149 |
+
selected = st.selectbox(
|
1150 |
"Main Menu",
|
1151 |
["Email Generator", "Cover Letter Generator", "Resume Analysis", "Application Tracking",
|
1152 |
"Interview Preparation", "Personalized Learning Paths", "Networking Opportunities",
|
1153 |
+
"Salary Estimation", "Feedback", "Gamification", "Resource Library", "Success Stories", "Chatbot Support", "Help"]
|
|
|
|
|
|
|
|
|
1154 |
)
|
1155 |
|
1156 |
# Route to the selected page
|
|
|
1183 |
elif selected == "Help":
|
1184 |
help_page()
|
1185 |
|
1186 |
+
|
1187 |
if __name__ == "__main__":
|
1188 |
main_app()
|