Skip to content

Commit

Permalink
scripts: add github_helpers.py
Browse files Browse the repository at this point in the history
This is meant to be a place where we can store generic zephyr wrappers
around the de-facto standard github API for python.

The first 'customer' will be a script that snapshots our open bugs at a
particular point in time, which will be added in a later patch.

I think it's useful to factor this file out of there from the
beginning just to keep things clean, even though I don't have a second
customer in mind at the moment.

Signed-off-by: Martí Bolívar <[email protected]>
Signed-off-by: Stephanos Ioannidis <[email protected]>
  • Loading branch information
mbolivar-nordic authored and carlescufi committed May 24, 2022
1 parent b2c8f26 commit 8aaea6d
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions scripts/github_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0

'''
Generic GitHub helper routines which may be useful to other scripts.
This file is not meant to be run directly, but rather to be imported
as a module from other scripts.
'''

# Note that the type annotations are not currently checked by mypy.
# Unless that changes, they serve as documentation, rather than
# guarantees from a type checker.

# stdlib
import getpass
import os
import netrc
import sys
from typing import Dict

# third party
import github

def get_github_credentials(ask: bool = True) -> Dict[str, str]:
'''Get credentials for constructing a github.Github object.
This function tries to get github.com credentials from these
places, in order:
1. a ~/.netrc file, if one exists
2. a GITHUB_TOKEN environment variable
3. if the 'ask' kwarg is truthy, from the user on the
at the command line.
On failure, RuntimeError is raised.
Scripts often need credentials because anonym access to
api.github.com is rate limited more aggressively than
authenticated access. Scripts which use anonymous access are
therefore more likely to fail due to rate limiting.
The return value is a dict which can be passed to the
github.Github constructor as **kwargs.
:param ask: if truthy, the user will be prompted for credentials
if none are found from other sources
'''

try:
nrc = netrc.netrc()
except (FileNotFoundError, netrc.NetrcParseError):
nrc = None

if nrc is not None:
auth = nrc.authenticators('github.com')
if auth is not None:
return {'login_or_token': auth[0], 'password': auth[2]}

token = os.environ.get('GITHUB_TOKEN')
if token:
return {'login_or_token': token}

if ask:
print('Missing GitHub credentials:\n'
'~/.netrc file not found or has no github.com credentials, '
'and GITHUB_TOKEN is not set in the environment. '
'Please give your GitHub token.',
file=sys.stderr)
token = getpass.getpass('token: ')
return {'login_or_token': token}

raise RuntimeError('no credentials found')

def get_github_object(ask: bool = True) -> github.Github:
'''Get a github.Github object, created with credentials.
:param ask: passed to get_github_credentials()
'''
return github.Github(**get_github_credentials())

0 comments on commit 8aaea6d

Please sign in to comment.