Skip to content

Commit 8aaea6d

Browse files
mbolivar-nordiccarlescufi
authored andcommitted
scripts: add github_helpers.py
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>
1 parent b2c8f26 commit 8aaea6d

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

scripts/github_helpers.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Copyright (c) 2022 Nordic Semiconductor ASA
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
'''
6+
Generic GitHub helper routines which may be useful to other scripts.
7+
8+
This file is not meant to be run directly, but rather to be imported
9+
as a module from other scripts.
10+
'''
11+
12+
# Note that the type annotations are not currently checked by mypy.
13+
# Unless that changes, they serve as documentation, rather than
14+
# guarantees from a type checker.
15+
16+
# stdlib
17+
import getpass
18+
import os
19+
import netrc
20+
import sys
21+
from typing import Dict
22+
23+
# third party
24+
import github
25+
26+
def get_github_credentials(ask: bool = True) -> Dict[str, str]:
27+
'''Get credentials for constructing a github.Github object.
28+
29+
This function tries to get github.com credentials from these
30+
places, in order:
31+
32+
1. a ~/.netrc file, if one exists
33+
2. a GITHUB_TOKEN environment variable
34+
3. if the 'ask' kwarg is truthy, from the user on the
35+
at the command line.
36+
37+
On failure, RuntimeError is raised.
38+
39+
Scripts often need credentials because anonym access to
40+
api.github.com is rate limited more aggressively than
41+
authenticated access. Scripts which use anonymous access are
42+
therefore more likely to fail due to rate limiting.
43+
44+
The return value is a dict which can be passed to the
45+
github.Github constructor as **kwargs.
46+
47+
:param ask: if truthy, the user will be prompted for credentials
48+
if none are found from other sources
49+
'''
50+
51+
try:
52+
nrc = netrc.netrc()
53+
except (FileNotFoundError, netrc.NetrcParseError):
54+
nrc = None
55+
56+
if nrc is not None:
57+
auth = nrc.authenticators('github.com')
58+
if auth is not None:
59+
return {'login_or_token': auth[0], 'password': auth[2]}
60+
61+
token = os.environ.get('GITHUB_TOKEN')
62+
if token:
63+
return {'login_or_token': token}
64+
65+
if ask:
66+
print('Missing GitHub credentials:\n'
67+
'~/.netrc file not found or has no github.com credentials, '
68+
'and GITHUB_TOKEN is not set in the environment. '
69+
'Please give your GitHub token.',
70+
file=sys.stderr)
71+
token = getpass.getpass('token: ')
72+
return {'login_or_token': token}
73+
74+
raise RuntimeError('no credentials found')
75+
76+
def get_github_object(ask: bool = True) -> github.Github:
77+
'''Get a github.Github object, created with credentials.
78+
79+
:param ask: passed to get_github_credentials()
80+
'''
81+
return github.Github(**get_github_credentials())

0 commit comments

Comments
 (0)