Spaces:
Sleeping
Sleeping
| import requests | |
| from datetime import datetime, timedelta | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from collections import defaultdict | |
| import pathlib | |
| import textwrap | |
| import json | |
| from tqdm import tqdm | |
| import openai | |
| # Assuming secrets is a module or a dictionary containing secrets | |
| from streamlit import secrets | |
| # Constants | |
| GITHUB_API = "https://api.github.com" | |
| # No default TOKEN assignment here, we will handle it dynamically | |
| # Replace with your actual OpenAI API key | |
| openai.api_key = secrets['OPEN_AI_TOKEN'] | |
| # Function to update headers with a new token | |
| def get_headers(updated_token=None): | |
| # Use the provided token or fallback to the existing secret token | |
| token = updated_token if updated_token!="" else secrets['GITHUB_API_TOKEN'] | |
| return { | |
| "Authorization": f"token {token}", | |
| "Accept": "application/vnd.github.v3+json" | |
| } | |
| # Example of refactored function to accept an optional token parameter | |
| def get_contributors(repo, updated_token=None): | |
| headers = get_headers(updated_token) | |
| url = f"{GITHUB_API}/repos/{repo}/contributors" | |
| response = requests.get(url, headers=headers) | |
| return [contributor['login'] for contributor in response.json()] | |
| # Function to get repository branches | |
| def get_repo_branches(repo_name, updated_token=None): | |
| """ | |
| Fetch and return a list of branches from a GitHub repository. | |
| Parameters: | |
| - repo_name: str - The full name of the repository (e.g., "owner/repo"). | |
| - updated_token: str - Optional. A GitHub token for authentication. | |
| Returns: | |
| - A list of branch names (str) of the specified repository. | |
| """ | |
| headers = get_headers(updated_token) | |
| url = f"{GITHUB_API}/repos/{repo_name}/branches" | |
| try: | |
| response = requests.get(url, headers=headers) | |
| response.raise_for_status() # Raises an HTTPError if the response status code is 4XX or 5XX | |
| branches = [branch['name'] for branch in response.json()] | |
| return branches | |
| except requests.exceptions.RequestException as e: | |
| print(f"Failed to fetch branches: {e}") | |
| return [] # Return an empty list in case of failure | |
| # Function to calculate the start date based on the period | |
| def get_start_date(period): | |
| if period == "month": | |
| return datetime.now() - timedelta(days=30) | |
| elif period == "3 months": | |
| return datetime.now() - timedelta(days=30*3) | |
| elif period == "6 months": | |
| return datetime.now() - timedelta(days=30*6) | |
| elif period == "year": | |
| return datetime.now() - timedelta(days=365) | |
| else: | |
| raise ValueError("Invalid period specified") | |
| def extract_commit_summary(commit_data): | |
| # Assuming commit_data is a dict containing commit information as fetched from GitHub's API | |
| commit_details = commit_data.get('commit', {}) | |
| author_info = commit_details.get('author', {}) | |
| files_info = commit_data.get('files', []) # Assuming this is where you get files information | |
| commit_summary = { | |
| 'message': commit_details.get('message', ''), | |
| 'author': author_info.get('name', ''), | |
| 'date': author_info.get('date', ''), # Include commit date | |
| } | |
| # 'file_patches': [ | |
| # {'filename': file.get('filename', ''), 'patch': file.get('patch', '')} | |
| # for file in files_info if 'patch' in file | |
| # ], | |
| # 'stats': { | |
| # 'additions': commit_details.get('stats', {}).get('additions', 0), | |
| # 'deletions': commit_details.get('stats', {}).get('deletions', 0), | |
| # 'total': commit_details.get('stats', {}).get('total', 0) | |
| # } | |
| return commit_summary | |
| # Adjusted function to get commit files and stats | |
| def get_commit_files_and_stats(commit_url, updated_token=None): | |
| headers = get_headers(updated_token) | |
| response = requests.get(commit_url, headers=headers) | |
| commit_data = response.json() | |
| files_info = [] | |
| if 'files' in commit_data: | |
| for file in commit_data['files']: | |
| files_info.append({ | |
| 'filename': file['filename'], | |
| 'status': file['status'], | |
| 'additions': file['additions'], | |
| 'deletions': file['deletions'], | |
| 'changes': file['changes'], | |
| 'patch': file.get('patch') # Use get to avoid KeyError if 'patch' does not exist | |
| }) | |
| stats_info = commit_data.get('stats', {}) | |
| author_name = commit_data['commit']['author']['name'] | |
| commit_message = commit_data['commit']['message'] | |
| return { | |
| 'author_name': author_name, | |
| 'commit_message': commit_message, | |
| 'files_info': files_info, | |
| 'stats_info': stats_info | |
| } | |
| # Function to fetch commits by a contributor in a given period | |
| def get_contributor_commits(repo_name, contributor, period,branches, updated_token=None): | |
| """ | |
| Fetch all commits made by a specific contributor within a specified period for a given repository. | |
| Parameters: | |
| - repo_name: str - The full name of the repository (e.g., "owner/repo"). | |
| - contributor: str - The GitHub username of the contributor. | |
| - period: str - The period for which to fetch commits ("month", "3 months", "6 months", "year"). | |
| - updated_token: str - Optional. A GitHub token for authentication. | |
| Returns: | |
| - A list of commits made by the specified contributor in the given period. | |
| """ | |
| print((repo_name, contributor, period,branches)) | |
| headers = get_headers(updated_token) | |
| start_date = get_start_date(period) | |
| commits = [] | |
| try: | |
| # Fetch commits for each branch | |
| for branch in branches: | |
| commits_url = f"{GITHUB_API}/repos/{repo_name}/commits" | |
| params = { | |
| "sha": branch, | |
| "since": start_date.isoformat(), | |
| "author": contributor | |
| } | |
| commits_response = requests.get(commits_url, headers=headers, params=params) | |
| commits_response.raise_for_status() | |
| branch_commits = commits_response.json() | |
| print("branch_commits") | |
| print(branch_commits) | |
| commits.extend(branch_commits) | |
| except requests.exceptions.RequestException as e: | |
| print(f"Failed to fetch commits: {e}") | |
| print("commits") | |
| all_commits = [] | |
| for commit in commits: | |
| commit_details = get_commit_files_and_stats(commit['url'], updated_token) | |
| commit['commit_files_stats'] = commit_details | |
| all_commits.append(commit) | |
| print(commits) | |
| summarized_commits = [extract_commit_summary(commit) for commit in all_commits] | |
| return summarized_commits | |
| def chat_complete(message, model="gpt-3.5-turbo-0125"): | |
| response = openai.ChatCompletion.create( | |
| model=model, | |
| messages=[ | |
| {"role": "user", "content": str(message)} | |
| ] | |
| ) | |
| return response.choices[0].message['content'] if response.choices else "response not available" | |
| def openai_get_AI_summary(commit_info): | |
| prompt_prefix = "Summarize this git commit given the following context in JSON:\n" | |
| prompt_suffix = "\n---\nPut the summary in the following JSON schema: {...}" | |
| # Construct the message with commit_info | |
| message = prompt_prefix + json.dumps(commit_info, indent=2) + prompt_suffix | |
| # Fetch the summary from OpenAI | |
| response = chat_complete(message) | |
| return response | |
| def process_commits_with_openai_summaries(commits): | |
| summaries = [] | |
| for commit in tqdm(commits, desc='Generating AI summaries'): | |
| # Assuming each commit includes 'commit_files_stats' with detailed info | |
| summary = openai_get_AI_summary(str(commit)) | |
| # commit['ai_summary'] = summary | |
| summaries.append(summary) | |
| return summaries | |
| def generate_contributor_report_prompt(summaries): | |
| """ | |
| Construct a prompt for generating a report on a contributor's achievements, skills, and areas of improvement. | |
| Parameters: | |
| - summaries: list of str - Summaries of the contributor's commits. | |
| Returns: | |
| - str: A prompt for the OpenAI model. | |
| """ | |
| summaries_joined = "\n".join([f"- {summary}" for summary in summaries]) | |
| if len(summaries_joined) > 40000: | |
| summaries_joined = summaries_joined[:40000] | |
| prompt = f""" | |
| Given the following list of commit summaries by a software developer, create a comprehensive report in markdown format outlining the developer's achievements, skills demonstrated through these commits, and areas for improvement. Use headings for each section. | |
| ## Commit Summaries | |
| {summaries_joined} | |
| ## Report structer | |
| ### Achievements | |
| - Analyze the summaries to highlight significant contributions and achievements.(1) | |
| --- | |
| ### Achievements | |
| - Analyze the summaries to highlight significant contributions and achievements.(2) | |
| --- | |
| ### Achievements | |
| - Analyze problems overcomed.(3) | |
| --- | |
| ### Skills Demonstrated | |
| - Based on the commit summaries, list the technical skills demonstrated by the developer. | |
| --- | |
| ### Skills Demonstrated | |
| - Based on the commit summaries, list the soft skills demonstrated by the developer. | |
| --- | |
| ### Skills Demonstrated | |
| - Based on the commit summaries, list the technical and soft skills demonstrated by the developer. | |
| ### Areas for Improvement | |
| /- Suggest areas where the developer could improve based on patterns or gaps identified in the commit summaries.(1) | |
| /- Suggest areas where the developer could improve based on patterns or gaps identified in the commit summaries.(2) | |
| /- Suggest areas where the developer could improve based on patterns or gaps identified in the commit summaries.(3) | |
| Please ensure the report is well-organized, respets the structure above, and provides clear insights into the developer's contributions and growth areas. | |
| use a lot of --- seperators to seperate sections and bullet points to have each section short | |
| and / to show continued informations | |
| """ | |
| markdown = chat_complete(prompt) | |
| return markdown | |