Rktim commited on
Commit
987d901
Β·
verified Β·
1 Parent(s): 1998285

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +212 -86
app.py CHANGED
@@ -6,31 +6,149 @@ from langchain_community.vectorstores import Chroma
6
  from langchain.chains import ConversationalRetrievalChain
7
  from langchain.memory import ConversationBufferMemory
8
  import os
9
- #from dotenv import load_dotenv
10
  import requests
11
  from bs4 import BeautifulSoup
12
- import gradio as gr
13
 
14
  # Load environment variables
15
- #load_dotenv()
16
- GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
17
-
18
- # Initialize global session states
19
- session_state = {
20
- "messages": [],
21
- "qa_chain": None,
22
- "current_blog_url": None,
23
- "blog_content": None
24
- }
25
-
26
- # Function to fetch and extract blog text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  def fetch_blog_text(url: str) -> str:
28
  response = requests.get(url)
29
  soup = BeautifulSoup(response.text, "html.parser")
30
  paragraphs = [p.get_text() for p in soup.find_all("p")]
31
  return "\n".join(paragraphs)
32
 
33
- # Function to create vector store from blog text
34
  def create_vector_store(text: str):
35
  splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
36
  chunks = splitter.split_text(text)
@@ -38,82 +156,90 @@ def create_vector_store(text: str):
38
  vectordb = Chroma.from_texts(chunks, embeddings)
39
  return vectordb
40
 
41
- # Set up the RAG chain
42
  def setup_chain(vectordb):
43
  memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
44
- llm = ChatGroq(api_key=GROQ_API_KEY, model="qwen-qwq-32b")
45
  qa_chain = ConversationalRetrievalChain.from_llm(
46
  llm, vectordb.as_retriever(), memory=memory
47
  )
48
  return qa_chain
49
 
50
- # Load and process blog function
51
- def load_blog(blog_url):
52
- try:
53
- text = fetch_blog_text(blog_url)
54
- vectordb = create_vector_store(text)
55
- session_state["qa_chain"] = setup_chain(vectordb)
56
- session_state["current_blog_url"] = blog_url
57
- session_state["blog_content"] = text
58
- session_state["messages"] = []
59
- return f"βœ… Blog loaded! You can now ask questions.\n\nPreview:\n{text[:1000]}{'...' if len(text) > 1000 else ''}"
60
- except Exception as e:
61
- return f"❌ Error loading blog: {str(e)}"
62
-
63
- # Chat handler
64
- def chat_with_blog(question):
65
- if not session_state["qa_chain"]:
66
- return "❌ Please load a blog first."
67
-
68
- session_state["messages"].append({"role": "user", "content": question})
69
- try:
70
- result = session_state["qa_chain"]({
71
- "question": question,
72
- "chat_history": [
73
- (m["content"] if m["role"] == "user" else "",
74
- m["content"] if m["role"] == "assistant" else "")
75
- for m in session_state["messages"][:-1]
76
- ]
77
- })
78
- response = result["answer"]
79
- session_state["messages"].append({"role": "assistant", "content": response})
80
- return response
81
- except Exception as e:
82
- return f"❌ Error: {str(e)}"
83
-
84
- # Gradio UI
85
- def main():
86
- with gr.Blocks(theme=gr.themes.Base(), css="""
87
- textarea, input, button {
88
- font-size: 1.2em;
89
- }
90
- .chat-box {
91
- height: 300px;
92
- overflow-y: auto;
93
- background-color: #1f1f1f;
94
- color: white;
95
- padding: 1em;
96
- border-radius: 8px;
97
- }
98
- """) as demo:
99
- gr.Markdown("# πŸ“ Blog Bot\nYour AI-powered blog analysis companion")
100
-
101
- with gr.Row():
102
- blog_url_input = gr.Textbox(label="Enter Blog URL", placeholder="Paste blog URL here...")
103
- load_btn = gr.Button("✨ Load Blog")
104
-
105
- blog_preview = gr.Markdown("", label="Blog Preview")
106
-
107
- with gr.Row():
108
- chat_input = gr.Textbox(label="Ask a question about the blog...", lines=2)
109
- send_btn = gr.Button("Send")
110
-
111
- chat_output = gr.Textbox(label="Response", lines=4)
112
-
113
- load_btn.click(fn=load_blog, inputs=blog_url_input, outputs=blog_preview)
114
- send_btn.click(fn=chat_with_blog, inputs=chat_input, outputs=chat_output)
115
-
116
- demo.launch()
 
 
 
 
 
 
 
 
 
 
117
 
