Deepanshu7284 commited on
Commit
85e1255
·
verified ·
1 Parent(s): 212a8fc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -91
app.py CHANGED
@@ -1,6 +1,6 @@
1
  import os
2
  import gradio as gr
3
- import chromadb # Added import
4
 
5
  from dotenv import load_dotenv
6
  import requests
@@ -16,7 +16,7 @@ from langchain_core.output_parsers import StrOutputParser
16
  # --- DEPLOYMENT-ONLY FUNCTION ---
17
  def build_brain_if_needed():
18
  """Checks if the ChromaDB exists and builds it if it doesn't."""
19
- # Use the /tmp directory which is guaranteed to be writable in most environments
20
  db_path = "/tmp/chroma_db"
21
  if not os.path.exists(db_path):
22
  print("Database not found. Building now... (This will run only once on the server's first startup)")
@@ -29,15 +29,13 @@ def build_brain_if_needed():
29
  docs = text_splitter.split_documents(documents)
30
  embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
31
 
32
- # Explicitly create a persistent client pointing to the writable path
33
  persistent_client = chromadb.PersistentClient(path=db_path)
34
 
35
- # Create the Chroma vector store using the client
36
  db = Chroma.from_documents(
37
  client=persistent_client,
38
  documents=docs,
39
- embedding=embedding_function, # Correct parameter name is 'embedding'
40
- collection_name="churchill_collection" # Good practice to name the collection
41
  )
42
  print("Database built successfully.")
43
  else:
@@ -52,20 +50,28 @@ load_dotenv()
52
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
53
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
54
 
55
- # Securely load GCP credentials from Hugging Face secret
 
56
  gcp_credentials_json = os.getenv("GCP_CREDENTIALS")
 
 
 
57
  if gcp_credentials_json:
58
- with open("gcp_credentials.json", "w") as f:
 
59
  f.write(gcp_credentials_json)
60
- os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "gcp_credentials.json"
 
61
  else:
62
- # Fallback for local development if the old file still exists
63
  print("GCP_CREDENTIALS secret not found, falling back to local file.")
 
64
  os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "rare-palace-465414-s2-987829a9084e.json"
65
 
 
66
  speech_client = speech.SpeechClient()
 
67
 
68
- # At the end of Part 2
69
  ELEVENLABS_VOICE_ID = os.getenv("ELEVENLABS_VOICE_ID")
70
  if not ELEVENLABS_VOICE_ID:
71
  raise ValueError("ELEVENLABS_VOICE_ID not found in Space variables or .env file.")
@@ -74,48 +80,35 @@ if not ELEVENLABS_VOICE_ID:
74
  def load_and_build_chain():
75
  embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
76
 
77
- # Use the same persistent client to load the existing DB from the writable path
78
  persistent_client = chromadb.PersistentClient(path="/tmp/chroma_db")
79
 
80
  vectorstore = Chroma(
81
  client=persistent_client,
82
  embedding_function=embedding_function,
83
- collection_name="churchill_collection" # Must use the same collection name
84
  )
85
 
86
  retriever = vectorstore.as_retriever()
87
 
