ai-interview-caller / dashboard.py
ranjithkumar111's picture
Upload 6 files
daab2d3 verified
Raw
History Blame Contribute Delete
5.49 kB
# File: dashboard.py
# Purpose: Streamlit recruiter dashboard with manual fetch report button
import requests
import streamlit as st
API_BASE = "http://localhost:8000"
st.set_page_config(page_title="AI Interview Caller", layout="wide")
st.title("AI Interview Screening Caller")
st.caption("Powered by Bland.ai Β· Groq Β· ElevenLabs")
# ── Sidebar: Initiate New Call ────────────────────────────────────────────────
with st.sidebar:
st.header("New Interview Call")
candidate_name = st.text_input("Candidate Name")
candidate_phone = st.text_input("Phone (E.164 e.g. +919876543210)")
candidate_email = st.text_input("Email (optional)")
resume_text = st.text_area("Paste Resume Text", height=200)
if st.button("Initiate Call", type="primary"):
if not candidate_name or not candidate_phone:
st.error("Name and phone are required.")
else:
payload = {
"candidate_name": candidate_name,
"candidate_phone": candidate_phone,
"candidate_email": candidate_email,
"resume_text": resume_text,
}
with st.spinner("Initiating call via Bland.ai..."):
resp = requests.post(f"{API_BASE}/api/initiate-call", json=payload)
if resp.status_code == 200:
data = resp.json()
st.success(f"Call initiated! Session ID: {data['session_id']}")
st.info("After the call ends, click 'Fetch Report' to get the evaluation.")
else:
st.error(f"Error: {resp.text}")
# ── Main: Session List ────────────────────────────────────────────────────────
st.header("Recent Interviews")
col_refresh, _ = st.columns([1, 5])
if col_refresh.button("Refresh List"):
st.rerun()
resp = requests.get(f"{API_BASE}/api/sessions")
if resp.status_code != 200:
st.warning("Could not reach the API server.")
st.stop()
sessions = resp.json()
if not sessions:
st.info("No interviews yet. Use the sidebar to start one.")
st.stop()
# Column headers
h1, h2, h3, h4, h5, h6 = st.columns([2, 1, 1, 2, 1, 1])
h1.markdown("**Candidate**")
h2.markdown("**Status**")
h3.markdown("**Score**")
h4.markdown("**Recommendation**")
h5.markdown("**Action**")
h6.markdown("**Report**")
st.divider()
for s in sessions:
with st.container():
col1, col2, col3, col4, col5, col6 = st.columns([2, 1, 1, 2, 1, 1])
col1.write(f"**{s['candidate']}**")
status_color = {"completed": "green", "active": "orange", "initiated": "blue"}.get(s["status"], "gray")
col2.markdown(f":{status_color}[{s['status']}]")
col3.write(f"{s['overall_score']:.1f}/10" if s["overall_score"] else "β€”")
col4.write(s["recommendation"] or "β€”")
if col5.button("Fetch Report", key=f"fetch_{s['id']}"):
with st.spinner("Fetching report from Bland.ai..."):
fetch_resp = requests.post(f"{API_BASE}/api/session/{s['id']}/fetch-report")
if fetch_resp.status_code == 200:
st.success(fetch_resp.json().get("message", "Done"))
st.rerun()
else:
st.error(fetch_resp.text)
if col6.button("View", key=f"view_{s['id']}"):
st.session_state["selected_session"] = s["id"]
st.divider()
# ── Report Viewer ─────────────────────────────────────────────────────────────
if "selected_session" in st.session_state:
sid = st.session_state["selected_session"]
report_resp = requests.get(f"{API_BASE}/api/session/{sid}/report")
if report_resp.status_code == 200:
data = report_resp.json()
st.subheader(f"Report β€” {data['candidate']}")
if data["status"] != "completed":
st.warning(f"Status: {data['status']} β€” Click 'Fetch Report' after the call ends.")
else:
st.markdown("### Full Analysis is Below")
col1, col2, col3, col4 = st.columns(4)
col1.metric("Communication", f"{data['communication_score']:.1f}/10")
col2.metric("Technical", f"{data['technical_score']:.1f}/10")
col3.metric("Confidence", f"{data['confidence_score']:.1f}/10")
col4.metric("Overall", f"{data['overall_score']:.1f}/10")
st.markdown(f"**Recommendation:** {data['recommendation']}")
st.markdown(f"**Skills:** {', '.join(data['skills'] or [])}")
with st.expander("Full Report"):
st.text(data["report"])
trans_resp = requests.get(f"{API_BASE}/api/session/{sid}/transcript")
if trans_resp.status_code == 200:
turns = trans_resp.json()
if turns:
with st.expander("View Transcript"):
for t in turns:
if t["speaker"] == "AI":
st.markdown(f"**AI:** {t['text']}")
else:
st.markdown(f"**Candidate:** {t['text']}")