import streamlit as st
class OutputDisplay:
"""
Renders structured execution results and debug logs.
"""
# ---------------- MAIN RENDERER ----------------
def render_output(self, result: dict):
success = result["returncode"] == 0
status_icon = "✅" if success else "❌"
st.markdown(f"**{status_icon} Exited {result['returncode']}**")
if result["stdout"].strip():
st.caption("stdout")
st.code(result["stdout"].rstrip(), language="text")
if result["stderr"].strip():
st.caption("stderr")
st.code(result["stderr"].rstrip(), language="text")
if result.get("logs"):
with st.expander("🪲 Debug log", expanded=False):
level_colors = {
"INFO": "#6c7086", "OUTPUT": "#a6e3a1", "ERROR": "#f38ba8",
"SYNTAX": "#fab387", "EXCEPTION": "#f38ba8",
"SUCCESS": "#a6e3a1", "FAIL": "#f38ba8",
}
icons = {
"INFO": "ℹ", "OUTPUT": "▶", "ERROR": "✖",
"SYNTAX": "⚠", "EXCEPTION": "💥", "SUCCESS": "✔", "FAIL": "✖",
}
lines = []
for e in result["logs"]:
color = level_colors.get(e["level"], "#cdd6f4")
icon = icons.get(e["level"], "•")
lines.append(
f'[{e["time"]}] '
f'{icon} {e["level"]} : '
f'{e["message"]}'
)
st.markdown("
".join(lines), unsafe_allow_html=True)
if not result["stdout"].strip() and not result["stderr"].strip():
st.caption("No output.")
# ---------------- HELPERS ----------------
def display_error(self, error_message: str):
st.error(f"❌ {error_message}")
def display_warning(self, warning_message: str):
st.warning(f"⚠️ {warning_message}")