A simple github HTTP api handler in python.
Project description
Package github_http_api
-
available on pypi
-
install it by typing
python -m pip install github-http-api
-
example of use available in the file example.py
Expand source code
from requests import get
from typing import List
from base64 import b64decode
class GithubHTTPApi():
def __init__(self):
self.ac_username = ""
self.ac_password = ""
#best api endpoints
self.base_repos_url = "https://api.github.com/repos/"
self.base_user_url = "https://api.github.com/users/"
self.base_raw_url = "https://raw.githubusercontent.com/"
def login():
pass
#private methods :
def __is_json_key(self,json:dict,key:str) -> bool:
try:
json[key]
return True
except:
return False
#public methods :
def get_last_event_date(self,username:str)->str:
"""
Basically just get the last event that an user made and return the date.
May be usefull to determine if an user is active or not.
:returns: a string containing the date
:raises UnknownUserException:
"""
if not self.user_exists(username):
raise UserNotFoundException
return get(self.base_user_url+username+"/events").json()[0]['created_at']
def try_determine_email(self,username:str,events_number:int=10)->List[str]:
"""
tries to gather user email address by events api endpoint, it may be very usefull if the user didn't put it as personnal information and for OSINT people ;)
:param username: the username (str)
:returns: A list of potential email addresses (List[str])
:raises UserNotFoundException:
"""
if not self.user_exists(username):
raise UserNotFoundException
json = get(self.base_user_url+username+"/events").json()[:events_number]
emails = []
for event in json:
if self.__is_json_key(event['payload'],'commits'):
for commit in event['payload']['commits']:
emails.append(commit['author']['email'])
return list(set(emails))
def user_exists(self,username:str)->bool:
"""
:param username: the username
:returns: a boolean
"""
#check if user exists
if self.__is_json_key(get(self.base_user_url+username).json(),"message"):
return False
else:
return True
def get_user_repos(self,username:str)-> list:
"""
list the publics repositories of the specified user
:raises: UserNotFoundException if user is not found
:returns: A list of dict containing repository 'repo_name' and 'repo_url' of user public repositories
"""
if not self.user_exists(username):
raise UserNotFoundException
json = get(f"{self.base_user_url}{username}/repos").json()
repos_names = [repo['full_name'] for repo in json]
repos_urls = [repo['html_url'] for repo in json]
ret = []
for i in range(len(repos_names)):
ret.append({'repo_name':repos_names[i],'repo_url':repos_urls[i],})
return ret
def repo_exists(self,repository_full_name:str) -> bool:
"""
:return: True if the repo exists False if not
"""
if self.__is_json_key(get(f"{self.base_repos_url}{repository_full_name}/releases").json(),'message'):
return False
else:
return True
def get_release_download_count(self,repository_full_name:str,release_number:int=0) -> List[tuple]:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:param release_number: (default is 0), the more you increase it, the more the release
will be an old one.
:returns: the release download count by assets (list of tuples ('asset_name',downloads_count) (from the lastest release by default)
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
"""
#get http response content
json = get(f"{self.base_repos_url}{repository_full_name}/releases").json()
#takes care of exceptions
if json == []:
raise NoReleaseException
elif not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
elif release_number > len(json):
raise InvalidReleaseIndexException
release_json = json[release_number]
assets = release_json['assets']
return [(asset['name'],asset['download_count']) for asset in assets]
def get_release_infos(self,repository_full_name:str,release_number:int=0) -> List[dict]:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:param release_number: (default is 0), the more you increase it, the more the release
will be an old one.
:returns: a dict of all the release stats that may be boring but quite usefull sometimes
- creation_date : when the release has been created (str)
- release_date : when the release has been..released :) (str)
- released_by : author of the release (github login) (str)
- version : tag name of the release (ofter the version) (str)
- title : title of the release (str)
- desc : description of the release (str)
- assets : assets files names (list of str)
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
"""
#get http response content
json = get(f"{self.base_repos_url}{repository_full_name}/releases").json()
#takes care of exceptions
if json == []:
raise NoReleaseException
elif not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
elif release_number > len(json):
raise InvalidReleaseIndexException
#now that we are sure no errors are coming, get the right release
json = json[release_number]
return {'title':json['name'],'version':json['tag_name'],'desc':json['body'],"creation_date":json['created_at'],"release_date":json['published_at'],"released_by":json['author']['login'],"assets":[asset[0] for asset in self.get_release_download_count(repository_full_name,release_number=release_number)]}
def get_raw_file_content(self,repository_full_name:str,file_name:str) -> str:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:param file_name: the file which you wanna get the raw content
:raises InvalidRepoNameException:
:raises UnknownFileException:
:returns: a string containing the raw file content
"""
if not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
content = get(f"{self.base_raw_url}{repository_full_name}/master/{file_name}").text
if content == "404: Not Found":
raise UnknownFileException
return content
def get_release_asset_download_link(self,repository_full_name:str,asset_name:str,release_number:int=0) -> str:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:param asset_name: the release asset file name
:param release_number: (default is 0), the more you increase it, the more the release
will be an old one.
:returns: a string containing the release asset's download url
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
:raises UnknownAssetException:
"""
#get http response content
json = get(f"{self.base_repos_url}{repository_full_name}/releases").json()
#takes care of exceptions
if json == []:
raise NoReleaseException
elif not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
elif release_number > len(json):
raise InvalidReleaseIndexException
json = json[release_number]
for asset in json['assets']:
if asset['name'] == asset_name:
return asset['browser_download_url']
raise UnknownAssetException
def download_release_asset(self,repository_full_name:str,asset_name:str,release_number:int=0,output_path:str=""):
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:param asset_name: the release asset file name
:param release_number: (default is 0), the more you increase it, the more the release
will be an old one.
:param output_path: (default is cwd), the path where the asset will be stored after download.
:returns: nothing
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
:raises UnknownAssetException:
"""
url = self.get_release_asset_download_link(repository_full_name,asset_name,release_number=release_number)
with open(f"{output_path}/{asset_name}" if output_path != "" else asset_name,"wb") as f:
f.write(get(url).content)
f.close()
def get_repo_license(self,repository_full_name:str)->dict:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:returns: {'url':str,'name':str,'content':str,'type':str}:
:raises InvalidRepoNameException:
"""
if not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
json = get(self.base_repos_url+repository_full_name+"/license").json()
return {"url":json['html_url'],"name":json['name'],"content":b64decode(json['content']),"type":json['type']}
def get_repo_issues(self,repository_full_name:str)->List[dict]:
"""
:param repository_full_name: the repository full name like thaaoblues/github_api
:returns: a list of dictionnary (1 by issue) containing:
- author : the issue's author username (str)
- created_at : the date/time when the author created the issue (str)
- updated_at : the date/time when the author modified the issue (str)
- title : the issue title (str)
- body : the issue's content (str)
- state : "open" or "closed"
- url : the url to open the issue on a web browser (str)
- labels : the issue labels List[str]
- comments_number : the number of comments under the issue (int)
:raises InvalidRepoNameException:
"""
if not self.repo_exists(repository_full_name):
raise InvalidRepoNameException
json = get(self.base_repos_url+repository_full_name+"/issues").json()
issues = []
for ele in json:
issues.append({"author":ele['user']['login'],"created_at":ele['created_at'],"updated_at":ele['updated_at'],"title":ele['title'],"body":ele['body'],"state":ele['state'], "url":ele["url"],"labels":ele['labels'],"comments_number":ele['comments']})
return issues
def get_user_infos(self,username:str) -> dict:
"""
get additionnal informations on a user like
- id (str)
- bio (str)
- name (str)
- twitter_account (null if not) (str)
- followers (list of usernames)
- following (list of usernames)
- starred_repos (list of urls)
- blog_url (null if not) (str)
- is_hireable (null if not specified) (bool)
- email (null if not specified) (str)
- user_location (null if not specified) (str)
- user_type (str)
- avatar_url (str)
- company (str)
- creation_date (str)
- url (str)
- organizations (List[dict{'login','url'}])
:raises UserNotFoundException if user is not found:
:returns: A dict with the upper specified keys
"""
if not self.user_exists(username):
raise UserNotFoundException
#getting basic infos
json = get(self.base_user_url+username).json()
#getting infos from special urls
followers = get(json['followers_url']).json()
following = get(str(json['following_url']).replace("{/other_user}","",1)).json()
starred_repos = [repo['html_url'] for repo in get(json['starred_url'].replace("{/owner}{/repo}","",1)).json()]
organizations = [{"login":org['login'],"url":org["url"]} for org in get(json['organizations_url']).json()]
return {"id": json['id'],"bio":json['bio'],"name":json['name'],"twitter_account":json['twitter_username'],"followers" : [f['login'] for f in followers], "following":[f['login'] for f in following],"starred_repos": starred_repos,"blog_url":json['blog'],"is_hireable":json['hireable'],"email":json['email'],"user_location":json['location'],"user_type":json['type'],"avatar_url":json['avatar_url'],"company":json['company'],"creation_date":json['created_at'],"url":json['url'],"organizations":organizations}
class UserNotFoundException(Exception):
"""
Exception raised if an username don't exists.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="Username not found on github."):
self.message = message
super().__init__(self.message)
class InvalidRepoNameException(Exception):
"""
Exception raised if a repository name does not exists or is malformed
Attributes:
message -- explanation of the error
"""
def __init__(self, message="Invalid repository name. It must look like : thaaoblues/github_api"):
self.message = message
super().__init__(self.message)
class InvalidReleaseIndexException(Exception):
"""
Exception raised if you decided to pass a certain release index to get stats not on the lastest but this index does not exists.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="Invalid release index. The user must not have released that amount of versions"):
self.message = message
super().__init__(self.message)
class NoReleaseException(Exception):
"""
Exception raised if you wanted to get stats from a release but the repo does not have any.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="No release found. The user must not have released anything."):
self.message = message
super().__init__(self.message)
class UnknownAssetException(Exception):
"""
Exception raised if you wanted to get download url for a specific release's asset but no assets has this name.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="No release's assets found with this name."):
self.message = message
super().__init__(self.message)
class UnknownFileException(Exception):
"""
Exception raised if you wanted to get raw content for a specific file but the file does not exists.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="No file found with this name."):
self.message = message
super().__init__(self.message)
Classes
- `class GithubHTTPApi`
Expand source code
class GithubHTTPApi(): def __init__(self): self.ac_username = "" self.ac_password = "" #best api endpoints self.base_repos_url = "https://api.github.com/repos/" self.base_user_url = "https://api.github.com/users/" self.base_raw_url = "https://raw.githubusercontent.com/" def login(): pass #private methods : def __is_json_key(self,json:dict,key:str) -> bool: try: json[key] return True except: return False #public methods : def get_last_event_date(self,username:str)->str: """ Basically just get the last event that an user made and return the date. May be usefull to determine if an user is active or not. :returns: a string containing the date :raises UnknownUserException: """ if not self.user_exists(username): raise UserNotFoundException return get(self.base_user_url+username+"/events").json()[0]['created_at'] def try_determine_email(self,username:str,events_number:int=10)->List[str]: """ tries to gather user email address by events api endpoint, it may be very usefull if the user didn't put it as personnal information and for OSINT people ;) :param username: the username (str) :returns: A list of potential email addresses (List[str]) :raises UserNotFoundException: """ if not self.user_exists(username): raise UserNotFoundException json = get(self.base_user_url+username+"/events").json()[:events_number] emails = [] for event in json: if self.__is_json_key(event['payload'],'commits'): for commit in event['payload']['commits']: emails.append(commit['author']['email']) return list(set(emails)) def user_exists(self,username:str)->bool: """ :param username: the username :returns: a boolean """ #check if user exists if self.__is_json_key(get(self.base_user_url+username).json(),"message"): return False else: return True def get_user_repos(self,username:str)-> list: """ list the publics repositories of the specified user :raises: UserNotFoundException if user is not found :returns: A list of dict containing repository 'repo_name' and 'repo_url' of user public repositories """ if not self.user_exists(username): raise UserNotFoundException json = get(f"{self.base_user_url}{username}/repos").json() repos_names = [repo['full_name'] for repo in json] repos_urls = [repo['html_url'] for repo in json] ret = [] for i in range(len(repos_names)): ret.append({'repo_name':repos_names[i],'repo_url':repos_urls[i],}) return ret def repo_exists(self,repository_full_name:str) -> bool: """ :return: True if the repo exists False if not """ if self.__is_json_key(get(f"{self.base_repos_url}{repository_full_name}/releases").json(),'message'): return False else: return True def get_release_download_count(self,repository_full_name:str,release_number:int=0) -> List[tuple]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: the release download count by assets (list of tuples ('asset_name',downloads_count) (from the lastest release by default) :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException release_json = json[release_number] assets = release_json['assets'] return [(asset['name'],asset['download_count']) for asset in assets] def get_release_infos(self,repository_full_name:str,release_number:int=0) -> List[dict]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: a dict of all the release stats that may be boring but quite usefull sometimes - creation_date : when the release has been created (str) - release_date : when the release has been..released :) (str) - released_by : author of the release (github login) (str) - version : tag name of the release (ofter the version) (str) - title : title of the release (str) - desc : description of the release (str) - assets : assets files names (list of str) :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException #now that we are sure no errors are coming, get the right release json = json[release_number] return {'title':json['name'],'version':json['tag_name'],'desc':json['body'],"creation_date":json['created_at'],"release_date":json['published_at'],"released_by":json['author']['login'],"assets":[asset[0] for asset in self.get_release_download_count(repository_full_name,release_number=release_number)]} def get_raw_file_content(self,repository_full_name:str,file_name:str) -> str: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param file_name: the file which you wanna get the raw content :raises InvalidRepoNameException: :raises UnknownFileException: :returns: a string containing the raw file content """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException content = get(f"{self.base_raw_url}{repository_full_name}/master/{file_name}").text if content == "404: Not Found": raise UnknownFileException return content def get_release_asset_download_link(self,repository_full_name:str,asset_name:str,release_number:int=0) -> str: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param asset_name: the release asset file name :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: a string containing the release asset's download url :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: :raises UnknownAssetException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException json = json[release_number] for asset in json['assets']: if asset['name'] == asset_name: return asset['browser_download_url'] raise UnknownAssetException def download_release_asset(self,repository_full_name:str,asset_name:str,release_number:int=0,output_path:str=""): """ :param repository_full_name: the repository full name like thaaoblues/github_api :param asset_name: the release asset file name :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :param output_path: (default is cwd), the path where the asset will be stored after download. :returns: nothing :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: :raises UnknownAssetException: """ url = self.get_release_asset_download_link(repository_full_name,asset_name,release_number=release_number) with open(f"{output_path}/{asset_name}" if output_path != "" else asset_name,"wb") as f: f.write(get(url).content) f.close() def get_repo_license(self,repository_full_name:str)->dict: """ :param repository_full_name: the repository full name like thaaoblues/github_api :returns: {'url':str,'name':str,'content':str,'type':str}: :raises InvalidRepoNameException: """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException json = get(self.base_repos_url+repository_full_name+"/license").json() return {"url":json['html_url'],"name":json['name'],"content":b64decode(json['content']),"type":json['type']} def get_repo_issues(self,repository_full_name:str)->List[dict]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :returns: a list of dictionnary (1 by issue) containing: - author : the issue's author username (str) - created_at : the date/time when the author created the issue (str) - updated_at : the date/time when the author modified the issue (str) - title : the issue title (str) - body : the issue's content (str) - state : "open" or "closed" - url : the url to open the issue on a web browser (str) - labels : the issue labels List[str] - comments_number : the number of comments under the issue (int) :raises InvalidRepoNameException: """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException json = get(self.base_repos_url+repository_full_name+"/issues").json() issues = [] for ele in json: issues.append({"author":ele['user']['login'],"created_at":ele['created_at'],"updated_at":ele['updated_at'],"title":ele['title'],"body":ele['body'],"state":ele['state'], "url":ele["url"],"labels":ele['labels'],"comments_number":ele['comments']}) return issues def get_user_infos(self,username:str) -> dict: """ get additionnal informations on a user like - id (str) - bio (str) - name (str) - twitter_account (null if not) (str) - followers (list of usernames) - following (list of usernames) - starred_repos (list of urls) - blog_url (null if not) (str) - is_hireable (null if not specified) (bool) - email (null if not specified) (str) - user_location (null if not specified) (str) - user_type (str) - avatar_url (str) - company (str) - creation_date (str) - url (str) - organizations (List[dict{'login','url'}]) :raises UserNotFoundException if user is not found: :returns: A dict with the upper specified keys """ if not self.user_exists(username): raise UserNotFoundException #getting basic infos json = get(self.base_user_url+username).json() #getting infos from special urls followers = get(json['followers_url']).json() following = get(str(json['following_url']).replace("{/other_user}","",1)).json() starred_repos = [repo['html_url'] for repo in get(json['starred_url'].replace("{/owner}{/repo}","",1)).json()] organizations = [{"login":org['login'],"url":org["url"]} for org in get(json['organizations_url']).json()] return {"id": json['id'],"bio":json['bio'],"name":json['name'],"twitter_account":json['twitter_username'],"followers" : [f['login'] for f in followers], "following":[f['login'] for f in following],"starred_repos": starred_repos,"blog_url":json['blog'],"is_hireable":json['hireable'],"email":json['email'],"user_location":json['location'],"user_type":json['type'],"avatar_url":json['avatar_url'],"company":json['company'],"creation_date":json['created_at'],"url":json['url'],"organizations":organizations}
Methods
- `def download_release_asset(self, repository_full_name: str, asset_name: str, release_number: int = 0, output_path: str = '')`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:param asset_name: the release asset file name
:param release_number: (default is 0), the more you increase it, the more the release will be an old one.
:param output_path: (default is cwd), the path where the asset will be stored after download.
:returns: nothing
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
:raises UnknownAssetException:
Expand source code
def download_release_asset(self,repository_full_name:str,asset_name:str,release_number:int=0,output_path:str=""): """ :param repository_full_name: the repository full name like thaaoblues/github_api :param asset_name: the release asset file name :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :param output_path: (default is cwd), the path where the asset will be stored after download. :returns: nothing :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: :raises UnknownAssetException: """ url = self.get_release_asset_download_link(repository_full_name,asset_name,release_number=release_number) with open(f"{output_path}/{asset_name}" if output_path != "" else asset_name,"wb") as f: f.write(get(url).content) f.close()
- `def get_last_event_date(self, username: str) ‑> str`
-
Basically just get the last event that an user made and return the date. May be usefull to determine if an user is active or not.
:returns: a string containing the date
:raises UnknownUserException:
Expand source code
def get_last_event_date(self,username:str)->str: """ Basically just get the last event that an user made and return the date. May be usefull to determine if an user is active or not. :returns: a string containing the date :raises UnknownUserException: """ if not self.user_exists(username): raise UserNotFoundException return get(self.base_user_url+username+"/events").json()[0]['created_at']
- `def get_raw_file_content(self, repository_full_name: str, file_name: str) ‑> str`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:param file_name: the file which you wanna get the raw content
:raises InvalidRepoNameException:
:raises UnknownFileException:
:returns: a string containing the raw file content
Expand source code
def get_raw_file_content(self,repository_full_name:str,file_name:str) -> str: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param file_name: the file which you wanna get the raw content :raises InvalidRepoNameException: :raises UnknownFileException: :returns: a string containing the raw file content """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException content = get(f"{self.base_raw_url}{repository_full_name}/master/{file_name}").text if content == "404: Not Found": raise UnknownFileException return content
- `def get_release_asset_download_link(self, repository_full_name: str, asset_name: str, release_number: int = 0) ‑> str`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:param asset_name: the release asset file name
:param release_number: (default is 0), the more you increase it, the more the release will be an old one.
:returns: a string containing the release asset's download url
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
:raises UnknownAssetException:
Expand source code
def get_release_asset_download_link(self,repository_full_name:str,asset_name:str,release_number:int=0) -> str: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param asset_name: the release asset file name :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: a string containing the release asset's download url :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: :raises UnknownAssetException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException json = json[release_number] for asset in json['assets']: if asset['name'] == asset_name: return asset['browser_download_url'] raise UnknownAssetException
- `def get_release_download_count(self, repository_full_name: str, release_number: int = 0) ‑> List[tuple]`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:param release_number: (default is 0), the more you increase it, the more the release will be an old one.
:returns: the release download count by assets (list of tuples ('asset_name',downloads_count) (from the lastest release by default)
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
Expand source code
def get_release_download_count(self,repository_full_name:str,release_number:int=0) -> List[tuple]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: the release download count by assets (list of tuples ('asset_name',downloads_count) (from the lastest release by default) :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException release_json = json[release_number] assets = release_json['assets'] return [(asset['name'],asset['download_count']) for asset in assets]
- `def get_release_infos(self, repository_full_name: str, release_number: int = 0) ‑> List[dict]`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:param release_number: (default is 0), the more you increase it, the more the release will be an old one.
:returns: a dict of all the release stats that may be boring but quite usefull sometimes
- creation_date : when the release has been created (str) - release_date : when the release has been..released :) (str) - released_by : author of the release (github login) (str) - version : tag name of the release (ofter the version) (str) - title : title of the release (str) - desc : description of the release (str) - assets : assets files names (list of str)
:raises InvalidRepoNameException:
:raises InvalidReleaseIndexException:
:raises NoReleaseException:
Expand source code
def get_release_infos(self,repository_full_name:str,release_number:int=0) -> List[dict]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :param release_number: (default is 0), the more you increase it, the more the release will be an old one. :returns: a dict of all the release stats that may be boring but quite usefull sometimes - creation_date : when the release has been created (str) - release_date : when the release has been..released :) (str) - released_by : author of the release (github login) (str) - version : tag name of the release (ofter the version) (str) - title : title of the release (str) - desc : description of the release (str) - assets : assets files names (list of str) :raises InvalidRepoNameException: :raises InvalidReleaseIndexException: :raises NoReleaseException: """ #get http response content json = get(f"{self.base_repos_url}{repository_full_name}/releases").json() #takes care of exceptions if json == []: raise NoReleaseException elif not self.repo_exists(repository_full_name): raise InvalidRepoNameException elif release_number > len(json): raise InvalidReleaseIndexException #now that we are sure no errors are coming, get the right release json = json[release_number] return {'title':json['name'],'version':json['tag_name'],'desc':json['body'],"creation_date":json['created_at'],"release_date":json['published_at'],"released_by":json['author']['login'],"assets":[asset[0] for asset in self.get_release_download_count(repository_full_name,release_number=release_number)]}
- `def get_repo_issues(self, repository_full_name: str) ‑> List[dict]`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:returns: a list of dictionnary (1 by issue) containing:
- author : the issue's author username (str) - created_at : the date/time when the author created the issue (str) - updated_at : the date/time when the author modified the issue (str) - title : the issue title (str) - body : the issue's content (str) - state : "open" or "closed" - url : the url to open the issue on a web browser (str) - labels : the issue labels List[str] - comments_number : the number of comments under the issue (int)
:raises InvalidRepoNameException:
Expand source code
def get_repo_issues(self,repository_full_name:str)->List[dict]: """ :param repository_full_name: the repository full name like thaaoblues/github_api :returns: a list of dictionnary (1 by issue) containing: - author : the issue's author username (str) - created_at : the date/time when the author created the issue (str) - updated_at : the date/time when the author modified the issue (str) - title : the issue title (str) - body : the issue's content (str) - state : "open" or "closed" - url : the url to open the issue on a web browser (str) - labels : the issue labels List[str] - comments_number : the number of comments under the issue (int) :raises InvalidRepoNameException: """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException json = get(self.base_repos_url+repository_full_name+"/issues").json() issues = [] for ele in json: issues.append({"author":ele['user']['login'],"created_at":ele['created_at'],"updated_at":ele['updated_at'],"title":ele['title'],"body":ele['body'],"state":ele['state'], "url":ele["url"],"labels":ele['labels'],"comments_number":ele['comments']}) return issues
- `def get_repo_license(self, repository_full_name: str) ‑> dict`
-
:param repository_full_name: the repository full name like thaaoblues/github_api
:returns: {'url':str,'name':str,'content':str,'type':str}:
:raises InvalidRepoNameException:
Expand source code
def get_repo_license(self,repository_full_name:str)->dict: """ :param repository_full_name: the repository full name like thaaoblues/github_api :returns: {'url':str,'name':str,'content':str,'type':str}: :raises InvalidRepoNameException: """ if not self.repo_exists(repository_full_name): raise InvalidRepoNameException json = get(self.base_repos_url+repository_full_name+"/license").json() return {"url":json['html_url'],"name":json['name'],"content":b64decode(json['content']),"type":json['type']}
- `def get_user_infos(self, username: str) ‑> dict`
-
get additionnal informations on a user like
-
id (str)
-
bio (str)
-
name (str)
-
twitter_account (null if not) (str)
-
followers (list of usernames)
-
following (list of usernames)
-
starred_repos (list of urls)
-
blog_url (null if not) (str)
-
is_hireable (null if not specified) (bool)
-
email (null if not specified) (str)
-
user_location (null if not specified) (str)
-
user_type (str)
-
avatar_url (str)
-
company (str)
-
creation_date (str)
-
url (str)
-
organizations (List[dict{'login','url'}])
:raises UserNotFoundException if user is not found:
:returns: A dict with the upper specified keys
Expand source code
def get_user_infos(self,username:str) -> dict: """ get additionnal informations on a user like - id (str) - bio (str) - name (str) - twitter_account (null if not) (str) - followers (list of usernames) - following (list of usernames) - starred_repos (list of urls) - blog_url (null if not) (str) - is_hireable (null if not specified) (bool) - email (null if not specified) (str) - user_location (null if not specified) (str) - user_type (str) - avatar_url (str) - company (str) - creation_date (str) - url (str) - organizations (List[dict{'login','url'}]) :raises UserNotFoundException if user is not found: :returns: A dict with the upper specified keys """ if not self.user_exists(username): raise UserNotFoundException #getting basic infos json = get(self.base_user_url+username).json() #getting infos from special urls followers = get(json['followers_url']).json() following = get(str(json['following_url']).replace("{/other_user}","",1)).json() starred_repos = [repo['html_url'] for repo in get(json['starred_url'].replace("{/owner}{/repo}","",1)).json()] organizations = [{"login":org['login'],"url":org["url"]} for org in get(json['organizations_url']).json()] return {"id": json['id'],"bio":json['bio'],"name":json['name'],"twitter_account":json['twitter_username'],"followers" : [f['login'] for f in followers], "following":[f['login'] for f in following],"starred_repos": starred_repos,"blog_url":json['blog'],"is_hireable":json['hireable'],"email":json['email'],"user_location":json['location'],"user_type":json['type'],"avatar_url":json['avatar_url'],"company":json['company'],"creation_date":json['created_at'],"url":json['url'],"organizations":organizations}
-
- `def get_user_repos(self, username: str) ‑> list`
-
list the publics repositories of the specified user
:raises: UserNotFoundException if user is not found
:returns: A list of dict containing repository 'repo_name' and 'repo_url' of user public repositories
Expand source code
def get_user_repos(self,username:str)-> list: """ list the publics repositories of the specified user :raises: UserNotFoundException if user is not found :returns: A list of dict containing repository 'repo_name' and 'repo_url' of user public repositories """ if not self.user_exists(username): raise UserNotFoundException json = get(f"{self.base_user_url}{username}/repos").json() repos_names = [repo['full_name'] for repo in json] repos_urls = [repo['html_url'] for repo in json] ret = [] for i in range(len(repos_names)): ret.append({'repo_name':repos_names[i],'repo_url':repos_urls[i],}) return ret
- `def login()`
Expand source code
def login(): pass
- `def repo_exists(self, repository_full_name: str) ‑> bool`
-
:return: True if the repo exists False if not
Expand source code
def repo_exists(self,repository_full_name:str) -> bool: """ :return: True if the repo exists False if not """ if self.__is_json_key(get(f"{self.base_repos_url}{repository_full_name}/releases").json(),'message'): return False else: return True
- `def try_determine_email(self, username: str, events_number: int = 10) ‑> List[str]`
-
tries to gather user email address by events api endpoint, it may be very usefull if the user didn't put it as personnal information and for OSINT people ;)
:param username: the username (str)
:returns: A list of potential email addresses (List[str])
:raises UserNotFoundException:
Expand source code
def try_determine_email(self,username:str,events_number:int=10)->List[str]: """ tries to gather user email address by events api endpoint, it may be very usefull if the user didn't put it as personnal information and for OSINT people ;) :param username: the username (str) :returns: A list of potential email addresses (List[str]) :raises UserNotFoundException: """ if not self.user_exists(username): raise UserNotFoundException json = get(self.base_user_url+username+"/events").json()[:events_number] emails = [] for event in json: if self.__is_json_key(event['payload'],'commits'): for commit in event['payload']['commits']: emails.append(commit['author']['email']) return list(set(emails))
- `def user_exists(self, username: str) ‑> bool`
-
:param username: the username
:returns: a boolean
Expand source code
def user_exists(self,username:str)->bool: """ :param username: the username :returns: a boolean """ #check if user exists if self.__is_json_key(get(self.base_user_url+username).json(),"message"): return False else: return True
- `class InvalidReleaseIndexException (message='Invalid release index. The user must not have released that amount of versions')`
-
Exception raised if you decided to pass a certain release index to get stats not on the lastest but this index does not exists.
Attributes
message – explanation of the error
Expand source code
class InvalidReleaseIndexException(Exception): """ Exception raised if you decided to pass a certain release index to get stats not on the lastest but this index does not exists. Attributes: message -- explanation of the error """ def __init__(self, message="Invalid release index. The user must not have released that amount of versions"): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
- `class InvalidRepoNameException (message='Invalid repository name. It must look like : thaaoblues/github_api')`
-
Exception raised if a repository name does not exists or is malformed
Attributes
message – explanation of the error
Expand source code
class InvalidRepoNameException(Exception): """ Exception raised if a repository name does not exists or is malformed Attributes: message -- explanation of the error """ def __init__(self, message="Invalid repository name. It must look like : thaaoblues/github_api"): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
- `class NoReleaseException (message='No release found. The user must not have released anything.')`
-
Exception raised if you wanted to get stats from a release but the repo does not have any.
Attributes
message – explanation of the error
Expand source code
class NoReleaseException(Exception): """ Exception raised if you wanted to get stats from a release but the repo does not have any. Attributes: message -- explanation of the error """ def __init__(self, message="No release found. The user must not have released anything."): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
- `class UnknownAssetException (message="No release's assets found with this name.")`
-
Exception raised if you wanted to get download url for a specific release's asset but no assets has this name.
Attributes
message – explanation of the error
Expand source code
class UnknownAssetException(Exception): """ Exception raised if you wanted to get download url for a specific release's asset but no assets has this name. Attributes: message -- explanation of the error """ def __init__(self, message="No release's assets found with this name."): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
- `class UnknownFileException (message='No file found with this name.')`
-
Exception raised if you wanted to get raw content for a specific file but the file does not exists.
Attributes
message – explanation of the error
Expand source code
class UnknownFileException(Exception): """ Exception raised if you wanted to get raw content for a specific file but the file does not exists. Attributes: message -- explanation of the error """ def __init__(self, message="No file found with this name."): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
- `class UserNotFoundException (message='Username not found on github.')`
-
Exception raised if an username don't exists.
Attributes
message – explanation of the error
Expand source code
class UserNotFoundException(Exception): """ Exception raised if an username don't exists. Attributes: message -- explanation of the error """ def __init__(self, message="Username not found on github."): self.message = message super().__init__(self.message)
Ancestors
- builtins.Exception
- builtins.BaseException
Generated by pdoc 0.9.2.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file github_http_api-0.2.5.tar.gz
.
File metadata
- Download URL: github_http_api-0.2.5.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3f0a184f7cfdbbf9deb3297bd80495b49ab10869795107d133a0699a90a7d985 |
|
MD5 | eba706df5bdf70d79bb49869a865d84c |
|
BLAKE2b-256 | 842d515fb26a268d798bb8ec8492669f8d588203be55f6181dfcb35a9c59888b |
File details
Details for the file github_http_api-0.2.5-py3-none-any.whl
.
File metadata
- Download URL: github_http_api-0.2.5-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed685ea50771753b471d321e43e1a7138f646cb29976ed67eee915074423218c |
|
MD5 | ccfc2db35a4ce905353fda8062e7810a |
|
BLAKE2b-256 | be3b6142baef88c61bad2d3be60a9fb960594bac5532c798d0df151d4c16b09e |