Metadata-Version: 2.4
Name: PyURLFetch
Version: 0.1.0
Summary: A Python library for implementing convenient resumable download functionality.
Author: Sha0huaZhang
License-Expression: MIT
Project-URL: Homepage, https://github.com/Sha0huaZhang/PyURLFetch
Project-URL: Repository, https://github.com/Sha0huaZhang/PyURLFetch
Project-URL: Issues, https://github.com/Sha0huaZhang/PyURLFetch/issues
Keywords: download,resumable,http,requests
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.20
Requires-Dist: urllib3>=1.25
Provides-Extra: progress
Requires-Dist: rich>=12.0; extra == "progress"
Dynamic: license-file

# PyURLFetch
A Python library for implementing convenient resumable download functionality.

Extracted from MacWave's package download flow. It handles `.partial` files and
HTTP Range requests for resuming, optional rate limiting, proxies, skipping SSL
verification, and a `rich` progress bar.

## Install

Not published on PyPI yet. Install name is `PyURLFetch`, import name is
`pyurlfetch` — install straight from the repository:

```bash
# core (requests + urllib3)
pip install "git+https://github.com/Sha0huaZhang/PyURLFetch.git"

# with the rich progress bar
pip install "pyurlfetch[progress] @ git+https://github.com/Sha0huaZhang/PyURLFetch.git"
```

Or from a local clone:

```bash
git clone https://github.com/Sha0huaZhang/PyURLFetch.git
cd PyURLFetch
pip install .
```

## Usage

```python
from pyurlfetch import download_file

download_file(
    "https://example.com/archive.tar.gz",
    "archive.tar.gz",
    resume=True,
    limit_rate="1M",
)
```

The download is written to `archive.tar.gz.partial` and renamed to the target
once complete, so an interrupted download can be resumed by calling the same
function again with `resume=True`.

Failures raise an exception instead of exiting the process:

```python
from pyurlfetch import HTTPStatusError, NetworkError, UserAborted

try:
    download_file(url, dest, resume=True)
except HTTPStatusError as error:
    print(error.status_code, error.url)
except (NetworkError, UserAborted) as error:
    print("download failed:", error)
```

### Retrying

`download_file` does not prompt interactively. Control retries either with
`max_retries` or with an `on_retry(attempt, error) -> bool` callback:

```python
download_file(url, dest, max_retries=3)

download_file(url, dest, on_retry=lambda attempt, error: input("retry? [y/N] ") == "y")
```
