Skip to main content

sciharvest

Zero-key, reproducible harvesting of public scientific datasets with auditable provenance.

sciharvest turns a tiny JSON "descriptor" (which source, which query) into a portable, self-describing dataset: every harvest writes a normalized payload plus a provenance manifest that records the request, the fetch time, the tool version, the source license, and a SHA-256 of the stored data. Re-run verify and reproduce at any time to prove the data hasn't drifted.

It has zero runtime dependencies (Python standard library only), which makes it trivial to install, audit, and run in air-gapped or long-term research environments.

CI Python 3.9+ License: MIT


Why

Reproducible research starts at the data boundary. All too often a figure's data lives in a file with no record of where it came from, when it was pulled, or under what license it was reused. sciharvest encodes that boundary:

  • Re-run nobody's logs — a descriptor fully names the query.
  • Prove provenance — the manifest hash means verifiable, self-describing data.
  • Detect drift — upstream data changes are caught by reproduce, not discovered in review.

Features

  • No API keys needed for any built-in source (USGS, OpenAlex, PubMed, Crossref).
  • Zero runtime dependencies: pure urllib + unittest.
  • Deterministic payload hashing (SHA-256) for offline re-verification.
  • fetch / verify / reproduce lifecycle that treats data as code.
  • Polite-pool etiquette: identifies itself (User-Agent, NCBI tool/email, Crossref mailto) and rate-limits NCBI calls.
  • Recorded offline fixtures so the test suite never needs the network.

Install & Quickstart

$ git clone https://github.com/kyoai-zhao/sciharvest.git
$ cd sciharvest
$ python -m pip install -e .
$ sciharvest --version
sciharvest 0.1.0

Fetch an example dataset (USGS daily discharge, Potomac River):

$ sciharvest fetch examples/usgs-potomac-discharge.json --out ./data
potomac-daily-discharge-60d: 59 rows from usgs
payload_sha256: f3f615a02bb978ba28cef96d208e4658d33a5db1d35bcc73557aa4896cf54244
manifest:       ./data/manifests/potomac-daily-discharge-60d.json

Verify that stored data still matches its manifest:

$ sciharvest verify examples/usgs-potomac-discharge.json --out ./data
potomac-daily-discharge-60d: OK: stored data matches the manifest (59 rows)

Re-fetch and detect upstream drift:

$ sciharvest reproduce examples/usgs-potomac-discharge.json --out ./data

The dataset is now ./data:

data/
├── raw/
│   └── potomac-daily-discharge-60d.json     # normalized rows + columns
└── manifests/
    └── potomac-daily-discharge-60d.json     # provenance manifest (hash, request, license, time)

CLI reference

Command Purpose
sciharvest fetch <descriptor> [--out DIR] [--preview N] Harvest and store a dataset.
sciharvest verify <descriptor> [--out DIR] Hash stored data against its manifest (ok/missing/drifted; non-zero exit on drift).
sciharvest reproduce <descriptor> [--out DIR] Re-fetch and report drift vs. the previous run.
sciharvest list-sources List registered data sources.
sciharvest describe <source> Show one source's schema, license, and docs.

Dataset descriptors

A descriptor is the reproducible recipe — a small JSON object:

{
  "name": "potomac-daily-discharge-60d",
  "source": "usgs",
  "request": {
    "endpoint": "dv",
    "params": { "sites": "01646500", "parameterCd": "00060", "period": "P60D" }
  },
  "notes": "Daily-mean discharge at Potomac River near Washington, DC.",
  "license": "Public domain (U.S. Government work)"
}
Field Required Meaning
name yes Slug used as the file name (letters, digits, ., _, -).
source yes A registered source (see sciharvest list-sources).
request yes Source-specific query; validated up front.
notes no Free-text provenance annotation.
license no Overrides the source's default license in the manifest.

Provenance manifest

Every payload is paired with an auditable manifest:

{
  "schema": "sciharvest/manifest.v1",
  "name": "potomac-daily-discharge-60d",
  "source": "usgs",
  "request": { "endpoint": "dv", "params": { "period": "P60D", ... } },
  "fetched_at": "2026-08-13T20:10:00Z",
  "tool_version": "0.1.0",
  "license": "Public domain (U.S. Government work)",
  "source_homepage": "https://waterdata.usgs.gov/",
  "source_documentation": "https://waterservices.usgs.gov/rest/",
  "record_count": 59,
  "columns": ["site_no", "variable", "unit", "datetime", "value", "qualifier"],
  "unit": "ft3/s",
  "hash_algorithm": "sha256",
  "payload_sha256": "f3f615a0..."
}

unit is read from the source payload (never assumed) and echoed into every row — a defensive check against silent unit mismatches in later analysis.

Built-in sources

Source What it provides License Keys?
usgs USGS NWIS: instantaneous (iv), daily (dv), site metadata Public domain no
openalex Scholarly works search (title, year, citations, authors, DOI) CC0 1.0 no
pubmed PubMed article metadata via NCBI E-utilities NCBI policies no
crossref Authoritative metadata for one DOI Crossref REST no

Development

$ python -m unittest discover -s tests -t .       # offline fixture-based suite
$ python -m pip install -e .
$ sciharvest list-sources

The suite never touches the network; fixtures in tests/fixtures/ are pruned, real API responses. To add a source, see CONTRIBUTING.md.

Roadmap

  • High-water-mark de-duplication and dataset diff output
  • CSV/Parquet exporters with a stable column contract
  • Descriptor validation schema convention ($schema)
  • More keyless sources (e.g., US Census, Open-Meteo, UNdata)

License

MIT — see LICENSE. Upstream data retains its own license, which is recorded in every manifest.

Metadata

Release files for sciharvest 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sciharvest 0.1.0
File Size Uploaded
sciharvest-0.1.0.tar.gz 24.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sciharvest 0.1.0
File Interpreter ABI Platform
sciharvest-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.9 kB

Release files / sciharvest-0.1.0.tar.gz

Download URL sciharvest-0.1.0.tar.gz
Size 24.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1020f6bc0917d169294b0dd9b3a30e0139b4114918b95177ce6ad61b0db57ea9
BLAKE2b-256 checksum
How to use checksums
aa774ad3b0410811e05e6ababad20c1123598fc15016718200d4e61dc33b8ea1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.1

Release files / sciharvest-0.1.0-py3-none-any.whl

Download URL sciharvest-0.1.0-py3-none-any.whl
Size 24.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2954e1d76fee2dc6c401a8e15d56e6fa273cd5cd7315471763702c31c3e3622c
BLAKE2b-256 checksum
How to use checksums
4a3a0319f8e1e63c40648c703451f1435e9332e40e4ecbb96f89d3b1095f6e4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.1

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release 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