Of course! Using the GitHub API with Python is a very common and powerful task. I'll guide you through it, starting from the basics and moving to more advanced examples.

We'll use the most popular and recommended library for this: PyGithub. It's a well-maintained, object-oriented Python library that makes interacting with the GitHub API a breeze.
Table of Contents
- Prerequisites: What you need before you start.
- Installation: How to install
PyGithub. - Authentication: Why and how to authenticate with GitHub.
- Core Concepts: Understanding the
Githubobject and resources. - Code Examples:
- Example 1: Getting information about a repository.
- Example 2: Listing issues in a repository.
- Example 3: Creating a new issue.
- Example 4: Listing pull requests.
- Example 5: Working with your own repositories (creating, forking).
- Alternative Libraries: A brief look at
requests. - Best Practices: Key things to remember.
Prerequisites
- Python 3: Ensure you have Python 3 installed on your system.
- GitHub Account: You need a GitHub account.
- Personal Access Token (PAT): For most operations (especially writing), you need to authenticate. We'll cover this in the next section.
Installation
The easiest way to install PyGithub is using pip.
pip install PyGithub
Authentication (Very Important!)
The GitHub API has two modes: unauthenticated and authenticated.
- Unauthenticated: You have a strict 60 requests per hour limit. This is fine for simple, read-only public data fetching.
- Authenticated: Using a Personal Access Token (PAT), you get a much higher 5,000 requests per hour limit. You must authenticate for any actions that modify data (creating issues, pull requests, comments, etc.).
How to Create a Personal Access Token (PAT)
- Go to your GitHub account settings:
https://github.com/settings/ - In the left sidebar, click on Developer settings.
- Click on Personal access tokens -> Tokens (classic).
- Click Generate new token (and select "Generate new token (classic)" if prompted).
- Give your token a descriptive Note (e.g., "My Python Script").
- Select an expiration date.
- Under Select scopes, choose the permissions your script needs. For most read/write operations, you'll need:
repo: Full control of public and private repositories.issues: Read and write issues.pull_requests: Read and write pull requests.- Note: It's best practice to only grant the minimum permissions necessary.
- Click Generate token.
- CRITICAL: Copy the token immediately! You will not be able to see it again. Store it securely (e.g., in an environment variable, not directly in your code).
Using the Token in Python
Never hardcode your token in your script. Use environment variables.

