Skip to main content

Resumable, cursor-based, CDN-safe HTTP downloads for Python

Project description

pyhaul

CI codecov PyPI License: MIT

Resumable HTTP downloads for Python.

pip install pyhaul[requests]   # or: httpx, niquests, urllib3, aiohttp (see below)
import requests
from pyhaul import haul

with requests.Session() as session:
    result = haul("https://example.com/big.zip", session, dest="big.zip")
    print(f"done: sha256={result.sha256[:16]}…")

What is it?

A small, pure-Python library that makes HTTP downloads resumable. Call haul() with your existing HTTP client, a URL, and a destination path — it handles byte-range negotiation, ETag validation, crash-safe checkpointing, and atomic file completion. Sync and async; works with requests, httpx, niquests, urllib3, and aiohttp (async).

Each call to haul() upholds these guarantees:

  • The destination file is either complete or absent. There is no state where a partially-written file sits at the final path. Incomplete data lives in a temporary .part file; on completion it is atomically moved into place.
  • Interrupted downloads resume, not restart. Checkpoint state lives on disk, not in memory. Kill the process, lose the network, get a 503 — the next haul() picks up from the last durable byte. Zero re-downloaded data if the resource hasn't changed.
  • Changed resources are detected, not silently corrupted. If the remote file changes between attempts, pyhaul detects the mismatch via ETag (a server-side fingerprint) and starts over cleanly instead of gluing mismatched halves together.
  • Your HTTP client is borrowed, not owned. pyhaul sets per-request headers and returns the session untouched. It never creates, configures, or closes sessions.
  • Transport errors pass through unwrapped. httpx.ReadTimeout stays httpx.ReadTimeout. You catch the types you already know.

How it fits into your code

One haul() = one HTTP request. It either succeeds and returns CompleteHaul, or it throws — possibly after saving progress to a .part file that allows the next call to resume. pyhaul never creates sessions, connections, or clients. Your HTTP library's native exceptions propagate through unwrapped, so you can drop haul() into existing code without changing your error handling. Retries are your call — a for-loop, tenacity, or nothing. Concurrency limiting (e.g. asyncio.Semaphore) is also yours — pyhaul downloads one file per call and doesn't manage parallelism.

def haul(url, client, *, dest, state=None) -> CompleteHaul: ...
async def haul_async(url, client, *, dest, state=None) -> CompleteHaul: ...

state is an optional HaulState bag, updated in-place as bytes land on disk — works identically in sync and async. See DESIGN.md for the exception hierarchy, transport adapters, and download lifecycle.

Project details


Download files

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

Source Distribution

pyhaul-0.3.0.tar.gz (35.5 kB view details)

Uploaded Source

Built Distribution

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

pyhaul-0.3.0-py3-none-any.whl (45.7 kB view details)

Uploaded Python 3

File details

Details for the file pyhaul-0.3.0.tar.gz.

File metadata

  • Download URL: pyhaul-0.3.0.tar.gz
  • Upload date:
  • Size: 35.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pyhaul-0.3.0.tar.gz
Algorithm Hash digest
SHA256 833586ddaedeabefa0fb27c58295555819e68aa0ed680302257c3986c40064ef
MD5 b05a98dbf6ff445692d5dfc10100a6dc
BLAKE2b-256 11a1e0936c385bda58e11e4bcffd2654da8e2acbe6ee507f8deeb1fa52708c19

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhaul-0.3.0.tar.gz:

Publisher: release.yml on chad-loder/pyhaul

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

File details

Details for the file pyhaul-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: pyhaul-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 45.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pyhaul-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f93f13145923109ee299f5a4dae54cf91867a5d309ae442295ef870c8a80cc2
MD5 96c05ca3a572e5a08765081e1db8c0a8
BLAKE2b-256 317e9211c7eba4d9f62be6ab4f345877e289a49df16617310bd3e7db9b233c48

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhaul-0.3.0-py3-none-any.whl:

Publisher: release.yml on chad-loder/pyhaul

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page