cstr commited on
Commit
74c5fd4
·
verified ·
1 Parent(s): 1f46ad2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -13
app.py CHANGED
@@ -75,12 +75,11 @@ def run_query(start_node, relation, end_node, limit):
75
  Runs an efficient query by filtering on text paths first,
76
  then joining by indexed IDs.
77
 
78
- *** FIX ***: This now queries the `node.id` column (which contains the full path)
79
- and the `relation.label` column, based on the raw query results.
80
  """
81
  print(f"Running query: start='{start_node}', rel='{relation}', end='{end_node}'")
82
 
83
- # --- FIX: Select the `id` column (which has the path) ---
84
  select_clause = """
85
  SELECT
86
  e.id AS edge_id,
@@ -106,26 +105,20 @@ def run_query(start_node, relation, end_node, limit):
106
  params = []
107
 
108
  try:
109
- # --- FIX: Query `node.id` for nodes, `relation.label` for relations ---
110
  if start_node:
111
- # We add a wildcard to the front to match the full http://... ID
112
- # unless the user has already added their own wildcard.
113
  param_val = start_node if "%" in start_node else f"%{start_node}"
114
  where_conditions.append(f"e.start_id IN (SELECT id FROM node WHERE id LIKE ?)")
115
  params.append(param_val)
116
 
117
  if relation:
118
- # Relation table uses `label` which is a direct match (e.g., /r/IsA)
119
  op = "LIKE" if "%" in relation else "="
120
  where_conditions.append(f"e.rel_id IN (SELECT id FROM relation WHERE label {op} ?)")
121
  params.append(relation)
122
 
123
  if end_node:
124
- # We add a wildcard to the front to match the full http://... ID
125
  param_val = end_node if "%" in end_node else f"%{end_node}"
126
  where_conditions.append(f"e.end_id IN (SELECT id FROM node WHERE id LIKE ?)")
127
  params.append(param_val)
128
- # --- End of Fix ---
129
 
130
  if not where_conditions:
131
  where_clause = " WHERE 1=1" # Get random edges if no filter
@@ -176,6 +169,73 @@ def run_raw_query(sql_query):
176
  traceback.print_exc()
177
  return pd.DataFrame(), f"**Query Failed!**\n\n`{e}`"
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
 
180
  # --- 3. Build the Gradio UI ---
181
 
@@ -184,6 +244,15 @@ with gr.Blocks(title="ConceptNet SQLite Explorer") as demo:
184
  gr.Markdown(f"**Note:** Initial query might take a few seconds as the database warms up.")
185
 
186
  with gr.Tabs():
 
 
 
 
 
 
 
 
 
187
  with gr.TabItem("Query Builder"):
188
  gr.Markdown(
189
  "**Run a query against the database.**\n"
@@ -191,7 +260,6 @@ with gr.Blocks(title="ConceptNet SQLite Explorer") as demo:
191
  "Use the *path part* of the ID (e.g., `/c/en/dog` or `/r/Is%`)."
192
  )
193
  with gr.Row():
194
- # --- FIX: Updated labels for clarity ---
195
  start_input = gr.Textbox(label="Start Node Path", placeholder="/c/en/dog")
196
  rel_input = gr.Textbox(label="Relation Path", placeholder="/r/IsA")
197
  end_input = gr.Textbox(label="End Node Path", placeholder="/c/en/animal")
@@ -204,10 +272,9 @@ with gr.Blocks(title="ConceptNet SQLite Explorer") as demo:
204
 
205
  with gr.TabItem("Raw SQL Query"):
206
  gr.Markdown("**Danger Zone:** Run a raw `SELECT` query against the database. Use the Schema Explorer tab to see table/column names.")
207
- # --- FIX: Updated placeholder to a useful, correct query ---
208
  raw_sql_input = gr.Textbox(
209
  label="Raw SQL Query",
210
- placeholder="SELECT id, label, language, path FROM node WHERE id LIKE '%/c/en/dog' LIMIT 5",
211
  lines=5
212
  )
