File size: 9,875 Bytes
79c84e2 1a45883 79c84e2 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 3bab898 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 79c84e2 e4b9b02 |
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 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
"""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)
|