OnlyTheTruth03 commited on
Commit
83d020e
Β·
verified Β·
1 Parent(s): bd14106

Update app.py

Browse files

Solve runtime error

Files changed (1) hide show
  1. app.py +121 -74
app.py CHANGED
@@ -2,14 +2,7 @@
2
  app.py
3
  ──────
4
  Gradio UI β€” the entry point for Hugging Face Spaces.
5
-
6
- This module ONLY handles UI concerns:
7
- - Layout and theming
8
- - Wiring user inputs to the RAG pipeline
9
- - Displaying answers and source citations
10
- - Error handling / friendly messages
11
-
12
- It delegates ALL logic to rag_pipeline.py.
13
  """
14
 
15
  import logging
@@ -20,9 +13,8 @@ from config import cfg
20
  from rag_pipeline import RAGPipeline, build_pipeline
21
 
22
  # ── Gradio version guard ──────────────────────────────────────────────────────
23
- # Detect which optional Chatbot kwargs are available in the installed version.
24
  import inspect as _inspect
25
- _chatbot_params = set(_inspect.signature(gr.Chatbot.__init__).parameters)
26
  _SUPPORTS_COPY = "show_copy_button" in _chatbot_params
27
  _SUPPORTS_BUBBLE = "bubble_full_width" in _chatbot_params
28
 
@@ -45,34 +37,111 @@ except Exception as exc:
45
  logger.exception("Pipeline initialisation failed: %s", exc)
46
 
47
 
48
- # ── Chat handler ──────────────────────────────────────────────────────────────
49
 
50
  def _msg(role: str, content: str) -> dict:
51
  """Return a Gradio-compatible message dict."""
52
  return {"role": role, "content": content}
53
 
54
 
55
- def chat(user_message: str, history: list, show_sources: bool):
56
  """
57
- Called by Gradio on every user message.
58
-
59
- Parameters
60
- ----------
61
- user_message : str
62
- history : list
63
- Gradio chat history β€” list of {"role": ..., "content": ...} dicts.
64
- show_sources : bool
65
- Whether to append source citations below the answer.
66
-
67
- Returns
68
- -------
69
- tuple[str, list, str]
70
- (cleared input, updated history, sources markdown)
71
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  if init_error:
73
- bot_reply = f"⚠️ **Setup error:** {init_error}\n\nPlease check your Space secrets and logs."
74
- history = history + [_msg("user", user_message), _msg("assistant", bot_reply)]
75
- return "", history, ""
76
 
77
  if not user_message.strip():
78
  return "", history, ""
@@ -86,21 +155,15 @@ def chat(user_message: str, history: list, show_sources: bool):
86
  bot_reply = "πŸ”­ Something went wrong while consulting the stars. Please try again."
87
  sources_md = ""
88
 
89
- history = history + [_msg("user", user_message), _msg("assistant", bot_reply)]
90
- return "", history, sources_md
91
 
92
 
93
  # ── Gradio UI ─────────────────────────────────────────────────────────────────
94
 
95
  CSS = """
96
- /* AstroBot custom styles */
97
  body, .gradio-container { font-family: 'Georgia', serif; }
98
  .title-banner { text-align: center; padding: 1rem 0 0.5rem; }
99
  .title-banner h1 { font-size: 2rem; letter-spacing: 0.04em; }
100
- .disclaimer {
101
- background: #1a1a2e; color: #a0aec0; border-radius: 8px;
102
- padding: 0.6rem 1rem; font-size: 0.82rem; margin-bottom: 0.5rem;
103
- }
104
  .sources-box { font-size: 0.82rem; color: #718096; }
105
  footer { display: none !important; }
106
  """
@@ -116,34 +179,25 @@ EXAMPLE_QUESTIONS = [
116
  "How does the Moon sign influence emotions?",
117
  ]
118
 
119
- # ── Gradio version-safe theme ─────────────────────────────────────────────────
120
  _SUPPORTS_THEMES = hasattr(gr, "themes") and hasattr(gr.themes, "Base")
121
  _theme = gr.themes.Base(
122
- primary_hue="indigo",
123
- secondary_hue="purple",
124
- neutral_hue="slate",
125
  ) if _SUPPORTS_THEMES else None
126
 
127
- with gr.Blocks(
128
- title=cfg.app_title,
129
- theme=_theme,
130
- css=CSS,
131
- ) as demo:
132
 
133
  # ── Header ────────────────────────────────────────────────────────────────
134
- gr.HTML(
135
- """
136
  <div class="title-banner">
137
  <h1>πŸ”­ AstroBot Demo</h1>
138
  <p style="color:#9b8ec4; font-size:1.05rem;">
139
  Your AI Astrology Assistant Β· Powered by Groq LLaMA-3.1-8b-instant
140
  </p>
141
  </div>
142
- """
143
- )
144
 
