How to Download All Assets from GitHub Releases in Python
Downloads every asset attached to the latest GitHub release of a repository, saving them locally using the GitHub API and Python's requests and pathlib libraries.
pip install requests
Python code
29 linesimport requests
import os
import zipfile
from pathlib import Path
def download_github_release_assets(owner: str, repo: str, output_dir: str = "release_assets") -> None:
"""Downloads all assets from the latest release of a GitHub repository."""
releases_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
response = requests.get(releases_url)
response.raise_for_status()
release_data = response.json()
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
print(f"Downloading assets from '{repo}' release: {release_data['tag_name']}")
for asset in release_data.get("assets", []):
asset_name = asset["name"]
download_url = asset["browser_download_url"]
file_path = output_path / asset_name
print(f" -> Downloading: {asset_name}")
file_response = requests.get(download_url)
file_response.raise_for_status()
with open(file_path, "wb") as f:
f.write(file_response.content)
if __name__ == "__main__":
# Example: Download assets from the 'curl' repo (win32 builds)
download_github_release_assets("curl", "curl", "curl_release_assets")
Output
Downloading assets from 'curl' release: curl-8_10_0
-> Downloading: curl-8.10.0-win32-mingw.zip
-> Downloading: curl-8.10.0-win64-mingw.zip
-> Downloading: curl-8.10.0.crt
How it works
This function uses the GitHub API endpoint /repos/{owner}/{repo}/releases/latest to fetch the latest release metadata. The requests.get(url) call retrieves the data, and raise_for_status() ensures we catch HTTP errors early. The JSON response contains an assets list, where each asset has a name and browser_download_url. We iterate over those, download each binary file with requests.get(download_url), and write the bytes to a local file using Path for path management. The mkdir(parents=True, exist_ok=True) ensures the output directory exists without raising errors if it already exists.
Common mistakes
- Not handling API rate limiting when downloading many releases in a loop.
- Assuming asset names are unique, which can overwrite files with same name in different releases.
- Forgetting to raise for status on the asset download request, silently writing error pages.
- Using the API without authentication, hitting stricter rate limits (max 60 requests/hour).
Variations
- Add a `requests.Session()` for better performance when downloading many assets.
- Use `tqdm` to show a progress bar during large asset downloads.
Real-world use cases
- Automating asset retrieval in CI/CD pipelines to fetch deployment binaries after a release.
- Mirroring release assets from an open-source project to an internal artifact store or CDN.
- Building a versioned backup system that archives all release files for regulatory compliance.
Sponsored
More from Automation & scripting
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with 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
Keep learning
Related tutorials and quizzes for this topic.