Skip to main content

bytehaul

Python bindings for the bytehaul Rust download library. This guide targets the published 0.2.2 release.

中文使用文档

Requirements

  • Python 3.9+
  • Rust toolchain and uv only when building from source; neither is required to install an available wheel.

Each source-build command block below assumes you start from the repository root.

Installation

From PyPI

pip install "bytehaul==0.2.2"

See the 0.2.2 release notes.

From source (development)

uv sync --project bindings/python
cd bindings/python
uv run --project . maturin develop -m Cargo.toml

Build wheel

cd bindings/python
uv run --project . maturin build --release -m Cargo.toml

Usage

Simple download

import bytehaul

bytehaul.download("https://example.com/file.bin", output_path="output.bin")

# Let bytehaul decide the filename and place it in downloads/
bytehaul.download("https://example.com/file.bin", output_dir="downloads")

With options

bytehaul.download(
    "https://example.com/file.bin",
    output_path="output.bin",
    max_connections=8,
    max_download_speed=1_000_000,  # 1 MB/s
    headers={"Authorization": "Bearer token"},
)

Network settings

bytehaul.download(
    "https://example.com/file.bin",
    output_path="output.bin",
    proxy="http://127.0.0.1:7890",
    dns_servers=["1.1.1.1", "8.8.8.8:53"],
    doh_servers=["https://dns.google/dns-query"],
    enable_ipv6=False,
)

doh_servers expects HTTPS URLs. If you pass a hostname such as dns.google, bytehaul will use the system resolver once during client construction to bootstrap the DoH endpoint addresses.

Logging

# Enable debug logging on the convenience function
bytehaul.download(
    "https://example.com/file.bin",
    output_path="output.bin",
    log_level="debug",
)

# Or on the Downloader object
from bytehaul import Downloader

downloader = Downloader(log_level="info")

Valid levels: "off" (default), "error", "warn", "info", "debug", "trace".

Object API with progress and cancellation

from bytehaul import Downloader

downloader = Downloader(
    connect_timeout=15.0,
    dns_servers=["1.1.1.1"],
    doh_servers=["https://dns.google/dns-query"],
    enable_ipv6=False,
)
task = downloader.download(
    "https://example.com/large.bin",
    output_dir="downloads",
    proxy="http://127.0.0.1:7890",
)

# Poll progress
snap = task.progress()
print(
    f"State: {snap.state}, Downloaded: {snap.downloaded}, "
    f"Speed: {snap.speed:.0f} B/s, ETA: {snap.eta_secs}"
)

# Pause or cancel if needed
# task.pause()
# task.cancel()

# Wait for completion
task.wait()

Error handling

from bytehaul import download, DownloadFailedError, CancelledError, PausedError, ConfigError

try:
    download("https://example.com/file.bin", output_path="output.bin")
except ConfigError as e:
    print(f"Invalid parameter: {e}")
except PausedError:
    print("Download was paused")
except CancelledError:
    print("Download was cancelled")
except DownloadFailedError as e:
    print(f"Download failed: {e}")

Response-body timeouts, connection resets and early EOF for a known-size body are retried within max_retries, which counts additional attempts after the first (0 disables retries). With a known total and matching object validators, continuation starts at the durable prefix confirmed by the writer; ignored Range requests or changed object metadata trigger a safe restart from zero. Disk write and synchronization errors are not retried as network failures.

API Reference

download(url, output_path=None, output_dir=None, **options)

Blocking convenience function. Downloads a file and returns when complete.

  • output_path: explicit filename or relative output path
  • output_dir: destination directory for explicit or auto-detected filenames
  • If output_path is omitted, bytehaul chooses Content-Disposition → URL path → download
  • Absolute output_path values are still accepted when output_dir is omitted

Downloader(connect_timeout=None, proxy=None, http_proxy=None, https_proxy=None, dns_servers=None, doh_servers=None, enable_ipv6=None, log_level=None)

Reusable downloader instance.

  • downloader.download(url, output_path=None, output_dir=None, **options) -> DownloadTask

Proxy settings passed to Downloader(...) act as defaults. You can override them per task by passing proxy, http_proxy, or https_proxy directly to downloader.download(...).

DownloadTask

