Skip to content

Commit

Permalink
Add: Add new GitHub API for downloading a repo artifact
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoernricks committed Sep 20, 2022
1 parent 65e74c8 commit c14b798
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pontos/github/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,32 @@ def get_repository_artifact(
response = self._request(api, request=httpx.get)
response.raise_for_status()
return response.json()

def download_repository_artifact(
self, repo: str, artifact: str, destination: Union[Path, str]
) -> ContextManager[DownloadProgressIterable]:
"""
Download a repository artifact zip file
Args:
repo: GitHub repository (owner/name) to use
destination: A path where to store the downloaded file
Raises:
HTTPError if the request was invalid
Example:
.. code-block:: python
api = GitHubRESTApi("...")
print("Downloading", end="")
with api.download_repository_artifact(
"org/repo", "artifact.zip"
) as progress_iterator:
for progress in progress_iterator:
print(".", end="")
"""
api = f"{self.url}/repos/{repo}/actions/artifacts/{artifact}/zip"
return download(api, destination, headers=self._request_headers())
45 changes: 45 additions & 0 deletions tests/github/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,3 +912,48 @@ def test_get_repository_artifact_invalid(self, requests_mock: MagicMock):
params=None,
follow_redirects=True,
)

@patch("pontos.helper.Path")
@patch("pontos.github.api.httpx.stream")
def test_download_repository_artifact(
self, requests_mock: MagicMock, path_mock: MagicMock
):
response = MagicMock()
response.iter_bytes.return_value = [b"foo", b"bar", b"baz"]
response_headers = MagicMock()
response.headers = response_headers
response_headers.get.return_value = None
response_stream = MagicMock()
response_stream.__enter__.return_value = response
requests_mock.return_value = response_stream

api = GitHubRESTApi("12345")
download_file = path_mock()
with api.download_repository_artifact(
"foo/bar", "123", download_file
) as download_progress:
requests_mock.assert_called_once_with(
"GET",
"https://api.github.com/repos/foo/bar/actions/artifacts/123/zip", # pylint: disable=line-too-long
timeout=DEFAULT_TIMEOUT,
follow_redirects=True,
headers={
"Accept": "application/vnd.github.v3+json",
"Authorization": "token 12345",
},
params=None,
)
response_headers.get.assert_called_once_with("content-length")

self.assertIsNone(download_progress.length)

it = iter(download_progress)
progress = next(it)
self.assertIsNone(progress)
progress = next(it)
self.assertIsNone(progress)
progress = next(it)
self.assertIsNone(progress)

with self.assertRaises(StopIteration):
next(it)

0 comments on commit c14b798

Please sign in to comment.