Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pybalt rewrite #3

Merged
merged 33 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e07993e
rewrite:initial
nichind Dec 24, 2024
a8575df
progress
nichind Dec 24, 2024
4661bbe
get tunnel, fix request not sending json, async with ... support for …
nichind Dec 25, 2024
badb1d8
Response class, tunnel info, other impr.
nichind Dec 26, 2024
204a72b
ref
nichind Dec 27, 2024
d56ea24
download_from_url;async file write
nichind Dec 27, 2024
a135785
debug option for Cobalt;fix cobalt.download
nichind Dec 27, 2024
24fcba7
format
nichind Dec 27, 2024
627f7ec
fix kwargs annotation for download
nichind Dec 27, 2024
1ee6b43
impr
nichind Dec 29, 2024
37a80a6
tunnel fixes for different services
nichind Jan 1, 2025
71a8583
status parent
nichind Jan 1, 2025
1833507
lprint ref
nichind Jan 2, 2025
cab6b08
ref
nichind Jan 4, 2025
a7de38e
fix status check
nichind Jan 6, 2025
e42f4fd
Impovements, local remux (!), insane options re-generator (i code pro…
nichind Jan 7, 2025
d5969c5
fix remux file alr existing confirmation
nichind Jan 7, 2025
5e8a56b
func to install cobalt instance docker image and start it
nichind Jan 7, 2025
7c7fa25
fix distro find
nichind Jan 7, 2025
e1b1226
ultra-fast remux
nichind Jan 8, 2025
fa59011
fx
nichind Jan 8, 2025
f4fc7d9
fast fixes
nichind Jan 15, 2025
ece1ad2
cli
nichind Jan 15, 2025
3cadd9e
a lot of terminal and status work
nichind Jan 16, 2025
8f9f2fb
prepare lprint for formatting, dont stop download status on lost conn…
nichind Jan 16, 2025
71af99b
choices for cli help
nichind Jan 16, 2025
773ff9f
some of old features ported, refactor
nichind Jan 16, 2025
73431e7
fix(temporary) file corrupting when connection is dropper and total f…
nichind Jan 16, 2025
32214ae
typo
nichind Jan 16, 2025
96d3e38
refactor download playlist to use generator (i'm truly python senior …
nichind Jan 17, 2025
f6c5201
restyle prints to match
nichind Jan 17, 2025
39f78cf
fix literal bad type for cli
nichind Jan 17, 2025
97f7a13
readme
nichind Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 58 additions & 124 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,168 +1,102 @@
<div align="center" style="display: flex; flex-flow: column wrap;">
<img src='./assets/logo.png' style='border-radius: 8px; width: 124px'></img>
<h3>pybalt</h3>
<h5>CLI tool and python module for downloading media through Cobalt processing instances.</h5>

[![Get on PyPI](https://img.shields.io/pypi/v/pybalt.svg)](https://pypi.org/project/pybalt/)
[![Last commit](https://img.shields.io/github/last-commit/nichind/pybalt.svg)](https://github.com/nichind/pybalt)
[![Pip module installs total downloads](https://img.shields.io/pypi/dm/pybalt.svg)](https://pypi.org/project/pybalt/)
[![GitHub stars](https://img.shields.io/github/stars/nichind/pybalt.svg)](https://github.com/nichind/pybalt)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

<div align="center" style="display: flex; flex-flow: column wrap;">
<h3>CLI Preview</h3>

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

</div>
<br><br>
<h1>Installation</h1>
<h4>Install pybalt using PowerShell on Windows</h4>

Downloads [install.bat](./install.bat) and executes it.

Powershell should be run as administrator, otherwise aliases (`cobalt`, `pybalt`) in terminal will not work.

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

<h4>Install using PIP</h4>

```shell
pip install pybalt
```

This should create aliases `pybalt` and `cobalt` in your shell.
# 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)

Try running `cobalt -h` to see the help message.
<img src="./assets/cli-preview2.gif" align="right" alt="pybalt cli preview gif" height="240">

If for some reason it didn't work, try using it directly from python package:
**pybalt** is a powerful and flexible tool for downloading media files from various platforms, including but not limited to YouTube, X (formerly Twitter), Reddit, Instagram, and TikTok. It works using [cobalt processing instances](https://github.com/imputnet/cobalt) and serves both as a CLI and a Python module.

```shell
python -m pybalt
```
<br><br>
<h1>Usage & Examples</h1>
* Download media files to your desktop effortlessly using pybalt as a **command-line interface**, with support for downloading **playlists** and **links from text files**.
* Integrate pybalt into your Python projects with ease with **just 2 lines of code**.
* **Easily** replace and build custom code extensions to suit your needs.

<img src='./assets/cli-preview.gif' style='border-radius: 8px'></img>
https://github.com/user-attachments/assets/cf5fd9a9-520b-4970-b8c2-42baa80d7523

<h3>Selecting processing instance</h3>
# ⚙️ Installation

You can set **processing instance URL**, **API key**, and **user-agent** as environment variables; pybalt will use them if none are provided.
install pybalt with pip

```sh
pip install pybalt -U
```
COBALT_API_URL=YOUR_INSTANCE_URL
COBALT_API_KEY=YOUR_API_KEY
COBALT_USER_AGENT=YOUR_USER_AGENT
```

> By default, pybalt attempts to use any available instance for you provided by [public list of instances](https://instances.cobalt.best). It is recommended to host your own instance or request an `API key` from someone else's instance.

<br>
<h2>As a CLI</h2>
<details open>
<summary></summary>

Every command here uses the `cobalt` alias; you can also use `pybalt` or `python -m pybalt`.

By default, all downloads are saved in the user's downloads folder `~/Downloads`, or the one specified by the `-f` (`-folder`) flag.

Get a list of all available commands by running:

```shell
cobalt -h
```

<br>
<h3>Download video from URL</h3>

```shell
cobalt -u 'https://youtube.com/watch?v=8ZP5eqm4JqM'
```
or install pybalt on windows with the [bat file](./install.bat) included in the repo (if you dont have python installed)

You can also provide the URL as a positional argument:
1. Open powershell or cmd with the administator rights (to allow pip create aliases `cobalt` and `pybalt` in the terminal)
2. Type this command

```shell
cobalt 'https://youtube.com/watch?v=8ZP5eqm4JqM'
```sh
powershell -Command "Invoke-WebRequest -Uri https://raw.githubusercontent.com/nichind/pybalt/main/install.bat -OutFile install.bat; .\install.bat"
```

<br>
<h3>Download YouTube playlist</h3>
# ⚡️ Quickstart

```shell
cobalt -pl 'https://youtube.com/playlist?list=PL_93TBqf4ymR9GsuI9W4kQ-G3WM7d2Tqj'
```
> [!NOTE]
> pybalt will auto-detect if you are hosting a local cobalt-api instance and will try to use it first instead of instances from [public instance list](https://instances.cobalt.best) and my fallback one.

<br>
<h3>Download from text file</h3>
> [!NOTE]
> if alias `cobalt` isn't working for you in the terminal use `python -m pybalt <command>` instead.

Create a text file with URLs on each line:
> [!CAUTION]
> Remuxing (`-r`) requires for ffmpeg to be installed on your device and being in system path.

```txt
https://youtube.com/watch?v=8ZP...
.....
....
...
The cli part of this project is very intuitive and easy to-use! Let's see a few examples:
1. Download video from YouTube in maximum resolution possible (`-vQ max`) and then [remux](https://cobalt.tools/remux) it (`-r`).
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -r -vQ max
```

Then run:

```shell
cobalt -l 'path/to/file.txt'
2. Remux video on your device
```sh
cobalt "C://Users/nichind/Videos/video.mp4" -r
```

<br>
<h3>More examples</h3>

Download all videos from a YouTube playlist in `720p` to folder `/Music/`, with filename style `classic`, using instance `https://dwnld.nichind.dev` and `API key` authorization:

```shell
cobalt -pl 'https://youtube.com/playlist?list=PL_93TBqf4ymR9GsuI9W4kQ-G3WM7d2Tqj' -q 720 -f './Music/' -fs 'classic' -i 'https://dwnld.nichind.dev' -k 'YOUR_API_KEY'
3. Download videos from the links in the text file
```sh
cobalt "c://Users/nichind/Desktop/very-important.txt"
```
> View all possible arguments using `-h`, pass them accordingly to the [api docs](https://github.com/imputnet/cobalt/blob/main/docs/api.md)

</details>
<br><br>
<h2>As a module</h2>
<details open>
<summary></summary>
# 💻 Integrate to your project

<h3>Download video from URL</h3>
pybalt originally comes as-a python module, integrating pybalt into your project is just **2 lines of code**:

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

async def main():
path = await download('https://youtube.com/watch?v=8ZP5eqm4JqM')
print('Downloaded: ', path) # Downloaded: /Users/%USER%/Downloads/8ZP5eqm4JqM.mp4
path = await download("your-video-url", filenameStyle="pretty", remux=True, youtubeHLS=False, videoQuality="1080", status_parent=status)
print(path)

run(main())
```

You can pass arguments inside the Cobalt object:
you can also construct custom `Cobalt` instance.

```python
from pybalt import Cobalt
from asyncio import run

async def main():
cobalt = Cobalt(api_instance='YOUR_INSTANCE_URL', api_key='YOUR_API_KEY', headers={...})
path = await cobalt.download(url='https://youtube.com/watch?v=8ZP5eqm4JqM', quality='1080')
print('Downloaded: ', path) # Downloaded: /Users/%USER%/Downloads/8ZP5eqm4JqM.mp4
cobalt = Cobalt(debug=True, proxy="http://...", user_agent="idk :)")
# then use await cobalt.download(url) to download
```

run(main())
```
run detached download and monitor progress using `StatusParent`

</details>
```python
from pybalt import StatusParent

<br><br>
<h1>Contributing</h1>
status = StatusParent() # You can use default python dict instead of StatusParent!
run_detached(await download(url, status_parent=status)) # run detached with your own logic
while not status.completed:
print(f"Still downloading... size: {status.downloaded_size}, time passed: {status.time_passed}")
print(f"download finished: {status.file_path}")
```

If you have any questions or suggestions, please [open an issue](https://github.com/nichind/pybalt/issues) or [create a pull request](https://github.com/nichind/pybalt/pulls).
disable print info

<h3>Contributors</h3>
```python
await download(url, status_callback=None, done_callback=None) # You can replace callbacks with your custom sync/async funcion!
```

<img src="https://contrib.rocks/image?repo=nichind/pybalt" alt="Contributors" style="max-width: 100%;"/>
# ...

I spent too much time on this project... please consider leaving a :star:
Binary file added assets/cli-preview2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 4 additions & 10 deletions pybalt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
from .cobalt import (
Cobalt,
Pybalt,
download,
get,
check_updates,
File,
DownloadedFile,
tl,
)
from .core.cobalt import Cobalt, Instance, StatusParent, Tunnel


__all__ = ["Cobalt", "Instance", "Downloader", "Tunnel", "StatusParent"]
Loading