gh-download 0.6.0
A CLI tool to download files from GitHub repositories, including private ones, by leveraging your existing gh CLI authentication.
Requires Python: >=3.10

# GitHub Downloader (gh-download)

`gh-download` is a Python command-line tool that allows you to download files from GitHub repositories, including private ones, using `GH_TOKEN`/`GITHUB_TOKEN` environment variables or your existing `gh` (GitHub CLI) authentication.

> [!TIP]
> If using [`uv`](https://docs.astral.sh/uv/), just run:
>
> 1. `uvx dotbins get cli/cli --name gh` to install the GitHub CLI.
> 2. `uvx gh-download --help` to see the help message.

<details><summary><b><u>[ToC]</u></b> 📚</summary>

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
  - [Examples](#examples)
  - [Arguments](#arguments)
  - [Options](#options)
  - [Authentication](#authentication)
    - [Examples](#examples-1)
- [Development](#development)
  - [Running Tests](#running-tests)
  - [Pre-commit Hooks](#pre-commit-hooks)
- [Contributing](#contributing)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

</details>

## Features

- Download files from public and private GitHub repositories.
- Supports authentication via `GH_TOKEN`/`GITHUB_TOKEN` environment variables or the `gh` CLI.
- Automatically prompts for `gh auth login` if no token is available.
- Provides clear, user-friendly output and error messages using the Rich library.
- Simple command-line interface.

## Prerequisites

- **Python**: Version 3.11 or higher.
- **Authentication** (one of the following):
  - **Environment variable**: Set `GH_TOKEN` or `GITHUB_TOKEN` (works in CI, Docker, and non-interactive environments).
  - **GitHub CLI (`gh`)**: Installed and in your system's PATH. You can install it from [https://cli.github.com/](https://cli.github.com/) or use [dotbins](https://github.com/basnijholt/dotbins) and run `uvx dotbins get cli/cli --name gh` to install it.

## Installation

Install `gh-download` using pip:

```bash
pip install gh-download
```

Or for development:

1. **Clone the repository:**

   ```bash
   git clone git@github.com:basnijholt/gh-download.git
   cd gh-download
   ```

2. **Install in development mode:**

   ```bash
   uv sync
   source .venv/bin/activate  # On Windows use `.venv\Scripts\activate`
   ```

## Usage

After installation, you can use the `gh-download` command:

```bash
gh-download REPO_OWNER REPO_NAME FILE_PATH [OPTIONS]
```

<details>
<summary>See the output of <code>gh-download -h</code></summary>

<!-- CODE:BASH:START -->
<!-- echo '```yaml' -->
<!-- export NO_COLOR=1 -->
<!-- export TERM=dumb -->
<!-- gh-download -h -->
<!-- echo '```' -->
<!-- CODE:END -->

<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
```yaml

 Usage: gh-download [OPTIONS] REPO_OWNER REPO_NAME FILE_PATH

 Download a specific file from a GitHub repository.

╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│ *    repo_owner      TEXT  The owner of the repository (e.g., 'octocat').    │
│                            [required]                                        │
│ *    repo_name       TEXT  The name of the repository (e.g., 'Spoon-Knife'). │
│                            [required]                                        │
│ *    file_path       TEXT  The path to the file or folder within the         │
│                            repository (e.g., 'README.md' or                  │
│                            'src/my_folder').                                 │
│                            [required]                                        │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --branch  -b      TEXT  The branch, tag, or commit SHA to download from.     │
│                         [default: main]                                      │
│ --output  -o      TEXT  Local path to save the downloaded file or folder. If │
│                         downloading a file, this can be a new filename or a  │
│                         directory. If downloading a folder, this is the      │
│                         directory where the folder will be placed. Defaults  │
│                         to the original filename/foldername in the current   │
│                         directory.                                           │
│ --help    -h            Show this message and exit.                          │
╰──────────────────────────────────────────────────────────────────────────────╯

```

<!-- OUTPUT:END -->

</details>

### Examples

```bash
# Download a file from a public repository
gh-download octocat Spoon-Knife README.md

# Download from a specific branch
gh-download octocat Spoon-Knife README.md --branch main

# Save to a specific location
gh-download octocat Spoon-Knife README.md --output ./my_readme.md

# Download from a different branch
gh-download microsoft vscode package.json --branch release/1.85
```

### Arguments

- `REPO_OWNER`: The owner of the repository (e.g., 'octocat')
- `REPO_NAME`: The name of the repository (e.g., 'Spoon-Knife')
- `FILE_PATH`: The path to the file within the repository (e.g., 'README.md')

### Options

- `--branch, -b`: The branch, tag, or commit SHA to download from (default: main)
- `--output, -o`: Local path to save the downloaded file (defaults to the original filename in the current directory)
- `--help`: Show help message

### Authentication

`gh-download` checks for authentication in this order:

1. **Environment variables**: Checks `GH_TOKEN`, then `GITHUB_TOKEN`. This is the recommended approach for CI/CD pipelines, Docker builds, and other non-interactive environments.
2. **`gh` CLI**: Falls back to `gh auth token` to get an OAuth token from the GitHub CLI.
3. **Interactive login**: If neither is available, prompts you to run `gh auth login`.

#### Examples

```bash
# Using an environment variable (CI/Docker)
GH_TOKEN=ghp_xxx gh-download owner repo path/to/file

# Using gh CLI authentication (interactive)
gh auth login  # one-time setup
gh-download owner repo path/to/file
```

## Development

### Running Tests

The project uses `pytest` for testing. To run tests using `uv`:

```bash
uv run pytest
```

### Pre-commit Hooks

This project uses pre-commit hooks (ruff for linting and formatting, mypy for type checking) to maintain code quality. To set them up:

1. Install pre-commit:

   ```bash
   pip install pre-commit
   ```

2. Install the hooks:

   ```bash
   pre-commit install
   ```

   Now, the hooks will run automatically before each commit.

## Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you'd like to contribute code, please fork the repository and submit a pull request.

## License

This project is licensed under the MIT License - see the `LICENSE` file for details.