A python client for the GitHub API
—
Authentication module providing OAuth device flow authentication, token management, and GitHub API scope handling for secure API access.
OAuth device flow authentication for obtaining GitHub access tokens interactively.
class GhDeviceAuth:
def __init__(self, client_id=None, *scopes):
"""
Initialize OAuth device flow authentication.
Parameters:
- client_id: str, OAuth application client ID (optional)
- *scopes: GitHub OAuth scopes to request
"""
def url_docs(self) -> str:
"""
Get default authentication instructions.
Returns:
str: Instructions with user code and verification URL
"""
def open_browser(self):
"""
Open web browser with verification URL.
"""
def auth(self) -> str:
"""
Check if authentication is complete.
Returns:
str: Access token if complete, None if pending
Raises:
Exception: If authentication failed
"""
def wait(self, cb: callable = None, n_polls=9999) -> str:
"""
Wait for authentication completion.
Parameters:
- cb: callable, callback function called after each poll
- n_polls: int, maximum number of polls
Returns:
str: Access token when authentication completes
"""Simplified interactive authentication function.
def github_auth_device(wb='', n_polls=9999):
"""
Authenticate with GitHub using device flow.
Parameters:
- wb: str, whether to open browser ('y' to open automatically)
- n_polls: int, maximum polls to wait for completion
Returns:
str: GitHub access token
"""Utilities for working with GitHub OAuth scopes.
def scope_str(*scopes) -> str:
"""
Convert scopes to comma-separated string.
Parameters:
- *scopes: GitHub OAuth scope objects or strings
Returns:
str: Comma-separated scope string
"""GitHub OAuth scopes available through the Scope object.
Scope = AttrDict({
'repo': 'repo', # Full repository access
'repo_status': 'repo:status', # Repository status access
'repo_deployment': 'repo_deployment', # Repository deployment access
'public_repo': 'public_repo', # Public repository access
'repo_invite': 'repo:invite', # Repository invitation access
'security_events': 'security_events', # Security events access
'admin_repo_hook': 'admin:repo_hook', # Repository webhook admin
'write_repo_hook': 'write:repo_hook', # Repository webhook write
'read_repo_hook': 'read:repo_hook', # Repository webhook read
'admin_org': 'admin:org', # Organization admin
'write_org': 'write:org', # Organization write
'read_org': 'read:org', # Organization read
'admin_public_key': 'admin:public_key', # Public key admin
'write_public_key': 'write:public_key', # Public key write
'read_public_key': 'read:public_key', # Public key read
'admin_org_hook': 'admin:org_hook', # Organization webhook admin
'gist': 'gist', # Gist access
'notifications': 'notifications', # Notification access
'user': 'user', # User profile access
'read_user': 'read:user', # User profile read
'user_email': 'user:email', # User email access
'user_follow': 'user:follow', # User follow access
'delete_repo': 'delete_repo', # Repository deletion
'write_discussion': 'write:discussion', # Discussion write
'read_discussion': 'read:discussion', # Discussion read
'write_packages': 'write:packages', # Package write
'read_packages': 'read:packages', # Package read
'delete_packages': 'delete:packages', # Package deletion
'admin_gpg_key': 'admin:gpg_key', # GPG key admin
'write_gpg_key': 'write:gpg_key', # GPG key write
'read_gpg_key': 'read:gpg_key', # GPG key read
'workflow': 'workflow' # GitHub Actions workflow
})from ghapi.all import GhApi
# Using environment variable GITHUB_TOKEN
api = GhApi()
# Using explicit token
api = GhApi(token='ghp_your_personal_access_token')
# Using JWT token
api = GhApi(jwt_token='your_jwt_token')
# Disable authentication
api = GhApi(authenticate=False)from ghapi.all import github_auth_device, GhApi
# Interactive device flow authentication
token = github_auth_device()
print(f"Obtained token: {token}")
# Use token with API client
api = GhApi(token=token)
user = api.users.get_authenticated()
print(f"Authenticated as: {user.login}")from ghapi.all import GhDeviceAuth, Scope, scope_str
# Create device auth with specific scopes
scopes = [Scope.repo, Scope.user, Scope.gist]
auth = GhDeviceAuth(scopes=scopes)
print(f"User code: {auth.user_code}")
print(f"Verification URL: {auth.verification_uri}")
# Open browser automatically
auth.open_browser()
# Wait for completion with progress callback
def progress():
print(".", end="", flush=True)
token = auth.wait(cb=progress)
print(f"\\nAuthentication complete: {token}")from ghapi.all import GhDeviceAuth, Scope
# Use custom OAuth application
auth = GhDeviceAuth(
client_id='your_oauth_app_client_id',
Scope.repo,
Scope.write_org,
Scope.gist
)
# Display authentication instructions
print(auth.url_docs())
# Manual polling
while True:
token = auth.auth()
if token:
print(f"Got token: {token}")
break
time.sleep(5)from ghapi.all import Scope, scope_str
# Create scope string for multiple scopes
scopes = scope_str(Scope.repo, Scope.user, Scope.gist)
print(f"Scope string: {scopes}") # "repo,user,gist"
# Use with device auth
auth = GhDeviceAuth(
client_id='your_client_id',
Scope.repo,
Scope.admin_org,
Scope.workflow
)# Set token as environment variable
export GITHUB_TOKEN=ghp_your_personal_access_token
# Or for JWT tokens
export GITHUB_JWT_TOKEN=your_jwt_tokenfrom ghapi.all import GhApi
# Automatically uses GITHUB_TOKEN or GITHUB_JWT_TOKEN
api = GhApi()
# Check authentication status
try:
user = api.users.get_authenticated()
print(f"Authenticated as: {user.login}")
except Exception:
print("Not authenticated or invalid token")from ghapi.all import GhApi
def validate_token(token):
"""Validate GitHub token by testing API access."""
try:
api = GhApi(token=token)
user = api.users.get_authenticated()
return True, user.login
except Exception as e:
return False, str(e)
# Test token
is_valid, result = validate_token('ghp_test_token')
if is_valid:
print(f"Token is valid for user: {result}")
else:
print(f"Token validation failed: {result}")Install with Tessl CLI
npx tessl i tessl/pypi-ghapi