Spaces:
Build error
Build error
Create app_min.py
Browse files- app_min.py +41 -0
app_min.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
# app_min.py
|
| 3 |
+
import io, json, pandas as pd, numpy as np, matplotlib.pyplot as plt
|
| 4 |
+
from PIL import Image
|
| 5 |
+
import gradio as gr
|
| 6 |
+
REQUIRED = {"date","revenue","cogs","opex"}
|
| 7 |
+
|
| 8 |
+
def load_csv(file):
|
| 9 |
+
try: df = pd.read_csv(file)
|
| 10 |
+
except Exception as e: raise gr.Error(json.dumps({"error":"Failed to read CSV","details":str(e)}, indent=2))
|
| 11 |
+
df.columns = [c.strip().lower() for c in df.columns]
|
| 12 |
+
miss = REQUIRED - set(df.columns)
|
| 13 |
+
if miss: raise gr.Error(json.dumps({"error":"CSV schema invalid","details":f"Missing columns: {sorted(list(miss))}"} , indent=2))
|
| 14 |
+
try:
|
| 15 |
+
df["date"] = pd.to_datetime(df["date"]).dt.to_period("M").dt.to_timestamp()
|
| 16 |
+
for col in ["revenue","cogs","opex"]: df[col] = pd.to_numeric(df[col])
|
| 17 |
+
except Exception as e: raise gr.Error(json.dumps({"error":"Parsing failed","details":str(e)}, indent=2))
|
| 18 |
+
return df.sort_values("date").reset_index(drop=True)
|
| 19 |
+
|
| 20 |
+
def plot(df):
|
| 21 |
+
fig, ax = plt.subplots(1,1, figsize=(8,4))
|
| 22 |
+
ax.plot(df["date"], df["revenue"], label="Revenue")
|
| 23 |
+
ax.plot(df["date"], df["cogs"], label="COGS")
|
| 24 |
+
ax.plot(df["date"], df["opex"], label="Opex")
|
| 25 |
+
ax.legend(); ax.set_title("P&L (minimal)")
|
| 26 |
+
buf = io.BytesIO(); plt.tight_layout(); fig.savefig(buf, format="png"); plt.close(fig)
|
| 27 |
+
return Image.open(buf)
|
| 28 |
+
|
| 29 |
+
def run(file):
|
| 30 |
+
df = load_csv(file); img = plot(df)
|
| 31 |
+
return img, ("echo.csv", df.to_csv(index=False).encode()), json.dumps({"rows":len(df)}, indent=2)
|
| 32 |
+
|
| 33 |
+
with gr.Blocks(title="Minimal Forecast Agent Test") as demo:
|
| 34 |
+
f = gr.File(file_types=[".csv"], label="Upload CSV")
|
| 35 |
+
btn = gr.Button("Run")
|
| 36 |
+
img = gr.Image(type="pil", label="Plot")
|
| 37 |
+
dl = gr.File(label="Echo CSV")
|
| 38 |
+
meta= gr.JSON(label="Diagnostics")
|
| 39 |
+
btn.click(lambda x: run(x.name if x else None), inputs=f, outputs=[img, dl, meta])
|
| 40 |
+
|
| 41 |
+
if __name__ == '__main__': demo.launch()
|