Automatically Download the Latest Software Release from GitHub with Python
Use the GitHub API to fetch the latest release metadata and download the first asset (binary or archive) to a local directory.
pip install requests
Python code
31 linesimport requests
import sys
from pathlib import Path
def download_latest_release(owner: str, repo: str, output_dir: str = ".") -> None:
"""Download the latest release asset from a GitHub repository."""
url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
response = requests.get(url)
response.raise_for_status()
release_data = response.json()
assets = release_data.get("assets", [])
if not assets:
print(f"No assets found for latest release of {owner}/{repo}")
return
# Download the first asset (commonly the binary/archive)
asset = assets[0]
asset_url = asset["browser_download_url"]
filename = asset["name"]
output_path = Path(output_dir) / filename
print(f"Downloading {filename} from {owner}/{repo}...")
asset_response = requests.get(asset_url, stream=True)
asset_response.raise_for_status()
with open(output_path, "wb") as f:
for chunk in asset_response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Saved to {output_path}")
if __name__ == "__main__":
# Example: download the latest release from python/cpython (source code archive)
download_latest_release("python", "cpython")
Output
Downloading python-3.12.1.tar.xz from python/cpython...
Saved to ./python-3.12.1.tar.xz
How it works
This script uses the GitHub Releases API to get the latest published release for a repository. requests.get(…)/.json() parses the JSON response into a dict. We access assets[0] to grab the first file attached to the release. The download uses stream=True and iter_content() to avoid loading the entire file into memory. Error handling with raise_for_status() ensures we stop on HTTP errors. The function accepts an optional output_dir to save the file anywhere.
Common mistakes
- Forgetting to handle repos that have no assets in their latest release (e.g., only a tag).
- Assuming the asset URL is always under `browser_download_url` and not checking for `upload_url` patterns.
- Not using `stream=True` for large binaries, causing memory exhaustion.
- Hardcoding authentication for private repos without using a token environment variable.
Variations
- Use `PyGithub` library for a more Pythonic interface (`from github import Github`).
- Add a `--tag` argument to download a specific release instead of `latest`.
- Filter assets by name or content type (e.g., only download `.tar.gz` files).
Real-world use cases
- Automating updates of CLI tools or language runtimes in a CI pipeline, always grabbing the newest stable build.
- Building a personal updater that downloads the latest binary for an open‑source tool you use daily.
- Syncing release artifacts from a private GitHub repo to an internal artifact server or deployment bucket.
Sponsored
More from Automation & scripting
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
- Automatically Log CPU, RAM, and Disk Usage Every Minute in Python easy
- Batch Rename Hundreds of Files in Python easy
- Benchmark File Read and Write Speed in Python medium
Keep learning
Related tutorials and quizzes for this topic.