SanthoshKumar99/Github_Analysis
0
1import streamlit as st2import plotly.express as px3import plotly.graph_objects as go4import pandas as pd5import requests6import time7from pymongo import MongoClient8from datetime import datetime9import calendar10import os11 12# Constants and configuration13ACCESS_TOKEN = os.environ.get("GITHUB_TOKEN")14MONGODB_CONNECTION_STRING = os.environ.get("MONGODB_CONNECTION_STRING")15GITHUB_API_URL = 'https://api.github.com'16HEADERS = {17 'Authorization': f'token {ACCESS_TOKEN}',18 'Accept': 'application/vnd.github.v3+json'19}20 21# Initialize MongoDB client22client = MongoClient(MONGODB_CONNECTION_STRING)23db = client["github"]24collection = db["users"]25 26# Helper functions27def get_rate_limit():28 response = requests.get(f'{GITHUB_API_URL}/rate_limit', headers=HEADERS)29 return response.json()['resources']30 31def handle_rate_limit():32 rate_limit = get_rate_limit()33 remaining_requests = rate_limit['core']['remaining']34 reset_time = rate_limit['core']['reset']35 if remaining_requests == 0:36 sleep_time = reset_time - time.time() + 137 st.warning(f'Rate limit exceeded. Waiting for {sleep_time:.2f} seconds...')38 time.sleep(sleep_time)39 40def fetch_user_data(username):41 handle_rate_limit()42 response = requests.get(f'{GITHUB_API_URL}/users/{username}', headers=HEADERS)43 if response.status_code == 200:44 user_data = response.json()45 user_info = {46 'Login': user_data['login'],47 'Name': user_data.get('name', ''),48 'Bio': user_data.get('bio', ''),49 'Public Repositories': user_data['public_repos'],50 'Followers Count': user_data['followers'],51 'Following Count': user_data['following'],52 'Created At': user_data['created_at'],53 'Updated At': user_data['updated_at'],54 'Avatar URL': user_data['avatar_url'],55 'Profile URL': user_data['html_url'],56 'Total Commits': fetch_total_commits(username),57 'Languages': fetch_languages(username),58 'Starred Repositories': fetch_starred_repositories(username),59 'Subscriptions': fetch_subscriptions(username),60 'Organizations': fetch_organizations(username),61 'Followers List': fetch_followers(username),62 'Following List': fetch_following(username),63 'Contribution Calendar': fetch_contribution_calendar(username)64 }65 return user_info66 elif response.status_code == 404:67 return {"error": "User not found"}68 else:69 return None70 71def fetch_total_commits(username):72 handle_rate_limit()73 repos_response = requests.get(f'{GITHUB_API_URL}/users/{username}/repos', headers=HEADERS)74 if repos_response.status_code == 200:75 repos = repos_response.json()76 total_commits = 077 for repo in repos:78 commits_response = requests.get(repo['commits_url'].replace('{/sha}', ''), headers=HEADERS)79 if commits_response.status_code == 200:80 total_commits += len(commits_response.json())81 return total_commits82 return 083 84def fetch_languages(username):85 handle_rate_limit()86 repos_response = requests.get(f'{GITHUB_API_URL}/users/{username}/repos', headers=HEADERS)87 if repos_response.status_code == 200:88 repos = repos_response.json()89 languages = {}90 for repo in repos:91 languages_response = requests.get(repo['languages_url'], headers=HEADERS)92 if languages_response.status_code == 200:93 repo_languages = languages_response.json()94 for lang, bytes_count in repo_languages.items():95 languages[lang] = languages.get(lang, 0) + bytes_count96 return languages97 return {}98 99def fetch_starred_repositories(username):100 handle_rate_limit()101 response = requests.get(f'{GITHUB_API_URL}/users/{username}/starred', headers=HEADERS)102 if response.status_code == 200:103 return [repo['full_name'] for repo in response.json()]104 return []105 106def fetch_subscriptions(username):107 handle_rate_limit()108 response = requests.get(f'{GITHUB_API_URL}/users/{username}/subscriptions', headers=HEADERS)109 if response.status_code == 200:110 return [repo['full_name'] for repo in response.json()]111 return []112 113def fetch_organizations(username):114 handle_rate_limit()115 response = requests.get(f'{GITHUB_API_URL}/users/{username}/orgs', headers=HEADERS)116 if response.status_code == 200:117 return [org['login'] for org in response.json()]118 return []119 120def fetch_followers(username):121 handle_rate_limit()122 response = requests.get(f'{GITHUB_API_URL}/users/{username}/followers', headers=HEADERS)123 if response.status_code == 200:124 return [user['login'] for user in response.json()]125 return []126 127def fetch_following(username):128 handle_rate_limit()129 response = requests.get(f'{GITHUB_API_URL}/users/{username}/following', headers=HEADERS)130 if response.status_code == 200:131 return [user['login'] for user in response.json()]132 return []133 134def fetch_contribution_calendar(username):135 handle_rate_limit()136 today = datetime.now()137 one_year_ago = today.replace(year=today.year - 1)138 139 contributions = {}140 for repo in fetch_user_repos(username):141 commits = fetch_repo_commits(repo['full_name'], since=one_year_ago.isoformat())142 for commit in commits:143 date = commit['commit']['author']['date'][:10] # YYYY-MM-DD144 contributions[date] = contributions.get(date, 0) + 1145 146 return contributions147 148def fetch_user_repos(username):149 handle_rate_limit()150 response = requests.get(f'{GITHUB_API_URL}/users/{username}/repos', headers=HEADERS)151 if response.status_code == 200:152 return response.json()153 return []154 155def fetch_repo_commits(repo_full_name, since):156 handle_rate_limit()157 response = requests.get(f'{GITHUB_API_URL}/repos/{repo_full_name}/commits', 158 params={'since': since},159 headers=HEADERS)160 if response.status_code == 200:161 return response.json()162 return []163 164def fetch_data_from_db(username):165 return collection.find_one({"Login": username})166 167# Streamlit UI168st.set_page_config(page_title="GitHub User Dashboard", page_icon=":octocat:", layout="wide")169 170st.title("๐ GitHub User Dashboard")171 172col1, col2 = st.columns([2, 1])173 174with col1:175 username = st.text_input("Enter a GitHub username:")176 177with col2:178 data_source = st.selectbox("Choose data source:", ["GitHub API", "MongoDB"])179 180if st.button("Fetch Data"):181 if username:182 with st.spinner("Fetching data..."):183 if data_source == "GitHub API":184 user_data = fetch_user_data(username)185 if user_data:186 if 'error' in user_data:187 st.error(user_data['error'])188 else:189 collection.replace_one({"Login": username}, user_data, upsert=True)190 st.success("User data fetched and saved to MongoDB")191 else:192 user_data = fetch_data_from_db(username)193 if user_data:194 st.success("User data fetched from MongoDB")195 else:196 st.error("User data not found in MongoDB")197 198 if user_data and 'error' not in user_data:199 st.subheader(f"๐ Dashboard for {user_data['Login']}")200 201 col1, col2, col3 = st.columns([1, 2, 1])202 203 with col1:204 st.image(user_data['Avatar URL'], width=200)205 206 with col2:207 st.write(f"**Name:** {user_data['Name']}")208 st.write(f"**Bio:** {user_data['Bio']}")209 st.write(f"**Public Repositories:** {user_data['Public Repositories']}")210 st.write(f"**Followers:** {user_data['Followers Count']}")211 st.write(f"**Following:** {user_data['Following Count']}")212 213 with col3:214 st.write(f"**Joined:** {user_data['Created At'][:10]}")215 st.write(f"**Updated:** {user_data['Updated At'][:10]}")216 st.write(f"**Total Commits:** {user_data['Total Commits']}")217 st.write(f"**Organizations:** {', '.join(user_data['Organizations'])}")218 st.markdown(f"[View Profile]({user_data['Profile URL']})")219 220 # Language Distribution221 st.subheader("๐ Language Distribution")222 lang_df = pd.DataFrame(list(user_data['Languages'].items()), columns=['Language', 'Bytes'])223 lang_df = lang_df.sort_values('Bytes', ascending=False)224 225 fig = px.treemap(lang_df, path=['Language'], values='Bytes',226 title="Language Distribution (Treemap)")227 st.plotly_chart(fig, use_container_width=True)228 229 fig = px.pie(lang_df, names='Language', values='Bytes',230 title="Language Distribution (Pie Chart)")231 st.plotly_chart(fig, use_container_width=True)232 233 # Contribution Calendar234 st.subheader("๐
Contribution Calendar")235 contrib_df = pd.DataFrame(list(user_data['Contribution Calendar'].items()), 236 columns=['Date', 'Contributions'])237 contrib_df['Date'] = pd.to_datetime(contrib_df['Date'])238 contrib_df = contrib_df.sort_values('Date')239 240 fig = px.scatter(contrib_df, x='Date', y='Contributions', 241 title="Contribution Activity Over Time")242 fig.update_traces(marker=dict(size=10))243 st.plotly_chart(fig, use_container_width=True)244 245 # Heatmap of contributions246 contrib_df['Weekday'] = contrib_df['Date'].dt.weekday247 contrib_df['WeekNumber'] = contrib_df['Date'].dt.isocalendar().week248 pivot_df = contrib_df.pivot(index='Weekday', columns='WeekNumber', values='Contributions')249 250 fig = go.Figure(data=go.Heatmap(251 z=pivot_df.values,252 x=pivot_df.columns,253 y=[calendar.day_abbr[i] for i in range(7)],254 colorscale='Viridis'))255 256 fig.update_layout(257 title='Contribution Heatmap',258 xaxis_nticks=53,259 yaxis_nticks=7260 )261 st.plotly_chart(fig, use_container_width=True)262 263 # Followers and Following264 st.subheader("๐ฅ Network")265 col1, col2 = st.columns(2)266 267 with col1:268 st.write("**Top Followers:**")269 st.write(", ".join(user_data['Followers List'][:10]))270 271 with col2:272 st.write("**Top Following:**")273 st.write(", ".join(user_data['Following List'][:10]))274 275 # Starred Repositories276 st.subheader("โญ Starred Repositories")277 starred_repos = user_data['Starred Repositories']278 if starred_repos:279 for repo in starred_repos[:10]:280 st.write(f"- [{repo}](https://github.com/{repo})")281 if len(starred_repos) > 10:282 st.write(f"... and {len(starred_repos) - 10} more")283 else:284 st.write("No starred repositories.")285 286 # Subscriptions287 st.subheader("๐ฌ Subscriptions")288 subscriptions = user_data['Subscriptions']289 if subscriptions:290 for sub in subscriptions[:10]:291 st.write(f"- [{sub}](https://github.com/{sub})")292 if len(subscriptions) > 10:293 st.write(f"... and {len(subscriptions) - 10} more")294 else:295 st.write("No subscriptions.")296 297 else:298 st.warning("Please enter a GitHub username.")