-
Notifications
You must be signed in to change notification settings - Fork 70
(SR NO- 9) Enhance Dashboard and UI with Real-Time GitHub Data Metrics, optimized API Calls and enriched Github Stats Response #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
chandansgowda
merged 6 commits into
AOSSIE-Org:main
from
SharkyBytes:feature/github-stats-frontend-integration
Apr 13, 2025
Merged
Changes from 9 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ce3aceb
Integrate FastAPI GitHub Stats API with Frontend for Dynamic Data Ren…
SharkyBytes 1b26445
Integrate dynamic GitHub data into frontend pages using FastAPI backe…
SharkyBytes 8d8e646
Refactored .env.example to align with current backend architecture
SharkyBytes 2a8ab4d
Merge branch 'main' into feature/github-stats-frontend-integration
SharkyBytes 20f39d6
Merge branch 'main' into feature/github-stats-frontend-integration
SharkyBytes 186e53f
Merge branch 'main' into feature/github-stats-frontend-integration
SharkyBytes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,6 @@ dist/ | |
| downloads/ | ||
| eggs/ | ||
| .eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| SUPABASE_URL= | ||
| SUPABASE_SERVICE_ROLE_KEY= | ||
| SUPABASE_SERVICE_ROLE_KEY= | ||
| CORS_ORIGINS=http://localhost:3000 | ||
| GITHUB_TOKEN= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Setting Up the .env File for FastAPI | ||
|
|
||
| This guide provides step-by-step instructions to configure your `.env` file and securely use a GitHub Personal Access Token in your FastAPI project. | ||
|
|
||
| ## 1. Create the `.env` File | ||
|
|
||
| 1. Navigate to the `backend` directory where your project is set up. | ||
| 2. Create a new file named `.env` (if it doesn’t already exist). | ||
|
|
||
| ## 2. Add the GitHub Access Token | ||
|
|
||
| 1. Open the `.env` file and add the following line: | ||
|
|
||
| ```text | ||
| GITHUB_TOKEN=your_personal_access_token_here | ||
| ``` | ||
|
|
||
| 2. Replace `your_personal_access_token_here` with your actual GitHub Personal Access Token. | ||
|
|
||
| ## 3. Generate a GitHub Personal Access Token | ||
|
|
||
| 1. Go to [GitHub Developer Settings](https://github.com/settings/tokens). | ||
| 2. Click on **Tokens (classic)** and then **Generate new token** and then generate the classic token. | ||
| 3. Select the required scopes for your application: | ||
| - **For public repositories**: Check `repo`. | ||
| - **For additional access**: Check `read:org`, `read:user`, etc., as needed. | ||
| 4. Copy the generated token (it will only be displayed once). | ||
|
|
||
|
|
||
| ## 5. Load Environment Variables in FastAPI | ||
|
|
||
| Ensure you have these things installed in your project: | ||
|
|
||
| ```bash | ||
| pip install python-dotenv requests fastapi uvicorn | ||
|
|
||
| ``` | ||
|
|
||
| ### Test API Requests | ||
| Run your FastAPI server: | ||
|
|
||
| ```bash | ||
| uvicorn backend.main:app --reload | ||
| ``` | ||
|
|
||
| Use `curl` or **Postman** to test the `/api/repo-stats` endpoint: | ||
|
|
||
| ```bash | ||
| curl -X POST http://localhost:8000/api/repo-stats \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"repo_url": "https://github.com/AOSSIE-Org/Devr.AI/"}' | ||
| ``` | ||
|
|
||
| If all the things correctly got setup then you will see the JSON repsponse | ||
|
|
||
| --- | ||
|
|
||
|
|
||
| Now, your FastAPI application is securely set up to use GitHub API credentials from a `.env` file! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from pydantic import BaseModel | ||
|
|
||
| class RepoRequest(BaseModel): | ||
| repo_url: str |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| from fastapi import APIRouter, HTTPException | ||
| from app.models import RepoRequest | ||
| from app.utils.github_api import get_repo_stats | ||
|
|
||
| router = APIRouter() | ||
|
|
||
| @router.post("/repo-stats") | ||
| async def repo_stats_endpoint(repo: RepoRequest): | ||
| try: | ||
| return await get_repo_stats(repo.repo_url) | ||
| except Exception as e: | ||
| raise HTTPException(status_code=500, detail=str(e)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| from fastapi import FastAPI, HTTPException | ||
| from pydantic import BaseModel | ||
| import requests | ||
| import os | ||
| from urllib.parse import urlparse | ||
| from dotenv import load_dotenv | ||
|
|
||
| load_dotenv() # Load environment variables | ||
|
|
||
| app = FastAPI() | ||
|
|
||
| class RepoRequest(BaseModel): | ||
| repo_url: str | ||
|
|
||
| def parse_github_url(url: str) -> tuple: | ||
| """Extract owner/repo from GitHub URL""" | ||
| parsed = urlparse(url) | ||
| path = parsed.path.strip('/').split('/') | ||
| if len(path) < 2: | ||
| raise ValueError("Invalid GitHub URL") | ||
| return path[0], path[1] | ||
|
|
||
| def github_api_request(endpoint: str) -> dict: | ||
| """Make authenticated GitHub API request""" | ||
| headers = { | ||
| "Authorization": f"token {os.getenv('GITHUB_TOKEN')}", | ||
| "Accept": "application/vnd.github.v3+json" | ||
| } | ||
| response = requests.get(f"https://api.github.com{endpoint}", headers=headers) | ||
| response.raise_for_status() | ||
| return response.json() | ||
|
|
||
|
|
||
| @app.post("/repo-stats") | ||
| async def get_repo_stats(repo_url: str): | ||
| try: | ||
| owner, repo_name = parse_github_url(repo_url) | ||
| # Rest of your function... | ||
| # Get basic repo info | ||
| repo_info = github_api_request(f"/repos/{owner}/{repo_name}") | ||
|
|
||
| # Get contributors | ||
| contributors = github_api_request(f"/repos/{owner}/{repo_name}/contributors") | ||
|
|
||
| # Get pull requests | ||
| prs = github_api_request(f"/repos/{owner}/{repo_name}/pulls?state=all") | ||
|
|
||
| # Get issues | ||
| issues = github_api_request(f"/repos/{owner}/{repo_name}/issues?state=all") | ||
|
|
||
| community_profile = github_api_request(f"/repos/{owner}/{repo_name}/community/profile") | ||
|
|
||
| # Recent commits (last 5) | ||
| commits = github_api_request(f"/repos/{owner}/{repo_name}/commits?per_page=5") | ||
|
|
||
| code_frequency = github_api_request(f"/repos/{owner}/{repo_name}/stats/code_frequency") | ||
|
|
||
| pull_requests_by_state = { | ||
| "open": sum(1 for pr in prs if pr["state"] == "open"), | ||
| "closed": sum(1 for pr in prs if pr["state"] == "closed"), | ||
| "draft": sum(1 for pr in prs if pr.get("draft", False)), | ||
| "merged": sum(1 for pr in prs if pr.get("merged_at")) | ||
| } | ||
| pr_details = [{ | ||
| "title": pr["title"], | ||
| "number": pr["number"], | ||
| "state": pr["state"], | ||
| "url": pr["html_url"], | ||
| "author": { | ||
| "login": pr["user"]["login"], | ||
| "avatar_url": pr["user"]["avatar_url"], | ||
| "profile_url": pr["user"]["html_url"] | ||
| }, | ||
| } for pr in prs] | ||
|
|
||
| return { | ||
| "name": repo_info["full_name"], | ||
| "stars": repo_info["stargazers_count"], | ||
| "forks": repo_info["forks_count"], | ||
| "watchers": repo_info["subscribers_count"], | ||
| "created_at": repo_info["created_at"], | ||
| "updated_at": repo_info["updated_at"], | ||
| # Licensing and topics | ||
| # "license": repo_info.get("license", {}).get("spdx_id", "No License"), | ||
|
|
||
| "topics": repo_info.get("topics", []), | ||
|
|
||
| "contributors": [{ | ||
| "login": c["login"], | ||
| "contributions": c["contributions"], | ||
| "avatar_url": c["avatar_url"] | ||
| } for c in contributors], | ||
| "recent_commits": [{ | ||
| "sha": commit["sha"][:7], | ||
| "author": commit["commit"]["author"]["name"], | ||
| "message": commit["commit"]["message"], | ||
| "date": commit["commit"]["author"]["date"] | ||
| } for commit in commits], | ||
|
|
||
|
|
||
| "community": { | ||
| "health_percentage": community_profile["health_percentage"], | ||
| "code_of_conduct": community_profile.get("files", {}).get("code_of_conduct") is not None, | ||
| "license": community_profile.get("files", {}).get("license") is not None, | ||
| "readme": community_profile.get("files", {}).get("readme") is not None | ||
| }, | ||
| # Issues | ||
| "issues": { | ||
| "total": len(issues), | ||
| "open": sum(1 for issue in issues if issue["state"] == "open"), | ||
| "closed": sum(1 for issue in issues if issue["state"] == "closed"), | ||
| "labels": list({label["name"] for issue in issues for label in issue["labels"]}) | ||
| }, | ||
|
|
||
| # Code statistics | ||
| "code_activity": { | ||
| "weekly_commits": len(code_frequency) if isinstance(code_frequency, list) else 0, | ||
| "total_additions": sum(week[1] for week in code_frequency) if isinstance(code_frequency, list) else 0, | ||
| "total_deletions": sum(abs(week[2]) for week in code_frequency) if isinstance(code_frequency, list) else 0 | ||
| }, | ||
|
|
||
| # Pull Requests | ||
| "pull_requests": { | ||
| **pull_requests_by_state, | ||
| "total": len(prs), | ||
| "details": pr_details | ||
| }, | ||
| } | ||
|
|
||
| except requests.HTTPError as e: | ||
| raise HTTPException(status_code=e.response.status_code, | ||
| detail="GitHub API error") | ||
| except ValueError: | ||
| raise HTTPException(status_code=400, | ||
| detail="Invalid GitHub URL format") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.