Browse Source
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 <marti.bolivar@nordicsemi.no> Signed-off-by: Stephanos Ioannidis <root@stephanos.io>pull/45982/head
1 changed files with 81 additions and 0 deletions
@ -0,0 +1,81 @@
@@ -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()) |
Loading…
Reference in new issue