118
- if __name__ == "__main__":
119
- main()
 
6
  from langchain.chains import ConversationalRetrievalChain
7
  from langchain.memory import ConversationBufferMemory
8
  import os
9
+ from dotenv import load_dotenv
10
  import requests
11
  from bs4 import BeautifulSoup
12
+ import streamlit as st
13
 
14
  # Load environment variables
15
+ load_dotenv()
16
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
17
+
18
+ # Custom CSS
19
+ st.markdown("""
20
+ <style>
21
+ /* Main container */
22
+ .stApp {
23
+ background-color: #0f0f0f;
24
+ color: white;
25
+ }
26
+
27
+ /* Headers */
28
+ h1 {
29
+ color: #ff0000 !important;
30
+ font-size: 2.5em !important;
31
+ text-align: center;
32
+ margin-bottom: 10px !important;
33
+ }
34
+
35
+ /* Subheaders */
36
+ h2, h3 {
37
+ color: #aaaaaa !important;
38
+ font-size: 1.5em !important;
39
+ }
40
+
41
+ /* Text input */
42
+ .stTextInput > div > div > input {
43
+ background-color: #1f1f1f !important;
44
+ color: white !important;
45
+ border: 1px solid #303030 !important;
46
+ border-radius: 4px !important;
47
+ font-size: 1.2em !important;
48
+ padding: 12px !important;
49
+ height: 60px !important;
50
+ }
51
+
52
+ /* Buttons */
53
+ .stButton > button {
54
+ background-color: #ff0000 !important;
55
+ color: white !important;
56
+ border: none !important;
57
+ border-radius: 4px !important;
58
+ padding: 12px 24px !important;
59
+ font-weight: 500 !important;
60
+ font-size: 1.2em !important;
61
+ width: 100% !important;
62
+ margin: 10px 0 !important;
63
+ }
64
+
65
+ .stButton > button:hover {
66
+ background-color: #cc0000 !important;
67
+ }
68
+
69
+ /* Chat messages */
70
+ .stChatMessage {
71
+ background-color: #1f1f1f !important;
72
+ border: 1px solid #303030 !important;
73
+ border-radius: 8px !important;
74
+ padding: 16px !important;
75
+ margin: 12px 0 !important;
76
+ font-size: 1.1em !important;
77
+ }
78
+
79
+ .stChatMessage[data-testid="user-message"] {
80
+ border-left: 4px solid #ff0000 !important;
81
+ }
82
+
83
+ .stChatMessage[data-testid="assistant-message"] {
84
+ border-left: 4px solid #3ea6ff !important;
85
+ }
86
+
87
+ /* Blog content preview */
88
+ .blog-preview {
89
+ background-color: #1f1f1f !important;
90
+ border: 1px solid #303030 !important;
91
+ border-radius: 8px !important;
92
+ padding: 20px !important;
93
+ margin: 20px 0 !important;
94
+ max-height: 400px !important;
95
+ overflow-y: auto !important;
96
+ font-size: 1.1em !important;
97
+ line-height: 1.6 !important;
98
+ }
99
+
100
+ /* Chat input */
101
+ .stChatInput > div > div > textarea {
102
+ background-color: #1f1f1f !important;
103
+ color: white !important;
104
+ border: 1px solid #303030 !important;
105
+ border-radius: 4px !important;
106
+ font-size: 1.2em !important;
107
+ padding: 12px !important;
108
+ min-height: 80px !important;
109
+ }
110
+
111
+ /* Scrollbar styling */
112
+ ::-webkit-scrollbar {
113
+ width: 10px;
114
+ }
115
+
116
+ ::-webkit-scrollbar-track {
117
+ background: #1f1f1f;
118
+ }
119
+
120
+ ::-webkit-scrollbar-thumb {
121
+ background: #303030;
122
+ border-radius: 5px;
123
+ }
124
+
125
+ ::-webkit-scrollbar-thumb:hover {
126
+ background: #404040;
127
+ }
128
+ </style>
129
+ """, unsafe_allow_html=True)
130
+
131
+ # Initialize session state
132
+ if "messages" not in st.session_state:
133
+ st.session_state.messages = []
134
+
135
+ if "qa_chain" not in st.session_state:
136
+ st.session_state.qa_chain = None
137
+
138
+ if "current_blog_url" not in st.session_state:
139
+ st.session_state.current_blog_url = None
140
+
141
+ if "blog_content" not in st.session_state:
142
+ st.session_state.blog_content = None
143
+
144
+ # 1. Function to fetch and extract blog text
145
  def fetch_blog_text(url: str) -> str:
