-
Notifications
You must be signed in to change notification settings - Fork 0
/
github.py
131 lines (98 loc) · 3.72 KB
/
github.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""
github.py
~~~~~~~~~
This module implements the Github class, which is
used to interact with the Github API. And
uses Streamlit to cache the API calls.
"""
import pandas as pd
import requests
import streamlit as st
from constants import CORE_TTL, SEARCH_CACHE_TTL
class GitHubAPIException(Exception):
"""Invalid API Server Responses"""
def __init__(self, code, resp):
self.code = code
self.resp = resp
def __str__(self):
return f"Server Response ({self.code}): {self.resp}"
class GitHubAPI:
"""GitHub API Wrapper"""
def __init__(self, gh_api: str = "https://api.github.com", token: str = ""):
self.gh_api = gh_api
self._token = token
@property
def token(self) -> str:
return self._token
@token.setter
def token(self, token: str) -> None:
"""Set the token for the API"""
if not token:
print("Note: GitHub API token not set")
self._token = token
def get(self, url: str, media_type: str = "vnd.github.v3+json", **params) -> dict:
"""GET request to the GitHub API"""
headers = {
"Accept": "application/" + media_type,
}
if self.token:
headers["Authorization"] = f"token {self.token}"
if media_type:
headers["Accept"] = "application/" + media_type
req_url = self.gh_api + url
req = requests.get(req_url, headers=headers, params=params)
if req.status_code not in range(200, 301):
raise GitHubAPIException(req.status_code, req.json())
return req.json()
@st.cache(ttl=CORE_TTL)
def get_repo(self, org: str, id: str) -> pd.DataFrame:
"""Get a repository by its ID and organization"""
req = self.get(f"/repos/{org}/{id}")
df = pd.json_normalize(req)
return df
@st.cache(ttl=SEARCH_CACHE_TTL)
def get_open_for_contrib_issues(
self, org: str, id: str, deployed: bool = False
) -> dict:
"""Get all issues that are open for contribution"""
if not deployed:
print("Cache miss: get_open_for_contrib_issues(", org, ", ", id, ") ran")
contrib_issue_count = {}
contrib_labels = ["good first issue", "question"]
q = f"repo:{org}/{id} is:open is:issue "
for label in contrib_labels:
params = {"q": q + f'label:"{label}"'}
try:
req = self.get("/search/issues", **params)
contrib_issue_count[label] = req["total_count"]
except GitHubAPIException:
contrib_issue_count[label] = "pending update..."
return contrib_issue_count
@st.cache(ttl=CORE_TTL)
def get_repo_health(self, org: str, id: str) -> dict:
url = f"/repos/{org}/{id}/community/profile"
req = self.get(url, media_type="vnd.github.mercy-preview+json")
return req
@st.cache(ttl=CORE_TTL)
def get_repo_files(self, org: str, id: str, filepath: str) -> dict:
url = f"/repos/{org}/{id}/contents/.github/{filepath}"
try:
req = self.get(url)
except GitHubAPIException as err:
print(err)
return {}
return req
@st.cache(ttl=CORE_TTL)
def get_repo_topics(self, org: str, id: str) -> pd.DataFrame:
url = f"/repos/{org}/{id}/topics"
params = {"per_page": 100}
req = self.get(url, media_type="vnd.github.mercy-preview+json", **params)
df = pd.json_normalize(req)
return df
@st.cache(ttl=CORE_TTL)
def get_repo_labels(self, org: str, id: str) -> pd.DataFrame:
url = f"/repos/{org}/{id}/labels"
params = {"per_page": 100}
req = self.get(url, **params)
df = pd.json_normalize(req)
return df