Metadata-Version: 2.4
Name: pybalt
Version: 2025.7.1
Summary: ☄️ Your ultimate tool & python module to download videos and audio from various platforms. Supports YouTube, Instagram, Twitter (X), Reddit, TikTok, BiliBili & More! Powered by cobalt instances
Author-email: nichind <nichinddev@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/nichind/pybalt
Project-URL: Issues, https://github.com/nichind/pybalt/issues
Keywords: downloader,cobalt,cobalt-cli,youtube,twitter,x,instagram,reddit,twitch,bilibili,download,youtube-downloader,twitter-downloader,x-downloader,instagram-downloader,reddit-downloader,twitch-downloader,bilibili-downloader
Classifier: Programming Language :: Python :: 3.11
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# pybalt [![cobalt.tools](https://img.shields.io/badge/wrapper/cli-gray.svg?logo=data:image/jpeg;base64,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)](https://cobalt.tools)  [![Get on PyPI](https://img.shields.io/pypi/v/pybalt.svg)](https://pypi.org/project/pybalt/) [![Pip module installs total downloads](https://img.shields.io/pypi/dm/pybalt.svg)](https://pypi.org/project/pybalt/) [![cobalt.tools](https://img.shields.io/badge/made%20by-nichind-white.svg)](https://nichind.dev) [![https://github.com/nichind/pybalt](https://img.shields.io/github/stars/nichind/pybalt)](https://github.com/nichind/pybalt)

