A python client for the GitHub API
—
The core API client provides the main interface to the GitHub API through the GhApi class, along with utility functions for date handling and request debugging.
The main API client that provides access to all GitHub API endpoints through dynamically generated methods organized by API groups.
class GhApi:
def __init__(self, owner=None, repo=None, token=None, jwt_token=None,
debug=None, limit_cb=None, gh_host=None, authenticate=True, **kwargs):
"""
Create a GitHub API client.
Parameters:
- owner: str, default repository owner
- repo: str, default repository name
- token: str, GitHub personal access token
- jwt_token: str, GitHub JWT token
- debug: callable, debug function for requests
- limit_cb: callable, rate limit callback function
- gh_host: str, GitHub API host URL
- authenticate: bool, whether to authenticate requests
- **kwargs: additional default parameters
"""
def __call__(self, path: str, verb: str = None, headers: dict = None,
route: dict = None, query: dict = None, data=None, timeout=None, decode=True):
"""
Call a fully specified API path using HTTP verb.
Parameters:
- path: str, API endpoint path
- verb: str, HTTP method (GET, POST, PUT, DELETE, etc.)
- headers: dict, additional HTTP headers
- route: dict, path parameters for URL templating
- query: dict, query string parameters
- data: request body data
- timeout: int, request timeout in seconds
- decode: bool, whether to decode JSON response
Returns:
API response data
"""
def __getitem__(self, k):
"""
Lookup and call an endpoint by path and verb.
Parameters:
- k: tuple of (path, verb) or just path (defaults to GET)
Returns:
API endpoint function
"""
def full_docs(self):
"""
Return complete documentation for all API endpoints.
Returns:
str: Markdown documentation
"""The GhApi client organizes endpoints into groups that mirror GitHub's API structure:
# Repository operations
api.repos.get(owner='user', repo='repo')
api.repos.list_for_user(username='user')
api.repos.create(name='new-repo', description='Description')
# Issue management
api.issues.list_for_repo(owner='user', repo='repo')
api.issues.create(owner='user', repo='repo', title='Title', body='Body')
api.issues.update(owner='user', repo='repo', issue_number=1, state='closed')
# Pull request operations
api.pulls.list(owner='user', repo='repo')
api.pulls.create(owner='user', repo='repo', title='Title', head='feature', base='main')
# Actions and workflows
api.actions.list_workflow_runs(owner='user', repo='repo')
api.actions.list_jobs_for_workflow_run(owner='user', repo='repo', run_id=123)
# Git operations
api.git.get_ref(owner='user', repo='repo', ref='heads/main')
api.git.create_ref(owner='user', repo='repo', ref='refs/heads/feature', sha='sha')
# User and organization operations
api.users.get_by_username(username='user')
api.orgs.get(org='organization')Additional methods added to GhApi for common repository operations.
def create_gist(self, description, content, filename='gist.txt', public=False):
"""
Create a gist containing a single file.
Parameters:
- description: str, gist description
- content: str, file content
- filename: str, filename for the gist
- public: bool, whether gist is public
Returns:
Gist object
"""
def delete_release(self, release):
"""
Delete a release and its associated tag.
Parameters:
- release: release object with id and tag_name
"""
def upload_file(self, rel, fn):
"""
Upload file to release endpoint.
Parameters:
- rel: release object with upload_url
- fn: str or Path, file to upload
Returns:
Upload response
"""
def create_release(self, tag_name, branch='master', name=None, body='',
draft=False, prerelease=False, files=None):
"""
Create release and upload files.
Parameters:
- tag_name: str, git tag name
- branch: str, target branch
- name: str, release name
- body: str, release description
- draft: bool, whether release is draft
- prerelease: bool, whether release is prerelease
- files: list, files to upload
Returns:
Release object
"""
def list_tags(self, prefix: str = ''):
"""
List all tags, optionally filtered by prefix.
Parameters:
- prefix: str, tag name prefix filter
Returns:
List of tag references
"""
def list_branches(self, prefix: str = ''):
"""
List all branches, optionally filtered by prefix.
Parameters:
- prefix: str, branch name prefix filter
Returns:
List of branch references
"""
def create_branch_empty(self, branch):
"""
Create empty branch with dummy file.
Parameters:
- branch: str, branch name
Returns:
Branch reference
"""
def delete_tag(self, tag: str):
"""
Delete a tag.
Parameters:
- tag: str, tag name to delete
"""
def delete_branch(self, branch: str):
"""
Delete a branch.
Parameters:
- branch: str, branch name to delete
"""
def get_branch(self, branch=None):
"""
Get branch information.
Parameters:
- branch: str, branch name (defaults to repository default)
Returns:
Branch reference object
"""
def list_files(self, branch=None):
"""
List files in repository.
Parameters:
- branch: str, branch name (defaults to repository default)
Returns:
Dict mapping file paths to file objects
"""
def get_content(self, path):
"""
Get file content (base64 decoded).
Parameters:
- path: str, file path in repository
Returns:
bytes: File content
"""
def create_or_update_file(self, path, message, committer, author,
content=None, sha=None, branch=''):
"""
Create or update file in repository.
Parameters:
- path: str, file path
- message: str, commit message
- committer: dict, committer info
- author: dict, author info
- content: str or bytes, file content
- sha: str, current file SHA (for updates)
- branch: str, target branch
Returns:
Commit response
"""
def create_file(self, path, message, committer, author, content=None, branch=None):
"""
Create new file in repository.
Parameters:
- path: str, file path
- message: str, commit message
- committer: dict, committer info
- author: dict, author info
- content: str or bytes, file content
- branch: str, target branch
Returns:
Commit response
"""
def delete_file(self, path, message, committer, author, sha=None, branch=None):
"""
Delete file from repository.
Parameters:
- path: str, file path
- message: str, commit message
- committer: dict, committer info
- author: dict, author info
- sha: str, current file SHA
- branch: str, target branch
Returns:
Commit response
"""
def update_contents(self, path, message, committer, author, content, sha=None, branch=None):
"""
Update file contents in repository.
Parameters:
- path: str, file path
- message: str, commit message
- committer: dict, committer info
- author: dict, author info
- content: str or bytes, new file content
- sha: str, current file SHA
- branch: str, target branch
Returns:
Commit response
"""
def enable_pages(self, branch=None, path="/"):
"""
Enable or update GitHub Pages for repository.
Parameters:
- branch: str, pages source branch
- path: str, pages source path ("/docs" or "/")
Returns:
Pages configuration
"""Helper functions for working with GitHub API requests and date formatting.
def print_summary(req: Request):
"""
Print request summary with authorization token removed.
Parameters:
- req: Request object to summarize
"""
def date2gh(dt: datetime) -> str:
"""
Convert datetime to GitHub API format.
Parameters:
- dt: datetime object (assumed UTC)
Returns:
str: ISO format string with Z suffix
"""
def gh2date(dtstr: str) -> datetime:
"""
Convert GitHub API date string to datetime.
Parameters:
- dtstr: str, GitHub API date string
Returns:
datetime: UTC datetime object
"""from ghapi.all import GhApi
# Initialize with authentication
api = GhApi(token='your_token', owner='username', repo='repository')
# Get repository information
repo_info = api.repos.get()
print(f"Repository: {repo_info.full_name}")
print(f"Description: {repo_info.description}")
print(f"Stars: {repo_info.stargazers_count}")
# List repository files
files = api.list_files()
for path, file_obj in files.items():
print(f"{path}: {file_obj.type}")
# Get file content
content = api.get_content('README.md')
print(content.decode('utf-8'))# List open issues
issues = api.issues.list_for_repo(state='open', per_page=10)
for issue in issues:
print(f"#{issue.number}: {issue.title}")
# Create new issue
new_issue = api.issues.create(
title='Bug Report',
body='Description of the bug...',
labels=['bug', 'needs-triage']
)
# Create pull request
pr = api.pulls.create(
title='Feature: Add new functionality',
body='This PR adds...',
head='feature-branch',
base='main'
)# Create release with file uploads
release = api.create_release(
tag_name='v1.0.0',
name='Version 1.0.0',
body='Release notes...',
files=['dist/package.tar.gz', 'dist/package.zip']
)
# List all releases
releases = api.repos.list_releases()
for release in releases:
print(f"{release.tag_name}: {release.name}")
# Delete release and tag
api.delete_release(release)# List branches
branches = api.list_branches()
for branch in branches:
print(f"Branch: {branch.ref}")
# Create new branch
api.create_branch_empty('new-feature')
# List tags with prefix filter
tags = api.list_tags(prefix='v1.')
for tag in tags:
print(f"Tag: {tag.ref}")
# Delete tag
api.delete_tag('old-tag')Install with Tessl CLI
npx tessl i tessl/pypi-ghapi