Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -21,7 +21,7 @@ def load_file_bytes_to_df(file) -> Tuple[Optional[pd.DataFrame], Optional[str]]:
|
|
| 21 |
# decide by filename or by sniffing bytes
|
| 22 |
name = getattr(file, "name", "") or ""
|
| 23 |
# Basic heuristic for CSV vs Excel
|
| 24 |
-
if name.lower().endswith(".csv") or b"," in content[:200]:
|
| 25 |
df = pd.read_csv(io.BytesIO(content))
|
| 26 |
else:
|
| 27 |
df = pd.read_excel(io.BytesIO(content))
|
|
@@ -37,7 +37,7 @@ def load_file_bytes_to_df(file) -> Tuple[Optional[pd.DataFrame], Optional[str]]:
|
|
| 37 |
return df, None
|
| 38 |
|
| 39 |
def simple_nl_to_action(df: pd.DataFrame, query: str):
|
| 40 |
-
"""
|
| 41 |
q = (query or "").strip().lower()
|
| 42 |
if q == "":
|
| 43 |
return None, "Please type a question like: 'show columns', 'show first 5 rows', 'describe column sales', or 'filter where Region = India and Year >= 2021'."
|
|
@@ -103,7 +103,6 @@ def process(file, query):
|
|
| 103 |
# Load into memory-only DataFrame
|
| 104 |
df, err = load_file_bytes_to_df(file)
|
| 105 |
if err:
|
| 106 |
-
# Ensure any partial objects are removed
|
| 107 |
try:
|
| 108 |
del file
|
| 109 |
except Exception:
|
|
@@ -114,16 +113,15 @@ def process(file, query):
|
|
| 114 |
# Run the NLP-to-action
|
| 115 |
try:
|
| 116 |
res, msg = simple_nl_to_action(df, query)
|
| 117 |
-
# Convert DataFrame result if any to a safe small object (head) to limit memory/time
|
| 118 |
if isinstance(res, pd.DataFrame):
|
| 119 |
-
out_df = res.copy()
|
| 120 |
else:
|
| 121 |
out_df = None
|
| 122 |
except Exception as e:
|
| 123 |
out_df = None
|
| 124 |
msg = f"Error while processing: {e}"
|
| 125 |
|
| 126 |
-
#
|
| 127 |
try:
|
| 128 |
del df
|
| 129 |
del file
|
|
@@ -140,9 +138,7 @@ def process(file, query):
|
|
| 140 |
def clear_all():
|
| 141 |
"""
|
| 142 |
Returns Gradio update objects that clear inputs and outputs.
|
| 143 |
-
This helps remove file from the browser UI and server-side.
|
| 144 |
"""
|
| 145 |
-
# gradio update helpers: set inputs/outputs back to empty values
|
| 146 |
return (
|
| 147 |
gr.File.update(value=None),
|
| 148 |
gr.Textbox.update(value=""),
|
|
@@ -159,13 +155,12 @@ with gr.Blocks() as demo:
|
|
| 159 |
with gr.Row():
|
| 160 |
submit = gr.Button("Run query")
|
| 161 |
clear_btn = gr.Button("Clear / Reset (remove uploaded file & results)")
|
| 162 |
-
|
|
|
|
| 163 |
status = gr.Textbox(label="Status / Messages", interactive=False)
|
| 164 |
|
| 165 |
submit.click(fn=process, inputs=[file_input, query_input], outputs=[output_table, status])
|
| 166 |
-
# Clear button clears UI (and removes server-side references)
|
| 167 |
clear_btn.click(fn=clear_all, inputs=None, outputs=[file_input, query_input, output_table, status])
|
| 168 |
|
| 169 |
if __name__ == "__main__":
|
| 170 |
-
# Do not enable "share" or persistent caching here; default launch is fine for Spaces
|
| 171 |
demo.launch()
|
|
|
|
| 21 |
# decide by filename or by sniffing bytes
|
| 22 |
name = getattr(file, "name", "") or ""
|
| 23 |
# Basic heuristic for CSV vs Excel
|
| 24 |
+
if name.lower().endswith(".csv") or (isinstance(content, (bytes, bytearray)) and b"," in content[:200]):
|
| 25 |
df = pd.read_csv(io.BytesIO(content))
|
| 26 |
else:
|
| 27 |
df = pd.read_excel(io.BytesIO(content))
|
|
|
|
| 37 |
return df, None
|
| 38 |
|
| 39 |
def simple_nl_to_action(df: pd.DataFrame, query: str):
|
| 40 |
+
"""Very small NL parser that recognizes a few common requests and returns a DataFrame or (None, message)."""
|
| 41 |
q = (query or "").strip().lower()
|
| 42 |
if q == "":
|
| 43 |
return None, "Please type a question like: 'show columns', 'show first 5 rows', 'describe column sales', or 'filter where Region = India and Year >= 2021'."
|
|
|
|
| 103 |
# Load into memory-only DataFrame
|
| 104 |
df, err = load_file_bytes_to_df(file)
|
| 105 |
if err:
|
|
|
|
| 106 |
try:
|
| 107 |
del file
|
| 108 |
except Exception:
|
|
|
|
| 113 |
# Run the NLP-to-action
|
| 114 |
try:
|
| 115 |
res, msg = simple_nl_to_action(df, query)
|
|
|
|
| 116 |
if isinstance(res, pd.DataFrame):
|
| 117 |
+
out_df = res.copy()
|
| 118 |
else:
|
| 119 |
out_df = None
|
| 120 |
except Exception as e:
|
| 121 |
out_df = None
|
| 122 |
msg = f"Error while processing: {e}"
|
| 123 |
|
| 124 |
+
# Remove references to large objects immediately
|
| 125 |
try:
|
| 126 |
del df
|
| 127 |
del file
|
|
|
|
| 138 |
def clear_all():
|
| 139 |
"""
|
| 140 |
Returns Gradio update objects that clear inputs and outputs.
|
|
|
|
| 141 |
"""
|
|
|
|
| 142 |
return (
|
| 143 |
gr.File.update(value=None),
|
| 144 |
gr.Textbox.update(value=""),
|
|
|
|
| 155 |
with gr.Row():
|
| 156 |
submit = gr.Button("Run query")
|
| 157 |
clear_btn = gr.Button("Clear / Reset (remove uploaded file & results)")
|
| 158 |
+
# Use headers=None to be compatible with the Gradio version in Spaces
|
| 159 |
+
output_table = gr.Dataframe(headers=None, label="Result table")
|
| 160 |
status = gr.Textbox(label="Status / Messages", interactive=False)
|
| 161 |
|
| 162 |
submit.click(fn=process, inputs=[file_input, query_input], outputs=[output_table, status])
|
|
|
|
| 163 |
clear_btn.click(fn=clear_all, inputs=None, outputs=[file_input, query_input, output_table, status])
|
| 164 |
|
| 165 |
if __name__ == "__main__":
|
|
|
|
| 166 |
demo.launch()
|