Spaces:
Running
Running
# app.py - Robust version with fallback | |
import gradio as gr | |
import logging | |
import traceback | |
# Set up logging | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
logger = logging.getLogger(__name__) | |
# Global debugger instance | |
debugger = None | |
debugger_status = "π Initializing..." | |
def initialize_debugger(): | |
"""Initialize the debugger with comprehensive error handling.""" | |
global debugger, debugger_status | |
try: | |
logger.info("π Starting debugger initialization...") | |
debugger_status = "π Loading AI model..." | |
# First, try the main model wrapper | |
try: | |
from model_wrapper import CodeDebuggerWrapper | |
logger.info("Attempting to load main model wrapper...") | |
debugger = CodeDebuggerWrapper() | |
debugger_status = "β AI model loaded successfully!" | |
logger.info("β Main model wrapper loaded successfully") | |
return debugger_status | |
except Exception as main_error: | |
logger.warning(f"Main model wrapper failed: {str(main_error)[:200]}...") | |
logger.debug(f"Full error: {traceback.format_exc()}") | |
# Try fallback debugger | |
try: | |
from model_wrapper import FallbackDebugger | |
logger.info("Falling back to rule-based debugger...") | |
debugger = FallbackDebugger() | |
debugger_status = "β οΈ Using fallback debugger (AI model unavailable)" | |
logger.info("β Fallback debugger loaded") | |
return debugger_status | |
except Exception as fallback_error: | |
logger.error(f"Fallback debugger also failed: {fallback_error}") | |
debugger_status = "β Both AI and fallback debuggers failed" | |
return debugger_status | |
except Exception as critical_error: | |
logger.error(f"Critical initialization error: {critical_error}") | |
logger.error(f"Full traceback: {traceback.format_exc()}") | |
debugger_status = f"β Critical error: {str(critical_error)[:100]}..." | |
return debugger_status | |
def debug_code(code: str): | |
"""Debug code with comprehensive error handling.""" | |
global debugger, debugger_status | |
# Input validation | |
if not code or not code.strip(): | |
return "β Please paste some code to debug." | |
# Initialize debugger if needed | |
if debugger is None: | |
logger.info("Debugger not initialized, initializing now...") | |
status = initialize_debugger() | |
if "β" in status: | |
return f"{status}\n\nπ§ **Manual Analysis:**\n{manual_debug_fallback(code)}" | |
# Try to debug with loaded debugger | |
try: | |
logger.info("π Processing debug request...") | |
result = debugger.debug(code) | |
logger.info("β Debug request completed") | |
return result | |
except Exception as debug_error: | |
logger.error(f"Debug processing failed: {debug_error}") | |
logger.error(f"Full traceback: {traceback.format_exc()}") | |
# Ultimate fallback | |
return f"β Debug processing failed: {str(debug_error)[:100]}...\n\nπ§ **Manual Analysis:**\n{manual_debug_fallback(code)}" | |
def manual_debug_fallback(code: str) -> str: | |
"""Ultimate fallback - basic syntax checking.""" | |
try: | |
issues = [] | |
lines = code.split('\n') | |
for i, line in enumerate(lines, 1): | |
stripped = line.strip() | |
if not stripped or stripped.startswith('#'): | |
continue | |
# Check for missing colons | |
control_keywords = ['if ', 'elif ', 'else:', 'for ', 'while ', 'def ', 'class ', 'try:', 'except', 'finally:'] | |
if any(keyword in stripped for keyword in control_keywords): | |
if not stripped.endswith(':') and 'else:' not in stripped and 'try:' not in stripped and 'finally:' not in stripped: | |
issues.append(f"Line {i}: Possible missing colon (:)") | |
# Check for unbalanced parentheses | |
if stripped.count('(') != stripped.count(')'): | |
issues.append(f"Line {i}: Unbalanced parentheses") | |
# Check for unbalanced quotes | |
single_quotes = stripped.count("'") | |
double_quotes = stripped.count('"') | |
if single_quotes % 2 != 0: | |
issues.append(f"Line {i}: Unbalanced single quotes") | |
if double_quotes % 2 != 0: | |
issues.append(f"Line {i}: Unbalanced double quotes") | |
# Generate response | |
result = f"**Your Code:**\n```python\n{code}\n```\n\n" | |
if issues: | |
result += "**Potential Issues Found:**\n" | |
for issue in issues: | |
result += f"β’ {issue}\n" | |
else: | |
result += "**No obvious syntax errors detected.**\n" | |
result += "\n**Debugging Checklist:**\n" | |
result += "β’ β Check for missing colons after if/for/def statements\n" | |
result += "β’ β Verify proper indentation (4 spaces per level)\n" | |
result += "β’ β Ensure parentheses and quotes are balanced\n" | |
result += "β’ β Check for typos in variable names\n" | |
result += "β’ β Verify all imports are included\n" | |
result += "β’ β Look for logic errors in conditions\n" | |
return result | |
except Exception as e: | |
return f"Even manual analysis failed: {e}\n\nOriginal code:\n{code}" | |
def get_status(): | |
"""Get current system status.""" | |
global debugger_status | |
return debugger_status | |
def create_app(): | |
"""Create the Gradio interface.""" | |
with gr.Blocks( | |
title="π AI Code Debugger", | |
theme=gr.themes.Soft(), | |
css=""" | |
.status-box { | |
background: linear-gradient(45deg, #f0f0f0, #e0e0e0); | |
border-radius: 10px; | |
padding: 10px; | |
} | |
.code-box { | |
font-family: 'Consolas', 'Monaco', monospace; | |
font-size: 14px; | |
} | |
""" | |
) as demo: | |
# Header | |
gr.Markdown(""" | |
# π AI Code Debugger | |
### Fine-tuned AI model for debugging Python code | |
**How to use:** | |
1. Paste your Python code in the left box | |
2. Click "π§ Debug Code" | |
3. Get AI-powered suggestions and fixes | |
""") | |
# Status display | |
status_display = gr.Textbox( | |
label="π System Status", | |
value="π Loading...", | |
interactive=False, | |
elem_classes=["status-box"] | |
) | |
# Main interface | |
with gr.Row(): | |
with gr.Column(scale=1): | |
code_input = gr.Textbox( | |
lines=16, | |
placeholder="Paste your Python code here...", | |
label="π Input Code", | |
elem_classes=["code-box"], | |
value="""# Example: Function with syntax error | |
def calculate_average(numbers): | |
total = 0 | |
for num in numbers | |
total += num | |
return total / len(numbers) | |
# Test with empty list (will cause error) | |
result = calculate_average([]) | |
print(result)""" | |
) | |
with gr.Row(): | |
debug_btn = gr.Button( | |
"π§ Debug Code", | |
variant="primary", | |
size="lg" | |
) | |
clear_btn = gr.Button( | |
"ποΈ Clear", | |
variant="secondary" | |
) | |
with gr.Column(scale=1): | |
output = gr.Textbox( | |
lines=16, | |
label="β¨ Debug Results", | |
placeholder="Debug results will appear here...", | |
elem_classes=["code-box"] | |
) | |
# Examples section | |
gr.Markdown("### π Example Problems:") | |
example_codes = [ | |
# Syntax error example | |
["""def greet(name): | |
if name | |
print(f"Hello, {name}!") | |
else: | |
print("Hello, stranger!") | |
greet("Alice")"""], | |
# Logic error example | |
["""def find_maximum(numbers): | |
max_num = 0 # Bug: assumes all numbers are positive | |
for num in numbers: | |
if num > max_num: | |
max_num = num | |
return max_num | |
result = find_maximum([-5, -2, -8, -1]) | |
print(f"Maximum: {result}")"""], | |
# Runtime error example | |
["""def divide_list(numbers, divisor): | |
result = [] | |
for num in numbers: | |
result.append(num / divisor) | |
return result | |
# This will cause division by zero | |
data = [10, 20, 30] | |
divided = divide_list(data, 0) | |
print(divided)"""], | |
] | |
gr.Examples( | |
examples=example_codes, | |
inputs=code_input, | |
label="Click any example to load:" | |
) | |
# Event handlers | |
debug_btn.click( | |
fn=debug_code, | |
inputs=code_input, | |
outputs=output | |
) | |
clear_btn.click( | |
lambda: ("", ""), | |
outputs=[code_input, output] | |
) | |
# Initialize status on load | |
demo.load( | |
fn=initialize_debugger, | |
outputs=status_display | |
) | |
# Footer | |
gr.Markdown(""" | |
--- | |
**Model:** `Girinath11/aiml_code_debug_model` | **Fallback:** Rule-based analysis | |
**Tips for better results:** | |
β’ Include complete, runnable code snippets | |
β’ Add comments explaining expected behavior | |
β’ Include any error messages you're seeing | |
""") | |
return demo | |
if __name__ == "__main__": | |
try: | |
logger.info("π Starting Code Debugger application...") | |
demo = create_app() | |
# Launch the app | |
demo.launch( | |
share=True, | |
server_name="0.0.0.0", | |
server_port=7860, | |
show_error=True | |
) | |
except Exception as e: | |
logger.error(f"Failed to start application: {e}") | |
logger.error(f"Full traceback: {traceback.format_exc()}") | |
raise |