From 9bd8ae99f6b557e3f248ed299f6c166267fec2cd Mon Sep 17 00:00:00 2001 From: Jarvis Date: Fri, 30 Jan 2026 19:46:17 +0000 Subject: [PATCH] Feat: Improved Dashboard Logging & Unbuffered Output --- Dockerfile | 1 + app.py | 76 ++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 540ffee..ed452e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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"] diff --git a/app.py b/app.py index cce4dd5..2dbcf78 100644 --- a/app.py +++ b/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')}") - - 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.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") + + 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.")