# On Linux/macOS export GITHUB_TOKEN="ghp_your_token_here" # On Windows (Command Prompt) set GITHUB_TOKEN="ghp_your_token_here"
Then, in your Python script, you can access it like this:
import os
from github import Github
# Use the token from an environment variable
g = Github(os.getenv("GITHUB_TOKEN"))
Core Concepts
-
Githubobject: This is the entry point to the library. You create it by passing your token (or leaving it empty for unauthenticated access).# Authenticated g = Github("ghp_your_token_here") # Unauthenticated g = Github() -
Resources: The
Githubobject gives you access to "resources" likeget_user(),get_repo(),get_organization(), etc.# Get a specific user user = g.get_user("octocat") # Get a specific repository repo = g.get_repo("octocat/Hello-World") -
Object Methods: Once you have a resource object (like a
RepoorUser), you can call methods on it to get more data or perform actions (e.g.,repo.get_issues(),user.create_repo()).
Code Examples
Let's assume you've set your GITHUB_TOKEN environment variable.
Example 1: Getting Repository Information
This script fetches details for a public repository and prints some of its attributes.
import os
from github import Github
# --- Authentication ---
# It's better to use an environment variable
g = Github(os.getenv("GITHUB_TOKEN"))
# --- Get a Repository ---
# Format is "owner/repository_name"
repo = g.get_repo("PyGithub/PyGithub")
# --- Print Repository Info ---
print(f"Repository Name: {repo.name}")
print(f"Full Name: {repo.full_name}")
print(f"Description: {repo.description}")
print(f"Clone URL: {repo.clone_url}")
print(f"Default Branch: {repo.default_branch}")
print(f"Stars (Stargazers): {repo.stargazers_count}")
print(f"Language: {repo.language}")
Example 2: Listing Issues in a Repository
This script gets the first 10 open issues from a repository and prints their titles and numbers.
import os
from github import Github
g = Github(os.getenv("GITHUB_TOKEN"))
repo = g.get_repo("pallets/flask")
# Get issues, state can be 'open', 'closed', or 'all'
issues = repo.get_issues(state='open')
print(f"Found {issues.totalCount} open issues. Showing the first 10:\n")
# Iterate through the first 10 issues
for issue in issues[:10]:
print(f"Issue #{issue.number}: {issue.title}")
print(f" - Created by: {issue.user.login}")
print(f" - URL: {issue.html_url}\n")
Example 3: Creating a New Issue
This script creates a new issue in a repository you have write access to. This requires authentication.
import os
from github import Github
g = Github(os.getenv("GITHUB_TOKEN"))
# IMPORTANT: Replace with your own repository
repo = g.get_repo("YOUR_USERNAME/YOUR_REPO_NAME")
# Create the issue
issue_title = "A new issue created by Python script"
issue_body = "This is a test issue created using the PyGithub library. Please ignore it."
created_issue = repo.create_issue(title=issue_title, body=issue_body)
print(f"Successfully created issue #{created_issue.number}")
print(f"Issue URL: {created_issue.html_url}")
Example 4: Listing Pull Requests
This script lists the open pull requests for a repository.
import os
from github import Github
g = Github(os.getenv("GITHUB_TOKEN"))
repo = g.get_repo("microsoft/vscode")
# Get pull requests, state can be 'open', 'closed', or 'all'
prs = repo.get_pulls(state='open')
print(f"Found {prs.totalCount} open pull requests. Showing the first 5:\n")
for pr in prs[:5]:
print(f"PR #{pr.number}: {pr.title}")
print(f" - Head: {pr.head.ref} -> Base: {pr.base.ref}")
print(f" - Created by: {pr.user.login}")
print(f" - URL: {pr.html_url}\n")
Example 5: Forking a Repository and Creating a Branch
This example shows more complex interactions. It forks a repository, gets the fork, creates a new branch, and creates a file.
import os
from github import Github, GithubException
g = Github(os.getenv("GITHUB_TOKEN"))
# A public repository to fork
source_repo = g.get_repo("psf/requests")
try:
# Fork the repository
print("Forking the repository...")
my_fork = source_repo.create_fork()
print(f"Fork successful. New fork: {my_fork.full_name}")
# Get your user object to work with your own repos
my_user = g.get_user()
# Get the forked repository from your user's list
my_repo = my_user.get_repo(my_fork.full_name)
print(f"Accessing forked repo: {my_repo.full_name}")
# Create a new branch
source_branch = my_repo.default_branch
new_branch_name = "feature/add-greeting"
print(f"Creating new branch: {new_branch_name}")
# The source_branch_ref is a GitRef object
source_branch_ref = my_repo.get_branch(source_branch)
# The create_git_ref method creates the branch
my_repo.create_git_ref(ref=f"refs/heads/{new_branch_name}", sha=source_branch_ref.commit.sha)
print(f"Branch '{new_branch_name}' created successfully.")
# Create a new file in the new branch
file_content = "Hello from my Python script!"
file_path = "greeting.txt"
commit_message = "Add greeting file via PyGithub"
print(f"Creating file '{file_path}' in branch '{new_branch_name}'...")
my_repo.create_file(
path=file_path,
message=commit_message,
content=file_content.encode("utf-8"), # Content must be bytes
branch=new_branch_name
)
print("File created successfully!")
except GithubException as e:
print(f"An error occurred: {e.status} - {e.data}")
Alternative: Using requests
For more granular control or if you prefer a lighter dependency, you can use the requests library to directly call the GitHub API. This requires you to construct the URLs and handle the responses manually.
Pros:
- Full control over every request.
- No extra library dependency.
Cons:
- More verbose code.
- You have to parse JSON responses yourself.
- You need to handle pagination manually for list endpoints.
Example with requests:
pip install requests
import requests
import os
# Use the same environment variable for the token
token = os.getenv("GITHUB_TOKEN")
headers = {
"Authorization": f"token {token}",
"Accept": "application/vnd.github.v3+json"
}
# API endpoint for listing issues
url = "https://api.github.com/repos/pallets/flask/issues"
params = {
"state": "open",
"per_page": 5
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
issues = response.json()
print(f"Found {len(issues)} issues:\n")
for issue in issues:
print(f"Issue #{issue['number']}: {issue['title']}")
else:
print(f"Error: {response.status_code}")
print(response.text)
Best Practices
- Authenticate: Always authenticate if you can. It gives you a much higher rate limit and is required for write operations.
- Use Environment Variables: Never, ever hardcode your Personal Access Token in your source code.
- Handle Exceptions: The
PyGithublibrary can raiseGithubException. Wrap your API calls intry...exceptblocks to handle potential errors gracefully (e.g., repository not found, insufficient permissions). - Check Rate Limits: The
Githubobject has arate_limitingproperty. You can check it to see how many requests you have left before making a call.print(g.rate_limiting) # e.g., (4980, 5000) print(g.rate_limiting_resettime) # The Unix timestamp when the limit resets
- Read the Docs: The official PyGithub documentation is excellent and full of examples for every method.