213
  raw_query_btn = gr.Button("Run Raw SQL", variant="secondary")
@@ -220,6 +287,13 @@ with gr.Blocks(title="ConceptNet SQLite Explorer") as demo:
220
  schema_output = gr.Markdown("Schema will appear here...")
221
 
222
  # --- 4. Connect UI Elements to Functions ---
 
 
 
 
 
 
 
223
  query_btn.click(
224
  fn=run_query,
225
  inputs=[start_input, rel_input, end_input, limit_slider],
@@ -242,5 +316,4 @@ with gr.Blocks(title="ConceptNet SQLite Explorer") as demo:
242
  )
243
 
244
  if __name__ == "__main__":
245
- # Removed experimental ssr_mode=False
246
  demo.launch(ssr_mode=False)
 
75
  Runs an efficient query by filtering on text paths first,
76
  then joining by indexed IDs.
77
 
78
+ This now queries the `node.id` column (which contains the full path)
79
+ and the `relation.label` column.
80
  """
81
  print(f"Running query: start='{start_node}', rel='{relation}', end='{end_node}'")
82
 
 
83
  select_clause = """
84
  SELECT
85
  e.id AS edge_id,
 
105
  params = []
106
 
107
  try:
 
108
  if start_node:
 
 
109
  param_val = start_node if "%" in start_node else f"%{start_node}"
110
  where_conditions.append(f"e.start_id IN (SELECT id FROM node WHERE id LIKE ?)")
111
  params.append(param_val)
112
 
113
  if relation:
 
114
  op = "LIKE" if "%" in relation else "="
115
  where_conditions.append(f"e.rel_id IN (SELECT id FROM relation WHERE label {op} ?)")
116
  params.append(relation)
117
 
118
  if end_node:
 
119
  param_val = end_node if "%" in end_node else f"%{end_node}"
120
  where_conditions.append(f"e.end_id IN (SELECT id FROM node WHERE id LIKE ?)")
121
  params.append(param_val)
 
122
 
123
  if not where_conditions:
124
  where_clause = " WHERE 1=1" # Get random edges if no filter
 
169
  traceback.print_exc()
170
  return pd.DataFrame(), f"**Query Failed!**\n\n`{e}`"
171
 
172
+ def get_semantic_profile(word, lang='en'):
173
+ """
174
+ NEW FUNCTION: Gets a convenient profile of a single word,
175
+ querying for its most important semantic relations.
176
+ """
177
+ if not word:
178
+ return "Please enter a word."
179
+
180
+ word = word.strip().lower().replace(' ', '_')
181
+ like_path = f"%/c/{lang}/{word}"
182
+ print(f"Getting semantic profile for: {like_path}")
183
+
184
+ # These are the relations we learned about from relations.py
185
+ relations_to_check = [
186
+ "/r/IsA", "/r/PartOf", "/r/HasA", "/r/UsedFor", "/r/CapableOf",
187
+ "/r/Causes", "/r/HasProperty", "/r/Synonym", "/r/Antonym",
188
+ "/r/AtLocation", "/r/RelatedTo"
189
+ ]
190
+
191
+ output_md = f"# Semantic Profile for '{word}'\n\n"
192
+
193
+ try:
194
+ with get_db_connection() as conn:
195
+ for rel in relations_to_check:
196
+ output_md += f"## {rel}\n\n"
197
+
198
+ # Query 1: Word as the start node
199
+ query1 = """
200
+ SELECT en.id, en.label
201
+ FROM edge e
202
+ JOIN node s ON e.start_id = s.id
203
+ JOIN node en ON e.end_id = en.id
204
+ JOIN relation r ON e.rel_id = r.id
205
+ WHERE s.id LIKE ? AND r.label = ?
206
+ ORDER BY e.weight DESC LIMIT 7
207
+ """
208
+ cursor1 = conn.execute(query1, (like_path, rel))
209
+ results1 = cursor1.fetchall()
210
+
211
+ # Query 2: Word as the end node
212
+ query2 = """
213
+ SELECT s.id, s.label
214
+ FROM edge e
215
+ JOIN node s ON e.start_id = s.id
216
+ JOIN node en ON e.end_id = en.id
217
+ JOIN relation r ON e.rel_id = r.id
218
+ WHERE en.id LIKE ? AND r.label = ?
219
+ ORDER BY e.weight DESC LIMIT 7
220
+ """
221
+ cursor2 = conn.execute(query2, (like_path, rel))
222
+ results2 = cursor2.fetchall()
223
+
224
+ if not results1 and not results2:
225
+ output_md += "- (No results)\n\n"
226
+ else:
227
+ for r_id, r_label in results1:
228
+ output_md += f"- `{word}` {rel} `{r_label}` *({r_id})*\n"
229
+ for r_id, r_label in results2:
230
+ output_md += f"- `{r_label}` {rel} `{word}` *({r_id})*\n"
231
+ output_md += "\n"
232
+
233
+ return output_md
234
+
235
+ except Exception as e:
236
+ print(f"Error in get_semantic_profile: {e}")
237
+ traceback.print_exc()
238
+ return f"**An error occurred while building the profile:**\n\n`{e}`"
239
 
