Skip to main content

Async Python wrapper for the GitHub API

Project description

asyncPyGithub

Testing Linting Type-Check Python 3.12+ Code style: black Validation: Pydantic v2

A fully asynchronous Python library for the GitHub API.

Install

git clone https://github.com/sudoDeVinci/asyncPyGithub.git
cd asyncPyGithub
pip install -r requirements.txt

Setup

Create a .env file:

GITHUB_TOKEN=your_token_here

Client Lifecycle

The library uses a shared httpx.AsyncClient under the hood. You have two options for managing it:

Option 1: Let it auto-start (simple)

The client starts automatically on first request. Just remember to close it when done:

import asyncio
from asyncPyGithub import GitHubPortal, GitHubUserPortal

async def main():
    # Client starts automatically on first request
    status, user = await GitHubPortal.authenticate("your_token")
    if status != 200:
        print(f"Auth failed: {user.message}")
        return
    
    print(f"Logged in as {user.login}")
    
    # Do stuff...
    status, other = await GitHubUserPortal.get_by_username("torvalds")
    if status == 200:
        print(f"Found: {other.login}")
    
    # Clean up when done
    await GitHubPortal.close()

asyncio.run(main())

Option 2: Use the context manager (scoped)

For scoped usage where you want automatic cleanup:

import asyncio
from asyncPyGithub import GitHubPortal, GitHubUserPortal

async def main():
    async with GitHubPortal.scoped_client():
        status, user = await GitHubPortal.authenticate("your_token")
        if status != 200:
            return
        
        status, other = await GitHubUserPortal.get_by_username("torvalds")
        # Client closes automatically when exiting the context

asyncio.run(main())

Concurrent Requests

The client uses connection pooling, so concurrent requests share connections efficiently:

import asyncio
from asyncPyGithub import GitHubPortal, GitHubUserPortal, GitHubRepositoryPortal

async def main():
    status, user = await GitHubPortal.authenticate("your_token")
    if status != 200:
        return
    
    # All requests run concurrently over the shared client
    results = await asyncio.gather(
        GitHubUserPortal.get_by_id(user.id),
        GitHubUserPortal.get_by_username(user.login),
        GitHubUserPortal.all(since=0, per_page=5),
        GitHubRepositoryPortal.get_organization_repos("LEGO", per_page=5),
    )
    
    for status, data in results:
        if status == 200:
            print(f"OK: {type(data).__name__}")
        else:
            print(f"Error: {data.message}")
    
    await GitHubPortal.close()

asyncio.run(main())

API

Every method returns tuple[int, Result | ErrorMessage]. Check the status code first.

GitHubPortal

Method What it does
authenticate(token) Auth and get your user info. Starts client if needed.
start() Manually start the HTTP client
close() Close the HTTP client
scoped_client() Context manager that auto-closes on exit

GitHubUserPortal

Method What it does
update(changes) Update your profile
get_by_id(uid) Get user by ID
get_by_username(username) Get user by username
all(since, per_page) List users
get_hovercard(username) Get hovercard info

GitHubRepositoryPortal

Method What it does
get_organization_repos(org, ...) List org repos
create_organization_repo(org, name, ...) Create repo in org
get_user_repo(owner, repo) Get a specific repo
update_repository(owner, repo, ...) Update repo settings
delete_repository(owner, repo) Delete a repo
list_contributors(owner, repo) List contributors
list_repository_languages(owner, repo) Get language breakdown
list_repository_tags(owner, repo) List tags
get_repository_topics(owner, repo) Get topics

Error Handling

status, result = await GitHubUserPortal.get_by_username("doesnt-exist")

if status == 200:
    print(result.login)
else:
    # result is an ErrorMessage
    print(f"Error {result.code}: {result.message}")

Structure

GitHubPortal              # Base - auth, client management
├── GitHubUserPortal      # /user and /users endpoints
└── GitHubRepositoryPortal # /repos and /orgs/.../repos endpoints

All responses are Pydantic models (PrivateUser, SimpleUser, MinimalRepository, etc.).

Testing

pip install -r requirements-dev.txt
pytest

Limitations

  • No rate limit handling
  • No pagination helpers
  • No webhooks

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asyncpygithub-0.1.0.tar.gz (26.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

asyncpygithub-0.1.0-py3-none-any.whl (28.1 kB view details)

Uploaded Python 3

File details

Details for the file asyncpygithub-0.1.0.tar.gz.

File metadata

  • Download URL: asyncpygithub-0.1.0.tar.gz
  • Upload date:
  • Size: 26.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for asyncpygithub-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ff6d687cc4fa3ea5456924ab50baf2c228f91260f0fe3c1a12aa3ab789990d0a
MD5 4c1e6ee57470f8103bdef22c22273a4b
BLAKE2b-256 f7cf035f29de941e780d1588d191ac870d926256ea23764e0f186bace03e3b83

See more details on using hashes here.

File details

Details for the file asyncpygithub-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: asyncpygithub-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for asyncpygithub-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b25e18cde7b6267cc58e546a16b831fc8390788f6281f42f12919e9829a927c6
MD5 d2126558b748b465d415fa8b47bfedb9
BLAKE2b-256 01a452efdc174f00443a8ed1731b9dc54a34801903b83449a31b734752692e90

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page