[![Run Tests](https://github.com/nichind/pybalt/actions/workflows/build.yml/badge.svg)](https://github.com/nichind/pybalt/actions/workflows/build.yml) [![Upload Python Package to PyPI when a Release is Created](https://github.com/nichind/pybalt/actions/workflows/publish.yml/badge.svg)](https://github.com/nichind/pybalt/actions/workflows/publish.yml)

<img src="./assets/cli-preview2.gif" align="right" alt="pybalt cli preview gif" height="240">

### Features

**pybalt** is a powerful and flexible tool for downloading media files from various platforms, including YouTube, X (formerly Twitter), Reddit, Instagram, TikTok, and more. It works using [cobalt processing instances](https://github.com/imputnet/cobalt) and serves both as a CLI and a Python module.

* Download media files to your desktop effortlessly using pybalt as a [**command-line interface**](#%EF%B8%8F-quickstart)
* Support for [**playlists**, **bulk downloads**, and processing **links from text files**](#%EF%B8%8F-quickstart)
* Runable [**web api**](#-api-server) that allows to try multiple instances at once for best latency
* Integrate pybalt into your Python projects with ease with [**just a few lines of code**](#-python-module-integration)
* [**Host your own local cobalt instance**](#%EF%B8%8F-local-instance) for improved privacy and reliability
* [**Customize configuration**](#%EF%B8%8F-configuration-system) with environment variables or the built-in config system

https://github.com/user-attachments/assets/cf5fd9a9-520b-4970-b8c2-42baa80d7523

# ⚙️ Installation

Install pybalt with pip:

```sh
pip install pybalt -U
```

Or install pybalt on Windows with the [bat file](./install.bat) included in the repo (if you don't have Python installed):

1. Open PowerShell or Command Prompt with administrator rights (to allow pip to create aliases `cobalt` and `pybalt` in the terminal, and install python if needed)
2. Type this command:

```sh
powershell -Command "Invoke-WebRequest -Uri https://raw.githubusercontent.com/nichind/pybalt/main/install.bat -OutFile install.bat; .\install.bat"
```

# ⚡️ Quickstart

> [!NOTE]
> pybalt will automatically detect if you're running a local cobalt instance and use it first before trying public instances.

> [!NOTE]
> If the `cobalt` alias isn't working in your terminal, use `python -m pybalt <command>` instead.

> [!CAUTION]
> Remuxing (`-r`) requires ffmpeg to be installed on your device and added to your system path.

## Command Line Usage

The CLI is intuitive and easy to use! Here are some examples:

1. Download a YouTube video at maximum resolution (`-vQ max`) and remux it (`-remux`):
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -remux -vQ max
```

2. Remux an existing video file:
```sh
cobalt "C:/Users/username/Videos/video.mp4"
```

3. Download multiple videos from links in a text file:
```sh
cobalt "path/to/links.txt"
```

4. Download a video and open it immediately:
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -o
```

5. Download a video and show it in File Explorer/Finder:
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -s
```

6. Specify quality, format, and download location:
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -vQ 1080 -aF mp3 --audioBitrate 320 -fp "C:/Downloads"
```

Use `cobalt -h` to see all available options.

## Managing Instances

pybalt can work with multiple cobalt instances, including your own local instance:

1. List configured instances:
```sh
cobalt -li
```

2. Add a new instance:
```sh
cobalt -ai "https://example-instance.com" "optional-api-key"
```

3. Remove an instance:
```sh
cobalt -ri 1
```

## Local Instance Management

Run your own cobalt instance with Docker:

1. Set up a local instance:
```sh
cobalt -ls
```

2. Start/stop your local instance:
```sh
cobalt -lstart
cobalt -lstop
```

3. Check local instance status:
```sh
cobalt -lstatus
```

# 💻 Python Module Integration

pybalt can be easily integrated into your Python projects:

## Basic Download

```python
from pybalt import download
from asyncio import run

async def main():
    # Simple download with default settings
    file_path = await download("https://youtube.com/watch?v=DG2QqcHwNdE")
    print(f"Downloaded to: {file_path}")
    
    # Download with custom parameters
    file_path = await download(
        "https://youtube.com/watch?v=DG2QqcHwNdE",
        videoQuality="1080",
        audioFormat="mp3",
        audioBitrate="320",
        filenameStyle="pretty",
        remux=True
    )
    print(f"Downloaded to: {file_path}")

run(main())
```

## Advanced Usage with InstanceManager

```python
from pybalt.core.wrapper import InstanceManager
from asyncio import run

async def main():
    # Create an instance manager
    manager = InstanceManager(debug=True)
    
    # Get a list of available instances
    instances = await manager.get_instances()
    print(f"Found {len(instances)} available instances")
    
    # Download a file using the first available instance
    file_path = await manager.download(
        url="https://youtube.com/watch?v=DG2QqcHwNdE",
        videoQuality="1080",
        remux=True
    )
    print(f"Downloaded to: {file_path}")
    
    # Bulk download multiple URLs
    urls = [
        "https://youtube.com/watch?v=DG2QqcHwNdE",
        "https://youtube.com/watch?v=anotherVideo"
    ]
    
    # Download multiple files concurrently
    async for path in manager.download_generator(urls=urls, remux=True):
        print(f"Downloaded: {path}")

run(main())
```

## Track Download Progress

```python
from pybalt import download
from asyncio import run

async def main():
    # Define a status callback function
    async def status_callback(downloaded_size, total_size, download_speed, eta, **kwargs):
        percent = (downloaded_size / total_size * 100) if total_size > 0 else 0
        print(f"Downloaded: {downloaded_size / 1024 / 1024:.2f}MB / "
              f"{total_size / 1024 / 1024:.2f}MB ({percent:.1f}%) at "
              f"{download_speed / 1024 / 1024:.2f}MB/s, ETA: {eta:.0f}s")
    
    # Define a completion callback
    async def done_callback(file_path, downloaded_size, time_passed, **kwargs):
        print(f"Download completed in {time_passed:.2f}s")
        print(f"File saved to: {file_path}")
    
    # Download with progress tracking
    file_path = await download(
        "https://youtube.com/watch?v=DG2QqcHwNdE",
        status_callback=status_callback,
        done_callback=done_callback
    )

run(main())
```

## Using Status Parent

```python
from pybalt import download
from asyncio import run, create_task

class StatusParent:
    def __init__(self):
        self.downloaded_size = 0
        self.total_size = 0
        self.download_speed = 0
        self.eta = 0
        self.completed = False
        self.file_path = None

async def main():
    # Create status parent object to track progress
    status = StatusParent()
    
    # Start download as a background task
    task = create_task(download(
        "https://youtube.com/watch?v=DG2QqcHwNdE",
        status_parent=status
    ))
    
    # Monitor progress while download is running
    while not task.done():
        if status.total_size > 0:
            percent = status.downloaded_size / status.total_size * 100
            print(f"Progress: {percent:.1f}% - Speed: {status.download_speed / 1024 / 1024:.2f}MB/s")
        await run(sleep(1))
    
    # Get the result
    file_path = await task
    print(f"Downloaded to: {file_path}")

run(main())
```

# ⚙️ Configuration System

pybalt features a comprehensive configuration system for customizing behavior:

## Command-line Configuration Interface

Open the interactive configuration interface:

```sh
cobalt -c
```

Get a specific configuration value:

```sh
cobalt -gc "network" "timeout"
```

Set a configuration value:

```sh
cobalt -sc "network" "timeout" "30"
```

## Configuration File Locations

- **Windows**: `%APPDATA%\pybalt\settings.ini`
- **macOS**: `~/Library/Application Support/pybalt/settings.ini`
- **Linux**: `~/.config/pybalt/settings.ini`

## Main Configuration Sections

- **general**: General settings like user agent and debug mode
- **network**: Connection settings like timeouts, proxies, and retries
- **instances**: Cobalt instance settings
- **user_instances**: User-defined cobalt instances
- **paths**: Download paths and file locations
- **local**: Local instance configuration
- **ffmpeg**: Remuxing settings
- **display**: UI/progress display settings

# 📦 Environment Variables

You can configure pybalt with environment variables:

```
PYBALT_CONFIG_DIR=path/to/config/dir        # Custom config directory
PYBALT_CONFIG_PATH=path/to/settings.ini     # Custom config file path

# Section-specific settings
PYBALT_GENERAL_DEBUG=True                   # Enable debug mode
PYBALT_GENERAL_USER_AGENT=custom-agent      # Custom user agent

PYBALT_NETWORK_TIMEOUT=30                   # Network timeout
PYBALT_NETWORK_USE_SYSTEM_PROXY=True        # Use system proxy
PYBALT_NETWORK_PROXY=http://my-proxy:8080   # Custom proxy

PYBALT_PATHS_DEFAULT_DOWNLOADS_DIR=/path    # Custom download directory

PYBALT_LOCAL_LOCAL_INSTANCE_PORT=9000       # Local instance port
```

You can also set variables in a `.env` file in your project directory.

# 🛠️ Local Instance

pybalt can set up and manage a local cobalt instance using Docker:

## Setting Up a Local Instance

```sh
cobalt -ls
```

This interactive wizard will guide you through:
- Setting a port for your instance
- Configuring API key authentication (optional)
- Setting duration limits
- Configuring proxy settings
- Setting up cookies for authenticated services

## Managing Your Local Instance

Start your local instance:

```sh
cobalt -lstart
```

Stop your local instance:

```sh
cobalt -lstop
```

Check the status:

```sh
cobalt -lstatus
```

Restart your instance:

```sh
cobalt -lrestart
```

# 🌐 API Server

pybalt includes a built-in API server that allows you to interact with multiple cobalt instances through a single HTTP request. It also provides a web UI for easy downloading.

## Starting the API Server

Start the API server in detached mode:

```sh
cobalt --api-start
```

Specify a custom port (default is 8009):

```sh
cobalt --api-port 8080 --api-start
```

## Managing the API Server

Check if the API server is running:

```sh
cobalt --api-status
```

Stop the running API server:

```sh
cobalt --api-stop
```

## API Endpoints

The API server exposes the following endpoints:

- **GET `/`**: Returns information about the API server, including version and instance count
- **POST `/`**: Accepts a JSON payload with a URL and parameters to download content and returns a JSON response with download information
- **GET `/ui`**: Serves a web-based user interface for downloading content

## Web UI

![{3896D5C8-0FC7-46D8-8B33-4669CA1EFADD}](https://github.com/user-attachments/assets/80acf3b2-765e-45da-ad56-6e6a31679e28)



The API server includes a comprehensive web UI that allows you to:

- Download videos from various platforms through a user-friendly interface
- Configure advanced settings such as video quality, audio format, and file naming
- Track the download progress
- Ignore specific instances that might be causing issues
- Copy direct download links

Access the web UI at `http://localhost:8009/ui` (or your custom port).

## API Usage Examples

### Example API Request:

```bash
curl -X POST "http://localhost:8009/" \
     -H "Content-Type: application/json" \
     -d '{"url": "https://www.youtube.com/watch?v=DG2QqcHwNdE", "videoQuality": "1080", "audioFormat": "mp3"}'
```

### Example API Response:

```json
{
  "status": "tunnel",
  "url": "http://download-link.mp4",
  "instance_info": {
    "url": "https://instance-url.com",
  },
}
```

# 👥 Used by

pybalt is used by the following projects:

- [download.nichind.dev](https://download.nichind.dev) - Website for downloading media files from various platforms

# 👥 Contributors

[![Contributors](https://contrib.rocks/image?repo=nichind/pybalt)](https://github.com/nichind/pybalt/graphs/contributors)

# 🌟 That's it!

I spent too much time on this project... please consider leaving a :star: if you like it!

[![Star History Chart](https://api.star-history.com/svg?repos=nichind/pybalt&type=Date)](https://github.com/nichind/pybalt)
