|
|
"""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_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: |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
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_dropdown = gr.Dropdown( |
|
|
choices=["Java", "Python", "Pharo"], label="Programming Language", value="Python" |
|
|
) |
|
|
|
|
|
|
|
|
categories_display = gr.Markdown(value=get_categories_for_language("Python")) |
|
|
|
|
|
|
|
|
language_dropdown.change( |
|
|
fn=update_categories, inputs=language_dropdown, outputs=categories_display |
|
|
) |
|
|
|
|
|
|
|
|
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_display = gr.HTML(label="Prediction Result") |
|
|
|
|
|
|
|
|
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], |
|
|
) |
|
|
|
|
|
|
|
|
clear_btn.click( |
|
|
fn=lambda: ("", "", "Python"), |
|
|
inputs=[], |
|
|
outputs=[text_input, class_name_input, language_dropdown], |
|
|
) |
|
|
|
|
|
|
|
|
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) |
|
|
|