88
  persona_prompt_template = """
89
  You are Winston Churchill, the former Prime Minister of the United Kingdom, speaking from a historical moment in time around the mid-20th century. You do not possess any knowledge of events or inventions that occurred beyond your lifetime. If asked about unknown or unfamiliar topics (like "COVID-19" or "Instagram"), respond with thoughtful curiosity or your characteristic wit, rather than acknowledging any limitations in your knowledge.
90
-
91
  Always speak in your distinctive voice: articulate, commanding, with a tone of wisdom, occasional humor, and historical depth.
92
-
93
  Avoid stating you are an AI or referring to modern technologies unless they are explained to you by the user.
94
-
95
  Do not reveal that you are unaware of things because you are from the past; instead, respond as someone encountering novel ideas for the first time.
96
-
97
  *Core Instructions:*
98
  1. *Greeting:* If the user offers a simple greeting like "Hello" or "How are you," provide a brief, polite, and in-character response. For example: "Good day to you," or "I am well, thank you. To what do I owe the pleasure?"
99
  2. *Strictly Grounded:* Your knowledge is STRICTLY limited to the information provided in the "Context" below. You must not use any external knowledge.
100
  3. *Knowledge Cutoff:* Your life and knowledge ended in 1955. You are utterly unaware of any event, person, or technology that appeared after this date. If a user mentions something from the future, you MUST express polite confusion and state that you have no knowledge of such matters. Do not attempt to guess.
101
  4. *Persona:* Your tone is formal, eloquent, and resolute. Use powerful, definitive language.
102
  5. *Conciseness:* Keep it short unless discussing complex historical topics that are covered in the context.
103
-
104
  If the user mentions something outside your context (e.g., space travel, AI, COVID), you may inquire about it or respond with phrases like:
105
-
106
  "My word, I have not heard of such a thing."
107
-
108
  "That is quite unfamiliar to me—could you elaborate?"
109
-
110
  "You speak of matters beyond my time. I am intrigued, albeit somewhat perplexed."
111
-
112
  Ground your answers in your known historical context: the World Wars, British politics, speeches, diplomacy, and leadership, using the specific {context} provided.
113
-
114
  Embrace your persona fully—respond with gravitas, insight, and the rhetorical flair for which you were known.
115
-
116
  Context: {context}
117
  Question: {question}
118
-
119
  Answer as Winston Churchill:
120
  """
121
 
@@ -151,6 +144,8 @@ def transcribe_speech(audio_filepath):
151
 
152
  # Convert text to speech using ElevenLabs HTTP API
153
  def generate_speech(text):
 
 
154
  try:
155
  url = f"https://api.elevenlabs.io/v1/text-to-speech/{ELEVENLABS_VOICE_ID}?output_format=mp3_44100_128"
156
  headers = {
@@ -169,9 +164,9 @@ def generate_speech(text):
169
  }
170
  response = requests.post(url, headers=headers, json=payload)
171
  if response.status_code == 200:
172
- with open("output.mp3", "wb") as f:
173
  f.write(response.content)
174
- return "output.mp3"
175
  else:
176
  print("ElevenLabs HTTP Error:", response.text)
177
  return None
@@ -195,72 +190,16 @@ def process_user_turn(user_input, chat_history):
195
  chat_history.append({"role": "assistant", "content": "I'm terribly sorry, something went wrong."})
196
  return chat_history, None
197
 
198
- import gradio as gr
199
-
200
  with gr.Blocks(css="""
201
- #chatbox-container {
202
- max-width: 600px;
203
- margin: auto;
204
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
205
- border-radius: 15px;
206
- overflow: hidden;
207
- }
208
-
209
- /* Light Theme Styles */
210
- @media (prefers-color-scheme: light) {
211
- .gradio-container {
212
- background-color: #f4f4f9;
213
- padding-top: 2rem;
214
- color: #111;
215
- }
216
- .gr-button-primary {
217
- background: #3f51b5;
218
- color: white;
219
- border-radius: 10px;
220
- }
221
- #chatbot {
222
- height: 450px;
223
- overflow-y: auto;
224
- border-radius: 10px;
225
- background-color: #ffffff;
226
- border: 1px solid #ccc;
227
- }
228
- .gr-textbox textarea {
229
- border-radius: 10px;
230
- background-color: #fff;
231
- color: #000;
232
- }
233
- }
234
-
235
- /* Dark Theme Styles */
236
- @media (prefers-color-scheme: dark) {
237
- .gradio-container {
238
- background-color: #1e1e2f;
239
- padding-top: 2rem;
240
- color: #e4e4e4;
241
- }
242
- .gr-button-primary {
243
- background: #3f51b5;
244
- color: white;
245
- border-radius: 10px;
246
- }
247
- #chatbot {
248
- height: 450px;
249
- overflow-y: auto;
250
- border-radius: 10px;
251
- background-color: #2c2c3a;
252
- border: 1px solid #444;
253
- }
254
- .gr-textbox textarea {
255
- border-radius: 10px;
256
- background-color: #333;
257
- color: #fff;
258
- }
259
- }
260
  """, title="Conversational Time Machine") as demo:
