GitPulse: GitHub Trending Tool
From black-box page to installable CLI in Python

I didn’t build GitPulse to solve a critical global problem. I built it to learn.
I wanted to understand how CLI tools feel to the user, how to integrate complex APIs, and how to transform raw data into something useful. Honestly? Building because you’re curious is the best way to grow as a developer.
The Challenge: Finding a “Trending” Endpoint that Doesn’t Exist This project was inspired by the Roadmap.sh backend project suggestions. I quickly ran into a roadblock: GitHub doesn’t actually provide a “Trending” endpoint in its REST API. The “Trending” page on GitHub’s website is a bit of a “black box” — it uses a secret algorithm to track star velocity.
To build GitPulse, I had to create my own definition of “Trending.” So, I decided to define trending as a combination of:
- Freshness — repositories created within a recent time window
- Popularity — repositories with a high star count
In practice, this means:
“Show me repositories created recently that are getting a lot of stars.”
This definition is simple, transparent, and achievable using GitHub’s Search API.
Getting Our Hands Dirty with the GitHub REST API
Before writing any code, I spent time exploring the GitHub API documentation. Within minutes, I found the endpoint I needed:
https://api.github.com/search/repositories
But there was a catch: this endpoint requires a query parameter (q). Without it, you get a validation error.
Building the Query Step by Step
The q parameter is flexible and powerful. Let me show you how I built it up:
Step 1: Filter by language
https://api.github.com/search/repositories?q=language:python
This returns up to 30 Python repositories, sorted by “best match” (GitHub’s default).
Step 2: Sort by stars
https://api.github.com/search/repositories?q=language:python&sort=stars&order=desc
Now we get the most-starred Python repos. The sort parameter can be:
stars(what we want!)forksupdatedhelp-wanted-issues
The order parameter defaults to desc, but you can change it to asc if needed.
Step 3: Limit the results
https://api.github.com/search/repositories?q=language:python&sort=stars&order=desc&per_page=3
The per_page parameter controls how many results you get (default is 30, max is 100).
This gives us the top 3 most-starred Python repositories on GitHub.
Adding the Time Component
Now for the crucial part: making it show recent trending repos,
Created vs Pushed: Which Date Should I Use?
This led me to an interesting question: what makes a repo “trending”?
- Created date (`created:>date`): Shows brand new projects launching
- Pushed date (`pushed:>date`): Shows actively maintained projects with recent updates.
Both have merit! A repo created yesterday with 1000 stars is definitely trending. But so is a popular repo that just pushed a major update.
My solution? : I built support for BOTH. Users can choose which “trending” they want to see. For the default behavior, I chose `pushed` because it captures both new projects AND established ones with recent activity.
Building the Date Filter
GitHub’s search API supports flexible date queries:
# After a specific date
q=pushed:>2025–12–16
# Between two dates (two ways to write it)
q=pushed:>2025–12–16 pushed:<2025–12–23
q=pushed:2025–12–16..2025–12–23
# Both work the same way!
Putting It All Together
Here’s what a complete GitPulse API call looks like:
curl "https://api.github.com/search/repositories?q=language:python+pushed:2025-12-16..2025-12-23&sort=stars&order=desc&per_page=10"
Breaking it down:
- q=language:python — Filter by language
- +pushed:2025–12–16..2025–12–23` — Date range (note the `+` separating queries)
- `&sort=stars` — Sort by star count (default = best match)
- `&order=desc` — Highest stars first (default = desc)
- `&per_page=10` — Limit results (default = 30)
Important: Multiple search qualifiers in `q` are separated by `+` (URL-encoded space) or actual spaces.
Pro tip: You can test these URLs directly in your browser or use `curl` to see the JSON response. This helped me understand the data structure before writing code.
From API Exploration to Actual Code
Now that we understand the GitHub REST API, it’s time to actually build the tool.
Before jumping straight into coding, the first thing we need is a proper folder structure. Writing everything in a single file — like a 500-line script — will only give you headaches later when you try to debug, edit, or extend the code. Keeping the project maintainable with a clear structure is always a best practice.
So instead of doing that, I went with a simple modular architecture. Nothing fancy — just splitting the code into logical parts where each file has a clear responsibility.
Here’s the folder structure:
GitPulse/
├── cli.py # Handles user input & arguments
├── github_api.py # Talks to GitHub API
├── formatter.py # Displays results beautifully
├── utils.py # Date calculations
└── config.py # Constants & defaults
This way, the code stays clean, readable, and much easier to work with as the project grows.
Here is the Repo Link and you can go through it.
https://github.com/Trishan0/github-trending-cli
Handling the Command Line
I used the python’s built-in “argparse” library to handle the CLI arguments. It's straightforward once you get the hang of it.
You may have heard of Python’s other built-in module, “sys”, and its “sys.argv” list, which can also handle basic CLI arguments. But using it means you have to check for options, convert types and handle errors.
That’s why we use “argparse”. It makes things much easier:
- Automatically parses arguments (like numbers or strings)
- Handle optional flags (like
--calendar) easily. - Support default values for arguments
- Generates help messages with
-h / --helpautomatically - Gives clean errors if something is missing or wrong rather than crashing.
If you’re new to argparse, I found these resources helpful:
The Date Range Feature
When I started to write the date filtering logic , I realized that “Last week” could mean two things
- Last 7 days from today
- Previous Monday-Sunday
So I decided to support for both since it wasn’t much extra work.
Here is the function — GitHub
def get_date_ranges(duration: str, calendar_mode: bool = False) -> str:
"""
Get date range string for GitHub API based on duration.
Args:
duration: 'day', 'week', 'month', or 'year'
calendar_mode: If True, use calendar-based ranges
If False, use rolling ranges (last X days)
"""
if calendar_mode:
# Calendar-based: previous calendar week/month/year
if duration == "week":
return get_previous_week_range() # Last Mon-Sun
elif duration == "month":
return get_last_month_range() # Previous calendar month
# ... and so on
else:
# Rolling: last X days from today
days_map = {"day": 1, "week": 7, "month": 30, "year": 365}
return get_last_x_days(days_map.get(duration, 7))
By default, --duration week shows the last 7 days. Add --calendar and it shows the previous calendar week instead.
Making It a Real CLI Tool
Now the next part is making this as a CLI Tool like git, then you can make it work like how git works in the cmd ,git status
so for that first we need to make this as an installable package
I used `pyproject.toml` to configure the package:
[project.scripts]
gitpulse = "GitPulse.cli:main"
full pyproject.toml file you can see from the github repo
After running `pip install -e .`, I could use `gitpulse` anywhere in my terminal — no more `python cli.py`.
This transformed it from “a Python script” to “a real tool.”
See It In Action
Here’s GitPulse running with different options:
gitpulse --duration week --language python --limit 5
![[Screenshot or terminal output showing the beautiful Rich table]](https://miro.medium.com/v2/resize:fit:700/1*G1HHq7_0pENMGMB2CpAVeg.png)
The tool displays:
- Repository names and descriptions
- Star and fork counts (formatted nicely: 1.2k, 45.3k)
- Programming languages
- Direct links to repos
Wrapping Up
That’s GitPulse. A simple CLI tool that shows GitHub trending repos. Nothing fancy, but it taught me how real command-line tools work.
The code’s on GitHub. if you want to check it out or build something similar.
If you’re learning backend development, pick a project and just build it. You’ll learn more from one project than from ten tutorials.
I have published this article also on Medium