Handle to a running download.

  • task.progress() -> ProgressSnapshot — current download progress
  • task.pause() — pause the download and persist resume metadata when available
  • task.cancel() — cancel the download
  • task.wait() — block until download completes (releases GIL)

wait() consumes the task handle. It cannot be called twice, and progress() is unavailable after it returns or raises.

ProgressSnapshot

Frozen snapshot of download progress.

Attribute Type Description
total_size int | None Total file size (if known)
downloaded int UI-oriented received bytes, not a durable resume offset
state str "pending", "downloading", "completed", "failed", "cancelled", "paused"
speed float Recent-window speed in bytes/second
eta_secs float | None Estimated remaining seconds
elapsed_secs float | None Elapsed time in seconds

downloaded may decrease during retries or already equal total_size when final synchronization fails. Final write or synchronization failures produce failed state, and the control file retains only confirmed durable progress. Use the result or exception from task.wait() to determine success; do not use the displayed byte count as a resume offset.

speed and eta_secs are computed from the same recent throughput window. speed is not a whole-download lifetime average, and eta_secs stays None until bytehaul has enough recent samples or a known total size.

Download options

Parameter Type Default
output_path str | Path | None None
output_dir str | Path | None None
headers dict[str, str] {}
max_connections int 4
connect_timeout float (secs) 30.0
read_timeout float (secs) 60.0
memory_budget int 67108864
file_allocation "none" | "prealloc" "prealloc"
resume bool True
piece_size int 1048576
min_split_size int 10485760
max_retries int 5
retry_base_delay float (secs) 1.0
retry_max_delay float (secs) 30.0
max_retry_elapsed float | None (secs) None
control_save_interval float (secs) 5.0
autosave_sync_every int 2
max_download_speed int 0 (unlimited)
checksum_sha256 str | None None
log_level str | None None ("off")

max_retries counts additional retries after the initial request/transfer attempt; 0 disables retries. Single-connection body failures resume from the writer's flushed contiguous prefix, while Range or object-metadata mismatches reset the file before restarting.

control_save_interval checks whether a checkpoint is due; autosave_sync_every batches those checks when unsaved progress exists. Set log_level on the convenience download(...) function or the Downloader(...) constructor.

Valid log_level values: "off", "error", "warn", "info", "debug", "trace" (case-insensitive).

Slow-transfer recovery

Available starting with version 0.2.2. These options apply to both download(...) and Downloader.download(...); None selects the Rust engine default.

Parameter Default Meaning
slow_transfer_mode "adaptive" "disabled", "adaptive", or "adaptive_with_hedging" (case-insensitive)
low_speed_limit None Optional positive absolute floor, bytes/second
low_speed_duration 15.0 Sustained low-speed time, seconds
slow_start_grace 5.0 Startup grace, seconds
slow_sample_window 5.0 Speed observation window, seconds

Durations must be finite, positive and at most 86,400 seconds. Adaptive recovery is on by default for multi-connection Range downloads. Hedging is opt-in, needs a strong ETag and a spare connection slot, and stages at most one small spare response before choosing a writer. It does not duplicate progress or exceed max_connections. All network payload shares the configured rate limit. Performance recovery and hedging together reserve at most min(total_size / 100, 16 MiB) of extra Range work; requests that do not fit are skipped. Normal error retries use the existing retry policy.

from bytehaul import Downloader

task = Downloader(log_level="debug").download(
    "https://example.com/file.bin",
    "file.bin",
    slow_transfer_mode="adaptive_with_hedging",
)
task.wait()

Use slow_transfer_mode="disabled" to retain the previous scheduling behavior. Single-connection and non-Range fallback behavior is unchanged. Recovery excludes intentional rate limiting and local backpressure; it cannot remove a shared origin bandwidth limit.

When max_download_speed is nonzero, automatic slow-request recovery and hedging are suppressed to avoid treating intentional rate limiting as a network fault. Ordinary timeouts and error retries still apply.

Network options

Use these on Downloader(...) to set defaults, or pass proxy, http_proxy, and https_proxy directly to downloader.download(...) or the blocking download(...) helper.

Parameter Type Default
proxy str | None None
http_proxy str | None None
https_proxy str | None None
dns_servers list[str] | None None
doh_servers list[str] | None None
enable_ipv6 bool | None True

Running tests

