chelouche9 commited on
Commit
e88040b
Β·
1 Parent(s): 0e66a86

first commit

Browse files
Files changed (3) hide show
  1. .gitignore +2 -0
  2. app.py +140 -0
  3. requirements.txt +58 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .venv
2
+ .env
app.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import requests
4
+ import git
5
+ import tempfile
6
+ import shutil
7
+ from openai import OpenAI
8
+ import dotenv
9
+
10
+ def generate_prompt(repo_url, role, repo_data, focus_areas=""):
11
+ """Generates the AI analysis prompt with repo details."""
12
+ return f"""
13
+ You are an AI expert in evaluating software engineering candidates based on their GitHub repositories. Your goal is to assess the quality, organization, and best practices of the submitted code repository. Below is the candidate's information:
14
+
15
+ ### Candidate Information:
16
+ - **Role Applied For**: {role}
17
+ - **GitHub Repository URL**: {repo_url}
18
+ - **Optional Key Focus Areas**: {focus_areas}
19
+
20
+ ### Repository Analysis:
21
+ You are provided with the repository's cloned structure and its contents. Analyze the following aspects:
22
+ {repo_data}
23
+
24
+ 1. **Code Organization & Architecture** (20 points)
25
+ 2. **Code Quality & Best Practices** (25 points)
26
+ 3. **Language Proficiency & Best Practices** (20 points)
27
+ 4. **Use of Frameworks & Libraries** (15 points)
28
+ 5. **Testing & Documentation** (20 points)
29
+
30
+ ### **Final Score Calculation**
31
+ - Score the repository **out of 100** based on the criteria above.
32
+ - Justify the **score** by explaining the candidate’s strengths and weaknesses.
33
+
34
+ ### **Expected Output:**
35
+ - **Strengths**: What is done well?
36
+ - **Weaknesses**: What needs improvement?
37
+ - **Final Score (0-100)**: Provide a numeric score with an explanation.
38
+ - **Summary**: Briefly summarize the candidate’s proficiency based on this analysis.
39
+ """
40
+
41
+ # Load environment variables
42
+ dotenv.load_dotenv()
43
+ client = OpenAI()
44
+
45
+ PASSWORD = os.getenv("PASSWORD", "defaultpass")
46
+
47
+ def authenticate(password):
48
+ """Check if the entered password is correct."""
49
+ if password != PASSWORD:
50
+ return "❌ Incorrect password! Access denied.", None
51
+ return None, "βœ… Access granted! You may proceed."
52
+
53
+ def analyze_repo(repo_url, role, focus_areas, password):
54
+ auth_error, auth_success = authenticate(password)
55
+ if auth_error:
56
+ return auth_error, gr.update(visible=False) # If incorrect password, return error
57
+
58
+ """Clone and analyze a GitHub repository with a loading state."""
59
+ if not repo_url.startswith("https://github.com/"):
60
+ return "❌ Invalid GitHub URL!", gr.update(visible=False)
61
+
62
+ # Extract repo details
63
+ repo_name = repo_url.split("/")[-1]
64
+ temp_dir = tempfile.mkdtemp()
65
+
66
+ try:
67
+ progress = gr.update(value="πŸ”„ Cloning repository...", visible=True)
68
+
69
+ # Clone the repo
70
+ repo_path = os.path.join(temp_dir, repo_name)
71
+ git.Repo.clone_from(repo_url, repo_path)
72
+
73
+ progress = gr.update(value="πŸ“‚ Analyzing repository structure...", visible=True)
74
+
75
+ # Gather repository file structure and contents
76
+ repo_data = ""
77
+ file_count = 0 # Initialize file counter
78
+
79
+ for root, _, filenames in os.walk(repo_path):
80
+ for file in filenames:
81
+ file_count += 1 # Increment file counter
82
+ file_path = os.path.join(root, file)
83
+
84
+ try:
85
+ with open(file_path, "r", encoding="utf-8") as f:
86
+ file_content = f.read()
87
+ repo_data += f"\n**File {file_count}:** {file_path.replace(repo_path, '')}\n```\n{file_content[:1000]}\n```\n"
88
+ except Exception:
89
+ repo_data += f"\n**File {file_count}:** {file_path.replace(repo_path, '')} (⚠️ Cannot read binary file)\n"
90
+
91
+ progress = gr.update(value="πŸ€– Sending data to AI for evaluation...", visible=True)
92
+
93
+ # AI-based evaluation
94
+ evaluation = f"βœ… **Evaluation for Role: {role}**\n\n"
95
+ evaluation += f"πŸ“‚ Repository `{repo_name}` has `{file_count}` files.\n"
96
+ evaluation += f"πŸ’‘ Key focus areas: {focus_areas}\n\n"
97
+ evaluation += "**πŸ” Code Quality Analysis:**\n"
98
+
99
+ completion = client.chat.completions.create(
100
+ model="o1",
101
+ messages=[
102
+ {
103
+ "role": "user",
104
+ "content": generate_prompt(repo_url, role, repo_data, focus_areas)
105
+ }
106
+ ]
107
+ )
108
+
109
+ evaluation += "\n" + completion.choices[0].message.content
110
+
111
+ progress = gr.update(value="βœ… Analysis complete!", visible=True)
112
+ return evaluation, progress
113
+
114
+ except Exception as e:
115
+ return f"❌ Error analyzing repository: {str(e)}", gr.update(visible=False)
116
+
117
+ finally:
118
+ shutil.rmtree(temp_dir) # Cleanup
119
+
120
+ # Gradio UI
121
+ with gr.Blocks() as app:
122
+ gr.Markdown("# πŸ› οΈ AI-Powered Candidate Evaluation System")
123
+
124
+ password = gr.Textbox(label="Enter Password")
125
+ role = gr.Textbox(label="Role the Candidate is Applying For")
126
+ repo_url = gr.Textbox(label="GitHub Repository URL")
127
+ focus_areas = gr.Textbox(label="Optional Focus Areas (e.g., Clean Code, Performance)")
128
+
129
+ output = gr.Markdown()
130
+ progress = gr.Markdown(visible=False) # Loader
131
+
132
+ submit_btn = gr.Button("πŸ” Evaluate")
133
+
134
+ submit_btn.click(
135
+ fn=analyze_repo,
136
+ inputs=[repo_url, role, focus_areas, password],
137
+ outputs=[output, progress]
138
+ )
139
+
140
+ app.launch()
requirements.txt ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ annotated-types==0.7.0
3
+ anyio==4.8.0
4
+ certifi==2025.1.31
5
+ charset-normalizer==3.4.1
6
+ click==8.1.8
7
+ distro==1.9.0
8
+ fastapi==0.115.8
9
+ ffmpy==0.5.0
10
+ filelock==3.17.0
11
+ fsspec==2025.2.0
12
+ gitdb==4.0.12
13
+ GitPython==3.1.44
14
+ gradio==5.15.0
15
+ gradio_client==1.7.0
16
+ h11==0.14.0
17
+ httpcore==1.0.7
18
+ httpx==0.28.1
19
+ huggingface-hub==0.28.1
20
+ idna==3.10
21
+ Jinja2==3.1.5
22
+ jiter==0.8.2
23
+ markdown-it-py==3.0.0
24
+ MarkupSafe==2.1.5
25
+ mdurl==0.1.2
26
+ numpy==2.2.2
27
+ openai==1.61.1
28
+ orjson==3.10.15
29
+ packaging==24.2
30
+ pandas==2.2.3
31
+ pillow==11.1.0
32
+ pydantic==2.10.6
33
+ pydantic_core==2.27.2
34
+ pydub==0.25.1
35
+ Pygments==2.19.1
36
+ python-dateutil==2.9.0.post0
37
+ python-dotenv==1.0.1
38
+ python-multipart==0.0.20
39
+ pytz==2025.1
40
+ PyYAML==6.0.2
41
+ requests==2.32.3
42
+ rich==13.9.4
43
+ ruff==0.9.4
44
+ safehttpx==0.1.6
45
+ semantic-version==2.10.0
46
+ shellingham==1.5.4
47
+ six==1.17.0
48
+ smmap==5.0.2
49
+ sniffio==1.3.1
50
+ starlette==0.45.3
51
+ tomlkit==0.13.2
52
+ tqdm==4.67.1
53
+ typer==0.15.1
54
+ typing_extensions==4.12.2
55
+ tzdata==2025.1
56
+ urllib3==2.3.0
57
+ uvicorn==0.34.0
58
+ websockets==14.2