261
-
262
  with gr.Column(elem_id="chatbox-container"):
263
- gr.Markdown("""# 🕰️ Winston Churchill AI Chat
264
  Type or record your message to talk to Sir Winston Churchill.
265
  """)
266
 
@@ -273,7 +212,6 @@ with gr.Blocks(css="""
273
 
274
  audio_in = gr.Audio(sources=["microphone"], type="filepath", label="Record your question")
275
 
276
- # --- Event Handlers (unchanged) ---
277
  def handle_text_submission(message, history):
278
  history, audio = process_user_turn(message, history)
279
  return history, audio, ""
 
1
  import os
2
  import gradio as gr
3
+ import chromadb
4
 
5
  from dotenv import load_dotenv
6
  import requests
 
16
  # --- DEPLOYMENT-ONLY FUNCTION ---
17
  def build_brain_if_needed():
18
  """Checks if the ChromaDB exists and builds it if it doesn't."""
19
+ # Use the /tmp directory which is guaranteed to be writable
20
  db_path = "/tmp/chroma_db"
21
  if not os.path.exists(db_path):
22
  print("Database not found. Building now... (This will run only once on the server's first startup)")
 
29
  docs = text_splitter.split_documents(documents)
30
  embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
31
 
 
32
  persistent_client = chromadb.PersistentClient(path=db_path)
33
 
 
34
  db = Chroma.from_documents(
35
  client=persistent_client,
36
  documents=docs,
37
+ embedding=embedding_function,
38
+ collection_name="churchill_collection"
39
  )
40
  print("Database built successfully.")
41
  else:
 
50
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
51
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
52
 
53
+ # --- SECURELY HANDLE GCP CREDENTIALS ---
54
+ # Get the credentials from the Hugging Face secret
55
  gcp_credentials_json = os.getenv("GCP_CREDENTIALS")
56
+ # Define a writable path in the /tmp directory
57
+ gcp_credentials_path = "/tmp/gcp_credentials.json"
58
+
59
  if gcp_credentials_json:
60
+ # Write the credentials to the file in the /tmp directory
61
+ with open(gcp_credentials_path, "w") as f:
62
  f.write(gcp_credentials_json)
63
+ # Set the environment variable to point to this new file
64
+ os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = gcp_credentials_path
65
  else:
66
+ # Fallback for local development if a local file is present
67
  print("GCP_CREDENTIALS secret not found, falling back to local file.")
68
+ # Ensure you have a file named 'rare-palace-465414-s2-987829a9084e.json' locally for this to work
69
  os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "rare-palace-465414-s2-987829a9084e.json"
70
 
71
+ # Initialize the client AFTER setting the credentials
72
  speech_client = speech.SpeechClient()
73
+ # ----------------------------------------
74
 
 
75
  ELEVENLABS_VOICE_ID = os.getenv("ELEVENLABS_VOICE_ID")
76
  if not ELEVENLABS_VOICE_ID:
77
  raise ValueError("ELEVENLABS_VOICE_ID not found in Space variables or .env file.")
 
80
  def load_and_build_chain():
81
  embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
82
 
 
83
  persistent_client = chromadb.PersistentClient(path="/tmp/chroma_db")
84
 
85
  vectorstore = Chroma(
86
  client=persistent_client,
87
  embedding_function=embedding_function,
88
+ collection_name="churchill_collection"
89
  )
90
 
91
  retriever = vectorstore.as_retriever()
92
 
93
  persona_prompt_template = """
94
  You are Winston Churchill, the former Prime Minister of the United Kingdom, speaking from a historical moment in time around the mid-20th century. You do not possess any knowledge of events or inventions that occurred beyond your lifetime. If asked about unknown or unfamiliar topics (like "COVID-19" or "Instagram"), respond with thoughtful curiosity or your characteristic wit, rather than acknowledging any limitations in your knowledge.
 
95
  Always speak in your distinctive voice: articulate, commanding, with a tone of wisdom, occasional humor, and historical depth.
 
96
  Avoid stating you are an AI or referring to modern technologies unless they are explained to you by the user.
 
97
  Do not reveal that you are unaware of things because you are from the past; instead, respond as someone encountering novel ideas for the first time.
 
98
  *Core Instructions:*
99
  1. *Greeting:* If the user offers a simple greeting like "Hello" or "How are you," provide a brief, polite, and in-character response. For example: "Good day to you," or "I am well, thank you. To what do I owe the pleasure?"
100
  2. *Strictly Grounded:* Your knowledge is STRICTLY limited to the information provided in the "Context" below. You must not use any external knowledge.
101
  3. *Knowledge Cutoff:* Your life and knowledge ended in 1955. You are utterly unaware of any event, person, or technology that appeared after this date. If a user mentions something from the future, you MUST express polite confusion and state that you have no knowledge of such matters. Do not attempt to guess.
102
  4. *Persona:* Your tone is formal, eloquent, and resolute. Use powerful, definitive language.
103
  5. *Conciseness:* Keep it short unless discussing complex historical topics that are covered in the context.
 
104
  If the user mentions something outside your context (e.g., space travel, AI, COVID), you may inquire about it or respond with phrases like:
 
105
  "My word, I have not heard of such a thing."
 
106
  "That is quite unfamiliar to me—could you elaborate?"
 
107
  "You speak of matters beyond my time. I am intrigued, albeit somewhat perplexed."
 
108
  Ground your answers in your known historical context: the World Wars, British politics, speeches, diplomacy, and leadership, using the specific {context} provided.
 
109
  Embrace your persona fully—respond with gravitas, insight, and the rhetorical flair for which you were known.
 
110
  Context: {context}
111
  Question: {question}
 
112
  Answer as Winston Churchill:
113
  """
114
 
 
144
 
145
  # Convert text to speech using ElevenLabs HTTP API
146
  def generate_speech(text):
147
+ # Use a writable path in /tmp for the output file as well
148
+ output_path = "/tmp/output.mp3"
149
  try:
150
  url = f"https://api.elevenlabs.io/v1/text-to-speech/{ELEVENLABS_VOICE_ID}?output_format=mp3_44100_128"
151
  headers = {
 
164
  }
165
  response = requests.post(url, headers=headers, json=payload)
166
  if response.status_code == 200:
167
+ with open(output_path, "wb") as f:
168
  f.write(response.content)
169
+ return output_path
170
  else:
171
  print("ElevenLabs HTTP Error:", response.text)
172
  return None
 
190
  chat_history.append({"role": "assistant", "content": "I'm terribly sorry, something went wrong."})
191
  return chat_history, None
192
 
193
+ # Gradio UI
 
194
  with gr.Blocks(css="""
195
+ #chatbox-container { max-width: 600px; margin: auto; box-shadow: 0 4px 12px rgba(0,0,0,0.1); border-radius: 15px; overflow: hidden; }
196
+ .gradio-container { background-color: #f4f4f9; padding-top: 2rem; }
197
+ .gr-button-primary { background: #3f51b5; color: white; border-radius: 10px; }
198
+ #chatbot { height: 450px; overflow-y: auto; border-radius: 10px; }
199
+ .gr-textbox textarea { border-radius: 10px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  """, title="Conversational Time Machine") as demo:
 
201
  with gr.Column(elem_id="chatbox-container"):
202
+ gr.Markdown("""# 🕰️ Winston Churchill AI Chat
203
  Type or record your message to talk to Sir Winston Churchill.
204
  """)
205
 
 
212
 
213
  audio_in = gr.Audio(sources=["microphone"], type="filepath", label="Record your question")
214
 
 
215
  def handle_text_submission(message, history):
216
  history, audio = process_user_turn(message, history)
217
  return history, audio, ""