Anustup commited on
Commit
aa5998e
1 Parent(s): aeaae19

Upload 6 files

Browse files
Files changed (6) hide show
  1. app.py +105 -0
  2. config.yaml +13 -0
  3. constants.py +4 -0
  4. prompts.py +29 -0
  5. requirements.txt +6 -0
  6. utils.py +32 -0
app.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import re
3
+ import streamlit_authenticator as stauth
4
+ import yaml
5
+ from yaml.loader import SafeLoader
6
+ from streamlit_player import st_player
7
+ from utils import create_transcript_from_youtube_api, create_open_ai_query
8
+ from prompts import DETECT_INTENT_OF_CONVERSATION, TOPIC_BASED_QUESTION, FOLLOW_UP_QUESTION, GENERAL_QUESTION, GENERAL_GREETING, \
9
+ VAGUE_QUERY_PROMPT
10
+
11
+ st.set_page_config(page_title="Youtube AI")
12
+ with open('config.yaml') as file:
13
+ config = yaml.load(file, Loader=SafeLoader)
14
+
15
+ authenticator = stauth.Authenticate(
16
+ config['credentials'],
17
+ config['cookie']['name'],
18
+ config['cookie']['key'],
19
+ config['cookie']['expiry_days'],
20
+ config['preauthorized']
21
+ )
22
+ name, authentication_status, username = authenticator.login()
23
+
24
+ if st.session_state["authentication_status"]:
25
+ authenticator.logout('Logout', 'main')
26
+ st.write(f'Welcome to Mentor Mode')
27
+ elif st.session_state["authentication_status"] is False:
28
+ st.error('Wrong password or username')
29
+ elif st.session_state["authentication_status"] is None:
30
+ st.warning('Please enter your username and password')
31
+ st.session_state["chat_history"] = []
32
+
33
+ if st.session_state["authentication_status"]:
34
+ if "chat_history" not in st.session_state:
35
+ st.session_state["chat_history"] = []
36
+
37
+ if "messages" not in st.session_state:
38
+ st.session_state.messages = []
39
+
40
+ for message in st.session_state.messages:
41
+ with st.chat_message(message["role"]):
42
+ st.markdown(message["content"])
43
+
44
+ with st.sidebar:
45
+ st.title("Your Video")
46
+ youtube_video_link = st.text_area("Please enter your video link")
47
+ st.button("Play Video", type="primary")
48
+ if youtube_video_link:
49
+ st_player(youtube_video_link)
50
+ else:
51
+ st.write("Please enter a valid link")
52
+
53
+ if prompt := st.chat_input("Hey AI!"):
54
+ st.session_state.messages.append({"role": "user", "content": prompt})
55
+ st.session_state.chat_history.append({"role": "user", "content": prompt})
56
+ with st.chat_message("user"):
57
+ st.markdown(prompt)
58
+
59
+ if youtube_video_link and prompt:
60
+ with st.spinner("Processing..."):
61
+ video_id = re.search(r'(?<=v=)[\w-]+', youtube_video_link).group(0)
62
+ yt_transcript = create_transcript_from_youtube_api(video_id)
63
+ if yt_transcript["success"]:
64
+ ADDITIONAL_PROMPT = f"""QUERY : ```{prompt}```, TRANSCRIPT:```{yt_transcript}```,
65
+ CHAT_HISTORY:```{st.session_state["chat_history"]}````"""
66
+ FINAL_PROMPT = ADDITIONAL_PROMPT + DETECT_INTENT_OF_CONVERSATION
67
+ intent = create_open_ai_query(FINAL_PROMPT)
68
+ print(intent["data"])
69
+ if intent["success"]:
70
+ if intent["data"] == "VAGUE_QUERY":
71
+ FINAL_PROMPT = ADDITIONAL_PROMPT + VAGUE_QUERY_PROMPT
72
+ response = create_open_ai_query(FINAL_PROMPT)
73
+ elif intent["data"] == "GENERAL_QUESTION":
74
+ FINAL_PROMPT = ADDITIONAL_PROMPT + GENERAL_QUESTION
75
+ response = create_open_ai_query(FINAL_PROMPT)
76
+ elif intent["data"] == "TOPIC_BASED_QUESTION":
77
+ FINAL_PROMPT = ADDITIONAL_PROMPT + TOPIC_BASED_QUESTION
78
+ response = create_open_ai_query(FINAL_PROMPT)
79
+ elif intent["data"] == "FOLLOW_UP_QUESTION":
80
+ FINAL_PROMPT = ADDITIONAL_PROMPT + FOLLOW_UP_QUESTION
81
+ response = create_open_ai_query(FINAL_PROMPT)
82
+ elif intent["data"] == "GENERAL_GREETING":
83
+ FINAL_PROMPT = ADDITIONAL_PROMPT + GENERAL_GREETING
84
+ response = create_open_ai_query(FINAL_PROMPT)
85
+
86
+ with st.chat_message("assistant"):
87
+ if response["success"]:
88
+ st.write(response["data"])
89
+ else:
90
+ st.write(response["error"])
91
+ st.session_state.messages.append({"role": "assistant", "content": response["data"]})
92
+ st.session_state.chat_history.append({"role": "assistant", "content": response["data"]})
93
+
94
+ if st.button("Download Chat History"):
95
+ # Combine role and content for each message
96
+ chat_history = "\n".join(
97
+ [f"{message['role']} : {message['content']}" for message in
98
+ st.session_state.messages if message["content"] is not None]
99
+ )
100
+ st.download_button(
101
+ label="Download",
102
+ data=chat_history,
103
+ file_name="chat_history.txt",
104
+ mime="text/plain"
105
+ )
config.yaml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ credentials:
2
+ usernames:
3
+ IssacNewton:
4
+ email: newton@newtonschool.co
5
+ name: Issac Newton
6
+ password: "$2b$12$CnkWEiaUjJTkRvUy4R5R6.UXjHkAxMbwB13AMklpnPcHfdadD9tBK" # To be replaced with hashed password
7
+ cookie:
8
+ expiry_days: 30
9
+ key: "issac" # Must be string
10
+ name: "newton"
11
+ preauthorized:
12
+ emails:
13
+ - newton@newtonschool.co
constants.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ import os
2
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
3
+ OPENAI_API_BASE_URL = "https://api.openai.com/v1"
4
+ OPEN_AI_MODEL = "gpt-4-1106-preview"
prompts.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ DETECT_INTENT_OF_CONVERSATION = """User is watching a youtube video, whose transcript is : TRANSCRIPT. Your task is to classify the type of the given
2
+ query : QUERY which is asked by the user. Always take inference from chat history: CHAT_HISTORY, while detecting type.
3
+ Here are the possible types along with the definition of the type:
4
+ 1.) VAGUE_QUERY: User is asking absolutely irrelevant question which is not present in transcript
5
+ 2.) GENERAL_QUESTION: User is asking in general about the video for eg what is the video about, give me a gist etc
6
+ 3.) TOPIC_BASED_QUESTION: User is asking questions based on specific parts of the video
7
+ 4.) FOLLOW_UP_QUESTION: User is asking follow up questions based on their previous chat history
8
+ 5.) GENERAL_GREETING: User is greeting by saying hi hello thank you.
9
+ OUTPUT FORMAT -> Just final type, no extra text"""
10
+
11
+ VAGUE_QUERY_PROMPT = """User is watching a youtube video, whose transcript is : TRANSCRIPT. The previous chat history of the
12
+ user: CHAT_HISTORY. The user had asked a vague query : QUERY. So please tell the user to please stick to a conversation regarding the video
13
+ only"""
14
+ GENERAL_QUESTION = """User is watching a youtube video, whose transcript is : TRANSCRIPT. The previous chat history of the
15
+ user: CHAT_HISTORY. The user had asked a general question: QUERY regarding the video. Reply the user by taking reference from transcript
16
+ as well from the chat history(if needed). Also be short and crunch , reply with in 100 to 80 words. Give short pointers and be to the point
17
+ """
18
+ TOPIC_BASED_QUESTION = """User is watching a youtube video, whose transcript is : TRANSCRIPT. The previous chat history of the
19
+ user: CHAT_HISTORY. The user had asked question from a specific part from the video:QUERY. You have to reply to the user by performing
20
+ the following steps internally :
21
+ 1.) First understand the question and figure out from which part of the transcript this topic will be.
22
+ 2.) Take time to think
23
+ 3.) Reply the user accordingly in 100 to 80 words and also be to the point always."""
24
+
25
+ FOLLOW_UP_QUESTION = """User is watching a youtube video, whose transcript is : TRANSCRIPT. The previous chat history of the
26
+ user: CHAT_HISTORY. The user is asking a follow up question: QUERY based on the chat history. Your task is to analyse the chat history
27
+ and reply the user accordingly. Always be short and to the point while replying , with in 100 to 80 words"""
28
+
29
+ GENERAL_GREETING = """User is greeting you : query, please ask the user if they have any question for you!"""
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ streamlit~=1.31.1
2
+ streamlit-player
3
+ streamlit_authenticator
4
+ pyyaml~=6.0.1
5
+ requests~=2.31.0
6
+ youtube-transcript-api
utils.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from youtube_transcript_api import YouTubeTranscriptApi
2
+ from constants import OPENAI_API_KEY, OPENAI_API_BASE_URL, OPEN_AI_MODEL
3
+ import json
4
+ import requests
5
+
6
+ def create_transcript_from_youtube_api(youtube_video_id):
7
+ if not youtube_video_id:
8
+ return {"success": False, "error": "Please pass your youtube video-id"}
9
+ try:
10
+ list_transcript = YouTubeTranscriptApi.get_transcript(youtube_video_id)
11
+ transcript = ' '.join(entry['text'] for entry in list_transcript)
12
+ return {"success": True, "data": transcript}
13
+ except Exception as e:
14
+ return {"success": False, "error": f"Transcription failed due to : {e}"}
15
+
16
+
17
+ def create_open_ai_query(input_query, system_message=None, model_engine=OPEN_AI_MODEL):
18
+ openai_url = f"{OPENAI_API_BASE_URL}/chat/completions"
19
+ headers = {'Authorization': f'Bearer {OPENAI_API_KEY}', 'Content-Type': 'application/json'}
20
+ messages = []
21
+ if system_message:
22
+ messages.append({"role": "system", "content": system_message})
23
+ messages.append({"role": "user", "content": input_query})
24
+ payload = {
25
+ 'model': model_engine,
26
+ 'messages': messages,
27
+ }
28
+ response = requests.post(openai_url, headers=headers, data=json.dumps(payload))
29
+ if response.status_code == 200 and 'choices' in response.json():
30
+ content_text = response.json()['choices'][0]['message']['content'].strip()
31
+ return {"success": True, "data": content_text, "response_json": response.json()}
32
+ return {"success": False, "error": response.text}