Pygithub: Скачивание больших файлов

Созданный на 20 нояб. 2017  ·  5Комментарии  ·  Источник: PyGithub/PyGithub

Использование метода .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)
question

Самый полезный комментарий

У меня та же проблема, и я делаю что-то вроде.

  1. если мы выгружаем все файлы из каталога, а некоторые из них больше 1M,
 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])

Настоящий код с проверкой ошибок длиннее, но идея здесь.

Все 5 Комментарий

Я тоже сталкивался с этой проблемой раньше. В моем случае, поскольку у меня всегда был SHA блоба, я просто использовал вместо него git_git_blob .

Однако get_git_blob не работает ни с одним типом объектов, кроме blob (отсюда и название). Вам необходимо знать тип объекта, прежде чем пытаться его вызвать.

Чтобы сделать откат, вам нужно знать две части информации:

  1. Тип объекта.
  2. SHA объекта.

Если get_contents терпит неудачу, он ничего вам не сообщает. Насколько я могу судить, на самом деле нет никакого хорошего способа сделать откат.

Закрыт как wontfix . Если у кого-то есть хорошая идея, как это решить, я с радостью открою. Насколько я могу судить, это не похоже на то, чтобы сделать это чисто.

У меня та же проблема, и я делаю что-то вроде.

  1. если мы выгружаем все файлы из каталога, а некоторые из них больше 1M,
 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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги