Использование метода .get_contents()
при попытке загрузить большой файл вызывает ошибку:
{'errors': [{'code': 'too_large', 'field': 'data',
'resource': 'Blob'}],
'message': 'This API returns blobs up to 1 MB in size. The requested blob is too large to fetch via the API, but you can use the Git Data API to request blobs up to 100 MB in size.',
'documentation_url': 'https://developer.github.com/v3/repos/contents/#get-contents'}
Есть ли способ обнаружить это и передать другому обработчику, который может загрузить файл?
Например, если что-то вроде этого не удается:
contents = repository.get_dir_contents(urllib.parse.quote(server_path), ref=sha)
for content in contents:
if content.type != 'dir':
file_content = repository.get_contents(urllib.parse.quote(content.path), ref=sha)
при желании вернуться к:
file_content = repository.get_git_blob(content.sha)
Я тоже сталкивался с этой проблемой раньше. В моем случае, поскольку у меня всегда был SHA блоба, я просто использовал вместо него git_git_blob
.
Однако get_git_blob
не работает ни с одним типом объектов, кроме blob
(отсюда и название). Вам необходимо знать тип объекта, прежде чем пытаться его вызвать.
Чтобы сделать откат, вам нужно знать две части информации:
Если get_contents
терпит неудачу, он ничего вам не сообщает. Насколько я могу судить, на самом деле нет никакого хорошего способа сделать откат.
Закрыт как wontfix
. Если у кого-то есть хорошая идея, как это решить, я с радостью открою. Насколько я могу судить, это не похоже на то, чтобы сделать это чисто.
У меня та же проблема, и я делаю что-то вроде.
file_contents = repo.get_contents(dir_name, ref=branch)
тогда sha
существует для каждого file_content
, и следующее можно использовать для захвата blob каждого файла
for file_content in file_contents:
try:
if file_content.encoding != 'base64':
# some error ...
# ok...
except GithubException:
# if file_content DOES NOT HAVE encoding, it is a large file
blob = repo.get_git_blob(file_content.sha)
# do something with blob
Если path_name
относится к одному файлу размером более 1M, это должен быть какой-то блок try / exception, как показано ниже:
try:
res = repo.get_contents(path_name, ref=branch)
# ok, we have the content
except GithubException:
return get_blob_content(repo, branch, path_name)
где get_blob_content
- это что-то вроде
def get_blob_content(repo, branch, path_name):
# first get the branch reference
ref = repo.get_git_ref(f'heads/{branch}')
# then get the tree
tree = repo.get_git_tree(ref.object.sha, recursive='/' in path_name).tree
# look for path in tree
sha = [x.sha for x in tree if x.path == path_name]
if not sha:
# well, not found..
return None
# we have sha
return repo.get_git_blob(sha[0])
Настоящий код с проверкой ошибок длиннее, но идея здесь.
При получении блоба будет полезен следующий код.
blob = repo.get_git_blob(sha[0])
b64 = base64.b64decode(blob.content)
return b64.decode("utf8")
Кроме того, файл обновления также столкнется с этой проблемой.
raise self.__createException(status, responseHeaders, output)
github.GithubException.UnknownObjectException: 404 {"message": "Not Found", "documentation_url": " https://docs.github.com/rest/reference/repos#get -repository-content"} появляется эта ошибка при попытке скачать полученные файлы репозитория для ветки master
Самый полезный комментарий
У меня та же проблема, и я делаю что-то вроде.
тогда
sha
существует для каждогоfile_content
, и следующее можно использовать для захвата blob каждого файлаЕсли
path_name
относится к одному файлу размером более 1M, это должен быть какой-то блок try / exception, как показано ниже:где
get_blob_content
- это что-то вродеНастоящий код с проверкой ошибок длиннее, но идея здесь.