Download streamlit_app.py from ashritaa-chinnari123/code_explainer_bug_checker_NLP_project: direct link, hf CLI and curl.
- Browser
- Download file 7.32 kB
-
https://huggingface.co/spaces/ashritaa-chinnari123/code_explainer_bug_checker_NLP_project/resolve/main/streamlit_app.py
- Command line
-
hf download hf://spaces/ashritaa-chinnari123/code_explainer_bug_checker_NLP_project/streamlit_app.py
-
curl -L -o streamlit_app.py https://huggingface.co/spaces/ashritaa-chinnari123/code_explainer_bug_checker_NLP_project/resolve/main/streamlit_app.py
7.32 kB
| """ | |
| Streamlit UI for the Code Explainer + Bug Fixer. | |
| Run: | |
| pip install streamlit | |
| streamlit run streamlit_app.py | |
| """ | |
| import streamlit as st | |
| import torch | |
| from transformers import AutoTokenizer, T5ForConditionalGeneration | |
| from line_explainer import explain_line_by_line | |
| from bug_checker import detect_bugs, check_style | |
| st.set_page_config(page_title="Code Explainer & Bug Fixer", page_icon="π οΈ", layout="wide") | |
| DEVICE = "cuda" if torch.cuda.is_available() else "cpu" | |
| EXPLAIN_MODEL_NAME = "Salesforce/codet5-base-multi-sum" | |
| def load_explain_model(): | |
| explain_tokenizer = AutoTokenizer.from_pretrained(EXPLAIN_MODEL_NAME, use_fast=False) | |
| explain_model = T5ForConditionalGeneration.from_pretrained(EXPLAIN_MODEL_NAME).to(DEVICE) | |
| return explain_tokenizer, explain_model | |
| explain_tokenizer, explain_model = load_explain_model() | |
| def explain_code(code: str) -> str: | |
| inputs = explain_tokenizer(code, return_tensors="pt", truncation=True, max_length=512).to(DEVICE) | |
| output_ids = explain_model.generate(**inputs, max_length=64, num_beams=5, early_stopping=True) | |
| return explain_tokenizer.decode(output_ids[0], skip_special_tokens=True) | |
| # --------------------------- Language config --------------------------- | |
| # codet5-base-multi-sum was trained on 6 languages for the EXPLANATION step. | |
| # line_explainer.py and bug_checker.py are Python-only (built on Python's ast | |
| # module), so those two features are gated to Python only below. | |
| LANGUAGE_OPTIONS = { | |
| "Python": {"extensions": ["py"], "st_lang": "python", "supports_static_analysis": True}, | |
| "Java": {"extensions": ["java"], "st_lang": "java", "supports_static_analysis": False}, | |
| "JavaScript": {"extensions": ["js"], "st_lang": "javascript", "supports_static_analysis": False}, | |
| "PHP": {"extensions": ["php"], "st_lang": "php", "supports_static_analysis": False}, | |
| "Ruby": {"extensions": ["rb"], "st_lang": "ruby", "supports_static_analysis": False}, | |
| "Go": {"extensions": ["go"], "st_lang": "go", "supports_static_analysis": False}, | |
| } | |
| # --------------------------- UI --------------------------- | |
| st.title("π οΈ Code Explainer & Bug Checker") | |
| st.caption("Paste code or upload a file. It will be explained in plain English and checked for bugs/style issues.") | |
| col_lang, col_upload = st.columns([1, 2]) | |
| with col_lang: | |
| language = st.selectbox("Language:", list(LANGUAGE_OPTIONS.keys())) | |
| with col_upload: | |
| all_extensions = [ext for cfg in LANGUAGE_OPTIONS.values() for ext in cfg["extensions"]] + ["txt"] | |
| uploaded_file = st.file_uploader("Or upload a code file:", type=all_extensions) | |
| lang_cfg = LANGUAGE_OPTIONS[language] | |
| if not lang_cfg["supports_static_analysis"]: | |
| st.info( | |
| f"Line-by-line breakdown and bug/style checking currently support Python only. " | |
| f"For {language}, you'll get the AI explanation only." | |
| ) | |
| default_code = """def add_numbers(a, b) | |
| return a + b""" | |
| if uploaded_file is not None: | |
| file_bytes = uploaded_file.read() | |
| try: | |
| starter_code = file_bytes.decode("utf-8") | |
| except UnicodeDecodeError: | |
| st.error("Couldn't decode the uploaded file as text (UTF-8). Please upload a plain text code file.") | |
| starter_code = default_code | |
| else: | |
| starter_code = default_code | |
| code_input = st.text_area("Your code:", value=starter_code, height=250, placeholder="Paste your code here...") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| run_explain = st.button("π Analyze Code", type="primary", use_container_width=True) | |
| with col2: | |
| clear = st.button("ποΈ Clear", use_container_width=True) | |
| if clear: | |
| st.rerun() | |
| if run_explain: | |
| if not code_input.strip(): | |
| st.warning("Please paste some code first.") | |
| else: | |
| report_sections = [] # collects (title, text) for the downloadable report | |
| with st.spinner("Analyzing..."): | |
| explanation = explain_code(code_input) | |
| st.subheader("π Explanation") | |
| st.info(explanation) | |
| report_sections.append(("Explanation", explanation)) | |
| if lang_cfg["supports_static_analysis"]: | |
| st.subheader("π Line-by-line breakdown") | |
| ok, breakdown = explain_line_by_line(code_input) | |
| if ok: | |
| breakdown_text = "\n".join(breakdown) | |
| st.code(breakdown_text, language="text") | |
| report_sections.append(("Line-by-line breakdown", breakdown_text)) | |
| else: | |
| st.warning(breakdown) | |
| report_sections.append(("Line-by-line breakdown", breakdown)) | |
| bug_result = detect_bugs(code_input) | |
| style_issues = check_style(code_input) if bug_result["syntax_valid"] else [] | |
| st.subheader("π Bug Check (static analysis)") | |
| st.caption("Checks for real errors: syntax mistakes, undefined variables, unused imports. Based on Python's own parser + pyflakes β deterministic, not a guess.") | |
| if not bug_result["syntax_valid"]: | |
| st.error(bug_result["syntax_error"]) | |
| bug_report_text = bug_result["syntax_error"] | |
| elif bug_result["has_bug"]: | |
| st.error(bug_result["summary"]) | |
| for issue in bug_result["static_issues"]: | |
| st.write(f"- {issue}") | |
| bug_report_text = bug_result["summary"] + "\n" + "\n".join(f"- {i}" for i in bug_result["static_issues"]) | |
| else: | |
| st.success(bug_result["summary"]) | |
| bug_report_text = bug_result["summary"] | |
| report_sections.append(("Bug Check", bug_report_text)) | |
| st.subheader("π¨ Style Check (PEP8)") | |
| st.caption("Checks formatting conventions (line length, spacing, naming) β not correctness. Code with style warnings can still run perfectly fine; this just flags deviations from Python's standard style guide.") | |
| if style_issues: | |
| st.warning(f"{len(style_issues)} style issue(s) found.") | |
| for issue in style_issues: | |
| st.write(f"- {issue}") | |
| style_report_text = "\n".join(f"- {i}" for i in style_issues) | |
| else: | |
| st.success("No PEP8 style issues found.") | |
| style_report_text = "No PEP8 style issues found." | |
| report_sections.append(("Style Check (PEP8)", style_report_text)) | |
| # --------------------------- Build downloadable report --------------------------- | |
| report_lines = [f"# Code Analysis Report\n", f"**Language:** {language}\n", "## Original Code\n", f"```{lang_cfg['st_lang']}\n{code_input}\n```\n"] | |
| for title, text in report_sections: | |
| report_lines.append(f"## {title}\n") | |
| report_lines.append(f"{text}\n") | |
| report_text = "\n".join(report_lines) | |
| st.divider() | |
| st.download_button( | |
| label="β¬οΈ Download Full Report (.md)", | |
| data=report_text, | |
| file_name="code_analysis_report.md", | |
| mime="text/markdown", | |
| ) | |
| st.divider() | |
| st.caption( | |
| "Bug detection uses real static analysis (Python's ast parser + pyflakes), " | |
| "so results are accurate and deterministic β not a model's guess." | |
| ) |