53 lines
2.1 KiB
Python
53 lines
2.1 KiB
Python
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'<span style="color:#585b70">[{e["time"]}]</span> '
|
||
f'<span style="color:{color}">{icon} <b>{e["level"]} :</b></span> '
|
||
f'<span style="color:#444444">{e["message"]}</span>'
|
||
)
|
||
st.markdown("<br>".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}") |