Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,9 +10,9 @@ import gradio as gr
|
|
| 10 |
from gliner import GLiNER
|
| 11 |
from collections import defaultdict
|
| 12 |
import numpy as np
|
| 13 |
-
import pandas as pd
|
| 14 |
import os
|
| 15 |
-
import tempfile
|
| 16 |
|
| 17 |
# 🧠 Supported models and their providers
|
| 18 |
MODEL_OPTIONS = {
|
|
@@ -69,7 +69,6 @@ def generate_from_prompt(prompt, provider, key_dict):
|
|
| 69 |
return ""
|
| 70 |
|
| 71 |
# --- UI Definitions ---
|
| 72 |
-
|
| 73 |
STANDARD_LABELS = [
|
| 74 |
"Person", "Organization", "Location", "Country", "City", "State",
|
| 75 |
"Nationality", "Group", "Date", "Event", "Law", "Legal Document",
|
|
@@ -153,15 +152,25 @@ with gr.Blocks(title="Historical Text Analysis Tool", css=".prose { word-break:
|
|
| 153 |
key_dict = {"openai_key": os.environ.get("OPENAI_API_KEY", openai_k), "anthropic_key": os.environ.get("ANTHROPIC_API_KEY", anthropic_k), "google_key": os.environ.get("GOOGLE_API_KEY", google_k)}
|
| 154 |
provider_id = MODEL_OPTIONS.get(provider)
|
| 155 |
if not topic or not provider or not key_dict.get(f"{provider_id}_key"): raise gr.Error("A topic, provider, and valid API Key for that provider are required.")
|
|
|
|
| 156 |
prompt = FRAMEWORK_PROMPT_TEMPLATE.format(topic=topic)
|
| 157 |
raw_framework = generate_from_prompt(prompt, provider, key_dict)
|
|
|
|
| 158 |
framework = defaultdict(list)
|
| 159 |
current_category = None
|
| 160 |
for line in raw_framework.split('\n'):
|
| 161 |
line = line.strip()
|
| 162 |
-
if line.startswith("###"):
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
if not framework: raise gr.Error("The AI failed to generate categories. Please try again or rephrase your topic.")
|
|
|
|
| 165 |
updates = {}
|
| 166 |
categories = list(framework.items())
|
| 167 |
for i in range(MAX_CATEGORIES):
|
|
@@ -178,6 +187,7 @@ with gr.Blocks(title="Historical Text Analysis Tool", css=".prose { word-break:
|
|
| 178 |
updates[cg] = gr.update(choices=[], value=[], visible=False)
|
| 179 |
updates[sel] = gr.update(visible=False)
|
| 180 |
updates[desel] = gr.update(visible=False)
|
|
|
|
| 181 |
updates[generate_btn] = gr.update(value="Generate Framework", interactive=True)
|
| 182 |
yield updates
|
| 183 |
except Exception as e:
|
|
@@ -241,8 +251,6 @@ with gr.Blocks(title="Historical Text Analysis Tool", css=".prose { word-break:
|
|
| 241 |
results_df = pd.DataFrame(table_rows)
|
| 242 |
if not results_df.empty: results_df = results_df.sort_values(by=["Label", "Instances"], ascending=[True, False])
|
| 243 |
|
| 244 |
-
# *** BUG FIX IS HERE ***
|
| 245 |
-
# The final dictionary MUST include a key for every component in the `outputs` list.
|
| 246 |
yield {
|
| 247 |
analyze_btn: gr.update(value="Find Entities", interactive=True),
|
| 248 |
analysis_status: gr.update(visible=False),
|
|
@@ -250,20 +258,15 @@ with gr.Blocks(title="Historical Text Analysis Tool", css=".prose { word-break:
|
|
| 250 |
detailed_results_output: results_df,
|
| 251 |
results_state: results_df,
|
| 252 |
debug_output: "Analysis complete.",
|
| 253 |
-
# This line was missing, which caused the bug.
|
| 254 |
csv_file_output: gr.update(visible=False, value=None)
|
| 255 |
}
|
| 256 |
|
| 257 |
def export_to_csv(df):
|
| 258 |
if df is None or df.empty:
|
| 259 |
gr.Info("No data to export. Please run 'Find Entities' first.")
|
| 260 |
-
# Return an update to ensure the component remains hidden
|
| 261 |
return gr.update(visible=False)
|
| 262 |
-
|
| 263 |
-
# Use a temporary file that Gradio can access
|
| 264 |
with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.csv', encoding='utf-8') as tmpfile:
|
| 265 |
df.to_csv(tmpfile.name, index=False)
|
| 266 |
-
# Return an update with the file path and set visibility to True
|
| 267 |
return gr.update(value=tmpfile.name, visible=True)
|
| 268 |
|
| 269 |
# --- Wire up UI events ---
|
|
|
|
| 10 |
from gliner import GLiNER
|
| 11 |
from collections import defaultdict
|
| 12 |
import numpy as np
|
| 13 |
+
import pandas as pd
|
| 14 |
import os
|
| 15 |
+
import tempfile
|
| 16 |
|
| 17 |
# 🧠 Supported models and their providers
|
| 18 |
MODEL_OPTIONS = {
|
|
|
|
| 69 |
return ""
|
| 70 |
|
| 71 |
# --- UI Definitions ---
|
|
|
|
| 72 |
STANDARD_LABELS = [
|
| 73 |
"Person", "Organization", "Location", "Country", "City", "State",
|
| 74 |
"Nationality", "Group", "Date", "Event", "Law", "Legal Document",
|
|
|
|
| 152 |
key_dict = {"openai_key": os.environ.get("OPENAI_API_KEY", openai_k), "anthropic_key": os.environ.get("ANTHROPIC_API_KEY", anthropic_k), "google_key": os.environ.get("GOOGLE_API_KEY", google_k)}
|
| 153 |
provider_id = MODEL_OPTIONS.get(provider)
|
| 154 |
if not topic or not provider or not key_dict.get(f"{provider_id}_key"): raise gr.Error("A topic, provider, and valid API Key for that provider are required.")
|
| 155 |
+
|
| 156 |
prompt = FRAMEWORK_PROMPT_TEMPLATE.format(topic=topic)
|
| 157 |
raw_framework = generate_from_prompt(prompt, provider, key_dict)
|
| 158 |
+
|
| 159 |
framework = defaultdict(list)
|
| 160 |
current_category = None
|
| 161 |
for line in raw_framework.split('\n'):
|
| 162 |
line = line.strip()
|
| 163 |
+
if line.startswith("###"):
|
| 164 |
+
current_category = line.replace("###", "").strip()
|
| 165 |
+
# *** BUG FIX WAS HERE ***
|
| 166 |
+
elif line.startswith("-") and current_category:
|
| 167 |
+
# Correctly assign the line content to a variable first
|
| 168 |
+
entities_string = line.replace("-", "").strip()
|
| 169 |
+
# Then use that variable
|
| 170 |
+
framework[current_category].extend([e.strip() for e in entities_string.split(',') if e.strip()])
|
| 171 |
+
|
| 172 |
if not framework: raise gr.Error("The AI failed to generate categories. Please try again or rephrase your topic.")
|
| 173 |
+
|
| 174 |
updates = {}
|
| 175 |
categories = list(framework.items())
|
| 176 |
for i in range(MAX_CATEGORIES):
|
|
|
|
| 187 |
updates[cg] = gr.update(choices=[], value=[], visible=False)
|
| 188 |
updates[sel] = gr.update(visible=False)
|
| 189 |
updates[desel] = gr.update(visible=False)
|
| 190 |
+
|
| 191 |
updates[generate_btn] = gr.update(value="Generate Framework", interactive=True)
|
| 192 |
yield updates
|
| 193 |
except Exception as e:
|
|
|
|
| 251 |
results_df = pd.DataFrame(table_rows)
|
| 252 |
if not results_df.empty: results_df = results_df.sort_values(by=["Label", "Instances"], ascending=[True, False])
|
| 253 |
|
|
|
|
|
|
|
| 254 |
yield {
|
| 255 |
analyze_btn: gr.update(value="Find Entities", interactive=True),
|
| 256 |
analysis_status: gr.update(visible=False),
|
|
|
|
| 258 |
detailed_results_output: results_df,
|
| 259 |
results_state: results_df,
|
| 260 |
debug_output: "Analysis complete.",
|
|
|
|
| 261 |
csv_file_output: gr.update(visible=False, value=None)
|
| 262 |
}
|
| 263 |
|
| 264 |
def export_to_csv(df):
|
| 265 |
if df is None or df.empty:
|
| 266 |
gr.Info("No data to export. Please run 'Find Entities' first.")
|
|
|
|
| 267 |
return gr.update(visible=False)
|
|
|
|
|
|
|
| 268 |
with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.csv', encoding='utf-8') as tmpfile:
|
| 269 |
df.to_csv(tmpfile.name, index=False)
|
|
|
|
| 270 |
return gr.update(value=tmpfile.name, visible=True)
|
| 271 |
|
| 272 |
# --- Wire up UI events ---
|