Spaces:
Sleeping
Sleeping
Fix: convert amounts to numeric before formatting (handles string + native)
Browse files
app.py
CHANGED
|
@@ -1,13 +1,5 @@
|
|
| 1 |
"""
|
| 2 |
VynFi Streamlit Template β Generate, Explore, Visualize
|
| 3 |
-
|
| 4 |
-
A ready-to-deploy Streamlit app that connects to the VynFi API,
|
| 5 |
-
generates synthetic financial data, and renders interactive dashboards.
|
| 6 |
-
Clone and customize for your use case.
|
| 7 |
-
|
| 8 |
-
Usage:
|
| 9 |
-
export VYNFI_API_KEY=vf_live_...
|
| 10 |
-
streamlit run app.py
|
| 11 |
"""
|
| 12 |
|
| 13 |
import os
|
|
@@ -29,8 +21,6 @@ if not api_key:
|
|
| 29 |
|
| 30 |
client = vynfi.VynFi(api_key=api_key)
|
| 31 |
|
| 32 |
-
# ββ Sidebar: generation config ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 33 |
-
|
| 34 |
st.sidebar.header("Generate")
|
| 35 |
|
| 36 |
sector = st.sidebar.selectbox(
|
|
@@ -42,7 +32,6 @@ rows = st.sidebar.slider("Rows", min_value=100, max_value=100_000, value=1000, s
|
|
| 42 |
companies = st.sidebar.slider("Companies", min_value=1, max_value=20, value=3)
|
| 43 |
fraud_rate = st.sidebar.slider("Fraud rate", min_value=0.0, max_value=0.20, value=0.03, step=0.01)
|
| 44 |
|
| 45 |
-
# NL config option
|
| 46 |
st.sidebar.divider()
|
| 47 |
nl_description = st.sidebar.text_area(
|
| 48 |
"Or describe what you want (Scale+)",
|
|
@@ -52,8 +41,6 @@ nl_description = st.sidebar.text_area(
|
|
| 52 |
|
| 53 |
generate = st.sidebar.button("Generate", type="primary", use_container_width=True)
|
| 54 |
|
| 55 |
-
# ββ Main area ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 56 |
-
|
| 57 |
if generate:
|
| 58 |
with st.spinner("Generating..."):
|
| 59 |
try:
|
|
@@ -87,8 +74,6 @@ if generate:
|
|
| 87 |
except Exception as e:
|
| 88 |
st.error(f"Error: {e}")
|
| 89 |
|
| 90 |
-
# ββ Display results ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 91 |
-
|
| 92 |
if "archive" in st.session_state:
|
| 93 |
archive = st.session_state["archive"]
|
| 94 |
|
|
@@ -98,9 +83,8 @@ if "archive" in st.session_state:
|
|
| 98 |
st.subheader("Journal Entries")
|
| 99 |
try:
|
| 100 |
entries = archive.json("journal_entries.json")
|
| 101 |
-
# Flatten
|
| 102 |
rows_flat = []
|
| 103 |
-
for entry in entries[:500]:
|
| 104 |
header = entry.get("header", entry)
|
| 105 |
lines = entry.get("lines", [entry])
|
| 106 |
for line in lines:
|
|
@@ -115,14 +99,20 @@ if "archive" in st.session_state:
|
|
| 115 |
"credit_amount": line.get("credit_amount", 0),
|
| 116 |
})
|
| 117 |
df = pd.DataFrame(rows_flat)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
st.metric("Line items", f"{len(df):,}")
|
| 119 |
|
| 120 |
col1, col2 = st.columns(2)
|
| 121 |
with col1:
|
| 122 |
st.metric("Total debits", f"${df['debit_amount'].sum():,.2f}")
|
| 123 |
with col2:
|
| 124 |
-
fraud_count = df["is_fraud"].sum()
|
| 125 |
-
|
|
|
|
| 126 |
|
| 127 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
| 128 |
except Exception as e:
|
|
|
|
| 1 |
"""
|
| 2 |
VynFi Streamlit Template β Generate, Explore, Visualize
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
"""
|
| 4 |
|
| 5 |
import os
|
|
|
|
| 21 |
|
| 22 |
client = vynfi.VynFi(api_key=api_key)
|
| 23 |
|
|
|
|
|
|
|
| 24 |
st.sidebar.header("Generate")
|
| 25 |
|
| 26 |
sector = st.sidebar.selectbox(
|
|
|
|
| 32 |
companies = st.sidebar.slider("Companies", min_value=1, max_value=20, value=3)
|
| 33 |
fraud_rate = st.sidebar.slider("Fraud rate", min_value=0.0, max_value=0.20, value=0.03, step=0.01)
|
| 34 |
|
|
|
|
| 35 |
st.sidebar.divider()
|
| 36 |
nl_description = st.sidebar.text_area(
|
| 37 |
"Or describe what you want (Scale+)",
|
|
|
|
| 41 |
|
| 42 |
generate = st.sidebar.button("Generate", type="primary", use_container_width=True)
|
| 43 |
|
|
|
|
|
|
|
| 44 |
if generate:
|
| 45 |
with st.spinner("Generating..."):
|
| 46 |
try:
|
|
|
|
| 74 |
except Exception as e:
|
| 75 |
st.error(f"Error: {e}")
|
| 76 |
|
|
|
|
|
|
|
| 77 |
if "archive" in st.session_state:
|
| 78 |
archive = st.session_state["archive"]
|
| 79 |
|
|
|
|
| 83 |
st.subheader("Journal Entries")
|
| 84 |
try:
|
| 85 |
entries = archive.json("journal_entries.json")
|
|
|
|
| 86 |
rows_flat = []
|
| 87 |
+
for entry in entries[:500]:
|
| 88 |
header = entry.get("header", entry)
|
| 89 |
lines = entry.get("lines", [entry])
|
| 90 |
for line in lines:
|
|
|
|
| 99 |
"credit_amount": line.get("credit_amount", 0),
|
| 100 |
})
|
| 101 |
df = pd.DataFrame(rows_flat)
|
| 102 |
+
|
| 103 |
+
# Convert amounts to numeric (handles both string and native)
|
| 104 |
+
for col in ["debit_amount", "credit_amount"]:
|
| 105 |
+
df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0)
|
| 106 |
+
|
| 107 |
st.metric("Line items", f"{len(df):,}")
|
| 108 |
|
| 109 |
col1, col2 = st.columns(2)
|
| 110 |
with col1:
|
| 111 |
st.metric("Total debits", f"${df['debit_amount'].sum():,.2f}")
|
| 112 |
with col2:
|
| 113 |
+
fraud_count = int(df["is_fraud"].sum())
|
| 114 |
+
pct = fraud_count / len(df) * 100 if len(df) > 0 else 0
|
| 115 |
+
st.metric("Fraud entries", f"{fraud_count} ({pct:.1f}%)")
|
| 116 |
|
| 117 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
| 118 |
except Exception as e:
|