Using Python PyGithub to Manage GitHub Actions Workflows
python pygithub github actions workflows: Learn how to use PyGithub to list, trigger, and monitor GitHub Actions workflows from Python, including authentication, pagin...
python pygithub github actions workflows requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
When you need to trigger or inspect GitHub Actions workflows from a Python script, PyGithub provides a direct way to interact with the GitHub API without writing raw HTTP calls. This article shows how to list workflows, dispatch runs, and monitor their status using PyGithub, covering the practical details that matter in real automation scripts.
Setting Up PyGithub and Authenticating
PyGithub is a Python library that wraps the GitHub REST API. Install it with pip install PyGithub. To access repository data, you need a personal access token or a GitHub App installation token. The token must have the appropriate scopes: repo for private repositories or public_repo for public ones, and workflow scope if you intend to trigger workflow runs.
from github import Github g = Github("your_token_here") repo = g.get_repo("owner/repository")
For automation, avoid hardcoding tokens. Use environment variables or a secrets manager. The token is passed to the Github constructor, and all subsequent API calls are authenticated automatically.
Listing Workflows in a Repository
To see all workflows defined in a repository, use get_workflows(). This returns a paginated list of Workflow objects, each with attributes like name, path, and id.
workflows = repo.get_workflows() for wf in workflows: print(wf.name, wf.path, wf.id)
This is useful for discovering workflow IDs, which you need to trigger a specific workflow. The path is the file path relative to .github/workflows/, such as deploy.yml.
Triggering a Workflow Run
To trigger a workflow that has a workflow_dispatch event, use create_workflow_dispatch(). This method requires the workflow ID and a reference (branch or tag). You can also pass inputs as a dictionary.
workflow = repo.get_workflow("deploy.yml") workflow.create_workflow_dispatch(ref="main", inputs={"environment": "staging"})
The ref must be a branch or tag that exists in the repository. If the workflow does not have workflow_dispatch configured, this call will fail with a GithubException. Make sure the workflow YAML includes the trigger:
on: workflow_dispatch: inputs: environment: type: string required: true
Monitoring Workflow Run Status
After dispatching a run, you often need to wait for it to complete and check the result. PyGithub provides get_workflow_runs() to list runs for a workflow, and you can filter by branch, status, or event.
runs = repo.get_workflow_runs("deploy.yml") latest_run = runs[0] print(latest_run.status, latest_run.conclusion)
To wait for a run to finish, poll the status attribute until it is completed. Be mindful of GitHub's API rate limits; a simple loop with time.sleep() is acceptable for short waits.
import time run = latest_run while run.status != "completed": time.sleep(5) run = run.refresh() # or re-fetch the run by ID
Note that refresh() is not a direct PyGithub method; you need to re-fetch the run using get_workflow_run(run.id). The example above is illustrative; adjust to your actual API calls.
Handling Pagination and Rate Limits
PyGithub returns paginated lists for collections like workflows and runs. By default, get_workflows() and get_workflow_runs() return a PaginatedList that lazily loads pages. You can iterate over all items, but be aware that each page consumes API rate limit.
all_runs = list(repo.get_workflow_runs("deploy.yml")) # loads all pages
For large repositories, this can be expensive. Use pagination parameters like per_page and page if you only need recent runs. PyGithub also exposes rate limit information via g.get_rate_limit(). To avoid hitting the limit, cache results and avoid repeated calls in loops.
Error Handling and Common Failures
Several errors can occur when working with workflows. The most common is GithubException with a 404 status, which means the workflow path or run ID does not exist. A 403 indicates insufficient permissions or a token without the workflow scope. A 422 often means invalid input, such as a missing required input field in workflow_dispatch.
from github import GithubException try: workflow.create_workflow_dispatch(ref="main", inputs={"env": "prod"}) except GithubException as e: print(f"Status: {e.status}, Message: {e.data.get('message')}")
Always validate that the workflow exists and the reference is correct before dispatching. Also, remember that workflow runs are asynchronous; the dispatch call returns immediately, and the run may take time to start.
Security and Token Scopes
When using PyGithub for workflow automation, token security is critical. Use a token with the minimum required scopes. For triggering workflows, the workflow scope is mandatory. If you only need to read workflow runs, repo or public_repo is sufficient. Never store tokens in source code; use environment variables or a secret manager. For GitHub Actions itself, you can use the built-in GITHUB_TOKEN with appropriate permissions, but that token is scoped to the current repository and cannot be used from external scripts.
For production automation, consider using a GitHub App instead of a personal token. GitHub Apps provide fine-grained permissions and rotating tokens. PyGithub supports GitHub App authentication via GithubIntegration, but that adds complexity. Choose the authentication method based on your environment and security requirements.