Team Ai
Apppublic

dgarzon/SQL-Explainer

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
streamlit_app.py155 linesDownload Raw Back to root
1#!/usr/bin/env python32"""Streamlit interface for SQL Explainer Agent."""3 4from __future__ import annotations5 6import streamlit as st7 8from sql_explainer_core import (9    DEFAULT_MAX_NEW_TOKENS,10    DEFAULT_MODEL,11    MAX_SQL_CHARS,12    call_local_model,13    get_free_local_models,14    get_device_label,15)16 17 18EXAMPLE_SQL = """SELECT19    employee_id,20    first_name,21    last_name,22    department,23    salary24FROM employees25WHERE department = 'Sales'26  AND salary > 5000027ORDER BY salary DESC;"""28 29SQL_INPUT_HEIGHT = 36030EXPLANATION_PANEL_HEIGHT = 43031 32 33def initialize_state() -> None:34    """Initialize session state once so reruns keep the current values."""35    st.session_state.setdefault("sql_input", "")36    st.session_state.setdefault("explanation", "")37    st.session_state.setdefault("error_message", "")38    st.session_state.setdefault("local_model_id", DEFAULT_MODEL)39    st.session_state.setdefault("max_new_tokens", DEFAULT_MAX_NEW_TOKENS)40 41 42def render_sidebar() -> tuple[str, int]:43    """Draw the sidebar and return the selected settings."""44    with st.sidebar:45        st.header("Settings")46        model_options = list(get_free_local_models())47        current_model = st.session_state.local_model_id48        default_index = model_options.index(current_model) if current_model in model_options else 049        st.session_state.local_model_id = st.selectbox(50            "Local model",51            options=model_options,52            index=default_index,53        )54 55        with st.expander("Advanced"):56            st.number_input(57                "Max new tokens",58                min_value=120,59                max_value=600,60                step=20,61                key="max_new_tokens",62            )63 64        st.divider()65        if st.button("Load Example", use_container_width=True):66            st.session_state.sql_input = EXAMPLE_SQL67        if st.button("Clear", use_container_width=True):68            st.session_state.sql_input = ""69            st.session_state.explanation = ""70            st.session_state.error_message = ""71 72        st.caption(73            "Fully free mode: the model runs locally inside the Hugging Face Space. "74            "No token and no paid inference provider are used."75        )76        st.caption(77            "Only small local models are exposed here to keep the Space inside free CPU limits."78        )79        st.caption(f"Runtime device: {get_device_label()}")80        st.caption(f"Demo protection: SQL input is limited to {MAX_SQL_CHARS} characters.")81 82    return st.session_state.local_model_id, int(st.session_state.max_new_tokens)83 84 85def explain_sql(sql: str, model_id: str, max_new_tokens: int) -> None:86    """Run local generation and store either the result or the error."""87    if not sql.strip():88        st.session_state.error_message = (89            "Please paste a SQL query before running the explanation."90        )91        st.session_state.explanation = ""92        return93 94    try:95        with st.spinner("Loading the local model if needed and generating the explanation..."):96            st.session_state.explanation = call_local_model(97                sql,98                model_id=model_id,99                max_new_tokens=max_new_tokens,100            )101            st.session_state.error_message = ""102    except Exception as exc:  # noqa: BLE001 - keep Streamlit errors simple for V1.103        st.session_state.error_message = str(exc)104        st.session_state.explanation = ""105 106 107def main() -> None:108    """Build the Streamlit interface and connect the UI to local inference."""109    st.set_page_config(page_title="SQL Explainer Agent", layout="wide")110    initialize_state()111    model_id, max_new_tokens = render_sidebar()112 113    st.title("SQL Explainer Agent")114    st.caption(115        "Paste a SQL query and get a practical explanation for analytics or business users "116        "using a local open model running inside this Space."117    )118    st.info(119        "This version is fully free to run on Hugging Face Spaces CPU Basic. "120        "The first request can be slow while the model is downloaded and loaded."121    )122 123    left_col, right_col = st.columns([1.05, 0.95], gap="large")124 125    with left_col:126        st.subheader("SQL Query")127        st.text_area(128            "Paste SQL",129            key="sql_input",130            height=SQL_INPUT_HEIGHT,131            label_visibility="collapsed",132            placeholder="SELECT * FROM your_table WHERE created_at >= CURRENT_DATE - INTERVAL '7 days';",133        )134 135        action_col, clear_col = st.columns(2)136        if action_col.button("Explain Query", type="primary", use_container_width=True):137            explain_sql(st.session_state.sql_input, model_id, max_new_tokens)138        if clear_col.button("Clear Result", use_container_width=True):139            st.session_state.explanation = ""140            st.session_state.error_message = ""141 142    with right_col:143        st.subheader("Explanation")144        with st.container(height=EXPLANATION_PANEL_HEIGHT):145            if st.session_state.error_message:146                st.error(st.session_state.error_message)147            elif st.session_state.explanation:148                st.markdown(st.session_state.explanation)149            else:150                st.info("Run the explanation to see the six-section output here.")151 152 153if __name__ == "__main__":154    main()155