DrishtiSharma commited on
Commit
2707344
·
verified ·
1 Parent(s): 012a1a6

Create test.py

Browse files
Files changed (1) hide show
  1. test.py +220 -0
test.py ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ from datetime import datetime
4
+ from pydub import AudioSegment
5
+ import tempfile
6
+ import pytz
7
+ from openai import OpenAI
8
+ from langchain.chains import ConversationalRetrievalChain
9
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
10
+ from langchain_openai import ChatOpenAI, OpenAIEmbeddings
11
+ from langchain_community.vectorstores import Chroma
12
+ from langchain_community.document_loaders import PyPDFLoader, TextLoader, CSVLoader
13
+
14
+
15
+ class DocumentRAG:
16
+ def __init__(self):
17
+ self.document_store = None
18
+ self.qa_chain = None
19
+ self.document_summary = ""
20
+ self.chat_history = []
21
+ self.last_processed_time = None
22
+ self.api_key = os.getenv("OPENAI_API_KEY") # Fetch the API key from environment variable
23
+ self.init_time = datetime.now(pytz.UTC)
24
+
25
+ if not self.api_key:
26
+ raise ValueError("API Key not found. Make sure to set the 'OPENAI_API_KEY' environment variable.")
27
+
28
+ # Persistent directory for Chroma to avoid tenant-related errors
29
+ self.chroma_persist_dir = "./chroma_storage"
30
+ os.makedirs(self.chroma_persist_dir, exist_ok=True)
31
+
32
+ def process_documents(self, uploaded_files):
33
+ """Process uploaded files by saving them temporarily and extracting content."""
34
+ if not self.api_key:
35
+ return "Please set the OpenAI API key in the environment variables."
36
+ if not uploaded_files:
37
+ return "Please upload documents first."
38
+
39
+ try:
40
+ documents = []
41
+ for uploaded_file in uploaded_files:
42
+ temp_file_path = tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1]).name
43
+ with open(temp_file_path, "wb") as temp_file:
44
+ temp_file.write(uploaded_file.read())
45
+
46
+ if temp_file_path.endswith('.pdf'):
47
+ loader = PyPDFLoader(temp_file_path)
48
+ elif temp_file_path.endswith('.txt'):
49
+ loader = TextLoader(temp_file_path)
50
+ elif temp_file_path.endswith('.csv'):
51
+ loader = CSVLoader(temp_file_path)
52
+ else:
53
+ return f"Unsupported file type: {uploaded_file.name}"
54
+
55
+ try:
56
+ documents.extend(loader.load())
57
+ except Exception as e:
58
+ return f"Error loading {uploaded_file.name}: {str(e)}"
59
+
60
+ if not documents:
61
+ return "No valid documents were processed. Please check your files."
62
+
63
+ text_splitter = RecursiveCharacterTextSplitter(
64
+ chunk_size=1000,
65
+ chunk_overlap=200,
66
+ length_function=len
67
+ )
68
+ documents = text_splitter.split_documents(documents)
69
+
70
+ combined_text = " ".join([doc.page_content for doc in documents])
71
+ self.document_summary = self.generate_summary(combined_text)
72
+
73
+ embeddings = OpenAIEmbeddings(api_key=self.api_key)
74
+ self.document_store = Chroma.from_documents(
75
+ documents,
76
+ embeddings,
77
+ persist_directory=self.chroma_persist_dir
78
+ )
79
+
80
+ self.qa_chain = ConversationalRetrievalChain.from_llm(
81
+ ChatOpenAI(temperature=0, model_name='gpt-4', api_key=self.api_key),
82
+ self.document_store.as_retriever(search_kwargs={'k': 6}),
83
+ return_source_documents=True,
84
+ verbose=False
85
+ )
86
+
87
+ self.last_processed_time = datetime.now(pytz.UTC)
88
+ return "Documents processed successfully!"
89
+ except Exception as e:
90
+ return f"Error processing documents: {str(e)}"
91
+
92
+ def generate_summary(self, text):
93
+ """Generate a summary of the provided text."""
94
+ if not self.api_key:
95
+ return "API Key not set. Please set it in the environment variables."
96
+ try:
97
+ client = OpenAI(api_key=self.api_key)
98
+ response = client.chat.completions.create(
99
+ model="gpt-4",
100
+ messages=[
101
+ {"role": "system", "content": "Summarize the document content concisely and provide 3-5 key points for discussion."},
102
+ {"role": "user", "content": text[:4000]}
103
+ ],
104
+ temperature=0.3
105
+ )
106
+ return response.choices[0].message.content
107
+ except Exception as e:
108
+ return f"Error generating summary: {str(e)}"
109
+
110
+ def create_podcast(self):
111
+ """Generate a podcast script and audio based on the document summary."""
112
+ if not self.document_summary:
113
+ return "Please process documents before generating a podcast.", None
114
+
115
+ if not self.api_key:
116
+ return "Please set the OpenAI API key in the environment variables.", None
117
+
118
+ try:
119
+ client = OpenAI(api_key=self.api_key)
120
+ script_response = client.chat.completions.create(
121
+ model="gpt-4",
122
+ messages=[
123
+ {"role": "system", "content": "You are a professional podcast producer. Create a natural dialogue based on the provided document summary."},
124
+ {"role": "user", "content": f"""Based on the following document summary, create a 1-2 minute podcast script:
125
+ 1. Clearly label the dialogue as 'Host 1:' and 'Host 2:'
126
+ 2. Keep the content engaging and insightful.
127
+ 3. Use conversational language suitable for a podcast.
128
+ 4. Ensure the script has a clear opening and closing.
129
+ Document Summary: {self.document_summary}"""}
130
+ ],
131
+ temperature=0.7
132
+ )
133
+
134
+ script = script_response.choices[0].message.content
135
+ if not script:
136
+ return "Error: Failed to generate podcast script.", None
137
+
138
+ final_audio = AudioSegment.empty()
139
+ is_first_speaker = True
140
+
141
+ lines = [line.strip() for line in script.split("\n") if line.strip()]
142
+ for line in lines:
143
+ if ":" not in line:
144
+ continue
145
+
146
+ speaker, text = line.split(":", 1)
147
+ if not text.strip():
148
+ continue
149
+
150
+ try:
151
+ voice = "nova" if is_first_speaker else "onyx"
152
+ audio_response = client.audio.speech.create(
153
+ model="tts-1",
154
+ voice=voice,
155
+ input=text.strip()
156
+ )
157
+
158
+ temp_audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
159
+ audio_response.stream_to_file(temp_audio_file.name)
160
+
161
+ segment = AudioSegment.from_file(temp_audio_file.name)
162
+ final_audio += segment
163
+ final_audio += AudioSegment.silent(duration=300)
164
+
165
+ is_first_speaker = not is_first_speaker
166
+ except Exception as e:
167
+ print(f"Error generating audio for line: {text}")
168
+ print(f"Details: {e}")
169
+ continue
170
+
171
+ if len(final_audio) == 0:
172
+ return "Error: No audio could be generated.", None
173
+
174
+ output_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
175
+ final_audio.export(output_file, format="mp3")
176
+ return script, output_file
177
+
178
+ except Exception as e:
179
+ return f"Error generating podcast: {str(e)}", None
180
+
181
+
182
+ # Initialize RAG system in session state
183
+ if "rag_system" not in st.session_state:
184
+ st.session_state.rag_system = DocumentRAG()
185
+
186
+ # Sidebar
187
+ with st.sidebar:
188
+ st.title("About")
189
+ st.markdown(
190
+ """
191
+ This app is inspired by the [RAG_HW HuggingFace Space](https://huggingface.co/spaces/wint543/RAG_HW).
192
+ It allows users to upload documents, generate summaries, ask questions, and create podcasts.
193
+ """
194
+ )
195
+ st.markdown("### Steps:")
196
+ st.markdown("1. Upload documents.")
197
+ st.markdown("2. Generate summaries.")
198
+ st.markdown("3. Ask questions.")
199
+ st.markdown("4. Create podcasts.")
200
+
201
+ # Main App
202
+ st.title("Document Analyzer and Podcast Generator")
203
+
204
+ uploaded_files = st.file_uploader("Upload files (PDF, TXT, CSV)", accept_multiple_files=True)
205
+
206
+ if st.button("Process Documents"):
207
+ if uploaded_files:
208
+ result = st.session_state.rag_system.process_documents(uploaded_files)
209
+ st.success(result) if "successfully" in result else st.error(result)
210
+ else:
211
+ st.warning("No files uploaded.")
212
+
213
+ if st.session_state.rag_system.document_summary:
214
+ st.subheader("Step 2: Generate Podcast")
215
+ if st.button("Generate Podcast"):
216
+ script, audio_path = st.session_state.rag_system.create_podcast()
217
+ if audio_path:
218
+ st.text_area("Generated Podcast Script", script, height=200)
219
+ st.audio(audio_path, format="audio/mp3")
220
+ st.success("Podcast generated successfully!")