Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -15,6 +15,7 @@ import requests
|
|
| 15 |
import json
|
| 16 |
import re
|
| 17 |
from datetime import datetime, timedelta
|
|
|
|
| 18 |
|
| 19 |
# Load environment variables
|
| 20 |
load_dotenv()
|
|
@@ -433,30 +434,59 @@ def perform_stack_search(query, tag, sort_by):
|
|
| 433 |
except Exception as e:
|
| 434 |
return f"Error searching Stack Overflow: {str(e)}"
|
| 435 |
|
| 436 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
|
| 438 |
current_session_id = gr.State(None)
|
| 439 |
-
|
|
|
|
| 440 |
gr.HTML("""
|
| 441 |
<div class="header">
|
| 442 |
<div class="header-title">Tech-Vision</div>
|
| 443 |
-
<div class="header-subtitle">
|
| 444 |
</div>
|
| 445 |
""")
|
|
|
|
| 446 |
with gr.Row(elem_classes="container"):
|
| 447 |
with gr.Column(scale=1, min_width=300):
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
model_dropdown = gr.Dropdown(
|
| 452 |
choices=["llama3-70b-8192", "llama3-8b-8192", "mixtral-8x7b-32768", "gemma-7b-it"],
|
| 453 |
value="llama3-70b-8192",
|
| 454 |
label="Select Groq Model"
|
| 455 |
)
|
| 456 |
|
| 457 |
-
#
|
| 458 |
gr.Markdown("### Developer Tools", elem_classes="tool-title")
|
| 459 |
-
with gr.
|
| 460 |
with gr.Tabs():
|
| 461 |
with gr.TabItem("GitHub Search"):
|
| 462 |
repo_query = gr.Textbox(label="Search Query", placeholder="Enter keywords to search for repositories")
|
|
@@ -503,11 +533,10 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
|
|
| 503 |
|
| 504 |
with gr.Column(scale=2, min_width=600):
|
| 505 |
with gr.Tabs():
|
| 506 |
-
with gr.TabItem("
|
| 507 |
-
with gr.Column(elem_classes="
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
stats_display = gr.Markdown("No PDF uploaded yet", elem_classes="stats-box")
|
| 511 |
|
| 512 |
with gr.TabItem("GitHub Results"):
|
| 513 |
repo_results = gr.Markdown("Search for repositories to see results here")
|
|
@@ -526,15 +555,28 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
|
|
| 526 |
send_btn = gr.Button("Send", scale=1)
|
| 527 |
clear_btn = gr.Button("Clear Conversation")
|
| 528 |
|
| 529 |
-
#
|
| 530 |
upload_button.click(
|
| 531 |
-
|
| 532 |
-
inputs=[
|
| 533 |
-
outputs=[current_session_id,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
).then(
|
| 535 |
-
|
| 536 |
-
inputs=[
|
| 537 |
-
outputs=[
|
| 538 |
)
|
| 539 |
|
| 540 |
msg.submit(
|
|
@@ -589,4 +631,85 @@ gr.HTML("""
|
|
| 589 |
|
| 590 |
# Launch the app
|
| 591 |
if __name__ == "__main__":
|
| 592 |
-
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
import json
|
| 16 |
import re
|
| 17 |
from datetime import datetime, timedelta
|
| 18 |
+
from pathlib import Path
|
| 19 |
|
| 20 |
# Load environment variables
|
| 21 |
load_dotenv()
|
|
|
|
| 434 |
except Exception as e:
|
| 435 |
return f"Error searching Stack Overflow: {str(e)}"
|
| 436 |
|
| 437 |
+
# Modify the file input and processing section
|
| 438 |
+
def process_code_file(file_obj):
|
| 439 |
+
"""Process uploaded code files"""
|
| 440 |
+
if file_obj is None:
|
| 441 |
+
return None, "No file uploaded", {}
|
| 442 |
+
try:
|
| 443 |
+
content = file_obj.read().decode('utf-8')
|
| 444 |
+
file_extension = Path(file_obj.name).suffix.lower()
|
| 445 |
+
language = detect_language(file_extension)
|
| 446 |
+
|
| 447 |
+
# Calculate metrics
|
| 448 |
+
metrics = calculate_complexity_metrics(content, language)
|
| 449 |
+
|
| 450 |
+
return str(uuid.uuid4()), f"β
Successfully analyzed {file_obj.name}", metrics
|
| 451 |
+
except Exception as e:
|
| 452 |
+
return None, f"Error processing file: {str(e)}", {}
|
| 453 |
+
|
| 454 |
+
# Update the Gradio interface
|
| 455 |
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
|
| 456 |
current_session_id = gr.State(None)
|
| 457 |
+
code_state = gr.State({})
|
| 458 |
+
|
| 459 |
gr.HTML("""
|
| 460 |
<div class="header">
|
| 461 |
<div class="header-title">Tech-Vision</div>
|
| 462 |
+
<div class="header-subtitle">Advanced Code Analysis System</div>
|
| 463 |
</div>
|
| 464 |
""")
|
| 465 |
+
|
| 466 |
with gr.Row(elem_classes="container"):
|
| 467 |
with gr.Column(scale=1, min_width=300):
|
| 468 |
+
file_input = gr.File(
|
| 469 |
+
label="Upload Code File",
|
| 470 |
+
file_types=[
|
| 471 |
+
".py", ".js", ".java", ".cpp", ".c", ".cs", ".php",
|
| 472 |
+
".rb", ".go", ".rs", ".swift", ".kt", ".ts", ".html",
|
| 473 |
+
".css", ".sql", ".r", ".m", ".h", ".hpp", ".jsx",
|
| 474 |
+
".tsx", ".vue", ".scala", ".pl", ".sh", ".bash",
|
| 475 |
+
".ps1", ".yaml", ".yml", ".json", ".xml", ".toml", ".ini"
|
| 476 |
+
],
|
| 477 |
+
type="binary"
|
| 478 |
+
)
|
| 479 |
+
upload_button = gr.Button("Analyze Code", variant="primary")
|
| 480 |
+
file_status = gr.Markdown("No file uploaded yet")
|
| 481 |
model_dropdown = gr.Dropdown(
|
| 482 |
choices=["llama3-70b-8192", "llama3-8b-8192", "mixtral-8x7b-32768", "gemma-7b-it"],
|
| 483 |
value="llama3-70b-8192",
|
| 484 |
label="Select Groq Model"
|
| 485 |
)
|
| 486 |
|
| 487 |
+
# Developer Tools Section
|
| 488 |
gr.Markdown("### Developer Tools", elem_classes="tool-title")
|
| 489 |
+
with gr.Group(elem_classes="tool-container"): # Replace Box with Group
|
| 490 |
with gr.Tabs():
|
| 491 |
with gr.TabItem("GitHub Search"):
|
| 492 |
repo_query = gr.Textbox(label="Search Query", placeholder="Enter keywords to search for repositories")
|
|
|
|
| 533 |
|
| 534 |
with gr.Column(scale=2, min_width=600):
|
| 535 |
with gr.Tabs():
|
| 536 |
+
with gr.TabItem("Code Analysis"):
|
| 537 |
+
with gr.Column(elem_classes="code-viewer-container"):
|
| 538 |
+
code_metrics = gr.Markdown("No code analyzed yet", elem_classes="stats-box")
|
| 539 |
+
code_recommendations = gr.Markdown("", elem_classes="recommendations-box")
|
|
|
|
| 540 |
|
| 541 |
with gr.TabItem("GitHub Results"):
|
| 542 |
repo_results = gr.Markdown("Search for repositories to see results here")
|
|
|
|
| 555 |
send_btn = gr.Button("Send", scale=1)
|
| 556 |
clear_btn = gr.Button("Clear Conversation")
|
| 557 |
|
| 558 |
+
# Update event handlers
|
| 559 |
upload_button.click(
|
| 560 |
+
process_code_file,
|
| 561 |
+
inputs=[file_input],
|
| 562 |
+
outputs=[current_session_id, file_status, code_state]
|
| 563 |
+
).then(
|
| 564 |
+
lambda state: (
|
| 565 |
+
f"### Code Analysis Results\n\n"
|
| 566 |
+
f"**Language:** {state.get('language', 'Unknown')}\n"
|
| 567 |
+
f"**Total Lines:** {state.get('total_lines', 0)}\n"
|
| 568 |
+
f"**Code Lines:** {state.get('code_lines', 0)}\n"
|
| 569 |
+
f"**Comment Lines:** {state.get('comments', 0)}\n"
|
| 570 |
+
f"**Functions:** {state.get('functions', 0)}\n"
|
| 571 |
+
f"**Classes:** {state.get('classes', 0)}\n"
|
| 572 |
+
f"**Complexity Score:** {state.get('cyclomatic_complexity', 0)}\n"
|
| 573 |
+
),
|
| 574 |
+
inputs=[code_state],
|
| 575 |
+
outputs=[code_metrics]
|
| 576 |
).then(
|
| 577 |
+
lambda state: generate_recommendations(state),
|
| 578 |
+
inputs=[code_state],
|
| 579 |
+
outputs=[code_recommendations]
|
| 580 |
)
|
| 581 |
|
| 582 |
msg.submit(
|
|
|
|
| 631 |
|
| 632 |
# Launch the app
|
| 633 |
if __name__ == "__main__":
|
| 634 |
+
demo.launch()
|
| 635 |
+
|
| 636 |
+
# Add new helper functions
|
| 637 |
+
def detect_language(extension):
|
| 638 |
+
"""Map file extensions to programming languages"""
|
| 639 |
+
extension_map = {
|
| 640 |
+
".py": "Python",
|
| 641 |
+
".js": "JavaScript",
|
| 642 |
+
".java": "Java",
|
| 643 |
+
".cpp": "C++",
|
| 644 |
+
".c": "C",
|
| 645 |
+
".cs": "C#",
|
| 646 |
+
".php": "PHP",
|
| 647 |
+
".rb": "Ruby",
|
| 648 |
+
".go": "Go",
|
| 649 |
+
".rs": "Rust",
|
| 650 |
+
".swift": "Swift",
|
| 651 |
+
".kt": "Kotlin",
|
| 652 |
+
".ts": "TypeScript",
|
| 653 |
+
".html": "HTML",
|
| 654 |
+
".css": "CSS",
|
| 655 |
+
".sql": "SQL",
|
| 656 |
+
".r": "R",
|
| 657 |
+
".scala": "Scala",
|
| 658 |
+
".pl": "Perl",
|
| 659 |
+
".sh": "Shell",
|
| 660 |
+
".yaml": "YAML",
|
| 661 |
+
".yml": "YAML",
|
| 662 |
+
".json": "JSON",
|
| 663 |
+
".xml": "XML",
|
| 664 |
+
".jsx": "React JSX",
|
| 665 |
+
".tsx": "React TSX",
|
| 666 |
+
".vue": "Vue",
|
| 667 |
+
}
|
| 668 |
+
return extension_map.get(extension.lower(), "Unknown")
|
| 669 |
+
|
| 670 |
+
def calculate_complexity_metrics(content, language):
|
| 671 |
+
"""Calculate code complexity metrics"""
|
| 672 |
+
lines = content.split('\n')
|
| 673 |
+
total_lines = len(lines)
|
| 674 |
+
blank_lines = len([line for line in lines if not line.strip()])
|
| 675 |
+
code_lines = total_lines - blank_lines
|
| 676 |
+
|
| 677 |
+
# Get language patterns
|
| 678 |
+
patterns = LANGUAGE_PATTERNS.get(language.lower(), LANGUAGE_PATTERNS.get("python"))
|
| 679 |
+
|
| 680 |
+
# Calculate metrics using patterns
|
| 681 |
+
metrics = {
|
| 682 |
+
"language": language,
|
| 683 |
+
"total_lines": total_lines,
|
| 684 |
+
"code_lines": code_lines,
|
| 685 |
+
"blank_lines": blank_lines,
|
| 686 |
+
"functions": len(re.findall(patterns["function"], content, re.MULTILINE)) if patterns else 0,
|
| 687 |
+
"classes": len(re.findall(patterns["class"], content, re.MULTILINE)) if patterns else 0,
|
| 688 |
+
"imports": len(re.findall(patterns["import"], content, re.MULTILINE)) if patterns else 0,
|
| 689 |
+
"comments": len(re.findall(patterns["comment"], content, re.MULTILINE)) if patterns else 0,
|
| 690 |
+
"conditionals": len(re.findall(patterns["conditional"], content, re.MULTILINE)) if patterns else 0,
|
| 691 |
+
"loops": len(re.findall(patterns["loop"], content, re.MULTILINE)) if patterns else 0,
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
# Calculate cyclomatic complexity
|
| 695 |
+
metrics["cyclomatic_complexity"] = 1 + metrics["conditionals"] + metrics["loops"]
|
| 696 |
+
|
| 697 |
+
return metrics
|
| 698 |
+
|
| 699 |
+
def generate_recommendations(metrics):
|
| 700 |
+
"""Generate code quality recommendations based on metrics"""
|
| 701 |
+
recommendations = []
|
| 702 |
+
|
| 703 |
+
if metrics.get("cyclomatic_complexity", 0) > 10:
|
| 704 |
+
recommendations.append("π High cyclomatic complexity detected. Consider breaking down complex functions.")
|
| 705 |
+
|
| 706 |
+
if metrics.get("code_lines", 0) > 300:
|
| 707 |
+
recommendations.append("π File is quite large. Consider splitting it into multiple modules.")
|
| 708 |
+
|
| 709 |
+
if metrics.get("functions", 0) > 10:
|
| 710 |
+
recommendations.append("π§ Large number of functions. Consider grouping related functions into classes.")
|
| 711 |
+
|
| 712 |
+
if metrics.get("comments", 0) / max(metrics.get("code_lines", 1), 1) < 0.1:
|
| 713 |
+
recommendations.append("π Low comment ratio. Consider adding more documentation.")
|
| 714 |
+
|
| 715 |
+
return "### Recommendations\n\n" + "\n\n".join(recommendations) if recommendations else ""
|