240
  # --- 3. Build the Gradio UI ---
241
 
 
244
  gr.Markdown(f"**Note:** Initial query might take a few seconds as the database warms up.")
245
 
246
  with gr.Tabs():
247
+ with gr.TabItem("Semantic Profile"):
248
+ gr.Markdown(
249
+ "**Get a simple semantic profile for a single English word.**\n"
250
+ "This will query for common relations like `/r/IsA`, `/r/HasA`, `/r/UsedFor`, etc."
251
+ )
252
+ word_input = gr.Textbox(label="Word", placeholder="dog")
253
+ semantic_btn = gr.Button("Get Profile", variant="primary")
254
+ semantic_output = gr.Markdown("Profile will appear here...")
255
+
256
  with gr.TabItem("Query Builder"):
257
  gr.Markdown(
258
  "**Run a query against the database.**\n"
 
260
  "Use the *path part* of the ID (e.g., `/c/en/dog` or `/r/Is%`)."
261
  )
262
  with gr.Row():
 
263
  start_input = gr.Textbox(label="Start Node Path", placeholder="/c/en/dog")
264
  rel_input = gr.Textbox(label="Relation Path", placeholder="/r/IsA")
265
  end_input = gr.Textbox(label="End Node Path", placeholder="/c/en/animal")
 
272
 
273
  with gr.TabItem("Raw SQL Query"):
274
  gr.Markdown("**Danger Zone:** Run a raw `SELECT` query against the database. Use the Schema Explorer tab to see table/column names.")
 
275
  raw_sql_input = gr.Textbox(
276
  label="Raw SQL Query",
277
+ placeholder="SELECT id, label, language FROM node WHERE id LIKE '%/c/en/dog' LIMIT 5",
278
  lines=5
279
  )
280
  raw_query_btn = gr.Button("Run Raw SQL", variant="secondary")
 
287
  schema_output = gr.Markdown("Schema will appear here...")
288
 
289
  # --- 4. Connect UI Elements to Functions ---
290
+ semantic_btn.click(
291
+ fn=get_semantic_profile,
292
+ inputs=[word_input],
293
+ outputs=[semantic_output],
294
+ api_name="get_semantic_profile"
295
+ )
296
+
297
  query_btn.click(
298
  fn=run_query,
299
  inputs=[start_input, rel_input, end_input, limit_slider],
 
316
  )
317
 
318
  if __name__ == "__main__":
 
319
  demo.launch(ssr_mode=False)