""" Code Review NLP Assistant — Gradio App Run with: python app.py """ import sys import os sys.path.insert(0, os.path.dirname(__file__)) import gradio as gr import plotly.graph_objects as go from models.code_analyzer import CodeReviewAnalyzer from utils.helpers import ( extract_functions, extract_classes, score_to_grade, score_color, build_report, ) from data.sample_code import SAMPLES analyzer = CodeReviewAnalyzer(use_gpu=False) def build_radar(doc_score, name_score, comp_score, overall): fig = go.Figure(go.Scatterpolar( r=[doc_score, name_score, comp_score, overall, doc_score], theta=["Documentation", "Naming", "Complexity", "Overall", "Documentation"], fill="toself", fillcolor="rgba(99,102,241,0.2)", line=dict(color="#6366f1", width=2), )) fig.update_layout( polar=dict(radialaxis=dict(visible=True, range=[0, 100])), showlegend=False, margin=dict(l=40, r=40, t=40, b=40), height=320, ) return fig def build_bars(doc_score, name_score, comp_score): fig = go.Figure(go.Bar( x=["Documentation", "Naming", "Complexity"], y=[doc_score, name_score, comp_score], marker_color=[ score_color(doc_score), score_color(name_score), score_color(comp_score), ], text=[str(doc_score), str(name_score), str(comp_score)], textposition="outside", )) fig.update_layout( yaxis=dict(range=[0, 115]), margin=dict(l=20, r=20, t=20, b=20), height=300, ) return fig def analyze_code(code, sample_choice, generate_doc, get_embed): if sample_choice != "None" and not code.strip(): code = SAMPLES[sample_choice] if not code.strip(): return ( "

⚠️ Please paste some code or pick a sample.

", None, None, "", "", "", "", "" ) result = analyzer.analyze( code, generate_doc=generate_doc, get_embedding=get_embed, ) functions = extract_functions(code) classes = extract_classes(code) grade, label = score_to_grade(result.overall_score) color = score_color(result.overall_score) score_html = f"""
Overall Score
{result.overall_score}
Grade {grade} — {label}
Docs
{result.documentation_score}
Naming
{result.naming_score}
Complexity
{result.complexity_score}
""" issues_md = "\n".join(f"⚠️ {i}" for i in result.issues) \ if result.issues else "✅ No critical issues found!" suggestions_md = "\n".join(f"💡 {s}" for s in result.suggestions) func_lines = [] for fn in functions: doc = "✓ docstring" if fn["has_docstring"] else "✗ no docstring" args = ", ".join(fn["args"]) if fn["args"] else "none" func_lines.append( f"**def {fn['name']}()** — args: `{args}` | " f"returns: `{fn['returns'] or 'not annotated'}` | {doc}" ) funcs_md = "\n\n".join(func_lines) if func_lines else "No functions found." class_lines = [] for cls in classes: doc = "✓ docstring" if cls["has_docstring"] else "✗ no docstring" methods = ", ".join(cls["methods"][:5]) class_lines.append( f"**class {cls['name']}** — methods: `{methods}` | {doc}" ) classes_md = "\n\n".join(class_lines) if class_lines else "No classes found." docstring_md = f"```python\n{result.generated_docstring}\n```" \ if result.generated_docstring else "Docstring generation was disabled." report = build_report(result) radar = build_radar( result.documentation_score, result.naming_score, result.complexity_score, result.overall_score, ) bars = build_bars( result.documentation_score, result.naming_score, result.complexity_score, ) return ( score_html, radar, bars, issues_md, suggestions_md, funcs_md, classes_md, docstring_md, report, ) def load_sample(sample_choice): if sample_choice == "None": return "" return SAMPLES[sample_choice] with gr.Blocks(title="Code Review NLP Assistant") as demo: gr.Markdown("# 🔬 Code Review NLP Assistant") gr.Markdown("Powered by **CodeBERT** · **CodeT5** · **AST Analysis** — 100% free & open source") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 📝 Input") sample_dropdown = gr.Dropdown( choices=["None"] + list(SAMPLES.keys()), value="None", label="Load a sample", ) code_input = gr.Code( language="python", label="Paste your Python code here", lines=20, ) sample_dropdown.change( fn=load_sample, inputs=sample_dropdown, outputs=code_input, ) with gr.Row(): generate_doc = gr.Checkbox(value=True, label="Generate docstring (CodeT5)") get_embed = gr.Checkbox(value=False, label="Get embedding (CodeBERT)") analyze_btn = gr.Button("🔍 Analyze Code", variant="primary", size="lg") with gr.Column(scale=2): gr.Markdown("### 📊 Results") score_html = gr.HTML() with gr.Row(): radar_chart = gr.Plot(label="Quality Radar") bar_chart = gr.Plot(label="Score Breakdown") with gr.Tabs(): with gr.Tab("⚠️ Issues"): issues_out = gr.Markdown() with gr.Tab("💡 Suggestions"): suggestions_out = gr.Markdown() with gr.Tab("🔧 Functions"): funcs_out = gr.Markdown() with gr.Tab("🏛️ Classes"): classes_out = gr.Markdown() with gr.Tab("🤖 Docstring"): docstring_out = gr.Markdown() with gr.Tab("📄 Full Report"): report_out = gr.Markdown() analyze_btn.click( fn=analyze_code, inputs=[code_input, sample_dropdown, generate_doc, get_embed], outputs=[ score_html, radar_chart, bar_chart, issues_out, suggestions_out, funcs_out, classes_out, docstring_out, report_out, ], ) if __name__ == "__main__": demo.launch(share=True)