usdata 0.4.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {usdata-0.4.0 → usdata-0.5.0}/PKG-INFO +35 -12
  2. {usdata-0.4.0 → usdata-0.5.0}/README.md +34 -11
  3. {usdata-0.4.0 → usdata-0.5.0}/pyproject.toml +1 -1
  4. {usdata-0.4.0 → usdata-0.5.0}/pyproject.toml.orig +1 -1
  5. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/cli/app.py +13 -4
  6. usdata-0.5.0/src/usdata/data/places.csv +3292 -0
  7. usdata-0.5.0/src/usdata/data/places.sources.json +20 -0
  8. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/data/registry.yaml +22 -18
  9. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/manifest.py +1 -0
  10. usdata-0.5.0/src/usdata/protocols/erddap.py +115 -0
  11. usdata-0.5.0/src/usdata/protocols/http.py +96 -0
  12. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/protocols/s3.py +1 -1
  13. usdata-0.5.0/src/usdata/providers/noaa/coastwatch.py +148 -0
  14. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/noaa/ghcnd.py +12 -3
  15. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/noaa/nexrad.py +24 -4
  16. usdata-0.5.0/src/usdata/providers/usgs/__init__.py +1 -0
  17. usdata-0.5.0/src/usdata/providers/usgs/daily.py +145 -0
  18. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/pull.py +24 -8
  19. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/query.py +50 -16
  20. usdata-0.4.0/src/usdata/data/places.yaml +0 -10
  21. usdata-0.4.0/src/usdata/protocols/http.py +0 -38
  22. usdata-0.4.0/src/usdata/providers/noaa/coastwatch.py +0 -20
  23. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/__init__.py +0 -0
  24. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/_files.py +0 -0
  25. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/cache.py +0 -0
  26. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/cli/__init__.py +0 -0
  27. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/data/nexrad_sites.csv +0 -0
  28. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/fetch.py +0 -0
  29. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/models.py +0 -0
  30. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/protocols/__init__.py +0 -0
  31. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/provenance.py +0 -0
  32. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/__init__.py +0 -0
  33. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/base.py +0 -0
  34. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/noaa/__init__.py +0 -0
  35. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/providers/noaa/sites.py +0 -0
  36. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/py.typed +0 -0
  37. {usdata-0.4.0 → usdata-0.5.0}/src/usdata/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: usdata
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Unified Python SDK and CLI for discovering, fetching, and tracking provenance of U.S. public scientific data
5
5
  Keywords: noaa,usgs,nasa,open-data,scientific-data,provenance
6
6
  Author: Jake Van Slyke
@@ -24,24 +24,25 @@ Description-Content-Type: text/markdown
24
24
  Unified Python SDK and CLI for discovering, fetching, and tracking the
25
25
  provenance of U.S. public scientific data (NOAA, USGS, NASA, and more).
26
26
 
27
- > Status: pre-alpha. `noaa:ghcn-daily` and `noaa:nexrad-level2` fetch real
28
- > data with provenance; other registry entries are stubs.
27
+ > Status: pre-alpha. v0.5 supports GHCN-Daily, NEXRAD Level II, USGS daily
28
+ > values, and CoastWatch SST subsets with provenance, plus Census state/county
29
+ > lookup. Other datasets are planned.
29
30
  > See [docs/roadmap.md](docs/roadmap.md).
30
31
 
31
32
  ## Providers
32
33
 
33
34
  <!-- registry:start -->
34
- | Provider | Available | Stub | Planned | Next up (0.5) | Datasets |
35
+ | Provider | Available | Stub | Planned | Next up (0.6) | Datasets |
35
36
  |---|---:|---:|---:|---|---|
36
- | [NOAA](docs/providers/noaa.md) | 2 | 1 | 26 | `gsom`, `gsoy`, `storm-events`, `mrms`, `goes-abi`, `hurdat2`, `ibtracs`, `climate-normals`, `coops-water-levels`, `coastwatch-sst` | `ghcn-daily`, `nexrad-level2`, _coastwatch-sst_, +26 planned |
37
+ | [NOAA](docs/providers/noaa.md) | 3 | 0 | 26 | `gfs`, `hrrr`, `oisst`, `etopo` | `ghcn-daily`, `nexrad-level2`, `coastwatch-sst`, +26 planned |
38
+ | [USGS](docs/providers/usgs.md) | 1 | 0 | 2 | — | `water-daily`, +2 planned |
37
39
  | [Census Bureau](docs/providers/census.md) | 0 | 0 | 1 | — | +1 planned |