146
  response = requests.get(url)
147
  soup = BeautifulSoup(response.text, "html.parser")
148
  paragraphs = [p.get_text() for p in soup.find_all("p")]
149
  return "\n".join(paragraphs)
150
 
151
+ # 2. Function to create vector store from blog text
152
  def create_vector_store(text: str):
153
  splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
154
  chunks = splitter.split_text(text)
 
156
  vectordb = Chroma.from_texts(chunks, embeddings)
157
  return vectordb
158
 
159
+ # 3. Set up the RAG chain
160
  def setup_chain(vectordb):
161
  memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
162
+ llm = ChatGroq(api_key=GROQ_API_KEY, model="gemma2-9b-it")
163
  qa_chain = ConversationalRetrievalChain.from_llm(
164
  llm, vectordb.as_retriever(), memory=memory
165
  )
166
  return qa_chain
167
 
168
+ # App title
169
+ st.markdown("<h1>Blog Bot πŸ“</h1>", unsafe_allow_html=True)
170
+ st.markdown("<p style='text-align: center; color: #aaaaaa; font-size: 1.2em;'>Your AI-powered blog analysis companion</p>", unsafe_allow_html=True)
171
+
172
+ # Create two columns
173
+ col1, col2 = st.columns(2)
174
+
175
+ with col1:
176
+ # Blog URL input
177
+ blog_url = st.text_input("πŸ“ Enter Blog URL", placeholder="Paste your blog URL here...", key="blog_url_input")
178
+
179
+ # Process button
180
+ if st.button("✨ Load Blog", key="load_blog_btn"):
181
+ if not blog_url:
182
+ st.error("Please enter a blog URL.")
183
+ else:
184
+ try:
185
+ with st.spinner("πŸ” Processing blog content..."):
186
+ # Fetch and process blog content
187
+ text = fetch_blog_text(blog_url)
188
+ st.session_state.blog_content = text # Store blog content
189
+ vectordb = create_vector_store(text)
190
+ st.session_state.qa_chain = setup_chain(vectordb)
191
+ st.session_state.current_blog_url = blog_url
192
+ st.session_state.messages = [] # Clear chat history
193
+ st.success("βœ… Blog content loaded! You can now ask questions about it.")
194
+ except Exception as e:
195
+ st.error(f"❌ Error processing blog: {str(e)}")
196
+
197
+ # Display blog content preview
198
+ if st.session_state.blog_content:
199
+ st.markdown("### πŸ“„ Blog Content Preview")
200
+ st.markdown(f"""
201
+ <div class="blog-preview">
202
+ {st.session_state.blog_content[:2000] + "..." if len(st.session_state.blog_content) > 2000 else st.session_state.blog_content}
203
+ </div>
204
+ """, unsafe_allow_html=True)
205
+
206
+ with col2:
207
+ # Chat interface
208
+ st.markdown("### πŸ’¬ Chat")
209
+
210
+ # Display chat messages
211
+ for message in st.session_state.messages:
212
+ with st.chat_message(message["role"]):
213
+ st.markdown(message["content"])
214
+
215
+ # Chat input
216
+ if prompt := st.chat_input("Ask a question about the blog...", key="chat_input"):
217
+ if not st.session_state.qa_chain:
218
+ st.error("Please load a blog first.")
219
+ else:
220
+ # Add user message to chat history
221
+ st.session_state.messages.append({"role": "user", "content": prompt})
222
+
223
+ # Display user message
224
+ with st.chat_message("user"):
225
+ st.markdown(prompt)
226
+
227
+ try:
228
+ # Get AI response
229
+ with st.spinner("πŸ€” Thinking..."):
230
+ result = st.session_state.qa_chain({
231
+ "question": prompt,
232
+ "chat_history": [(m["content"] if m["role"] == "user" else "", m["content"] if m["role"] == "assistant" else "")
233
+ for m in st.session_state.messages[:-1]]
234
+ })
235
+ response = result["answer"]
236
+
237
+ # Add assistant message to chat history
238
+ st.session_state.messages.append({"role": "assistant", "content": response})
239
+
240
+ # Display assistant message
241
+ with st.chat_message("assistant"):
242
+ st.markdown(response)
243
+ except Exception as e:
244
+ st.error(f"❌ Error: {str(e)}")
245