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: pyhaul[httpx], pyhaul[niquests], pyhaul[urllib3]
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, and urllib3.

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.2.0.tar.gz (27.3 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.2.0-py3-none-any.whl (36.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyhaul-0.2.0.tar.gz
Algorithm Hash digest
SHA256 235efec34fbc7af2b2d86e9ab1a92e6db8ae4af12bbc8064d20c65a0d1632b36
MD5 a6a91f3907d0fedc16ad840e4da7837a
BLAKE2b-256 9e8d0111aa666bd98bc196bfe58dec2a7b92ee82ed00c1ed737252bd34272d38

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhaul-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyhaul-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.2 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4eb7d4219aa48707c4e87ba86f05dbd3c151e86cd52bae904bf7726d3ce0c4b6
MD5 9eb677114e74ff84f24aacaa919f4210
BLAKE2b-256 e8a6e6d1d8dbfd6119ed57f8ebd683847e96eb149ab0210d8e1890208a27aa4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyhaul-0.2.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