Fonty02's picture
Update nygaardcodecommentclassification/api/frontend.py
3bab898 verified
"""Gradio Frontend Application.
This module provides a web-based user interface for the code comment classification API.
Users can input code comments and get real-time predictions through an interactive interface.
"""
import os
import gradio as gr
import requests
# API configuration for deploy
API_URL = os.getenv("API_URL", "https://se4ai2526-uniba-nygaard-nygaardcodecomment-backend.hf.space/")
def get_categories_for_language(language: str) -> str:
"""Get supported categories for a specific programming language.
Args:
language: The programming language
Returns:
Formatted string with supported categories
"""
categories = {
"Java": [
"summary: A brief description of the behavior of the code",
"Ownership: Describes the authors and ownership",
"Expand: Aims to describe the associated code",
"usage: Describes how to use the code",
"Pointer: Points to related code or resources",
"deprecation: Indicates deprecated code",
"rational: Explains the reasoning behind the implementation",
],
"Python": [
"Usage: Describes usage of the code",
"Parameters: Documents function/method parameters",
"DevelopmentNotes: Contains notes for developers",
"Expand: Provides detailed explanations",
"Summary: Summarizes the functionality",
],
"Pharo": [
"Keyimplementationpoints: Highlights key implementation details",
"Example: Provides code examples",
"Responsibilities: Describes object responsibilities",
"Intent: Explains the intent or purpose",
"Keymessages: Documents key messages or methods",
"Collaborators: Lists collaborating objects/classes",
],
}
lang_categories = categories.get(language, [])
if lang_categories:
return f"**Supported Categories for {language}:**\n" + "\n".join(
f"- {cat}" for cat in lang_categories
)
return "**Supported Categories:** Not available"
def predict_gradio(text: str, class_name: str, language: str) -> str:
"""Gradio interface function for single text prediction.
Args:
text: The code comment to classify
class_name: The name of the class containing the comment
language: The programming language
Returns:
Formatted HTML string with prediction results
"""
if not text.strip():
return """
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
⚠️ Please enter a code comment to classify.
</div>
"""
if not class_name.strip():
return """
<div style="background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
⚠️ Please enter the class name containing the comment.
</div>
"""
try:
# Call the API with separate texts and class_names
# Backend will combine them as "comment | class_name" before passing to the model
response = requests.post(
f"{API_URL}/predict",
json={
"texts": [text],
"class_names": [class_name],
"language": language.lower(),
"model_type": "catboost",
},
timeout=30,
)
if response.status_code == 200:
data = response.json()
results = data.get("data", {}).get("results", [])
if results and len(results) > 0:
labels = results[0].get("labels", [])
if labels:
labels_html = "".join(
[
f'<span style="background: #4CAF50; color: white; padding: 4px 8px; '
f'margin: 2px; border-radius: 12px; font-size: 14px; display: inline-block;">'
f"🏷️ {label}</span>"
for label in labels
]
)
return f"""
<div style="background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
border-radius: 15px; padding: 20px; margin: 10px 0;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
<h3 style="color: white; margin: 0 0 15px 0; text-align: center;">
βœ… Prediction Successful
</h3>
<div style="text-align: center;">
{labels_html}
</div>
</div>
"""
return """
<div style="background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
πŸ“Š No labels predicted (below threshold)
</div>
"""
return """
<div style="background: linear-gradient(135deg, #9c27b0 0%, #7b1fa2 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
πŸ” No prediction results available
</div>
"""
else:
return f"""
<div style="background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
❌ API Error: {response.status_code}<br>
<small style="font-weight: normal;">{response.text}</small>
</div>
"""
except requests.exceptions.ConnectionError:
return f"""
<div style="background: linear-gradient(135deg, #607d8b 0%, #455a64 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
🌐 Connection Error<br>
<small style="font-weight: normal;">Cannot connect to API at {API_URL}</small>
</div>
"""
except requests.exceptions.Timeout:
return """
<div style="background: linear-gradient(135deg, #ff5722 0%, #d84315 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
⏱️ Timeout Error<br>
<small style="font-weight: normal;">The request took too long</small>
</div>
"""
except Exception as e:
return f"""
<div style="background: linear-gradient(135deg, #9e9e9e 0%, #757575 100%);
border-radius: 10px; padding: 20px; margin: 10px 0;
color: white; text-align: center; font-weight: bold;">
⚠️ Unexpected Error<br>
<small style="font-weight: normal;">{str(e)}</small>
</div>
"""
def update_categories(language: str) -> str:
"""Update the categories display when language changes.
Args:
language: The selected programming language
Returns:
Updated description text with categories
"""
return get_categories_for_language(language)
# Create Gradio interface with dynamic categories
with gr.Blocks(title="πŸ” Nygaard Code Comment Classifier") as gradio_app:
gr.Markdown("# πŸ” Nygaard Code Comment Classifier")
gr.Markdown("Classify code comments into multiple categories using machine learning.")
# Language selector
language_dropdown = gr.Dropdown(
choices=["Java", "Python", "Pharo"], label="Programming Language", value="Python"
)
# Dynamic categories display
categories_display = gr.Markdown(value=get_categories_for_language("Python"))
# Connect language change to categories update
language_dropdown.change(
fn=update_categories, inputs=language_dropdown, outputs=categories_display
)
# Input components
with gr.Row():
text_input = gr.Textbox(
label="Code Comment", placeholder="Enter your code comment here...", lines=5
)
with gr.Row():
class_name_input = gr.Textbox(
label="Class Name", placeholder="Enter the class name...", lines=1
)
# Output
output_display = gr.HTML(label="Prediction Result")
# Buttons
with gr.Row():
clear_btn = gr.Button("Clear", variant="secondary")
submit_btn = gr.Button("Submit", variant="primary")
gr.Examples(
examples=[
["@deprecated Use newMethod() instead", "Java"],
["This method calculates the factorial of a number", "Python"],
["Returns the sum of all elements in the collection", "Pharo"],
],
inputs=[text_input, language_dropdown],
)
# Connect clear button to reset inputs
clear_btn.click(
fn=lambda: ("", "", "Python"),
inputs=[],
outputs=[text_input, class_name_input, language_dropdown],
)
# Connect submit button to prediction function
submit_btn.click(
fn=predict_gradio,
inputs=[text_input, class_name_input, language_dropdown],
outputs=output_display,
)
if __name__ == "__main__":
gradio_app.launch(server_name="0.0.0.0", server_port=9001)