Team Ai
Apppublic

Sumayyea/CodeExplainerBot

sourceHugging Faceupdated 18d agoView on Hugging Face
0likes
app.py90 linesDownload Raw Back to root
1import os2import streamlit as st3from openai import OpenAI4 5# ─────────────── Page setup ───────────────6st.set_page_config(page_title="Code Explainer Bot", page_icon="🤖")7st.title("🤖 Code Explainer Bot (Gemini via OpenRouter)")8st.write("Paste your code below for line-by-line explanations!")9 10# ─────────────── API configuration ───────────────11def get_api_key():12    """Read the key from an environment variable (Hugging Face secret) or Streamlit secrets."""13    key = os.getenv("OPENROUTER_API_KEY")14    if key:15        return key16    try:17        return st.secrets["OPENROUTER_API_KEY"]18    except Exception:19        return None20 21OPENROUTER_API_KEY = get_api_key()22if not OPENROUTER_API_KEY:23    st.error("❌ OPENROUTER_API_KEY not found. Add it to your Space secrets or .streamlit/secrets.toml.")24    st.stop()25 26client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=OPENROUTER_API_KEY)27MODEL_NAME = "google/gemini-2.5-flash"28EXTRA_HEADERS = {29    "HTTP-Referer": "https://huggingface.co/spaces",  # replace with your Space URL30    "X-Title": "Code Explainer Bot",31}32 33# ─────────────── Input ───────────────34code = st.text_area("Enter your code:", height=250, placeholder="Your code here...")35 36def number_lines(code):37    """Add line numbers ourselves so the model's numbering matches the real code."""38    return "\n".join(f"{i:>3} | {line}" for i, line in enumerate(code.splitlines(), 1))39 40def generate_explanation(code):41    """Generate a line-by-line explanation with Gemini through OpenRouter."""42    prompt = f"""Explain this code line by line in plain English for beginners.43Each line is prefixed with its line number and a "|" separator.44 45Rules:46- Use this format: **Line N:** explanation47- Skip blank lines. Group closely related lines if it helps (e.g. **Lines 4-6:**).48- Keep each explanation short and simple.49- End with a 2-3 sentence summary of what the whole program does.50 51Code:52{number_lines(code)}53"""54    try:55        response = client.chat.completions.create(56            model=MODEL_NAME,57            extra_headers=EXTRA_HEADERS,58            messages=[{"role": "user", "content": prompt}],59            max_tokens=2000,60            temperature=0.2,61        )62        return response.choices[0].message.content63    except Exception as e:64        msg = str(e)65        if "401" in msg:66            return "❌ Invalid or expired API key. Check OPENROUTER_API_KEY in your secrets."67        if "402" in msg:68            return "❌ Not enough OpenRouter credits. Add credits or lower max_tokens."69        if "429" in msg:70            return "⏳ Rate limit reached. Please wait a moment and try again."71        return f"❌ Error generating explanation: {msg}"72 73# ─────────────── Explain button ───────────────74if st.button("Explain Code", type="primary"):75    if not code.strip():76        st.error("Please enter some code to explain.")77    else:78        with st.spinner("Analyzing code with Gemini..."):79            explanation = generate_explanation(code)80 81        st.subheader("Code Explanation")82        st.markdown("---")83        st.markdown(explanation)84        st.markdown("---")85        if not explanation.startswith(("❌", "⏳")):86            st.success("Analysis complete!")87 88# ─────────────── Footer ───────────────89st.markdown("---")90st.markdown("*Built with Streamlit, OpenRouter and Google Gemini*")