如何用Python调用GitHub API获取搜索到的仓库最后提交信息?
Hey there! Let's work through how to get the latest commit details for each repo from your GitHub API results.
First off, a quick heads-up: the GitHub Search Repositories API (/search/repositories) doesn't return commit details by default. You'll need to make an additional API call for each repository to fetch its latest commit. Here's how to implement this step by step:
实现思路
- First, fetch the list of repositories using the search API as you already do.
- Loop through each repository in the results, and use the
commits_urlfield from each repo object to build a request for its latest commit. - Call the GitHub Commits API for each repo to get the most recent commit (the API returns commits in reverse chronological order by default, so we just need the first one).
- Attach the latest commit data to the original repository object, then pass everything to your template.
修改后的代码
import requests from django.views.generic import CreateView from django.shortcuts import render class GhNavigator(CreateView): def get(self, request, *args, **kwargs): term = request.GET.get('search_term') username = 'arycloud' token = 'API_TOKEN' auth_credentials = (username, token) # Step 1: Fetch repo list via search API search_api_url = f'https://api.github.com/search/repositories?q={term}' search_response = requests.get(search_api_url, auth=auth_credentials) repo_data = search_response.json() # Step 2: Fetch latest commit for each repo for repo in repo_data.get('items', []): # Clean up the commits_url (remove the {/sha} placeholder) and add per_page=1 to get only the latest commit latest_commit_url = f"{repo['commits_url'].split('{')[0]}?per_page=1" commit_response = requests.get(latest_commit_url, auth=auth_credentials) if commit_response.status_code == 200: commits = commit_response.json() if commits: # Attach the latest commit to the repo object repo['latest_commit'] = commits[0] else: # Handle cases where we can't fetch commits (e.g., rate limits, private repos) repo['latest_commit'] = None return render(request, 'navigator/template.html', {'response': repo_data, 'term': term})
关键细节说明
- Handling
commits_url: Each repo'scommits_urllooks likehttps://api.github.com/repos/{owner}/{repo}/commits{/sha}. We strip off the{/sha}part to get the base URL for the repo's commits list, then add?per_page=1to only retrieve the most recent commit. - Reusing authentication: Make sure to pass your
auth_credentialsto the commit API calls too—authenticated requests have a much higher rate limit than unauthenticated ones, which helps avoid hitting GitHub's API limits. - Error handling: The code includes basic status code checking, but you can expand this with retry logic or logging if you need more robustness for production use.
在模板中使用最新提交信息
In your template.html, you can access the latest commit data like this:
{% for repo in response.items %} <div class="repo-card"> <h3><a href="{{ repo.html_url }}">{{ repo.full_name }}</a></h3> <p>{{ repo.description }}</p> {% if repo.latest_commit %} <div class="latest-commit"> <p><strong>Latest Commit SHA:</strong> {{ repo.latest_commit.sha }}</p> <p><strong>Message:</strong> {{ repo.latest_commit.commit.message }}</p> <p><strong>Committed On:</strong> {{ repo.latest_commit.commit.committer.date }}</p> </div> {% else %} <p>Could not retrieve latest commit information.</p> {% endif %} </div> {% endfor %}
Quick performance note: If you're dealing with a lot of search results, making sequential API calls can be slow. For better speed, you could use concurrent requests (with a library like
requests-futures), just be mindful of GitHub's rate limits to avoid getting blocked.
内容的提问来源于stack exchange,提问作者Abdul Rehman




