Pull data from GitHub API, cache it locally, display stats in terminal, and generate ready-to-use fragments for README and CI/CD workflows.
📦 Installation • 🚀 Quick Start • 📖 Documentation • 🤝 Contributing
- 📊 Repository Statistics — stars, forks, issues, releases, and more
- 👤 User Profile Analytics — top repositories, overall activity metrics
- 🏷️ Badge Generation — ready-to-use Markdown shields for your README
- 💾 Local Caching — blazing fast repeated queries with smart cache
- 📤 Data Export — JSON output for CI/CD integration and automation
- 🎨 Beautiful Terminal Output — rich tables and panels with colors
- 🔒 Secure Token Storage — encrypted credential management with keyring
- ⚡ High Performance — async HTTP client with connection pooling
Get a feel for gh-pulse with a few screenshots:
pip install gh-pulseuv is a blazingly fast Python package installer and resolver.
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install gh-pulse
uv pip install gh-pulse
# Or run without installation
uvx gh-pulse --helpgit clone https://github.com/ruslanlap/gh-pulse.git
cd gh-pulse
pip install -e .Create a GitHub Personal Access Token:
- Go to https://github.com/settings/tokens
- Click Generate new token (classic)
- Select scope:
public_repo(for public repositories) - Copy the generated token
Save your token securely:
gh-pulse auth ghp_YOUR_TOKEN_HEREToken will be stored in ~/.gh-pulse/config with restricted permissions (600).
Alternative: Use environment variable
export GITHUB_TOKEN=ghp_YOUR_TOKEN_HEREgh-pulse repo ruslanlap/gh-pulsegh-pulse badges ruslanlap/gh-pulsegh-pulse user ruslanlap --top 5Get comprehensive statistics for any GitHub repository:
gh-pulse repo owner/repositoryExample output:
📊 Repository: ruslanlap/PowerToysRun-QuickAi
┌──────────────────┬────────────┐
│ Metric │ Value │
├──────────────────┼────────────┤
│ ⭐ Stars │ 145 │
│ 🍴 Forks │ 12 │
│ 👀 Watchers │ 8 │
│ 📖 Open Issues │ 3 │
│ 💻 Language │ C# │
│ 📦 Size │ 2341 KB │
│ 🌿 Default Branch│ main │
│ 📅 Created │ 2024-01-15 │
│ 🔄 Last Updated │ 2025-11-10 │
│ 📤 Last Push │ 2025-11-12 │
└──────────────────┴────────────┘
Options:
--no-cache— Force refresh data from API (bypass cache)
Analyze GitHub user profiles with top repositories:
gh-pulse user username
gh-pulse user username --top 5 # Show top 5 repositoriesExample output:
👤 User: @ruslanlap
┌─────────────────┬─────────┐
│ Metric │ Value │
├─────────────────┼─────────┤
│ Name │ Ruslan │
│ 📚 Public Repos │ 42 │
│ 📝 Public Gists │ 8 │
│ 👥 Followers │ 156 │
│ ➡️ Following │ 89 │
│ 📅 Joined │2020-03-15│
└─────────────────┴─────────┘
⭐ Top 3 Repositories by Stars
┌────────────────────┬───────┬──────────┬─────────────────┐
│ Repository │ Stars │ Language │ Description │
├────────────────────┼───────┼──────────┼─────────────────┤
│ awesome-project │ 1.2k │ Python │ Cool tool │
│ another-repo │ 345 │TypeScript│ Web app │
│ third-repo │ 123 │ Go │ CLI utility │
└────────────────────┴───────┴──────────┴─────────────────┘
Total stars from top 3 repos: ⭐ 1,668
Options:
--top Nor-n N— Number of top repositories (default: 3)--no-cache— Force refresh data
Generate beautiful Markdown badges for your README:
gh-pulse badges owner/repositoryExample output:
✓ Badges generated!
┌──────────────────────────────────────────┐
│ Markdown Badges │
├──────────────────────────────────────────┤
│  │
│  │
│  │
│ ... │
└──────────────────────────────────────────┘
Copy and paste the above Markdown into your README.md
Custom badges:
# Select specific badges only
gh-pulse badges owner/repo --custom stars,forks,licenseAvailable types: stars, forks, issues, license, release, language, downloads, commit
Export data as JSON for automation and CI/CD workflows:
# Export repository statistics
gh-pulse export --repo owner/repository
# Export user profile
gh-pulse export --user username
# Save to file
gh-pulse export --repo owner/repo --output stats.json
# Export both
gh-pulse export --repo owner/repo --user username -o full.jsonJSON format:
{
"repository": {
"name": "gh-pulse",
"full_name": "ruslanlap/gh-pulse",
"stats": {
"stars": 123,
"forks": 45,
"watchers": 12,
"open_issues": 3
},
"language": "Python",
"releases": [...]
},
"user": {
"login": "ruslanlap",
"stats": {
"public_repos": 42,
"followers": 156
},
"top_repos": [...]
}
}Clear all cached data:
gh-pulse clear-cacheCache is stored in ~/.gh-pulse/cache/ with 1-hour TTL.
~/.gh-pulse/
├── config # GitHub token (secure storage)
└── cache/ # Cached API responses
├── repo_owner_name.json
└── user_username.json
GITHUB_TOKEN— GitHub API token (alternative togh-pulse auth)
name: Update README Badges
on:
schedule:
- cron: "0 0 * * 0" # Weekly on Sunday
workflow_dispatch:
jobs:
update-badges:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Generate badges
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
uvx gh-pulse badges ${{ github.repository }} > badges.md
- name: Update README
run: |
# Insert badges into README...
cat badges.md
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add README.md
git commit -m "docs: update badges" || exit 0
git push- name: Export GitHub metrics
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
uvx gh-pulse export --repo ${{ github.repository }} -o metrics.json
- name: Upload metrics artifact
uses: actions/upload-artifact@v4
with:
name: github-metrics
path: metrics.json# Clone the repository
git clone https://github.com/ruslanlap/gh-pulse.git
cd gh-pulse
# Install with development dependencies (using uv)
uv pip install -e ".[dev]"
# Or with pip
pip install -e ".[dev]"# Run tests with pytest
pytest
# With coverage
pytest --cov=gh-pulse --cov-report=html
# Using uv
uv run pytest# Check with ruff
ruff check src/
# Auto-fix issues
ruff check src/ --fix
# Format code
ruff format src/gh-pulse/
├── assets/ # Project assets (logos, images, etc.)
├── src/gh-pulse/
│ ├── __init__.py # Package version
│ ├── cli.py # Typer CLI application
│ ├── github_api.py # GitHub REST API client
│ ├── models.py # Pydantic data models
│ ├── cache.py # File-based caching
│ └── badges.py # Badge generator
├── tests/
│ ├── test_github_api.py
│ └── test_badges.py
├── pyproject.toml
├── README.md
└── LICENSE
from gh-pulse.github_api import GitHubClient
# Initialize client
with GitHubClient(token="ghp_xxx") as client:
# Repository operations
stats = client.get_repo_stats("owner/repo")
releases = client.get_repo_releases("owner/repo", limit=5)
# User operations
user = client.get_user_stats("username")
top_repos = client.get_top_repos("username", limit=3)from gh-pulse.badges import BadgeGenerator
gen = BadgeGenerator()
# Generate individual badges
stars_badge = gen.stars("owner/repo", count=100)
forks_badge = gen.forks("owner/repo")
# Generate full badge set
all_badges = gen.generate_full_set("owner/repo")
# Generate custom badge set
custom_badges = gen.generate_custom("owner/repo", ["stars", "forks", "license"])Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow the existing code style (Ruff formatting)
- Write tests for new features
- Update documentation as needed
- Use Conventional Commits for commit messages
This project is licensed under the MIT License — see the LICENSE file for details.
Built with awesome open-source tools:
- typer — CLI framework with beautiful output
- rich — Terminal formatting and colors
- httpx — Modern async HTTP client
- pydantic — Data validation and settings management
- keyring — Secure credential storage
- uv — Lightning-fast Python package manager
- Documentation: GitHub Wiki
- Issue Tracker: GitHub Issues
- PyPI Package: pypi.org/project/gh-pulse
- Changelog: CHANGELOG.md
Made with ❤️ by Ruslan
If you find this project useful, please consider giving it a ⭐️




