Library / SDK
sigmavirus24/github3.py avatar
sigmavirus24/github3.py

sigmavirus24/github3.py: an object model over the GitHub REST API

Hi, I'm a library for interacting with GItHub's REST API in a convenient and ergonomic way. I work on Python 3.6+.

1,259 stars406 forksPythonBSD-3-Clause

At a glance

What is it?
github3.py is a BSD licensed Python library that wraps the GitHub REST API in a set of Python objects, with a four dependency base of requests, uritemplate, python-dateutil and PyJWT, a test suite that records real API traffic with Betamax, and a packaging setup that keeps the source in a src directory with the version read from a single file. The library supports Python 3.7 and later, or pypy3.
Who is it for?
Adopt github3.py if you want to work with GitHub from Python in an object oriented way rather than assembling URLs and dictionaries by hand, since the library has been maintained for a long time and its test suite replays recorded API traffic, which is what keeps a client like this working as the API changes. Do not adopt it if your GitHub integration is a one-off script, because the dependency and the object model are more than you need there.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library is

github3.py describes itself as a comprehensive, actively developed and extraordinarily stable wrapper around the GitHub API, version 3, and the project description in the repository metadata is a first person version of the same claim, a library for interacting with GitHub's REST API in a convenient and ergonomic way.

Those adjectives are the project's own, and it is worth separating them. The claim that is checkable is the era: the library has been in the ecosystem long enough that its author, Ian Stapleton Cordasco, is also the author of betamax, the HTTP recording library the tests are built on. A wrapper for a large REST API that has been maintained across that many GitHub API changes is a real asset, because the work is in the maintenance.

The shape of the library is an object model rather than a thin request layer. Repositories, issues, pull requests, users, organisations and the rest are Python objects with methods, and the objects are returned by the client rather than assembled by the caller. That is the difference from using `requests` against `api.github.com` directly, and it is the reason to accept four dependencies.

The documentation is on Read the Docs at github3.readthedocs.io, with a section of more examples, a changelog in the release notes, and links to the released versions.

The dependency list explains the design

Four runtime dependencies, and each one tells you what part of the GitHub API is awkward.

`requests` is the HTTP layer, with the version floor at 2.18, which is a very old floor and a sign the project has kept the dependency range wide on purpose.

`uritemplate` is the interesting one, and it is the reason the library is comfortable with GitHub's API. GitHub's endpoints use URI templates, the `{/owner}{/repo}` style, so a client that wants to support them properly needs a template expander rather than string concatenation. The uritemplate implementation is by the same author, and the floor is 3.0.0.

`python-dateutil` handles the timestamp parsing, which matters because GitHub returns timestamps in several formats and a client that hands you strings instead of datetimes is a client you will end up parsing by hand anyway.

`PyJWT` with the crypto extra, at 2.3.0 or later, is for the signed parts of the API, and the fact that the crypto extra is required rather than optional tells you the library supports the endpoints that involve a signed payload rather than only the plain REST ones.

The project metadata is otherwise conservative. The licence is BSD-3-Clause with the licence file declared, the development status is Production/Stable, the audience is Developers, and it is CPython only, which is worth noting given that the README says the library works with pypy3 as well.

Testing: recorded traffic, then tox across environments

The testing setup is the part of the repository that reveals how the maintainer works, and it is a good model for any client library.

The test suite needs two extra packages, betamax and coverage, and they can be installed either with `pip install -e .[dev]` or with `make test-deps`, and the documentation suggests doing it in a virtual environment. The optional test dependencies in the packaging list them properly, with pytest and pytest-xdist for parallel runs, betamax and betamax_matchers.

Betamax is the important one. It is an HTTP recording and playback library, so the test suite runs against recorded responses rather than against the live GitHub API. That has two consequences. The tests are deterministic and they do not consume rate limit, and more importantly they do not fail because GitHub changed something overnight, which is the failure mode that makes a client library's test suite useless in CI.

The Makefile shows the shape of the workflow. The default goal is the tests, which delegate to a `ga` target that runs tox, so the suite is run across the environment matrix tox defines rather than in one interpreter. There is a `test-deps` target for the editable install, an `htmlcov` target that generates coverage HTML while omitting the `github3/packages` directory from the report, and a `docs` target that builds the documentation through tox. The `clean` target removes the ignored files and the build and dist directories.

The repository also carries a `report_issue.py` script, which is a small convenience for the kind of project where users file bugs against a service they do not control.

Packaging: src layout, one version file, and 78 columns

The packaging is modern and the details are worth a look.

