Pygithub: Große Dateien herunterladen

Erstellt am 20. Nov. 2017  ·  5Kommentare  ·  Quelle: PyGithub/PyGithub

Wenn Sie versuchen, .get_contents() Methode

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

Gibt es eine Möglichkeit , dies zu erkennen und übergeht in einem anderen Handler, der die Datei herunterladen kann?

Wenn beispielsweise so etwas fehlschlägt:

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)

Optional können Sie auf Folgendes zurückgreifen:

file_content = repository.get_git_blob(content.sha)
question

Hilfreichster Kommentar

Ich habe das gleiche Problem und mache am Ende etwas in der Art von.

  1. Wenn wir alle Dateien aus einem Verzeichnis sichern und einige größer als 1 MB sind,
 file_contents = repo.get_contents(dir_name, ref=branch)

dann existiert sha für jedes file_content , und das Folgende könnte verwendet werden, um den Blob jeder Datei zu erfassen

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

Wenn sich path_name auf eine einzelne Datei bezieht, die größer als 1 MB ist, muss es sich um einen Try / Exception-Block wie folgt handeln:

        try:
            res = repo.get_contents(path_name, ref=branch)
            # ok, we have the content
        except GithubException:
           return get_blob_content(repo, branch, path_name)

wo get_blob_content so etwas ist

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

Echter Code mit Fehlerprüfung ist länger, aber die Idee ist hier.

Alle 5 Kommentare

Ich bin auch schon einmal auf dieses Problem gestoßen. In meinem Fall habe ich stattdessen nur git_git_blob verwendet, da ich immer den SHA des Blobs hatte.

get_git_blob funktioniert jedoch für keinen anderen Objekttyp als blob (daher der Name). Sie müssen den Typ des Objekts kennen, bevor Sie versuchen, es aufzurufen.

Um den Fallback durchführen zu können, müssen Sie zwei Informationen kennen:

  1. Der Typ des Objekts.
  2. Die SHA des Objekts.

Wenn get_contents fehlschlägt, sagt es Ihnen keines dieser Dinge. Soweit ich das beurteilen kann, gibt es keine wirklich gute Möglichkeit, den Fallback durchzuführen.

Geschlossen als wontfix . Wenn jemand eine gute Idee hat, wie man das löst, bin ich froh, wieder zu öffnen. Soweit ich das beurteilen kann, sieht es nicht so aus, als ob es auf saubere Weise möglich wäre.

Ich habe das gleiche Problem und mache am Ende etwas in der Art von.

  1. Wenn wir alle Dateien aus einem Verzeichnis sichern und einige größer als 1 MB sind,
 file_contents = repo.get_contents(dir_name, ref=branch)

dann existiert sha für jedes file_content , und das Folgende könnte verwendet werden, um den Blob jeder Datei zu erfassen

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

Wenn sich path_name auf eine einzelne Datei bezieht, die größer als 1 MB ist, muss es sich um einen Try / Exception-Block wie folgt handeln:

        try:
            res = repo.get_contents(path_name, ref=branch)
            # ok, we have the content
        except GithubException:
           return get_blob_content(repo, branch, path_name)

wo get_blob_content so etwas ist

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

Echter Code mit Fehlerprüfung ist länger, aber die Idee ist hier.

Wenn Sie den Blob erhalten, ist der folgende Code hilfreich.

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

Bei der Aktualisierung der Datei tritt dieses Problem ebenfalls auf.

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"} Beim Versuch wird dieser Fehler angezeigt um eine Got-Repository-Datei für den Hauptzweig herunterzuladen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen