Comprehensive Python client library providing full access to the GitHub REST API v3 for programmatic management of repositories, users, organizations, issues, pull requests, and other GitHub entities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
GitHub Actions workflow management, workflow runs, jobs, artifacts, and self-hosted runners. Supports automation and CI/CD pipeline integration with comprehensive access to GitHub Actions functionality.
Access and manage GitHub Actions workflows within repositories.
class Repository:
def get_workflows(self):
"""
Get repository workflows.
Returns:
PaginatedList[Workflow]: List of workflows
"""
def get_workflow(self, id_or_name: Union[int, str]):
"""
Get a specific workflow by ID or filename.
Args:
id_or_name (Union[int, str]): Workflow ID or filename
Returns:
Workflow: Workflow object
"""
class Workflow:
@property
def id(self) -> int: ...
@property
def name(self) -> str: ...
@property
def path(self) -> str: ...
@property
def state(self) -> str: ... # "active", "deleted", "disabled_fork", "disabled_inactivity", "disabled_manually"
@property
def created_at(self) -> datetime: ...
@property
def updated_at(self) -> datetime: ...
@property
def url(self) -> str: ...
@property
def html_url(self) -> str: ...
@property
def badge_url(self) -> str: ...
def create_dispatch(self, ref: str, inputs: dict = None):
"""
Trigger a workflow dispatch event.
Args:
ref (str): Git reference (branch or tag) to run workflow on
inputs (dict, optional): Input parameters for the workflow
"""
def get_runs(
self,
actor: str = None,
branch: str = None,
event: str = None,
status: str = None,
created: str = None,
exclude_pull_requests: bool = None
):
"""
Get workflow runs.
Args:
actor (str, optional): Filter by actor username
branch (str, optional): Filter by branch name
event (str, optional): Filter by event type
status (str, optional): Filter by status ("completed", "action_required", "cancelled", "failure", "neutral", "skipped", "stale", "success", "timed_out", "in_progress", "queued", "requested", "waiting", "pending")
created (str, optional): Filter by creation date (ISO 8601)
exclude_pull_requests (bool, optional): Exclude pull request runs
Returns:
PaginatedList[WorkflowRun]: List of workflow runs
"""
def enable(self):
"""Enable the workflow."""
def disable(self):
"""Disable the workflow."""Manage individual workflow run instances, including cancellation, re-running, and accessing logs.
class Repository:
def get_workflow_runs(
self,
actor: str = None,
branch: str = None,
event: str = None,
status: str = None,
created: str = None,
exclude_pull_requests: bool = None
):
"""
Get all workflow runs for the repository.
Args:
actor (str, optional): Filter by actor username
branch (str, optional): Filter by branch name
event (str, optional): Filter by event type
status (str, optional): Filter by status
created (str, optional): Filter by creation date
exclude_pull_requests (bool, optional): Exclude PR runs
Returns:
PaginatedList[WorkflowRun]: List of workflow runs
"""
def get_workflow_run(self, id: int):
"""
Get a specific workflow run.
Args:
id (int): Workflow run ID
Returns:
WorkflowRun: Workflow run object
"""
class WorkflowRun:
@property
def id(self) -> int: ...
@property
def name(self) -> str: ...
@property
def head_branch(self) -> str: ...
@property
def head_sha(self) -> str: ...
@property
def path(self) -> str: ...
@property
def display_title(self) -> str: ...
@property
def run_number(self) -> int: ...
@property
def event(self) -> str: ...
@property
def status(self) -> str: ... # "queued", "in_progress", "completed", "waiting"
@property
def conclusion(self) -> str: ... # "success", "failure", "neutral", "cancelled", "skipped", "timed_out", "action_required"
@property
def workflow_id(self) -> int: ...
@property
def check_suite_id(self) -> int: ...
@property
def check_suite_node_id(self) -> str: ...
@property
def url(self) -> str: ...
@property
def html_url(self) -> str: ...
@property
def pull_requests(self) -> list: ...
@property
def created_at(self) -> datetime: ...
@property
def updated_at(self) -> datetime: ...
@property
def actor(self) -> NamedUser: ...
@property
def run_attempt(self) -> int: ...
@property
def referenced_workflows(self) -> list: ...
@property
def run_started_at(self) -> datetime: ...
@property
def triggering_actor(self) -> NamedUser: ...
@property
def jobs_url(self) -> str: ...
@property
def logs_url(self) -> str: ...
@property
def check_suite_url(self) -> str: ...
@property
def artifacts_url(self) -> str: ...
@property
def cancel_url(self) -> str: ...
@property
def rerun_url(self) -> str: ...
@property
def previous_attempt_url(self) -> str: ...
@property
def workflow_url(self) -> str: ...
@property
def head_commit(self) -> dict: ...
@property
def repository(self) -> Repository: ...
@property
def head_repository(self) -> Repository: ...
def cancel(self):
"""Cancel the workflow run."""
def rerun(self, enable_debug_logging: bool = None):
"""
Re-run the workflow run.
Args:
enable_debug_logging (bool, optional): Enable debug logging for re-run
"""
def rerun_failed_jobs(self, enable_debug_logging: bool = None):
"""
Re-run failed jobs in the workflow run.
Args:
enable_debug_logging (bool, optional): Enable debug logging for re-run
"""
def get_jobs(self, filter: str = None):
"""
Get jobs for the workflow run.
Args:
filter (str, optional): Filter jobs ("latest", "all")
Returns:
PaginatedList[WorkflowJob]: List of jobs
"""
def get_artifacts(self, name: str = None):
"""
Get artifacts for the workflow run.
Args:
name (str, optional): Filter by artifact name
Returns:
PaginatedList[Artifact]: List of artifacts
"""
def delete(self):
"""Delete the workflow run."""
def get_logs(self):
"""
Get logs archive URL for the workflow run.
Returns:
str: URL to download logs archive
"""
def delete_logs(self):
"""Delete logs for the workflow run."""
def get_pending_deployments(self):
"""
Get pending deployments for the workflow run.
Returns:
list: List of pending deployments
"""
def approve_pending_deployments(self, environment_ids: list, state: str, comment: str):
"""
Approve or reject pending deployments.
Args:
environment_ids (list): List of environment IDs
state (str): Approval state ("approved", "rejected")
comment (str): Approval comment
"""Access individual job information within workflow runs.
class WorkflowJob:
@property
def id(self) -> int: ...
@property
def run_id(self) -> int: ...
@property
def workflow_name(self) -> str: ...
@property
def head_branch(self) -> str: ...
@property
def run_url(self) -> str: ...
@property
def run_attempt(self) -> int: ...
@property
def node_id(self) -> str: ...
@property
def head_sha(self) -> str: ...
@property
def url(self) -> str: ...
@property
def html_url(self) -> str: ...
@property
def status(self) -> str: ... # "queued", "in_progress", "completed", "waiting"
@property
def conclusion(self) -> str: ... # "success", "failure", "neutral", "cancelled", "skipped", "timed_out", "action_required"
@property
def created_at(self) -> datetime: ...
@property
def started_at(self) -> datetime: ...
@property
def completed_at(self) -> datetime: ...
@property
def name(self) -> str: ...
@property
def steps(self) -> list: ... # List of WorkflowStep objects
@property
def check_run_url(self) -> str: ...
@property
def labels(self) -> list: ...
@property
def runner_id(self) -> int: ...
@property
def runner_name(self) -> str: ...
@property
def runner_group_id(self) -> int: ...
@property
def runner_group_name(self) -> str: ...
def get_logs(self):
"""
Get logs for the job.
Returns:
str: Job logs content
"""
class WorkflowStep:
@property
def name(self) -> str: ...
@property
def status(self) -> str: ...
@property
def conclusion(self) -> str: ...
@property
def number(self) -> int: ...
@property
def started_at(self) -> datetime: ...
@property
def completed_at(self) -> datetime: ...Handle workflow artifacts for storing and retrieving build outputs.
class Repository:
def get_artifacts(self, name: str = None):
"""
Get repository artifacts.
Args:
name (str, optional): Filter by artifact name
Returns:
PaginatedList[Artifact]: List of artifacts
"""
def get_artifact(self, artifact_id: int):
"""
Get a specific artifact.
Args:
artifact_id (int): Artifact ID
Returns:
Artifact: Artifact object
"""
class Artifact:
@property
def id(self) -> int: ...
@property
def node_id(self) -> str: ...
@property
def name(self) -> str: ...
@property
def size_in_bytes(self) -> int: ...
@property
def url(self) -> str: ...
@property
def archive_download_url(self) -> str: ...
@property
def expired(self) -> bool: ...
@property
def created_at(self) -> datetime: ...
@property
def expires_at(self) -> datetime: ...
@property
def updated_at(self) -> datetime: ...
@property
def workflow_run(self) -> dict: ...
def delete(self):
"""Delete the artifact."""
def download_url(self):
"""
Get download URL for the artifact.
Returns:
str: Download URL
"""Manage self-hosted runners for organizations and repositories.
class Repository:
def get_self_hosted_runners(self, name: str = None):
"""
Get self-hosted runners for the repository.
Args:
name (str, optional): Filter by runner name
Returns:
PaginatedList[SelfHostedActionsRunner]: List of runners
"""
def get_self_hosted_runner(self, runner_id: int):
"""
Get a specific self-hosted runner.
Args:
runner_id (int): Runner ID
Returns:
SelfHostedActionsRunner: Runner object
"""
def create_runner_registration_token(self):
"""
Create a registration token for adding a self-hosted runner.
Returns:
dict: Registration token information
"""
def create_runner_removal_token(self):
"""
Create a removal token for removing a self-hosted runner.
Returns:
dict: Removal token information
"""
def remove_self_hosted_runner(self, runner_id: int):
"""
Remove a self-hosted runner.
Args:
runner_id (int): Runner ID
"""
class Organization:
def get_self_hosted_runners(self, name: str = None):
"""
Get self-hosted runners for the organization.
Args:
name (str, optional): Filter by runner name
Returns:
PaginatedList[SelfHostedActionsRunner]: List of runners
"""
def get_self_hosted_runner(self, runner_id: int):
"""
Get a specific self-hosted runner.
Args:
runner_id (int): Runner ID
Returns:
SelfHostedActionsRunner: Runner object
"""
def create_runner_registration_token(self):
"""
Create a registration token for adding a self-hosted runner.
Returns:
dict: Registration token information
"""
def create_runner_removal_token(self):
"""
Create a removal token for removing a self-hosted runner.
Returns:
dict: Removal token information
"""
def remove_self_hosted_runner(self, runner_id: int):
"""
Remove a self-hosted runner.
Args:
runner_id (int): Runner ID
"""
class SelfHostedActionsRunner:
@property
def id(self) -> int: ...
@property
def name(self) -> str: ...
@property
def os(self) -> str: ...
@property
def status(self) -> str: ... # "online", "offline"
@property
def busy(self) -> bool: ...
@property
def labels(self) -> list: ...
def remove(self):
"""Remove the runner."""Manage repository secrets and variables for Actions workflows.
class Repository:
def get_secrets(self):
"""
Get repository secrets.
Returns:
PaginatedList[Secret]: List of secrets
"""
def get_secret(self, secret_name: str):
"""
Get a specific repository secret.
Args:
secret_name (str): Secret name
Returns:
Secret: Secret object
"""
def create_secret(self, secret_name: str, secret_value: str):
"""
Create or update a repository secret.
Args:
secret_name (str): Secret name
secret_value (str): Secret value
"""
def delete_secret(self, secret_name: str):
"""
Delete a repository secret.
Args:
secret_name (str): Secret name
"""
def get_variables(self):
"""
Get repository variables.
Returns:
PaginatedList[Variable]: List of variables
"""
def get_variable(self, variable_name: str):
"""
Get a specific repository variable.
Args:
variable_name (str): Variable name
Returns:
Variable: Variable object
"""
def create_variable(self, variable_name: str, value: str):
"""
Create or update a repository variable.
Args:
variable_name (str): Variable name
value (str): Variable value
"""
def delete_variable(self, variable_name: str):
"""
Delete a repository variable.
Args:
variable_name (str): Variable name
"""
class Secret:
@property
def name(self) -> str: ...
@property
def created_at(self) -> datetime: ...
@property
def updated_at(self) -> datetime: ...
class Variable:
@property
def name(self) -> str: ...
@property
def value(self) -> str: ...
@property
def created_at(self) -> datetime: ...
@property
def updated_at(self) -> datetime: ...from github import Github, Auth
g = Github(auth=Auth.Token("your_token"))
repo = g.get_repo("owner/repository")
# List all workflows
workflows = repo.get_workflows()
for workflow in workflows:
print(f"Workflow: {workflow.name} ({workflow.state})")
print(f"Path: {workflow.path}")
print(f"Badge: {workflow.badge_url}")
# Get specific workflow
workflow = repo.get_workflow("ci.yml")
print(f"Workflow ID: {workflow.id}")
# Trigger workflow dispatch
workflow.create_dispatch(
ref="main",
inputs={
"environment": "production",
"debug": "true"
}
)
print("Workflow dispatch triggered")# Get recent workflow runs
runs = repo.get_workflow_runs(status="completed")
for run in runs[:5]:
print(f"Run #{run.run_number}: {run.conclusion}")
print(f"Branch: {run.head_branch}")
print(f"Actor: {run.actor.login}")
print(f"Started: {run.run_started_at}")
# Get runs for specific workflow
ci_runs = workflow.get_runs(branch="main", status="completed")
for run in ci_runs[:3]:
print(f"CI Run: {run.conclusion} at {run.updated_at}")
# Cancel a running workflow
running_runs = repo.get_workflow_runs(status="in_progress")
if running_runs.totalCount > 0:
running_run = running_runs[0]
running_run.cancel()
print(f"Cancelled run #{running_run.run_number}")
# Re-run failed workflow
failed_runs = repo.get_workflow_runs(conclusion="failure")
if failed_runs.totalCount > 0:
failed_run = failed_runs[0]
failed_run.rerun_failed_jobs()
print(f"Re-running failed jobs for run #{failed_run.run_number}")# Get jobs for a specific run
run = repo.get_workflow_run(12345)
jobs = run.get_jobs()
for job in jobs:
print(f"Job: {job.name}")
print(f"Status: {job.status}")
print(f"Conclusion: {job.conclusion}")
print(f"Runner: {job.runner_name}")
# Get job steps
for step in job.steps:
print(f" Step: {step.name}")
print(f" Status: {step.status}")
print(f" Conclusion: {step.conclusion}")
# Get job logs
logs = job.get_logs()
print(f"Logs (first 200 chars): {logs[:200]}...")# List artifacts for repository
artifacts = repo.get_artifacts()
for artifact in artifacts:
print(f"Artifact: {artifact.name}")
print(f"Size: {artifact.size_in_bytes} bytes")
print(f"Expired: {artifact.expired}")
print(f"Created: {artifact.created_at}")
# Get artifacts for specific run
run_artifacts = run.get_artifacts()
for artifact in run_artifacts:
print(f"Run artifact: {artifact.name}")
# Get download URL (requires authentication)
download_url = artifact.download_url()
print(f"Download URL: {download_url}")
# Delete old artifacts
expired_artifacts = repo.get_artifacts()
for artifact in expired_artifacts:
if artifact.expired:
artifact.delete()
print(f"Deleted expired artifact: {artifact.name}")# List self-hosted runners
runners = repo.get_self_hosted_runners()
for runner in runners:
print(f"Runner: {runner.name}")
print(f"OS: {runner.os}")
print(f"Status: {runner.status}")
print(f"Busy: {runner.busy}")
print(f"Labels: {runner.labels}")
# Create registration token for new runner
token_info = repo.create_runner_registration_token()
print(f"Registration token: {token_info['token']}")
print(f"Expires at: {token_info['expires_at']}")
# Remove offline runners
for runner in runners:
if runner.status == "offline":
runner.remove()
print(f"Removed offline runner: {runner.name}")# List repository secrets
secrets = repo.get_secrets()
for secret in secrets:
print(f"Secret: {secret.name}")
print(f"Updated: {secret.updated_at}")
# Create/update secret
repo.create_secret("API_KEY", "secret_value_here")
print("Secret created/updated")
# List repository variables
variables = repo.get_variables()
for variable in variables:
print(f"Variable: {variable.name} = {variable.value}")
# Create/update variable
repo.create_variable("ENVIRONMENT", "production")
print("Variable created/updated")
# Delete old secrets
repo.delete_secret("OLD_API_KEY")
print("Old secret deleted")# Organization runners
org = g.get_organization("myorg")
org_runners = org.get_self_hosted_runners()
for runner in org_runners:
print(f"Org runner: {runner.name} ({runner.status})")
# Organization secrets
org_secrets = org.get_secrets()
for secret in org_secrets:
print(f"Org secret: {secret.name}")
# Create organization-level secret
org.create_secret("ORG_API_KEY", "organization_secret_value")
print("Organization secret created")from datetime import datetime, timedelta
# Get recent failed runs
recent_date = datetime.now() - timedelta(days=7)
recent_runs = repo.get_workflow_runs(
created=recent_date.isoformat(),
status="completed"
)
failed_count = 0
success_count = 0
for run in recent_runs:
if run.conclusion == "failure":
failed_count += 1
print(f"Failed run #{run.run_number}: {run.name}")
elif run.conclusion == "success":
success_count += 1
success_rate = success_count / (success_count + failed_count) * 100
print(f"Success rate in last 7 days: {success_rate:.2f}%")
# Find long-running jobs
for run in recent_runs[:10]:
jobs = run.get_jobs()
for job in jobs:
if job.started_at and job.completed_at:
duration = job.completed_at - job.started_at
if duration.total_seconds() > 1800: # 30 minutes
print(f"Long-running job: {job.name} took {duration}")Install with Tessl CLI
npx tessl i tessl/pypi-pygithub