A Python SDK for interacting with the GitHub REST API. This library provides a modular, object-oriented approach to managing GitHub resources including repositories, organizations, teams, actions, and more.
- Installation
- Quick Start
- Authentication
- Available Modules
- Usage Examples
- Response Format
- Error Handling
- Contributing
- Python 3.8+
- A GitHub Personal Access Token (PAT) with appropriate permissions
pip install requests pynaclClone the repository:
git clone https://github.com/shanpira14-bit/github-python-sdk.git
cd github-python-sdkfromgithubimportGitHubModules# Initialize with your GitHub tokengithub=GitHubModules(
token="your_github_token",
org="your-organization", # For organization-level operationsowner="your-username", # For owner-level operationsusername="your-username", # For user-level operationslog_level="INFO"# Optional: DEBUG, INFO, WARNING, ERROR
)
# List repositoriesrepos=github.repository.repositories.list_org_repos()
print(repos)The SDK requires a GitHub Personal Access Token (PAT) for authentication. You can create one in your GitHub Settings.
importosfromgithubimportGitHubModules# Recommended: Use environment variablesgithub_token=os.environ.get("GH_TOKEN")
github=GitHubModules(
token=github_token,
org="my-organization"
)Depending on the operations you want to perform, you may need the following token scopes:
| Operation | Required Scopes |
|---|---|
| Read repositories | repo |
| Manage secrets | admin:org |
| Manage teams | admin:org, write:org |
| Copilot management | manage_billing:copilot |
| Dependabot | security_events |
| Module | Description | Access via |
|---|---|---|
| Actions | Manage workflows, artifacts, secrets, variables, runners | github.actions |
| Apps | GitHub Apps management | github.apps |
| Billing | Billing information | github.billing |
| Branch | Branch management and protection rules | github.branch |
| Collaborator | Repository collaborator management | github.collaborator |
| Copilot | Copilot seat management and metrics | github.copilot |
| Dependabot | Dependabot alerts and secrets | github.dependabot |
| Deployment | Deployment management | github.deployment |
| Git Database | Low-level Git operations | github.git_database |
| GitIgnore | GitIgnore templates | github.gitignore |
| Issue | Issue management | github.issue |
| Organization | Organization settings and members | github.organization |
| Packages | Package management | github.packages |
| Private Registries | Private registry configuration | github.private_registries |
| Pull Request | Pull request management | github.pull_request |
| Rate Limit | API rate limit information | github.rate_limit |
| Release | Release management | github.release |
| Repository | Repository CRUD operations | github.repository |
| Team | Team management | github.team |
fromgithubimportGitHubModulesgithub=GitHubModules(token="your_token", org="my-org")
# List all repositoriesrepos=github.repository.repositories.list_org_repos(per_page=50, page=1)
# Get a specific repositoryrepo=github.repository.repositories.get_repository(repo="my-repo")
print(f"Repository: {repo['data']['name']}")importbase64# Get file contentscontent=github.repository.contents.get_repository_content(
repo="my-repo",
path="README.md"
)
# Create or update a fileencoded_content=base64.b64encode("# My New File".encode()).decode()
result=github.repository.contents.create_or_update_file_contents(
repo="my-repo",
path="docs/example.md",
message="Add example documentation",
content=encoded_content,
branch="main"
)# List autolinksautolinks=github.repository.autolinks.list_autolinks(repo="my-repo")
# Create an autolinkgithub.repository.autolinks.create_autolink(
repo="my-repo",
key_prefix="TICKET-",
url_template="https://jira.company.com/browse/TICKET-<num>"
)github=GitHubModules(token="your_token", org="my-org")
# Get organization API summary statsstats=github.organization.api_insights.get_summary_stats(
min_timestamp="2024-01-01T00:00:00Z",
max_timestamp="2024-01-31T23:59:59Z"
)
# Get time-based statisticstime_stats=github.organization.api_insights.get_time_stats(
min_timestamp="2024-01-01T00:00:00Z",
timestamp_increment="1h"
)github=GitHubModules(token="your_token", org="my-org")
# List organization secretssecrets=github.actions.secrets.list_org_secrets(per_page=100)
# Get the public key for encryptionpublic_key=github.actions.secrets.get_org_public_key()
# Encrypt and create a secretencrypted_value=github.encrypt_secret(
public_key=public_key["data"]["key"],
secret_value="my-secret-value"
)
github.actions.secrets.create_or_update_org_secret(
secret_name="MY_SECRET",
encrypted_secret_value=encrypted_value,
visibility="selected",
selected_repository_ids=[123456, 789012]
)
# Add repository access to a secretgithub.actions.secrets.add_repo_access_to_org_secret(
secret_name="MY_SECRET",
repo_id=123456
)# List artifacts for a repositoryartifacts=github.actions.artifacts.list_artifacts(repo="my-repo")
# Get a specific artifactartifact=github.actions.artifacts.get_an_artifact(
repo="my-repo",
artifact_id=12345
)
# Delete an artifactgithub.actions.artifacts.delete_an_artifact(
repo="my-repo",
artifact_id=12345
)github=GitHubModules(token="your_token", org="my-org")
# List all teamsteams=github.team.teams.list_teams()
# Create a new teamnew_team=github.team.teams.create_team(
name="backend-developers",
description="Backend development team",
privacy="closed",
permission="push"
)
# Get team by slugteam=github.team.teams.get_team_by_name(team_slug="backend-developers")
# Update teamgithub.team.teams.update_team(
team_slug="backend-developers",
description="Updated description"
)
# Delete teamgithub.team.teams.delete_team(team_slug="old-team")# List team membersmembers=github.team.members.list_team_members(
team_slug="backend-developers",
role="all"
)
# Add a member to a teamgithub.team.members.add_or_update_team_membership(
team_slug="backend-developers",
username="new-developer",
role="member"# or "maintainer"
)
# Remove a member from a teamgithub.team.members.remove_team_membership(
team_slug="backend-developers",
username="former-developer"
)github=GitHubModules(token="your_token", org="my-org")
# List pull requestsprs=github.pull_request.pull_requests.list_pull_requests(
repo="my-repo",
state="open"
)
# Create a pull requestnew_pr=github.pull_request.pull_requests.create_pull_request(
repo="my-repo",
head="feature-branch",
base="main",
title="Add new feature",
body="This PR adds a new feature...",
draft=False
)
# Get pull request detailspr=github.pull_request.pull_requests.get_pull_request(
repo="my-repo",
pull_number=42
)
# List files changed in a PRfiles=github.pull_request.pull_requests.list_pull_requests_files(
repo="my-repo",
pull_number=42
)
# Check if PR is mergedis_merged=github.pull_request.pull_requests.check_if_pull_request_merged(
repo="my-repo",
pull_number=42
)github=GitHubModules(token="your_token", org="my-org")
# List assignees for a repositoryassignees=github.issue.assignees.list_assignees(repo="my-repo")
# Check if user can be assignedcan_assign=github.issue.assignees.check_if_user_can_be_assigned(
repo="my-repo",
username="developer"
)
# Add assignees to an issuegithub.issue.assignees.add_assignee(
repo="my-repo",
issue_number=123,
assignees=["developer1", "developer2"]
)# List comments for a repositorycomments=github.issue.comments.list_comments_for_repository(
repo="my-repo",
sort="created",
direction="desc"
)
# Get a specific commentcomment=github.issue.comments.get_comment(
repo="my-repo",
comment_id=456789
)github=GitHubModules(token="your_token", org="my-org")
# List branchesbranches=github.branch.branches.list_branches(
repo="my-repo",
protected=True# Filter protected branches only
)
# Get a specific branchbranch=github.branch.branches.get_branch(
repo="my-repo",
branch="main"
)
# Rename a branchgithub.branch.branches.rename_branch(
repo="my-repo",
old_branch="master",
new_branch="main"
)
# Merge branchesgithub.branch.branches.merge_branch(
repo="my-repo",
base="main",
head="feature-branch",
commit_message="Merge feature-branch into main"
)
# Sync fork with upstreamgithub.branch.branches.sync_fork_branch_upstream(
repo="my-forked-repo",
branch="main"
)github=GitHubModules(token="your_token", owner="my-username")
# List releasesreleases=github.release.releases.list_releases(repo="my-repo")
# Create a releasenew_release=github.release.releases.create_release(
repo="my-repo",
tag_name="v1.0.0",
name="Version 1.0.0",
body="## What's New\n- Feature A\n- Bug fix B",
draft=False,
prerelease=False,
generate_release_notes=True
)
# Get the latest releaselatest=github.release.releases.get_latest_release(repo="my-repo")
# Get release by tagrelease=github.release.releases.get_release_by_tag(
repo="my-repo",
tag="v1.0.0"
)github=GitHubModules(token="your_token", org="my-org")
# Get Copilot billing infobilling=github.copilot.user_management.get_org_seat_info_settings()
# List seat assignmentsseats=github.copilot.user_management.list_org_seat_assignments(per_page=100)
# Assign Copilot seats to usersgithub.copilot.user_management.add_users_seat_assignments(
selected_usernames=["developer1", "developer2"]
)
# Remove Copilot seats from usersgithub.copilot.user_management.remove_users_seat_assignments(
selected_usernames=["former-employee"]
)
# Assign seats to teamsgithub.copilot.user_management.add_teams_seat_assignments(
selected_teams=["engineering-team", "devops-team"]
)# Get organization-wide metricsmetrics=github.copilot.metrics.get_org_metrics(
since="2024-01-01T00:00:00Z",
until="2024-01-31T23:59:59Z"
)
# Get team-specific metricsteam_metrics=github.copilot.metrics.get_team_metrics(
team_slug="engineering-team",
since="2024-01-01T00:00:00Z"
)github=GitHubModules(token="your_token", org="my-org", owner="my-username")
# List organization Dependabot alertsorg_alerts=github.dependabot.alerts.list_org_dependabot_alerts(
state="open",
severity="high"
)
# List repository Dependabot alertsrepo_alerts=github.dependabot.alerts.list_repository_dependabot_alerts(
repo="my-repo",
state="open",
ecosystem="npm"
)
# Get a specific alertalert=github.dependabot.alerts.get_dependabot_alert(
repo="my-repo",
alert_number=42
)
# Dismiss an alertgithub.dependabot.alerts.update_dependabot_alert(
repo="my-repo",
alert_number=42,
state="dismissed",
dismissal_reason="not_used",
dismissal_message="This dependency is not used in production"
)All API responses follow a consistent format:
{
"status_code": 200, # HTTP status code"data": { ... } # Response payload (dict, list, or primitive type)
}response=github.repository.repositories.get_repository(repo="my-repo")
ifresponse["status_code"] ==200:
repo_data=response["data"]
print(f"Repository: {repo_data['name']}")
print(f"Stars: {repo_data['stargazers_count']}")
else:
print(f"Error: {response['data']}")fromgithubimportGitHubModulesgithub=GitHubModules(token="your_token", org="my-org", log_level="DEBUG")
try:
response=github.repository.repositories.get_repository(repo="non-existent-repo")
ifresponse["status_code"] ==404:
print("Repository not found")
elifresponse["status_code"] ==403:
print("Access forbidden - check your token permissions")
elifresponse["status_code"] ==401:
print("Authentication failed - invalid token")
elifresponse["status_code"] >=400:
print(f"Error: {response['data']}")
else:
print(f"Success: {response['data']}")
exceptExceptionase:
print(f"Request failed: {e}")Here's a complete example script that adds repository access to organization secrets:
importosfromtypingimportListfromgithubimportGitHubModulesdefget_secret_names(github: GitHubModules) ->List[str]:
"""Retrieve all organization secret names."""secrets_list: List[str] = []
page=1whileTrue:
response=github.actions.secrets.list_org_secrets(per_page=100, page=page)
secrets=response.get("data", {}).get("secrets", [])
forsecretinsecrets:
secrets_list.append(secret["name"])
iflen(secrets) <100:
breakpage+=1returnsecrets_listdefadd_repo_access_to_secrets(
secrets_list: List[str],
repo_id: int,
github: GitHubModules,
prefix_filter: str=""
) ->None:
"""Add repository access to organization secrets."""forsecret_nameinsecrets_list:
ifprefix_filterandprefix_filternotinsecret_name:
continueresponse=github.actions.secrets.add_repo_access_to_org_secret(
secret_name=secret_name,
repo_id=repo_id
)
ifresponse.get("status_code") ==204:
print(f"✓ Added access to '{secret_name}'")
else:
print(f"✗ Failed for '{secret_name}': {response}")
defmain():
github_token=os.environ.get("GH_TOKEN")
github=GitHubModules(
github_token,
org="my-organization",
log_level="INFO"
)
# Get repository IDrepo_response=github.repository.repositories.get_repository(repo="my-repo")
repo_id=repo_response["data"]["id"]
# Get all secrets and add accesssecrets=get_secret_names(github)
add_repo_access_to_secrets(secrets, repo_id, github)
if__name__=="__main__":
main()This project is open source and available under the MIT License.