85 lines
3 KiB
Python
85 lines
3 KiB
Python
from typing import Any
|
|
import logging
|
|
import requests
|
|
|
|
from majordome.errors import NoReleaseFound, AssetNotFound, DownloadFailure
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class GithubConnector:
|
|
def __init__(self, token: str):
|
|
self.base_url = "https://api.github.com"
|
|
self.token = token
|
|
|
|
@property
|
|
def headers(self) -> dict[str, str]:
|
|
return {
|
|
"Accept": "application/vnd.github.v3+json",
|
|
"Authorization": f"Bearer {self.token}",
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
}
|
|
|
|
def get_latest_release(self, owner: str, repo: str) -> dict[str, Any]:
|
|
logger.info("Getting latest release from Github")
|
|
logger.debug(
|
|
"GET %s with headers %s", self.latest_release_url(owner, repo), self.headers
|
|
)
|
|
response = requests.get(
|
|
self.latest_release_url(owner, repo), headers=self.headers
|
|
)
|
|
if response.ok:
|
|
logger.debug("Latest release found")
|
|
return response.json()[0]
|
|
logger.error(
|
|
"Failed to get latest release from Github. Response code was: %s",
|
|
response.status_code,
|
|
)
|
|
raise NoReleaseFound(
|
|
f"No release found on Github for the repo {repo} from owner {owner}"
|
|
)
|
|
|
|
@staticmethod
|
|
def latest_release_url(owner: str, repo: str) -> str:
|
|
return f"https://api.github.com/repos/{owner}/{repo}/releases?per_page=1"
|
|
|
|
def download_asset(self, owner: str, repo: str, asset_id: int) -> bytes:
|
|
logger.info(
|
|
"Downloading asset with id %s from Github owner %s and repo %s",
|
|
asset_id,
|
|
owner,
|
|
repo,
|
|
)
|
|
asset_response = requests.get(
|
|
self.asset_url(owner, repo, asset_id), headers=self.headers
|
|
)
|
|
if asset_response.ok:
|
|
download_url = asset_response.json().get("browser_download_url")
|
|
downloaded_response = requests.get(download_url, headers=self.headers)
|
|
if downloaded_response.ok:
|
|
return downloaded_response.content
|
|
|
|
logger.error(
|
|
"Failed to download asset from Github repo %s of owner %s. Response code was: %s",
|
|
repo,
|
|
owner,
|
|
downloaded_response.status_code,
|
|
)
|
|
raise DownloadFailure(
|
|
f"The asset {asset_id} was not found on Github for the repo {repo} from owner {owner}"
|
|
)
|
|
|
|
logger.error(
|
|
"Failed to find asset with id %s from Github repo %s of owner %s. Response code was: %s",
|
|
asset_id,
|
|
repo,
|
|
owner,
|
|
asset_response.status_code,
|
|
)
|
|
raise AssetNotFound(
|
|
f"The asset {asset_id} was not found on Github for the repo {repo} from owner {owner}"
|
|
)
|
|
|
|
@staticmethod
|
|
def asset_url(owner: str, repo: str, asset_id: int) -> str:
|
|
return f"https://api.github.com/repos/{owner}/{repo}/releases/assets/{asset_id}"
|