uv sync --project bindings/python
cd bindings/python
uv run --project . maturin develop -m Cargo.toml
uv run --no-sync --project . pytest tests/ -v

After maturin develop, use --no-sync for tests so uv does not replace the freshly built development extension during another environment sync.

Building wheels for release

Single platform:

cd bindings/python
uv run --project . maturin build --release -m Cargo.toml

Cross-platform (via CI):

# Linux x86_64 + aarch64, macOS x86_64 + arm64, Windows x86_64
# Use maturin's GitHub Actions: https://github.com/PyO3/maturin-action

The project uses abi3-py39, so a single wheel per platform covers all Python 3.9+ versions.

License

MIT. See the repository LICENSE file.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bytehaul-0.2.2.tar.gz (242.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bytehaul-0.2.2-cp39-abi3-win_amd64.whl (3.0 MB view details)

Uploaded CPython 3.9+Windows x86-64

bytehaul-0.2.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

bytehaul-0.2.2-cp39-abi3-macosx_11_0_arm64.whl (3.1 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

bytehaul-0.2.2-cp39-abi3-macosx_10_12_x86_64.whl (3.2 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file bytehaul-0.2.2.tar.gz.

File metadata

  • Download URL: bytehaul-0.2.2.tar.gz
  • Upload date:
  • Size: 242.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bytehaul-0.2.2.tar.gz
Algorithm Hash digest
SHA256 80f603bf45bd00a1c2fd375a78369700c8bd43abac57012ccd5fd3997a36e26f
MD5 16d802e00c068cde9676dca9c9a0eb4f
BLAKE2b-256 92b53046711ea33ea2d273c37dac88241707f2154aed2e3bf7c39725b6d8b437

See more details on using hashes here.

Provenance

The following attestation bundles were made for bytehaul-0.2.2.tar.gz:

Publisher: publish-pypi.yml on triwinds/bytehaul

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bytehaul-0.2.2-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: bytehaul-0.2.2-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.0 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bytehaul-0.2.2-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5e0dcec261bfa30c66449e5ed066c1553e99536803fb12b2c154fe923fa54dab
MD5 b0134c7581c7e409bc90201878bbaab1
BLAKE2b-256 58d7c7a5ba95f44f25ecc10e1ace794a2b497910ed2feff21e7e90be7462ae06

See more details on using hashes here.

Provenance

The following attestation bundles were made for bytehaul-0.2.2-cp39-abi3-win_amd64.whl:

Publisher: publish-pypi.yml on triwinds/bytehaul

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bytehaul-0.2.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for bytehaul-0.2.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a65e726d24abb7efa0a768324f86a9f081a3caf1ccd7de7df549e9524b76165d
MD5 02fc22e18b72d7129567405d04eb1f2b
BLAKE2b-256 c187c9c43b7f7500ab6cd79fa95b6f7bfc0fe306d957f6801ba32a68684ff6e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for bytehaul-0.2.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on triwinds/bytehaul

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bytehaul-0.2.2-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bytehaul-0.2.2-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cd8f0e676078de851e9d6d4dc487d2cf8309cc54aaefa93536f48408e5f9bfbf
MD5 f53d6c42c7f065f975d74c265e85c06e
BLAKE2b-256 6ce5858acbf3750087f84432f6cae9582a936eafc240ca0dfac43edec5f7e8a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for bytehaul-0.2.2-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on triwinds/bytehaul

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bytehaul-0.2.2-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for bytehaul-0.2.2-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7a7f11f2485c8e3380d365a1af2baea2835dd26b3c59b495599d091c0e9868c2
MD5 8f24518378ef5175ea1ccf7f12932058
BLAKE2b-256 024c35bb165945458492cc6ac922a8813ec23e7541a66332a8a556c808b1b248

See more details on using hashes here.

Provenance

The following attestation bundles were made for bytehaul-0.2.2-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: publish-pypi.yml on triwinds/bytehaul

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.6

5 files

0.2.5

5 files

0.2.4

5 files

0.2.3

5 files

This release

0.2.2 This release

5 files

0.2.1

5 files

0.2.0

5 files

0.1.9

5 files

0.1.8

5 files

0.1.7

5 files

0.1.6

5 files

0.1.5

5 files

0.1.4

5 files

0.1.3

5 files

0.1.2

5 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page