Spaces:
Sleeping
Sleeping
File size: 7,878 Bytes
15dd7d9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | import gradio as gr
import os
import requests
from dotenv import load_dotenv
# -------------------------------------
# Load environment variables
# -------------------------------------
load_dotenv()
API_KEY = os.getenv("GROQ_API_KEY")
API_URL = "https://api.groq.com/openai/v1/chat/completions"
MODEL = "llama-3.3-70b-versatile"
# -------------------------------------
# Helpers
# -------------------------------------
def read_uploaded_file(file_obj):
try:
with open(file_obj.name, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
return f"⚠️ Error reading file: {str(e)}"
def detect_language(code, file_name=None):
if file_name:
ext = os.path.splitext(file_name)[1].lower()
mapping = {
".py": "Python", ".js": "JavaScript", ".cpp": "C++", ".cc": "C++", ".c": "C++",
".java": "Java", ".html": "HTML", ".htm": "HTML", ".css": "CSS", ".php": "PHP",
".cs": "C#", ".rb": "Ruby", ".rs": "Rust", ".go": "Go", ".ts": "TypeScript",
".jsx": "JavaScript", ".tsx": "TypeScript", ".txt": "PlainText"
}
if ext in mapping:
return mapping[ext]
if "def " in code or "import " in code:
return "Python"
if "function " in code or "console.log" in code or "=> " in code:
return "JavaScript"
if "#include" in code or "int main(" in code:
return "C++"
if "public static void main" in code:
return "Java"
return "Unknown"
LANG_TO_SHORT = {
"Python": "python", "JavaScript": "javascript", "C++": "cpp", "Java": "java",
"HTML": "html", "CSS": "css", "PHP": "php", "C#": "csharp", "Ruby": "ruby",
"Rust": "rust", "Go": "go", "TypeScript": "typescript", "PlainText": "python",
"Unknown": "python"
}
# -------------------------------------
# File upload handler
# -------------------------------------
def handle_file_upload(file_obj):
if file_obj is None:
return "", LANG_TO_SHORT["Unknown"], "Unknown"
code = read_uploaded_file(file_obj)
lang_name = detect_language(code, file_obj.name)
lang_short = LANG_TO_SHORT.get(lang_name, "python")
return code, lang_short, lang_name
# -------------------------------------
# Main AI Review Logic
# -------------------------------------
def review_code(code, file, mode, lang_name_state):
if (not code or not code.strip()) and file is not None:
code = read_uploaded_file(file)
if not code or code.startswith("⚠️"):
return (code if code else "⚠️ Please paste or upload code first."), None
if not API_KEY:
return "⚠️ Missing API Key. Please check your .env file.", None
language = lang_name_state if lang_name_state and lang_name_state != "Unknown" else detect_language(code, file.name if file else None)
if mode == "Summarize/Explain":
prompt = f"Provide both a short summary and a beginner-friendly explanation for this {language} code:\n\n{code}"
elif mode == "Improve":
prompt = f"Suggest improvements for this {language} code and show the improved version in the SAME {language}:\n\n{code}"
elif mode == "Optimize":
prompt = f"Rewrite this {language} code to be more efficient, clean, and professional. Output only {language} code:\n\n{code}"
else:
prompt = f"Summarize this {language} code:\n\n{code}"
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": f"You are an expert {language} programmer and AI code reviewer."},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 1500
}
try:
response = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json=payload,
timeout=60
)
data = response.json()
if "choices" in data and len(data["choices"]) > 0:
result = data["choices"][0]["message"]["content"].strip()
safe_ext = {"Python": "py", "JavaScript": "js", "C++": "cpp", "Java": "java"}.get(language, "txt")
output_filename = f"ai_output.{safe_ext}"
with open(output_filename, "w", encoding="utf-8") as f:
f.write(result)
return result, output_filename
elif "error" in data:
return f"❌ API Error: {data['error'].get('message', 'Unknown error')}", None
else:
return f"❌ Unexpected API response: {data}", None
except Exception as e:
return f"⚠️ Exception: {str(e)}", None
# -------------------------------------
# Clear All Function
# -------------------------------------
def clear_all():
return "", None, "python", "Unknown", "Summarize/Explain", "", None
# -------------------------------------
# Gradio UI
# -------------------------------------
with gr.Blocks(
theme=gr.themes.Soft(),
css="""
#code_input textarea, #output_text textarea {
white-space: pre-wrap !important;
resize: vertical !important; /* Allow vertical resizing like IDE panels */
overflow-y: auto !important;
min-height: 300px !important;
max-height: 800px !important;
height: 400px !important;
}
"""
) as app:
gr.Markdown("# 🤖 AI Code Reviewer & Optimizer")
gr.Markdown("Analyze, explain, and improve code in multiple programming languages.")
with gr.Row(equal_height=True):
# Left column - Input
with gr.Column(scale=1, min_width=500):
code_input = gr.Code(
label="💻 Paste Code Here (or Upload Below)",
language="python",
lines=25,
elem_id="code_input"
)
file_input = gr.File(label="📁 Upload Code File",
file_types=[".py", ".js", ".cpp", ".java", ".html", ".css", ".php", ".txt"])
syntax_state = gr.State("python")
lang_name_state = gr.State("Unknown")
file_input.change(handle_file_upload,
inputs=[file_input],
outputs=[code_input, syntax_state, lang_name_state]) \
.then(lambda short: gr.update(language=short),
inputs=syntax_state,
outputs=code_input)
mode = gr.Radio(["Summarize/Explain", "Improve", "Optimize"],
value="Summarize/Explain", label="Select Mode")
with gr.Row():
run_btn = gr.Button("🚀 Run Analysis", variant="primary")
clear_btn = gr.Button("🧹 Clear All", variant="secondary")
# Right column - Output
with gr.Column(scale=1, min_width=500):
output_text = gr.Textbox(
label="🧠 AI Output (Resizable Text Window)",
elem_id="output_text",
lines=25,
show_copy_button=True,
interactive=False
)
download_btn = gr.File(label="⬇️ Download AI Output")
# Button logic
run_btn.click(review_code,
inputs=[code_input, file_input, mode, lang_name_state],
outputs=[output_text, download_btn])
clear_btn.click(clear_all,
outputs=[code_input, file_input, syntax_state,
lang_name_state, mode, output_text, download_btn])
gr.Markdown("---")
gr.Markdown("Built by **jlsonon** · Day 9 of 30 Days of Generative AI Journey")
if __name__ == "__main__":
app.launch()
|