asyncgh
A minimal async GitHub API transport — the plumbing an account-wide config tool needs before any of its domain logic: authentication, a connection, retrying error handling, REST pagination, and GraphQL.
GitHubClient is the actual client. For a script that only ever talks to
one account, module-level functions (api_json, graphql, fetch_repos,
...) wrap one shared default instance, so there's nothing to construct --
they read the token gh auth login already stored and go. Construct a
GitHubClient directly to talk to a second account in the same process, use
your own retry budget, or as an async context manager.
How this compares
| Library | Async | Shape |
|---|---|---|
| PyGithub | no | typed objects |
| githubkit | yes | Pydantic models, generated from GitHub's OpenAPI spec |
| gidgethub | yes | sans-I/O, bring-your-own HTTP client |
| ghapi (fast.ai) | no | OpenAPI-generated, dynamic attribute access |
| asyncgh | yes | plain dicts, ~550 lines |
githubkit gives you typed responses and full API coverage, at the cost of
codegen'd models and a pydantic dependency. gidgethub is closest in
spirit -- sans-I/O, no models -- but leaves auth, retry, and the client
itself to the caller. asyncgh picks a specific point in that space: an
async client with almost no code between you and the wire, no generated
models or schema (you read GitHub's own docs and index the JSON), retry and
GraphQL built in rather than bolted on.
API
Full API reference, generated from the docstrings:
hugoh.github.io/fleet-tools/asyncgh
(rebuilt on every push that touches this package -- see
.github/workflows/docs.yml).
Auth
Authorization: Bearer $(gh auth token), resolved lazily on the first
request and cached for the client's lifetime. gh must be installed and
logged in -- or pass GitHubClient(token=...) to skip the gh dependency
entirely and use your own.
Retries
api_raw retries transport errors (DNS, timeout, reset) and transient
statuses — 429, 500, 502, 503, 504 — via stamina.
A Retry-After header sets the exact wait; otherwise exponential backoff with
jitter. max_retries (default from GH_MAX_RETRIES, else 3) caps the
retries per GitHubClient instance; there is no wall-clock timeout, so a
minute-long Retry-After is honoured in full. When the retries are spent the
last response is returned unchanged for the caller to judge.
graphql() retries the same cases (transport errors, 429/5xx) plus one more,
in the same single retry loop: GitHub answers GraphQL rate limiting with HTTP
200 and an errors[].type == "RATE_LIMITED" body, invisible to a
status-based retry. Any other GraphQL error (bad query, not found) is not
transient and raises immediately, with the failing error's type on
GhError.error_type.
Consumers
repo-admin/ (in this repo) uses it for every account-wide GitHub command --
repo_admin.py's sync subcommands and activity.py via api_raw/
api_json/pagination; digest.py (wrapped by ../digest-action/) is the
one driving graphql().
Metadata
Release files for asyncgh 0.5.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| asyncgh-0.5.3.tar.gz | 16.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asyncgh-0.5.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.8 kB
Release files / asyncgh-0.5.3.tar.gz
| Download URL | asyncgh-0.5.3.tar.gz |
|---|---|
| Size | 16.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f1c3135d1cab73acdae5a07083607722e83d1e0998ee37e9eec029250969de43
|
|
BLAKE2b-256 checksum How to use checksums |
fc880d8c2323954280775a97aafe088c6bbdcb99747107dbcec934afe74246cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / asyncgh-0.5.3-py3-none-any.whl
| Download URL | asyncgh-0.5.3-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e801716f89210a2c7688d47d06243c2c24d0ee21152dbfa7be50a33bf687873
|
|
BLAKE2b-256 checksum How to use checksums |
7a8b2b56ffc7085b6a02c8a42c005d31eb2052e5f0d919f9480e858aabe5d42b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency log