upload_asset with data in memory (#1601)

* Expose upload from memory functionality
* Upload from memory basic test
* Test for custom file like object
* Reorganized existing release tests
* Remove docstrings & comments from tests
* Modify logic
* Explain why encode ignores its argument

Fixes #1140
This commit is contained in:
Jesse Li
2020-08-03 18:42:06 +10:00
committed by GitHub
parent 06dae3877c
commit a778639362
36 changed files with 1599 additions and 558 deletions
+43
View File
@@ -41,6 +41,8 @@ import github.GithubObject
import github.GitReleaseAsset
import github.NamedUser
from . import Consts
class GitRelease(github.GithubObject.CompletableGithubObject):
"""
@@ -264,6 +266,47 @@ class GitRelease(github.GithubObject.CompletableGithubObject):
self._requester, resp_headers, data, completed=True
)
def upload_asset_from_memory(
self,
file_like,
file_size,
name,
content_type=github.GithubObject.NotSet,
label="",
):
"""Uploads an asset. Unlike ``upload_asset()`` this method allows you to pass in a file-like object to upload.
Note that this method is more strict and requires you to specify the ``name``, since there's no file name to infer these from.
:calls: `POST https://<upload_url>/repos/:owner/:repo/releases/:release_id/assets <https://developer.github.com/v3/repos/releases/#upload-a-release-asset>`_
:param file_like: binary file-like object, such as those returned by ``open("file_name", "rb")``. At the very minimum, this object must implement ``read()``.
:param file_size: int, size in bytes of ``file_like``
:param content_type: string
:param name: string
:param label: string
:rtype: :class:`github.GitReleaseAsset.GitReleaseAsset`
"""
assert isinstance(name, str), name
assert isinstance(file_size, int), file_size
assert isinstance(label, str), label
post_parameters = {"label": label, "name": name}
content_type = (
content_type
if content_type is not github.GithubObject.NotSet
else Consts.defaultMediaType
)
headers = {"Content-Type": content_type, "Content-Length": str(file_size)}
resp_headers, data = self._requester.requestMemoryBlobAndCheck(
"POST",
self.upload_url.split("{?")[0],
parameters=post_parameters,
headers=headers,
file_like=file_like,
)
return github.GitReleaseAsset.GitReleaseAsset(
self._requester, resp_headers, data, completed=True
)
def get_assets(self):
"""
:calls: `GET /repos/:owner/:repo/releases/:release_id/assets <https://developer.github.com/v3/repos/releases/#list-assets-for-a-release>`_
+15
View File
@@ -447,6 +447,21 @@ class Requester:
headers["Content-Length"] = str(os.path.getsize(input))
return self.__requestEncode(cnx, verb, url, parameters, headers, input, encode)
def requestMemoryBlobAndCheck(
self, verb, url, parameters, headers, file_like, cnx=None
):
# The expected signature of encode means that the argument is ignored.
def encode(_):
return headers["Content-Type"], file_like
if not cnx:
cnx = self.__customConnection(url)
return self.__check(
*self.__requestEncode(
cnx, verb, url, parameters, headers, file_like, encode
)
)
def __requestEncode(
self, cnx, verb, url, parameters, requestHeaders, input, encode
):