Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected

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.

Medium Python 3.9+ Jun 28, 2026 Automation & scripting 2 views 0 copies

Requires third-party packages — install first
pip install requests

Python code

29 lines
Python 3.9+
import 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

stdout
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

  1. Add a `requests.Session()` for better performance when downloading many assets.
  2. 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

Sponsored Reserved space — layout preview until AdSense is connected

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Automation & scripting

Related tutorials and quizzes for this topic.