Feat: Improved Dashboard Logging & Unbuffered Output
This commit is contained in:
@@ -6,4 +6,5 @@ COPY . .
|
||||
|
||||
RUN pip install streamlit pandas
|
||||
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
|
||||
|
||||
74
app.py
74
app.py
@@ -2,54 +2,74 @@ import streamlit as st
|
||||
import pandas as pd
|
||||
from db import get_leads, init_db
|
||||
import json
|
||||
from enrich import run_sync # Import our sync function
|
||||
|
||||
st.set_page_config(page_title="TradingTwins Lead Engine", layout="wide")
|
||||
|
||||
st.title("🚀 Lead Engine: TradingTwins")
|
||||
|
||||
# Metrics
|
||||
# Sidebar Actions
|
||||
st.sidebar.header("Actions")
|
||||
|
||||
if st.sidebar.button("1. Ingest Emails (Mock)"):
|
||||
from ingest import ingest_mock_leads
|
||||
init_db()
|
||||
count = ingest_mock_leads()
|
||||
st.sidebar.success(f"Ingested {count} new leads.")
|
||||
st.rerun()
|
||||
|
||||
if st.sidebar.button("2. Sync to Company Explorer"):
|
||||
with st.spinner("Syncing with Company Explorer API..."):
|
||||
# Capture output for debugging
|
||||
try:
|
||||
# We redirect stdout to capture prints
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
f = io.StringIO()
|
||||
with redirect_stdout(f):
|
||||
run_sync()
|
||||
output = f.getvalue()
|
||||
|
||||
st.success("Sync finished!")
|
||||
with st.expander("See Process Log", expanded=True):
|
||||
st.code(output)
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Sync Failed: {e}")
|
||||
|
||||
# Main View
|
||||
leads = get_leads()
|
||||
df = pd.DataFrame(leads)
|
||||
|
||||
if not df.empty:
|
||||
col1, col2, col3 = st.columns(3)
|
||||
col1.metric("Total Leads", len(df))
|
||||
col2.metric("New Today", len(df[df['status'] == 'new']))
|
||||
col3.metric("Action Required", len(df[df['status'] == 'enriched']))
|
||||
col2.metric("New / Unsynced", len(df[df['status'] == 'new']))
|
||||
col3.metric("Synced to CE", len(df[df['status'] == 'synced']))
|
||||
|
||||
st.subheader("Latest Inquiries")
|
||||
st.subheader("Lead Pipeline")
|
||||
|
||||
for index, row in df.iterrows():
|
||||
with st.expander(f"{row['company_name']} - {row['status']}"):
|
||||
with st.expander(f"{row['company_name']} ({row['status']})"):
|
||||
c1, c2 = st.columns(2)
|
||||
c1.write(f"**Contact:** {row['contact_name']}")
|
||||
c1.write(f"**Email:** {row['email']}")
|
||||
c1.text(row['raw_body'][:200] + "...")
|
||||
|
||||
enrichment = json.loads(row['enrichment_data']) if row['enrichment_data'] else {}
|
||||
|
||||
if enrichment:
|
||||
c2.success(f"Score: {enrichment.get('score')}")
|
||||
c2.write(f"**Vertical:** {enrichment.get('vertical')}")
|
||||
c2.info(f"💡 {enrichment.get('recommendation')}")
|
||||
c2.write("--- Integration Status ---")
|
||||
if enrichment.get('ce_id'):
|
||||
c2.success(f"✅ Linked to Company Explorer (ID: {enrichment['ce_id']})")
|
||||
c2.write(f"**CE Status:** {enrichment.get('ce_status')}")
|
||||
else:
|
||||
c2.warning("⚠️ Not yet synced or failed")
|
||||
|
||||
if st.button(f"Generate Response for {row['id']}"):
|
||||
st.write("Generating draft... (Simulated)")
|
||||
# Here we would call the LLM
|
||||
draft = f"Hallo {row['contact_name']},\n\ndanke für Ihre Anfrage..."
|
||||
st.text_area("Draft", draft, height=200)
|
||||
c2.info(f"Log: {enrichment.get('message')}")
|
||||
|
||||
if enrichment.get('ce_data'):
|
||||
c2.json(enrichment['ce_data'])
|
||||
|
||||
else:
|
||||
st.info("No leads found. Waiting for ingest...")
|
||||
|
||||
if st.sidebar.button("Run Ingest (Mock)"):
|
||||
from ingest import ingest_mock_leads
|
||||
init_db()
|
||||
count = ingest_mock_leads()
|
||||
st.sidebar.success(f"Ingested {count} leads.")
|
||||
st.rerun()
|
||||
|
||||
if st.sidebar.button("Run Enrichment"):
|
||||
from enrich import run_enrichment
|
||||
run_enrichment()
|
||||
st.sidebar.success("Enrichment complete.")
|
||||
st.rerun()
|
||||
st.info("No leads found. Click 'Ingest Emails' in the sidebar.")
|
||||
|
||||
Reference in New Issue
Block a user