145
- gr.HTML(
146
- """
147
  <div style="background-color:#3b3777; color:#f0eeff; border:1px solid #6c67c4;
148
  border-radius:8px; padding:10px 16px; font-size:0.92rem;
149
  margin-bottom:8px; line-height:1.6;">
@@ -152,20 +206,17 @@ with gr.Blocks(
152
  It does <strong style="color:#ffffff;">not</strong> make personal predictions
153
  or interpret individual birth charts.
154
  </div>
155
- """
156
- )
157
 
158
  # ── Main layout ────────��──────────────────────────────────────────────────
159
  with gr.Row():
160
  with gr.Column(scale=3):
161
  _chatbot_kwargs = {"label": "AstroBot", "height": 500}
162
- if _SUPPORTS_BUBBLE:
163
- _chatbot_kwargs["bubble_full_width"] = False
164
- if _SUPPORTS_COPY:
165
- _chatbot_kwargs["show_copy_button"] = True
166
- if "type" in _chatbot_params:
167
- _chatbot_kwargs["type"] = "messages" # role/content dict format
168
  chatbot = gr.Chatbot(**_chatbot_kwargs)
 
169
  with gr.Row():
170
  txt_input = gr.Textbox(
171
  placeholder="Ask a concept question about astrology…",
@@ -176,31 +227,29 @@ with gr.Blocks(
176
 
177
  with gr.Column(scale=1):
178
  gr.Markdown("### βš™οΈ Options")
179
- _checkbox_kwargs = {
180
- "label": "Show source excerpts",
181
- "value": False,
182
- }
183
  _checkbox_params = set(_inspect.signature(gr.Checkbox.__init__).parameters)
184
  if "info" in _checkbox_params:
185
- _checkbox_kwargs["info"] = "Display the course material passages used to answer."
186
  show_sources = gr.Checkbox(**_checkbox_kwargs)
 
187
  gr.Markdown("### πŸ’‘ Example Questions")
188
  for q in EXAMPLE_QUESTIONS:
189
- gr.Button(q, size="sm").click(
190
- fn=lambda x=q: x, outputs=txt_input
191
- )
 
 
 
192
 
193
  # ── Source citations panel ────────────────────────────────────────────────
194
  sources_display = gr.Markdown(
195
- value="",
196
- label="Source Excerpts",
197
- elem_classes=["sources-box"],
198
  )
199
 
200
- # ── State ────────────────────────────────────────────────────────────────
201
  state = gr.State([])
202
 
203
- # ── Event wiring ──────────────────────────────────────────────────────────
204
  send_btn.click(
205
  fn=chat,
206
  inputs=[txt_input, state, show_sources],
@@ -212,13 +261,11 @@ with gr.Blocks(
212
  outputs=[txt_input, chatbot, sources_display],
213
  )
214
 
215
- # ── Footer ────────────────────────────────────────────────────────────────
216
  gr.Markdown(
217
  "_Built with [Groq](https://groq.com) Β· [LangChain](https://langchain.com) Β· "
218
  "[Hugging Face](https://huggingface.co) β€” for astrology students everywhere πŸŒ™_"
219
  )
220
 
221
 
222
- # ── Entry point ───────────────────────────────────────────────────────────────
223
  if __name__ == "__main__":
224
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  app.py
3
  ──────
4
  Gradio UI β€” the entry point for Hugging Face Spaces.
5
+ Delegates ALL logic to rag_pipeline.py.
 
 
 
 
 
 
 
6
  """
7
 
8
  import logging
 
13
  from rag_pipeline import RAGPipeline, build_pipeline
14
 
15
  # ── Gradio version guard ──────────────────────────────────────────────────────
 
16
  import inspect as _inspect
17
+ _chatbot_params = set(_inspect.signature(gr.Chatbot.__init__).parameters)
18
  _SUPPORTS_COPY = "show_copy_button" in _chatbot_params
19
  _SUPPORTS_BUBBLE = "bubble_full_width" in _chatbot_params
20
 
 
37
  logger.exception("Pipeline initialisation failed: %s", exc)
38
 
39
 
40
+ # ── Helpers ───────────────────────────────────────────────────────────────────
41
 
42
  def _msg(role: str, content: str) -> dict:
43
  """Return a Gradio-compatible message dict."""
44
  return {"role": role, "content": content}
45
 
46
 
47
+ def _handle_debug_command(command: str) -> str:
48
  """
49
+ Handle special slash commands for in-chat debugging.
50
+ No terminal needed β€” results appear directly in the chat.
 
 
 
 
 
 
 
 
 
 
 
 
51
  """
52
+ from data_loader import get_dataset_info
53
+ import vector_store as vs_module
54
+
55
+ cmd = command.strip().lower()
56
+
57
+ # ── /debug β€” show dataset info ────────────────────────────────────────────
58
+ if cmd == "/debug":
59
+ info = get_dataset_info()
60
+ if info["status"] == "error":
61
+ return f"❌ **Dataset error:**\n```\n{info['error']}\n```"
62
+ lines = [
63
+ "### πŸ” Dataset Debug Info",
64
+ f"**Dataset:** `{info['dataset']}`",
65
+ f"**Total rows:** {info['total_rows']}",
66
+ f"**All columns:** `{info['columns']}`",
67
+ f"**Detected text column:** `{info['detected_text_col']}`",
68
+ f"**Non-empty rows:** {info['non_empty_rows']}",
69
+ "",
70
+ "**Sample text from row 0:**",
71
+ f"```\n{info['sample_text']}\n```",
72
+ "",
73
+ ]
74
+ if info["detected_text_col"] not in ["text", "content", "body", "page_content", "extracted_text"]:
75
+ lines.append(
76
+ f"⚠️ **Column `{info['detected_text_col']}` is not a standard name.**\n"
77
+ "Add it to `text_column_candidates` in `config.py`."
78
+ )
79
+ lines.append(
80
+ "❌ **No usable text rows found.**" if info["non_empty_rows"] == 0
81
+ else "βœ… Dataset looks healthy."
82
+ )
83
+ return "\n".join(lines)
84
+
85
+ # ── /retrieve <query> β€” show raw retrieval results ────────────────────────
86
+ if cmd.startswith("/retrieve "):
87
+ test_query = command[len("/retrieve "):].strip()
88
+ if not test_query:
89
+ return "Usage: `/retrieve your test query here`"
90
+ if pipeline is None:
91
+ return "❌ Pipeline not initialised."
92
+ docs = vs_module.retrieve(pipeline._index, test_query, k=5)
93
+ if not docs:
94
+ return (
95
+ f"❌ **No chunks retrieved** for: `{test_query}`\n"
96
+ "FAISS index may be empty or text column is wrong."
97
+ )
98
+ lines = [f"### πŸ“„ Retrieved {len(docs)} chunks for: `{test_query}`\n"]
99
+ for i, doc in enumerate(docs, 1):
100
+ src = doc.metadata.get("source", doc.metadata.get("source_row", "?"))
101
+ lines.append(f"**Chunk {i}** (source: {src})")
102
+ lines.append(f"```\n{doc.page_content[:300]}\n```")
103
+ return "\n".join(lines)
104
+
105
+ # ── /status β€” pipeline health ─────────────────────────────────────────────
106
+ if cmd == "/status":
107
+ if init_error:
108
+ return f"❌ **Pipeline failed:**\n```\n{init_error}\n```"
109
+ if pipeline is None:
110
+ return "❌ Pipeline is None β€” startup may still be in progress."
111
+ total_vectors = pipeline._index.index.ntotal
112
+ lines = [
113
+ "### βœ… Pipeline Status",
114
+ f"**FAISS vectors:** {total_vectors}",
115
+ f"**Groq model:** `{cfg.groq_model}`",
116
+ f"**Dataset:** `{cfg.hf_dataset}`",
117
+ f"**Chunk size:** {cfg.chunk_size} | **Top-K:** {cfg.top_k}",
118
+ (
119
+ "\n❌ **0 vectors β€” retrieval will always fail!**"
120
+ if total_vectors == 0
121
+ else "\nβœ… Index looks healthy."
122
+ ),
123
+ ]
124
+ return "\n".join(lines)
125
+
126
+ return (
127
+ "**Debug commands:**\n"
128
+ "- `/debug` β€” dataset columns, row count, sample text\n"
129
+ "- `/status` β€” pipeline health and vector count\n"
130
+ "- `/retrieve your question` β€” raw retrieval results"
131
+ )
132
+
133
+
134
+ def chat(user_message: str, history: list, show_sources: bool):
135
+ """Called by Gradio on every user message."""
136
+
137
+ # ── Handle debug slash commands first ─────────────────────────────────────
138
+ if user_message.strip().startswith("/"):
139
+ bot_reply = _handle_debug_command(user_message)
140
+ return "", history + [_msg("user", user_message), _msg("assistant", bot_reply)], ""
141
+
142
  if init_error:
143
+ bot_reply = f"⚠️ **Setup error:** {init_error}\n\nCheck Space secrets and logs."
144
+ return "", history + [_msg("user", user_message), _msg("assistant", bot_reply)], ""
 
145
 
146
  if not user_message.strip():
147
  return "", history, ""
 
155
  bot_reply = "πŸ”­ Something went wrong while consulting the stars. Please try again."
156
  sources_md = ""
157
 
158
+ return "", history + [_msg("user", user_message), _msg("assistant", bot_reply)], sources_md
 
159
 
160
 
161
  # ── Gradio UI ─────────────────────────────────────────────────────────────────
162
 
163
  CSS = """
 
164
  body, .gradio-container { font-family: 'Georgia', serif; }
165
  .title-banner { text-align: center; padding: 1rem 0 0.5rem; }
166
  .title-banner h1 { font-size: 2rem; letter-spacing: 0.04em; }
 
 
 
 
167
  .sources-box { font-size: 0.82rem; color: #718096; }
168
  footer { display: none !important; }
169
  """
 
179
  "How does the Moon sign influence emotions?",
180
  ]
181
 
 
182
  _SUPPORTS_THEMES = hasattr(gr, "themes") and hasattr(gr.themes, "Base")
183
  _theme = gr.themes.Base(
184
+ primary_hue="indigo", secondary_hue="purple", neutral_hue="slate",
 
 
185
  ) if _SUPPORTS_THEMES else None
186
 
187
+ with gr.Blocks(title=cfg.app_title, theme=_theme, css=CSS) as demo:
 
 
 
 
188
 
189
  # ── Header ────────────────────────────────────────────────────────────────
190
+ gr.HTML("""
 
191
  <div class="title-banner">
192
  <h1>πŸ”­ AstroBot Demo</h1>
193
  <p style="color:#9b8ec4; font-size:1.05rem;">
194
  Your AI Astrology Assistant Β· Powered by Groq LLaMA-3.1-8b-instant
195
  </p>
196
  </div>
197
+ """)
 
198
 
199
+ # ── Disclaimer β€” fully inline styles for reliability ──────────────────────
200
+ gr.HTML("""
201
  <div style="background-color:#3b3777; color:#f0eeff; border:1px solid #6c67c4;
202
  border-radius:8px; padding:10px 16px; font-size:0.92rem;
203
  margin-bottom:8px; line-height:1.6;">
 
206
  It does <strong style="color:#ffffff;">not</strong> make personal predictions
207
  or interpret individual birth charts.
208
  </div>
209
+ """)
 
210
 
211
  # ── Main layout ────────��──────────────────────────────────────────────────
212
  with gr.Row():
213
  with gr.Column(scale=3):
214
  _chatbot_kwargs = {"label": "AstroBot", "height": 500}
215
+ if _SUPPORTS_BUBBLE: _chatbot_kwargs["bubble_full_width"] = False
216
+ if _SUPPORTS_COPY: _chatbot_kwargs["show_copy_button"] = True
217
+ if "type" in _chatbot_params: _chatbot_kwargs["type"] = "messages"
 
 
 
218
  chatbot = gr.Chatbot(**_chatbot_kwargs)
219
+
220
  with gr.Row():
221
  txt_input = gr.Textbox(
222
  placeholder="Ask a concept question about astrology…",
 
227
 
228
  with gr.Column(scale=1):
229
  gr.Markdown("### βš™οΈ Options")
230
+ _checkbox_kwargs = {"label": "Show source excerpts", "value": False}
 
 
 
231
  _checkbox_params = set(_inspect.signature(gr.Checkbox.__init__).parameters)
232
  if "info" in _checkbox_params:
233
+ _checkbox_kwargs["info"] = "Display course material passages used to answer."
234
  show_sources = gr.Checkbox(**_checkbox_kwargs)
235
+
236
  gr.Markdown("### πŸ’‘ Example Questions")
237
  for q in EXAMPLE_QUESTIONS:
238
+ gr.Button(q, size="sm").click(fn=lambda x=q: x, outputs=txt_input)
239
+
240
+ gr.Markdown(
241
+ "---\nπŸ› οΈ **Debug commands:**\n"
242
+ "`/status` Β· `/debug` Β· `/retrieve <query>`"
243
+ )
244
 
245
  # ── Source citations panel ────────────────────────────────────────────────
246
  sources_display = gr.Markdown(
247
+ value="", label="Source Excerpts", elem_classes=["sources-box"]
 
 
248
  )
249
 
250
+ # ── State & event wiring ──────────────────────────────────────────────────
251
  state = gr.State([])
252
 
 
253
  send_btn.click(
254
  fn=chat,
255
  inputs=[txt_input, state, show_sources],
 
261
  outputs=[txt_input, chatbot, sources_display],
262
  )
263
 
 
264
  gr.Markdown(
265
  "_Built with [Groq](https://groq.com) Β· [LangChain](https://langchain.com) Β· "
266
  "[Hugging Face](https://huggingface.co) β€” for astrology students everywhere πŸŒ™_"
267
  )
268
 
269
 
 
270
  if __name__ == "__main__":
271
  demo.launch(server_name="0.0.0.0", server_port=7860)