The build backend is hatchling, with the version marked dynamic and read from a single file, `src/github3/__about__.py`, which means the version number exists in exactly one place and the build picks it up. The layout is a src directory, so an accidental import of the working tree rather than the installed package is not possible, and both the sdist and the wheel targets are configured with `strict-naming = false`, which is the kind of small accommodation that a package with a dotted name needs.

The formatter configuration is Black with a line length of 78 and a target version of py37, which is a smaller line length than most modern Python projects use and a visible statement about the code's era. The exclusion list in the Black configuration skips a handful of directories, which in a project with vendored or generated files is the usual reason to have one.

The rest of the tree follows the same pattern of a mature library: a `tox.ini` for the environment matrix, a `.pre-commit-config.yaml`, a `.readthedocs.yml` for the documentation build, a `MANIFEST.in` for the source distribution, an `AUTHORS.rst`, a `CODE_OF_CONDUCT.md` and a `SECURITY.md`.

There is also an `example-notebooks/` directory, which is a nice touch for a library whose documentation is otherwise prose and API reference, since a notebook shows the object model in use.

Where github3.py is the wrong choice

The first wrong case is a script that makes three API calls. For that, `requests` against the API is a dozen lines with no dependency and no object model to learn, and a library is a poor trade at that scale.

The second is a project that wants the newest GitHub surface. The library wraps the v3 REST API, and GitHub's direction has been towards GraphQL for the endpoints that need multiple round trips. A project that wants a single query for a complex view of a repository will find the REST model awkward, because the library is organised around one endpoint per method.

The third is a project that needs to be sure about the API's current behaviour. The library's own strength is that it has been maintained against API changes for years, and that is also its risk, because a maintained wrapper lags a moment behind a brand new endpoint. The answer is to check the documentation for the specific call you need, and the release notes are where you will find out what was added when.

The fourth is a support story. This is a library maintained by one person, and the contact options in the README are a Stack Overflow tag, GitHub discussions and an email address, with the author asking that discussions be preferred over Stack Overflow and that the email be used if you wish to include sensitive data. That is a healthy, small project support model, and it is also one person.

On the state of the project, the repository is not archived and the last push was on 2026-10-12, and there are no GitHub releases, so the version history lives in the documentation's release notes, which the packaging metadata links from the project URLs. The licence is the modified BSD, and the package is on PyPI under the name `github3.py`.

Editorial conclusion

Adopt github3.py if you want to work with GitHub from Python in an object oriented way rather than assembling URLs and dictionaries by hand, since the library has been maintained for a long time and its test suite replays recorded API traffic, which is what keeps a client like this working as the API changes. Do not adopt it if your GitHub integration is a one-off script, because the dependency and the object model are more than you need there. Verify first that the endpoints you use are in the version of the library you install, since GitHub adds and changes API surface continuously and this library tracks the v3 REST API, and check the release notes in the documentation before a major upgrade, because the repository itself publishes no GitHub releases and the changelog lives in the docs.

Frequently asked questions

What is github3.py?

It is a comprehensive wrapper around the GitHub REST API, version 3, for Python, presenting GitHub's resources as Python objects with methods rather than as URLs and dictionaries. It is BSD licensed, with the author Ian Stapleton Cordasco, and the documentation is at github3.readthedocs.io.

Which Python versions does github3.py support?

The library currently works with Python 3.7 and later, or pypy3, and for older versions you should use version 1.3.0. The package metadata sets `requires-python` to 3.7 or above and classifies the project as CPython only, despite the pypy3 support statement in the README.

What does github3.py depend on?

Four runtime dependencies, requests at 2.18 or newer, uritemplate at 3.0.0 or newer for expanding GitHub's URI template endpoints, python-dateutil at 2.6.0 or newer for timestamp parsing, and PyJWT with the crypto extra at 2.3.0 or newer for the signed parts of the API.

How are the github3.py tests run?

The test suite uses betamax to record and replay HTTP traffic so it is deterministic and does not hit the live API, and coverage for the report. `make tests` runs tox across the environment matrix, `make test-deps` does the editable install of the dev extras, and the packaging declares a test extra with pytest, pytest-xdist, betamax and betamax_matchers.

How is the github3.py version managed?

The build backend is hatchling and the version is dynamic, read from a single file at `src/github3/__about__.py`, with the source living in a src directory. The project publishes no GitHub releases, so the changelog lives in the documentation's release notes.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. sigmavirus24/github3.py on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sigmavirus24-github3-py.svg)](https://hysenlabs.com/projects/sigmavirus24-github3-py)

Was this useful?