38
40
  | [EPA](docs/providers/epa.md) | 0 | 0 | 1 | — | +1 planned |
39
41
  | [FEMA](docs/providers/fema.md) | 0 | 0 | 1 | — | +1 planned |
40
- | [NASA](docs/providers/nasa.md) | 0 | 0 | 1 | — | +1 planned |
42
+ | [NASA](docs/providers/nasa.md) | 0 | 0 | 1 | `gpm-imerg` | +1 planned |
41
43
  | [USDA](docs/providers/usda.md) | 0 | 0 | 1 | — | +1 planned |
42
- | [USGS](docs/providers/usgs.md) | 0 | 0 | 3 | `water-daily` | +3 planned |
43
44
 
44
- Available datasets are in `code`, stubs in _italics_; planned ones are counted. Each provider page has access notes and full dataset details; [docs/roadmap.md](docs/roadmap.md) lists datasets by target version.
45
+ Available datasets are in `code`, stubs in _italics_; planned ones are counted. Available means implemented in this source checkout; consult the [releases](https://github.com/jakeryderv/usdata/releases) for published support. Each provider page has access notes and full dataset details; [docs/roadmap.md](docs/roadmap.md) lists datasets by target version.
45
46
  <!-- registry:end -->
46
47
 
47
48
  ## Install
@@ -74,6 +75,7 @@ for item in fetch(ds, query):
74
75
 
75
76
  ```sh
76
77
  usdata search "tornado radar" --state OK
78
+ usdata search precipitation --location "Cleveland County, OK"
77
79
  usdata info noaa:ghcn-daily
78
80
  usdata fetch noaa:ghcn-daily --lat 35.39 --lon -97.60 --radius-km 15 \
79
81
  --start 2024-05-06 --end 2024-05-07 --vars PRCP,TMAX
@@ -81,6 +83,10 @@ usdata fetch noaa:ghcn-daily -p stations=USW00013967 --start 2024-01-01 --end 20
81
83
  usdata fetch noaa:nexrad-level2 --lat 35.47 --lon -97.52 \
82
84
  --start 2024-05-06T20:00 --end 2024-05-06T23:00 # nearest radar (KTLX)
83
85
  usdata fetch noaa:nexrad-level2 -p site=KTLX --start 2024-05-06T20:00 --end 2024-05-06T20:30 --dry-run
86
+ usdata fetch usgs:water-daily -p sites=07164500 --vars 00060 \
87
+ --start 2024-05-06 --end 2024-05-07
88
+ usdata fetch noaa:coastwatch-sst --bbox=-80.08,30.02,-80.02,30.08 \
89
+ --start 2024-05-06T12:00Z --end 2024-05-06T12:00Z # four grid cells
84
90
  usdata pull dataset.yaml # resolve, fetch, write dataset.lock.json
85
91
  usdata verify dataset.yaml # exit 1 if any cached input drifted
86
92
  ```
@@ -89,6 +95,11 @@ Fetched files land in `~/.cache/usdata/<provider>/<dataset>/` (override with
89
95
  `USDATA_CACHE_DIR` or `--cache-dir`), each with a `.provenance.json` sidecar
90
96
  recording source URL, retrieval time, checksum, size, and license.
91
97
 
98
+ Locations accept state names/postal codes, county/state names, and quoted FIPS
99
+ codes. These select bounding rectangles; see [place lookup](docs/reference/places.md)
100
+ for coverage, ambiguity, and antimeridian limits. CoastWatch CSV includes a
101
+ second header row containing units; see its [access notes](docs/providers/noaa.md#coastwatch-sst).
102
+
92
103
  Manifest and source fields are validated strictly; unknown fields are errors.
93
104
  Provider-specific options belong under `params`.
94
105
 
@@ -96,8 +107,15 @@ A manifest declares every input a project needs. `pull` resolves each source,
96
107
  fetches it, and writes `dataset.lock.json` pinning every asset with its checksum
97
108
  and provenance. A second `pull` restores exactly what the lockfile pins without
98
109
  re-querying upstream, so the inputs stay reproducible even if the source
99
- changes. `verify` re-hashes the cached files against the lockfile. Editing the
100
- manifest after locking requires `pull --force` to re-resolve.
110
+ changes. `verify` checks the manifest checksum and re-hashes cached files
111
+ against the lockfile. Editing the manifest after locking requires `pull --force`
112
+ to re-resolve. A required source matching no assets fails the pull; set
113
+ `allow_empty: true` on a source only when an empty result is intentional.
114
+
115
+ Checksums detect upstream changes; they cannot recover historical bytes that
116
+ are no longer available. Preserve the cache for long-lived reproducibility.
117
+ See the [manifest reference](docs/reference/manifests.md) and the small
118
+ [NOAA/USGS example](examples/weather-and-streamflow/README.md).
101
119
 
102
120
  ```yaml
103
121
  name: tornado-environment
@@ -120,11 +138,16 @@ Requires [uv](https://docs.astral.sh/uv/) and [just](https://just.systems/).
120
138
  git clone https://github.com/jakeryderv/usdata && cd usdata
121
139
  just setup # install toolchain and dependencies
122
140
  just test # unit tests
123
- just check # format, lint, typecheck, tests (what CI runs)
141
+ just check # format, lint, typecheck, offline tests, generated docs
142
+ just build # build wheel and sdist
143
+ just smoke # install and exercise the built wheel outside the checkout
124
144
  just run search radar
125
145
  ```
126
146
 
127
- Integration tests that hit live services run with `just test-integration`.
147
+ Unit tests mechanically block network connections. Integration tests that hit
148
+ live services run with `just test-integration`. CI checks Python 3.11 and 3.14 on
149
+ Linux and smoke-tests the installed wheel on Linux, macOS, and Windows. The
150
+ full unit and live-service suites currently run on Linux.
128
151
 
129
152
  Releases: `just release minor` opens a version-bump PR; merging it publishes
130
153
  to PyPI and creates the tag and GitHub release. See
@@ -3,24 +3,25 @@
3
3
  Unified Python SDK and CLI for discovering, fetching, and tracking the
4
4
  provenance of U.S. public scientific data (NOAA, USGS, NASA, and more).
5
5
 
6
- > Status: pre-alpha. `noaa:ghcn-daily` and `noaa:nexrad-level2` fetch real
7
- > data with provenance; other registry entries are stubs.
6
+ > Status: pre-alpha. v0.5 supports GHCN-Daily, NEXRAD Level II, USGS daily
7
+ > values, and CoastWatch SST subsets with provenance, plus Census state/county
8
+ > lookup. Other datasets are planned.
8
9
  > See [docs/roadmap.md](docs/roadmap.md).
9
10
 
10
11
  ## Providers
11
12
 
12
13
  <!-- registry:start -->
13
- | Provider | Available | Stub | Planned | Next up (0.5) | Datasets |
14
+ | Provider | Available | Stub | Planned | Next up (0.6) | Datasets |
14
15
  |---|---:|---:|---:|---|---|
15
- | [NOAA](docs/providers/noaa.md) | 2 | 1 | 26 | `gsom`, `gsoy`, `storm-events`, `mrms`, `goes-abi`, `hurdat2`, `ibtracs`, `climate-normals`, `coops-water-levels`, `coastwatch-sst` | `ghcn-daily`, `nexrad-level2`, _coastwatch-sst_, +26 planned |
16
+ | [NOAA](docs/providers/noaa.md) | 3 | 0 | 26 | `gfs`, `hrrr`, `oisst`, `etopo` | `ghcn-daily`, `nexrad-level2`, `coastwatch-sst`, +26 planned |
17
+ | [USGS](docs/providers/usgs.md) | 1 | 0 | 2 | — | `water-daily`, +2 planned |
16
18
  | [Census Bureau](docs/providers/census.md) | 0 | 0 | 1 | — | +1 planned |
17
19
  | [EPA](docs/providers/epa.md) | 0 | 0 | 1 | — | +1 planned |
18
20
  | [FEMA](docs/providers/fema.md) | 0 | 0 | 1 | — | +1 planned |
19
- | [NASA](docs/providers/nasa.md) | 0 | 0 | 1 | — | +1 planned |
21
+ | [NASA](docs/providers/nasa.md) | 0 | 0 | 1 | `gpm-imerg` | +1 planned |
20
22
  | [USDA](docs/providers/usda.md) | 0 | 0 | 1 | — | +1 planned |
21
- | [USGS](docs/providers/usgs.md) | 0 | 0 | 3 | `water-daily` | +3 planned |
22
23
 
23
- Available datasets are in `code`, stubs in _italics_; planned ones are counted. Each provider page has access notes and full dataset details; [docs/roadmap.md](docs/roadmap.md) lists datasets by target version.
24
+ Available datasets are in `code`, stubs in _italics_; planned ones are counted. Available means implemented in this source checkout; consult the [releases](https://github.com/jakeryderv/usdata/releases) for published support. Each provider page has access notes and full dataset details; [docs/roadmap.md](docs/roadmap.md) lists datasets by target version.
24
25
  <!-- registry:end -->
25
26
 
26
27
  ## Install
@@ -53,6 +54,7 @@ for item in fetch(ds, query):
53
54
 
54
55
  ```sh
55
56
  usdata search "tornado radar" --state OK
57
+ usdata search precipitation --location "Cleveland County, OK"
56
58
  usdata info noaa:ghcn-daily
57
59
  usdata fetch noaa:ghcn-daily --lat 35.39 --lon -97.60 --radius-km 15 \
58
60
  --start 2024-05-06 --end 2024-05-07 --vars PRCP,TMAX
@@ -60,6 +62,10 @@ usdata fetch noaa:ghcn-daily -p stations=USW00013967 --start 2024-01-01 --end 20
60
62
  usdata fetch noaa:nexrad-level2 --lat 35.47 --lon -97.52 \
61
63
  --start 2024-05-06T20:00 --end 2024-05-06T23:00 # nearest radar (KTLX)
62
64
  usdata fetch noaa:nexrad-level2 -p site=KTLX --start 2024-05-06T20:00 --end 2024-05-06T20:30 --dry-run
65
+ usdata fetch usgs:water-daily -p sites=07164500 --vars 00060 \
66
+ --start 2024-05-06 --end 2024-05-07
67
+ usdata fetch noaa:coastwatch-sst --bbox=-80.08,30.02,-80.02,30.08 \
68
+ --start 2024-05-06T12:00Z --end 2024-05-06T12:00Z # four grid cells
63
69
  usdata pull dataset.yaml # resolve, fetch, write dataset.lock.json
64
70
  usdata verify dataset.yaml # exit 1 if any cached input drifted
65
71
  ```
@@ -68,6 +74,11 @@ Fetched files land in `~/.cache/usdata/<provider>/<dataset>/` (override with
68
74
  `USDATA_CACHE_DIR` or `--cache-dir`), each with a `.provenance.json` sidecar
69
75
  recording source URL, retrieval time, checksum, size, and license.
70
76
 
77
+ Locations accept state names/postal codes, county/state names, and quoted FIPS
78
+ codes. These select bounding rectangles; see [place lookup](docs/reference/places.md)
79
+ for coverage, ambiguity, and antimeridian limits. CoastWatch CSV includes a
80
+ second header row containing units; see its [access notes](docs/providers/noaa.md#coastwatch-sst).
81
+
71
82
  Manifest and source fields are validated strictly; unknown fields are errors.
72
83
  Provider-specific options belong under `params`.
73
84
 
@@ -75,8 +86,15 @@ A manifest declares every input a project needs. `pull` resolves each source,
75
86
  fetches it, and writes `dataset.lock.json` pinning every asset with its checksum
76
87
  and provenance. A second `pull` restores exactly what the lockfile pins without
77
88
  re-querying upstream, so the inputs stay reproducible even if the source
78
- changes. `verify` re-hashes the cached files against the lockfile. Editing the
79
- manifest after locking requires `pull --force` to re-resolve.
89
+ changes. `verify` checks the manifest checksum and re-hashes cached files
90
+ against the lockfile. Editing the manifest after locking requires `pull --force`
91
+ to re-resolve. A required source matching no assets fails the pull; set
92
+ `allow_empty: true` on a source only when an empty result is intentional.
93
+
94
+ Checksums detect upstream changes; they cannot recover historical bytes that
95
+ are no longer available. Preserve the cache for long-lived reproducibility.
96
+ See the [manifest reference](docs/reference/manifests.md) and the small
97
+ [NOAA/USGS example](examples/weather-and-streamflow/README.md).
80
98
 
81
99
  ```yaml
82
100
  name: tornado-environment
@@ -99,11 +117,16 @@ Requires [uv](https://docs.astral.sh/uv/) and [just](https://just.systems/).
99
117
  git clone https://github.com/jakeryderv/usdata && cd usdata
100
118
  just setup # install toolchain and dependencies
101
119
  just test # unit tests
102
- just check # format, lint, typecheck, tests (what CI runs)
120
+ just check # format, lint, typecheck, offline tests, generated docs
121
+ just build # build wheel and sdist
122
+ just smoke # install and exercise the built wheel outside the checkout
103
123
  just run search radar
104
124
  ```
105
125
 
106
- Integration tests that hit live services run with `just test-integration`.
126
+ Unit tests mechanically block network connections. Integration tests that hit
127
+ live services run with `just test-integration`. CI checks Python 3.11 and 3.14 on
128
+ Linux and smoke-tests the installed wheel on Linux, macOS, and Windows. The
129
+ full unit and live-service suites currently run on Linux.
107
130
 
108
131
  Releases: `just release minor` opens a version-bump PR; merging it publishes
109
132
  to PyPI and creates the tag and GitHub release. See
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "usdata"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  description = "Unified Python SDK and CLI for discovering, fetching, and tracking provenance of U.S. public scientific data"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "usdata"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  description = "Unified Python SDK and CLI for discovering, fetching, and tracking provenance of U.S. public scientific data"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -14,7 +14,7 @@ from usdata.fetch import fetch as fetch_query
14
14
  from usdata.manifest import lockfile_path
15
15
  from usdata.providers import load_adapter
16
16
  from usdata.providers.base import NotImplementedProvider
17
- from usdata.pull import ManifestChanged, UnknownDatasets
17
+ from usdata.pull import EmptySource, ManifestChanged, UnknownDatasets
18
18
  from usdata.pull import pull as pull_manifest
19
19
  from usdata.pull import verify as verify_manifest
20
20
  from usdata.query import UnknownPlace
@@ -50,7 +50,10 @@ def search(
50
50
  provider: Annotated[
51
51
  str | None, typer.Option(help="Restrict to one provider, e.g. noaa.")
52
52
  ] = None,
53
- state: Annotated[str | None, typer.Option(help="State name or postal code.")] = None,
53
+ state: Annotated[
54
+ str | None,
55
+ typer.Option("--location", "--state", help="State, 'County, ST', or quoted FIPS code."),
56
+ ] = None,
54
57
  start: Annotated[str | None, typer.Option(help="ISO date or datetime.")] = None,
55
58
  end: Annotated[str | None, typer.Option(help="ISO date or datetime.")] = None,
56
59
  planned: Annotated[
@@ -104,7 +107,10 @@ def info(
104
107
  @app.command()
105
108
  def fetch(
106
109
  dataset_id: Annotated[str, typer.Argument(help="Dataset id, e.g. noaa:ghcn-daily")],
107
- state: Annotated[str | None, typer.Option(help="State name or postal code.")] = None,
110
+ state: Annotated[
111
+ str | None,
112
+ typer.Option("--location", "--state", help="State, 'County, ST', or quoted FIPS code."),
113
+ ] = None,
108
114
  bbox: Annotated[str | None, typer.Option(help="west,south,east,north in degrees.")] = None,
109
115
  lat: Annotated[float | None, typer.Option()] = None,
110
116
  lon: Annotated[float | None, typer.Option()] = None,
@@ -190,6 +196,9 @@ def pull(
190
196
  """Fetch every source in a manifest and write (or restore from) its lockfile."""
191
197
  try:
192
198
  result = pull_manifest(manifest, root=cache_dir, force=force)
199
+ except EmptySource as e:
200
+ typer.secho(str(e), err=True, fg="yellow")
201
+ raise typer.Exit(code=1) from None
193
202
  except (DatasetNotFound, UnknownDatasets, ManifestChanged, UnknownPlace, ValueError) as e:
194
203
  typer.secho(str(e), err=True, fg="red")
195
204
  raise typer.Exit(code=2) from None
@@ -218,7 +227,7 @@ def verify(
218
227
  raise typer.Exit(code=2)
219
228
  try:
220
229
  drift = verify_manifest(manifest, root=cache_dir)
221
- except (ValueError, OSError) as e:
230
+ except (ManifestChanged, ValueError, OSError) as e:
222
231
  typer.secho(str(e), err=True, fg="red")
223
232
  raise typer.Exit(code=2) from None
224
233
  for d in drift: