diff --git a/allspice/apiobject.py b/allspice/apiobject.py index 4212bbb..d6eb870 100644 --- a/allspice/apiobject.py +++ b/allspice/apiobject.py @@ -1531,6 +1531,28 @@ def __eq__(self, other): def __hash__(self): return hash(self.uuid) + def download_to_file(self, io: IO): + """ + Download the raw, binary data of this Attachment to a file-like object. + + Example: + + with open("my_file.zip", "wb") as f: + attachment.download_to_file(f) + + :param io: The file-like object to write the data to. + """ + + response = self.allspice_client.requests.get( + self.browser_download_url, + headers=self.allspice_client.headers, + stream=True, + ) + # 4kb chunks + for chunk in response.iter_content(chunk_size=4096): + if chunk: + io.write(chunk) + class Comment(ApiObject): assets: List[Union[Any, Dict[str, Union[int, str]]]] diff --git a/tests/test_api.py b/tests/test_api.py index fe825cc..7b3239e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -627,6 +627,27 @@ def test_get_issue_attachments(instance): assert attachments[0].name == "requirements.txt" +def test_download_issue_attachment(instance, tmp_path): + org = Organization.request(instance, test_org) + repo = Repository.request(instance, org.username, test_repo) + issue = repo.get_issues()[0] + comment = issue.get_comments()[0] + attachment = comment.get_attachments()[0] + + filename = uuid.uuid4().hex[:8] + ".txt" + filepath = tmp_path / filename + with open(filepath, "wb") as f: + attachment.download_to_file(f) + + with open(filepath, "r") as actual_f: + with open("requirements.txt", "r") as expected_f: + attachment_content = actual_f.read() + assert len(attachment_content) > 0 + + expected_content = expected_f.read() + assert expected_content == attachment_content + + def test_edit_issue_attachment(instance): org = Organization.request(instance, test_org) repo = Repository.request(instance, org.username, test_repo)