Skip to content

fix: download dataset atomically so an interrupted download can't block retries#8

Open
steps-re wants to merge 1 commit into
qoherent:mainfrom
steps-re:fix/atomic-dataset-download
Open

fix: download dataset atomically so an interrupted download can't block retries#8
steps-re wants to merge 1 commit into
qoherent:mainfrom
steps-re:fix/atomic-dataset-download

Conversation

@steps-re

@steps-re steps-re commented Jul 7, 2026

Copy link
Copy Markdown

Summary

An interrupted dataset download leaves a corrupt file that permanently blocks all future download attempts.

Details

download_dataset.py streams the ~6 GB dataset straight into the final path. If the download is interrupted (network stall, HTTP error, Ctrl+C), a corrupt partial file is left there. On the next run the os.path.exists() guard sees it, prints "already exists", and exit(1)s with no integrity check — the user is stuck with a corrupt file they must manually find and delete. Contributing factors: timeout=3 aborts on any brief stall during a multi-GB download, and there was no raise_for_status(), so an HTTP error body would be written into the .hdf5 file.

Fix

Download to a temporary .part file, verify the SHA-256 checksum, then os.replace() atomically into place; remove partials on any failure. A pre-existing target is now checksum-validated (skip if valid, re-download if corrupt). Timeout raised to 30s; added raise_for_status().

Verification

  • Byte-compiles clean; passes the repo's flake8 config with zero warnings.
  • Local HTTP-server harness with identical control flow, 6 scenarios all pass: happy-path + checksum, valid-existing skip, mid-download interrupt (no corrupt target, no .part), retry-after-interrupt, corrupt-existing re-download, HTTP 404 raises and leaves nothing behind.

(Verified against a local server rather than the real 6 GB URL; the control flow is identical.)

…ck retries

The dataset downloader wrote directly to spectrum_sensing_dataset.hdf5. If the
download failed partway (network stall, HTTP error, or Ctrl+C), a corrupt
partial file was left at the target path. On the next run the "already exists"
guard saw it and exited without any integrity check, permanently trapping the
user with a corrupt file they had to manually locate and delete.

- Download to a temporary ".part" file and os.replace() into place only after
  the SHA-256 checksum verifies.
- Remove the partial file on any error or interruption (KeyboardInterrupt).
- Validate the checksum of a pre-existing target instead of blindly aborting;
  exit(0) when it is already valid, re-download when it is corrupt.
- Add r.raise_for_status() so an HTTP error body is never written as the dataset.
- Raise the streaming timeout from 3s to 30s (3s aborts on any brief stall
  during the ~6 GB download).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Mike German <mike@stepsventures.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant