Pygithub: Téléchargement de fichiers volumineux

Créé le 20 nov. 2017  ·  5Commentaires  ·  Source: PyGithub/PyGithub

L'utilisation de la méthode .get_contents() pour essayer de télécharger un fichier volumineux génère l'erreur:

{'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'}

Existe-t-il un moyen de détecter cela et de passer à un autre gestionnaire qui peut télécharger le fichier?

Par exemple, si quelque chose comme ça échoue:

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)

éventuellement revenir à:

file_content = repository.get_git_blob(content.sha)
question

Commentaire le plus utile

J'ai le même problème et je finis par faire quelque chose du genre.

  1. si nous vidons tous les fichiers d'un répertoire et certains sont plus grands que 1M,
 file_contents = repo.get_contents(dir_name, ref=branch)

puis sha existe pour chaque file_content , et ce qui suit pourrait être utilisé pour récupérer le blob de chaque fichier

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

Si path_name fait référence à un seul fichier de plus de 1M, il doit s'agir d'un bloc try / exception comme suit:

        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 est quelque chose comme

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])

Le vrai code avec vérification des erreurs est plus long, mais l'idée est là.

Tous les 5 commentaires

J'ai déjà rencontré ce problème auparavant. Dans mon cas, comme j'ai toujours eu le SHA du blob, j'ai simplement utilisé git_git_blob place.

Cependant, get_git_blob ne fonctionne pour aucun type d'objet autre que blob (d'où le nom). Vous devez connaître le type de l'objet avant de tenter de l'appeler.

Pour effectuer le remplacement, vous devez connaître deux informations:

  1. Le type de l'objet.
  2. Le SHA de l'objet.

Si get_contents échoue, il ne vous dit aucune de ces choses. Pour autant que je sache, il n'y a pas vraiment de bon moyen de faire le repli.

Fermé en wontfix . Si quelqu'un a une bonne idée sur la façon de résoudre ce problème, je suis heureux de rouvrir. Pour autant que je sache, il ne semble pas possible de le faire de manière propre.

J'ai le même problème et je finis par faire quelque chose du genre.

  1. si nous vidons tous les fichiers d'un répertoire et certains sont plus grands que 1M,
 file_contents = repo.get_contents(dir_name, ref=branch)

puis sha existe pour chaque file_content , et ce qui suit pourrait être utilisé pour récupérer le blob de chaque fichier

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

Si path_name fait référence à un seul fichier de plus de 1M, il doit s'agir d'un bloc try / exception comme suit:

        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 est quelque chose comme

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])

Le vrai code avec vérification des erreurs est plus long, mais l'idée est là.

Lorsque vous récupérez le blob, le code suivant sera utile.

    blob = repo.get_git_blob(sha[0])
    b64 = base64.b64decode(blob.content)
    return b64.decode("utf8")

En outre, le fichier de mise à jour rencontrera également ce problème.

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"} obtenant cette erreur lors de la tentative pour télécharger un fichier de référentiel obtenu pour la branche principale

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

RitamDey picture RitamDey  ·  13Commentaires

GrapeBaBa picture GrapeBaBa  ·  14Commentaires

ChaiBapchya picture ChaiBapchya  ·  12Commentaires

nwalsh1995 picture nwalsh1995  ·  13Commentaires

gschaffner picture gschaffner  ·  24Commentaires