From 3c1b4b3fb2e56c12eccedc400993d4a3415cf500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 5 Nov 2021 09:58:48 +0100 Subject: [PATCH] Make GitHub calls async --- pyproject.toml | 2 +- requirements.txt | 3 +++ src/runboat/api.py | 6 ++---- src/runboat/exceptions.py | 2 +- src/runboat/github.py | 37 +++++++++++++++++++------------------ 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 358fb35..d2ed388 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,9 +12,9 @@ classifiers = [ dependencies = [ "fastapi", "gunicorn", + "httpx", "jinja2", "kubernetes", - "requests", # TODO for github, to replace by aiohttp or httpx "rich", "uvicorn", ] diff --git a/requirements.txt b/requirements.txt index a38c3d5..b7a1bfb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,8 @@ fastapi==0.70.0 google-auth==2.3.3 gunicorn==20.1.0 h11==0.12.0 +httpcore==0.13.7 +httpx==0.20.0 idna==3.3 Jinja2==3.0.2 kubernetes==19.15.0 @@ -24,6 +26,7 @@ python-dateutil==2.8.2 PyYAML==6.0 requests==2.26.0 requests-oauthlib==1.3.0 +rfc3986==1.5.0 rich==10.12.0 rsa==4.7.2 six==1.16.0 diff --git a/src/runboat/api.py b/src/runboat/api.py index 47e84de..fdfe413 100644 --- a/src/runboat/api.py +++ b/src/runboat/api.py @@ -79,8 +79,7 @@ async def builds(repo: Optional[str] = None): ) async def trigger_branch(repo: str, branch: str): """Trigger build for a branch.""" - # TODO async github call - branch_info = github.get_branch_info(repo, branch) + branch_info = await github.get_branch_info(repo, branch) await controller.deploy_or_delay_start( repo=branch_info.repo, target_branch=branch_info.name, @@ -95,8 +94,7 @@ async def trigger_branch(repo: str, branch: str): ) async def trigger_pull(repo: str, pr: int): """Trigger build for a pull request.""" - # TODO async github call - pull_info = github.get_pull_info(repo, pr) + pull_info = await github.get_pull_info(repo, pr) await controller.deploy_or_delay_start( repo=pull_info.repo, target_branch=pull_info.target_branch, diff --git a/src/runboat/exceptions.py b/src/runboat/exceptions.py index aeaa806..6a678d1 100644 --- a/src/runboat/exceptions.py +++ b/src/runboat/exceptions.py @@ -10,7 +10,7 @@ class BranchNotFound(ClientError): pass -class NotFoundOnGithub(ClientError): +class NotFoundOnGitHub(ClientError): pass diff --git a/src/runboat/github.py b/src/runboat/github.py index 6f1bb13..114e8f6 100644 --- a/src/runboat/github.py +++ b/src/runboat/github.py @@ -1,24 +1,25 @@ from dataclasses import dataclass from typing import Any -import requests +import httpx -from .exceptions import NotFoundOnGithub +from .exceptions import NotFoundOnGitHub from .settings import settings -def _github_get(url: str) -> Any: - full_url = f"https://api.github.com{url}" - headers = { - "Accept": "application/vnd.github.v3+json", - } - if settings.github_token: - headers["Authorization"] = f"token {settings.github_token}" - response = requests.get(full_url, headers=headers) - if response.status_code == 404: - raise NotFoundOnGithub(f"GitHub URL not found: {full_url}.") - response.raise_for_status() - return response.json() +async def _github_get(url: str) -> Any: + async with httpx.AsyncClient() as client: + full_url = f"https://api.github.com{url}" + headers = { + "Accept": "application/vnd.github.v3+json", + } + if settings.github_token: + headers["Authorization"] = f"token {settings.github_token}" + response = await client.get(full_url, headers=headers) + if response.status_code == 404: + raise NotFoundOnGitHub(f"GitHub URL not found: {full_url}.") + response.raise_for_status() + return response.json() @dataclass @@ -28,8 +29,8 @@ class BranchInfo: head_sha: str -def get_branch_info(repo: str, branch: str) -> BranchInfo: - branch_data = _github_get(f"/repos/{repo}/git/ref/heads/{branch}") +async def get_branch_info(repo: str, branch: str) -> BranchInfo: + branch_data = await _github_get(f"/repos/{repo}/git/ref/heads/{branch}") return BranchInfo( repo=repo, name=branch, @@ -45,8 +46,8 @@ class PullInfo: target_branch: str -def get_pull_info(repo: str, pr: int) -> PullInfo: - pr_data = _github_get(f"/repos/{repo}/pulls/{pr}") +async def get_pull_info(repo: str, pr: int) -> PullInfo: + pr_data = await _github_get(f"/repos/{repo}/pulls/{pr}") return PullInfo( repo=repo, number=pr,