An asynchronous GitHub API library designed as a sans-I/O library for GitHub API access
—
Ready-to-use implementations of the GitHubAPI abstract base class for popular asynchronous HTTP libraries. These implementations handle the low-level HTTP details while providing the same high-level GitHub API interface.
Implementation using the aiohttp library for HTTP requests.
import aiohttp
from gidgethub.abc import GitHubAPI as GitHubAPIBase
class GitHubAPI(GitHubAPIBase):
"""aiohttp-based GitHub API client."""
def __init__(
self,
session: aiohttp.ClientSession,
*args: Any,
**kwargs: Any
) -> None:
"""
Initialize GitHub API client with aiohttp session.
Parameters:
- session: aiohttp ClientSession for making HTTP requests
- *args: Additional arguments passed to GitHubAPIBase
- **kwargs: Additional keyword arguments passed to GitHubAPIBase
"""
async def _request(
self,
method: str,
url: str,
headers: Mapping[str, str],
body: bytes = b""
) -> Tuple[int, Mapping[str, str], bytes]:
"""Make an HTTP request using aiohttp."""
async def sleep(self, seconds: float) -> None:
"""Sleep for the specified number of seconds."""Implementation using the httpx library for HTTP requests.
import httpx
from gidgethub.abc import GitHubAPI as GitHubAPIBase
class GitHubAPI(GitHubAPIBase):
"""httpx-based GitHub API client."""
def __init__(
self,
client: httpx.AsyncClient,
*args: Any,
**kwargs: Any
) -> None:
"""
Initialize GitHub API client with httpx client.
Parameters:
- client: httpx AsyncClient for making HTTP requests
- *args: Additional arguments passed to GitHubAPIBase
- **kwargs: Additional keyword arguments passed to GitHubAPIBase
"""
async def _request(
self,
method: str,
url: str,
headers: Mapping[str, str],
body: bytes = b""
) -> Tuple[int, Mapping[str, str], bytes]:
"""Make an HTTP request using httpx."""
async def sleep(self, seconds: float) -> None:
"""Sleep for the specified number of seconds."""Implementation using the Tornado HTTP client.
from tornado import httpclient
from gidgethub.abc import GitHubAPI as GitHubAPIBase
class GitHubAPI(GitHubAPIBase):
"""Tornado-based GitHub API client."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
Initialize GitHub API client for Tornado.
Parameters:
- *args: Arguments passed to GitHubAPIBase
- **kwargs: Keyword arguments passed to GitHubAPIBase
Note: Uses Tornado's singleton AsyncHTTPClient internally
"""
async def _request(
self,
method: str,
url: str,
headers: Mapping[str, str],
body: bytes = b""
) -> Tuple[int, Mapping[str, str], bytes]:
"""Make an HTTP request using Tornado."""
async def sleep(self, seconds: float) -> None:
"""Sleep for the specified number of seconds."""import asyncio
import aiohttp
from gidgethub.aiohttp import GitHubAPI
async def aiohttp_example():
async with aiohttp.ClientSession() as session:
gh = GitHubAPI(session, "my-app/1.0", oauth_token="your_token")
# Use any GitHubAPI method
repo = await gh.getitem("/repos/octocat/Hello-World")
print(f"Repository: {repo['name']}")
# Create an issue
issue = await gh.post(
"/repos/owner/repo/issues",
data={"title": "Test issue", "body": "Issue description"}
)
print(f"Created issue #{issue['number']}")
asyncio.run(aiohttp_example())import asyncio
import httpx
from gidgethub.httpx import GitHubAPI
async def httpx_example():
async with httpx.AsyncClient() as client:
gh = GitHubAPI(client, "my-app/1.0", oauth_token="your_token")
# Same interface as other implementations
user = await gh.getitem("/user")
print(f"Authenticated as: {user['login']}")
# Iterate through repositories
async for repo in gh.getiter("/user/repos"):
print(f"Repository: {repo['name']}")
# GraphQL query
query = """
query {
viewer {
login
repositories(first: 5) {
nodes {
name
stargazerCount
}
}
}
}
"""
result = await gh.graphql(query)
print(f"GraphQL result: {result['viewer']['login']}")
asyncio.run(httpx_example())import asyncio
from tornado import httpclient
from gidgethub.tornado import GitHubAPI
async def tornado_example():
# Tornado implementation doesn't require external session/client
gh = GitHubAPI("my-app/1.0", oauth_token="your_token")
try:
# Check rate limit
rate_limit = await gh.getitem("/rate_limit")
print(f"Rate limit: {rate_limit['rate']['remaining']}/{rate_limit['rate']['limit']}")
# Get organization info
org = await gh.getitem("/orgs/github")
print(f"Organization: {org['name']}")
finally:
# Clean up Tornado's HTTP client
httpclient.AsyncHTTPClient().close()
asyncio.run(tornado_example())import asyncio
import aiohttp
from gidgethub.aiohttp import GitHubAPI
async def custom_timeout_example():
# Configure custom timeouts
timeout = aiohttp.ClientTimeout(total=30, connect=10)
async with aiohttp.ClientSession(timeout=timeout) as session:
gh = GitHubAPI(session, "my-app/1.0")
try:
repo = await gh.getitem("/repos/octocat/Hello-World")
print(f"Repository loaded: {repo['name']}")
except asyncio.TimeoutError:
print("Request timed out")
asyncio.run(custom_timeout_example())import asyncio
import httpx
from gidgethub.httpx import GitHubAPI
from gidgethub import HTTPException, RateLimitExceeded
async def error_handling_example():
async with httpx.AsyncClient() as client:
gh = GitHubAPI(client, "my-app/1.0", oauth_token="your_token")
try:
# Attempt to access a private repository
repo = await gh.getitem("/repos/private-org/private-repo")
except HTTPException as exc:
if exc.status_code == 404:
print("Repository not found or access denied")
else:
print(f"HTTP error: {exc.status_code}")
except RateLimitExceeded as exc:
print(f"Rate limit exceeded. Resets at: {exc.rate_limit.reset_datetime}")
asyncio.run(error_handling_example())import asyncio
import aiohttp
from gidgethub.aiohttp import GitHubAPI
async def enterprise_example():
async with aiohttp.ClientSession() as session:
# Use GitHub Enterprise Server
gh = GitHubAPI(
session,
"my-app/1.0",
oauth_token="your_token",
base_url="https://github.company.com/api/v3"
)
# Same API, different server
user = await gh.getitem("/user")
print(f"Enterprise user: {user['login']}")
asyncio.run(enterprise_example())| Feature | aiohttp | httpx | Tornado |
|---|---|---|---|
| Session Management | Required | Required | Built-in |
| HTTP/2 Support | No | Yes | No |
| Timeout Configuration | Flexible | Flexible | Limited |
| Connection Pooling | Yes | Yes | Yes |
| Proxy Support | Yes | Yes | Yes |
| SSL/TLS Configuration | Advanced | Advanced | Basic |
| Community Support | Large | Growing | Mature |
All implementations provide identical GitHub API functionality through the same interface.
from typing import Any, Mapping, Tuple
import aiohttp
import httpx
from tornado import httpclient
# Implementation-specific session/client types
AiohttpSession = aiohttp.ClientSession
HttpxClient = httpx.AsyncClient
TornadoClient = httpclient.AsyncHTTPClient # Used internallyInstall with Tessl CLI
npx tessl i tessl/pypi-gidgethub