ghapi is a Python client library and command-line interface that wraps GitHub's entire REST API, built for Python developers, notebook users, and script authors who want to call GitHub endpoints without hand-writing HTTP requests.
What it is
ghapi is a Python package, released under the Apache-2.0 licence, that exposes GitHub's REST API as a structured set of callable operations. It lives in the Python ecosystem and is developed with nbdev, the notebook-driven development toolchain associated with fast.ai, which is also why the documentation is hosted at ghapi.fast.ai. Version 2, released in July 2026, is async by default: every API call is awaited, so a repository lookup reads as res = await api.repos.get(). Operation names follow the shape of the GitHub REST API itself — the git group contains git.create_blob, git.create_commit, git.create_ref, git.create_tag, git.create_tree, git.delete_ref, git.get_blob, git.get_commit, git.get_ref, git.get_tag, git.get_tree, git.list_matching_refs, and git.update_ref — so the client's surface mirrors the official documentation rather than inventing a new vocabulary.
The concrete problem it solves is the boilerplate tax of talking to GitHub directly. Instead of assembling URLs, managing authentication headers, encoding JSON bodies, and handling pagination by hand, a caller invokes a named operation and passes arguments. The same operations are reachable from the shell through a ghapi command, which means a one-off query does not require writing a Python file at all. In that sense it replaces hand-rolled requests calls and ad-hoc curl invocations against the GitHub REST endpoints with a single, uniformly generated interface.
Key capabilities
- Async-by-default API in v2: calls such as
res = await api.repos.get() are awaited, with top-level await working directly in Jupyter and modern REPLs.
- Sync compatibility mode for existing code: construct
GhApi(sync=True) to keep synchronous behaviour that is largely compatible with v1.
- Shell command with tab completion: typing
ghapi git. and pressing Tab lists every operation in the git group, and typing ghapi g lists all groups beginning with g.
- Per-operation help:
ghapi git.get_ref --help prints the accepted signature, shown as git.get_ref(owner, repo, ref), along with a link to the matching page under docs.github.com/rest/reference/.
- Extra request headers via
--headers, supplied as a JSON-encoded list.
- Authentication through
--token, which accepts a GitHub authentication token on the command line.
- Request tracing with
--debug, which prints requests before they are sent.
Who uses it and how
- Notebook users working in Jupyter or nbdev can await API calls at the top level of a cell, without wrapping each call in an event loop.
- Script authors writing standalone Python run their async calls inside
asyncio.run, the documented approach for non-notebook contexts.
- Shell users issue ad-hoc GitHub queries through the
ghapi command and rely on tab completion to discover operation names and groups interactively.
- Teams with existing synchronous codebases keep working by constructing
GhApi(sync=True), or by pinning to the previous major version rather than migrating.
- Automated jobs that need non-default behaviour pass
--token for authentication, --headers for extra JSON-encoded headers, and --debug to inspect outgoing requests.
Getting started
Install the ghapi Python package; the project is versioned so that pinning keeps an existing deployment on the pre-v2 line. From there, either await calls in Python (res = await api.repos.get()), construct GhApi(sync=True) for synchronous use, or run the ghapi command directly against an operation such as git.get_ref.
How it compares
The provided facts name no paid products that ghapi replaces, and no comparable client libraries by name. On the evidence available, it stands alone in this registry as the Python GitHub REST API client.
When to use it — and when not to
The main cost of adoption is the v2 migration: async-by-default means existing synchronous code must either switch to GhApi(sync=True), be rewritten around asyncio.run, or stay pinned to the older release. The project carries 49 open issues against 686 stars, so users should expect an actively changing surface rather than a frozen one. Anyone unwilling to track breaking changes, or needing a client for a language other than Python, should look elsewhere.