1

I'm trying to download Helm's latest release using a script. I want to download the binary and copy it to a file. I tried looking at the documentation, but it's very confusing to read and I don't understand this. I have found a way to download specific files, but nothing regarding the binary. So far, I have:

from github import Github

def get_helm(filename):
    f = open(filename, 'w') # The file I want to copy the binary to
    g = Github()
    r = g.get_repo("helm/helm")
    # Get binary and use f.write() to transfer it to the file
    f.close
    return filename

I am also well aware of the limits of queries that I can do since there are no credentials.

BloodLord
  • 49
  • 5

1 Answers1

1

For Helm in particular, you're not going to have a good time since they apparently don't publish their release files via GitHub, only the checksum metadata.

See https://github.com/helm/helm/releases/tag/v3.6.0 ...

Otherwise, this would be as simple as:

  1. get the JSON data from https://api.github.com/repos/{repo}/releases
  2. get the first release in the list (it's the newest)
  3. look through the assets of that release to find the file you need (e.g. for your architecture)
  4. download it using your favorite HTTP client (e.g. the one you used to get the JSON data in the first step)

Nevertheless, here's a script that works for Helm's additional hoops-to-jump-through:

import requests


def download_binary_with_progress(source_url, dest_filename):
    binary_resp = requests.get(source_url, stream=True)
    binary_resp.raise_for_status()
    with open(dest_filename, "wb") as f:
        for chunk in binary_resp.iter_content(chunk_size=524288):
            f.write(chunk)
            print(f.tell(), "bytes written")
    return dest_filename


def download_newest_helm(desired_architecture):
    releases_resp = requests.get(
        f"https://api.github.com/repos/helm/helm/releases"
    )
    releases_resp.raise_for_status()
    releases_data = releases_resp.json()
    newest_release = releases_data[0]
    for asset in newest_release.get("assets", []):
        name = asset["name"]
        # For a project using regular releases, this would be simplified to
        # checking for the desired architecture and doing
        # download_binary_with_progress(asset["browser_download_url"], name)
        if desired_architecture in name and name.endswith(".tar.gz.asc"):
            tarball_filename = name.replace(".tar.gz.asc", ".tar.gz")
            tarball_url = f"https://get.helm.sh/{tarball_filename}"
            return download_binary_with_progress(
                source_url=tarball_url, dest_filename=tarball_filename
            )
    raise ValueError("No matching release found")


download_newest_helm("darwin-arm64")
AKX
  • 152,115
  • 15
  • 115
  • 172
  • I didn't realize that I would still need to use requests to get it. I thought the PyGithub offered that option. Thank you, this helps a lot. – BloodLord Jun 04 '21 at 15:17