usdata 0.20.0__tar.gz → 0.22.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 (79) hide show
  1. {usdata-0.20.0 → usdata-0.22.0}/PKG-INFO +2 -2
  2. {usdata-0.20.0 → usdata-0.22.0}/README.md +1 -1
  3. {usdata-0.20.0 → usdata-0.22.0}/pyproject.toml +1 -1
  4. {usdata-0.20.0 → usdata-0.22.0}/pyproject.toml.orig +1 -1
  5. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/__init__.py +11 -1
  6. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/data/registry.yaml +150 -23
  7. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/models.py +59 -0
  8. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/__init__.py +2 -0
  9. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/base.py +28 -1
  10. usdata-0.22.0/src/usdata/providers/fema/__init__.py +1 -0
  11. usdata-0.22.0/src/usdata/providers/fema/declarations.py +220 -0
  12. usdata-0.22.0/src/usdata/providers/noaa/nws_vtec.py +151 -0
  13. usdata-0.22.0/src/usdata/providers/noaa/spc.py +135 -0
  14. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/storm_events.py +50 -12
  15. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/params.py +19 -0
  16. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/query.py +30 -8
  17. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/readers.py +22 -8
  18. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/testing.py +38 -3
  19. usdata-0.20.0/src/usdata/providers/noaa/spc.py +0 -99
  20. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/__main__.py +0 -0
  21. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_fetch.py +0 -0
  22. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_files.py +0 -0
  23. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_grib.py +0 -0
  24. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_hurdat2.py +0 -0
  25. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_netcdf.py +0 -0
  26. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_progress.py +0 -0
  27. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/_radar.py +0 -0
  28. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cache.py +0 -0
  29. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cache_ops.py +0 -0
  30. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cite.py +0 -0
  31. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/__init__.py +0 -0
  32. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/app.py +0 -0
  33. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/cache.py +0 -0
  34. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/cite.py +0 -0
  35. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/doctor.py +0 -0
  36. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/inspect.py +0 -0
  37. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/cli/progress.py +0 -0
  38. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/data/nexrad_sites.csv +0 -0
  39. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/data/places.csv +0 -0
  40. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/data/places.sources.json +0 -0
  41. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/doctor.py +0 -0
  42. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/inspect.py +0 -0
  43. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/manifest.py +0 -0
  44. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/mirror.py +0 -0
  45. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/protocols/__init__.py +0 -0
  46. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/protocols/erddap.py +0 -0
  47. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/protocols/http.py +0 -0
  48. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/protocols/listing.py +0 -0
  49. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/protocols/s3.py +0 -0
  50. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/provenance.py +0 -0
  51. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/http.py +0 -0
  52. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/__init__.py +0 -0
  53. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/coastwatch.py +0 -0
  54. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/coops.py +0 -0
  55. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/gfs.py +0 -0
  56. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/ghcnd.py +0 -0
  57. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/glm.py +0 -0
  58. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/goes.py +0 -0
  59. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/grib_index.py +0 -0
  60. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/gsom.py +0 -0
  61. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/gsoy.py +0 -0
  62. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/hrrr.py +0 -0
  63. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/hurdat2.py +0 -0
  64. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/ibtracs.py +0 -0
  65. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/lcd.py +0 -0
  66. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/mrms.py +0 -0
  67. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/nbm.py +0 -0
  68. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/nexrad.py +0 -0
  69. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/nexrad_level3.py +0 -0
  70. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/normals.py +0 -0
  71. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/rap.py +0 -0
  72. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/noaa/sites.py +0 -0
  73. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/usgs/__init__.py +0 -0
  74. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/usgs/daily.py +0 -0
  75. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/providers/usgs/earthquakes.py +0 -0
  76. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/pull.py +0 -0
  77. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/py.typed +0 -0
  78. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/registry.py +0 -0
  79. {usdata-0.20.0 → usdata-0.22.0}/src/usdata/selection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: usdata
3
- Version: 0.20.0
3
+ Version: 0.22.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,open-data,scientific-data,provenance,reproducible-research,weather,climate,meteorology
6
6
  Author: Jake Van Slyke
@@ -93,7 +93,7 @@ breaking changes.
93
93
  | [docs.usdata.dev](https://docs.usdata.dev/) | How to use it: [install](https://docs.usdata.dev/install/), [getting started](https://docs.usdata.dev/getting-started/), guides, dataset notes, and reference |
94
94
  | [Severe-weather case study](https://usdata.dev/examples/severe-weather-case-study/) | One tornado, six sources, one manifest and lockfile, ending in a citation |
95
95
 
96
- Twenty-three datasets are available today and twenty-one more are planned, grouped
96
+ Twenty-five datasets are available today and twenty more are planned, grouped
97
97
  by agency and product family in the [catalog](docs/providers/README.md).
98
98
 
99
99
  ## How this compares
@@ -48,7 +48,7 @@ breaking changes.
48
48
  | [docs.usdata.dev](https://docs.usdata.dev/) | How to use it: [install](https://docs.usdata.dev/install/), [getting started](https://docs.usdata.dev/getting-started/), guides, dataset notes, and reference |
49
49
  | [Severe-weather case study](https://usdata.dev/examples/severe-weather-case-study/) | One tornado, six sources, one manifest and lockfile, ending in a citation |
50
50
 
51
- Twenty-three datasets are available today and twenty-one more are planned, grouped
51
+ Twenty-five datasets are available today and twenty more are planned, grouped
52
52
  by agency and product family in the [catalog](docs/providers/README.md).
53
53
 
54
54
  ## How this compares
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "usdata"
3
- version = "0.20.0"
3
+ version = "0.22.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.20.0"
3
+ version = "0.22.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"
@@ -13,7 +13,16 @@ except PackageNotFoundError: # running from a source tree without an install
13
13
  from usdata._fetch import ChecksumMismatch, FetchedAsset, fetch, fetch_asset
14
14
  from usdata.cite import Citation, cite_dataset, cite_lockfile
15
15
  from usdata.inspect import inspect_asset, inspect_path
16
- from usdata.models import Asset, BBox, Dataset, Provenance, Query, TemporalSelection, TimeRange
16
+ from usdata.models import (
17
+ Asset,
18
+ BBox,
19
+ Dataset,
20
+ Place,
21
+ Provenance,
22
+ Query,
23
+ TemporalSelection,
24
+ TimeRange,
25
+ )
17
26
  from usdata.pull import pull, verify
18
27
  from usdata.query import build_query
19
28
  from usdata.registry import DatasetNotFound, Registry, SearchResult, default_registry
@@ -27,6 +36,7 @@ __all__ = [
27
36
  "Dataset",
28
37
  "DatasetNotFound",
29
38
  "FetchedAsset",
39
+ "Place",
30
40
  "Provenance",
31
41
  "Query",
32
42
  "Registry",
@@ -308,19 +308,21 @@ datasets:
308
308
  NCEI's significant-weather event details since 1950, with locations, impacts, and
309
309
  narratives. Anonymous whole-year gzipped CSV archives; select the latest creation-date
310
310
  revision for each requested year. No server-side row, location, or variable subsetting.
311
- Historical event coverage and reporting practices vary; fatalities and locations tables
312
- are separate products not included by this adapter. The catalog lists the identifying
313
- columns; the full column set is documented in the NCEI bulk format reference.
311
+ Historical event coverage and reporting practices vary. The default is the details
312
+ table; the fatalities table (one row per death) and the locations table (points per
313
+ event, with rows from 1996) are chosen with the table parameter and join to details on
314
+ EVENT_ID. The catalog lists the identifying columns; the full column set is documented
315
+ in the NCEI bulk format reference.
314
316
  keywords: [storms, tornado, hail, wind, flood, damage, severe weather, events]
315
317
  protocol: http
316
318
  homepage: https://www.ncei.noaa.gov/access/storm-events-database/
317
319
  license: US Government Work (public domain)
318
320
  temporal_extent: { start: "1950-01-01T00:00:00Z" }
319
321
  capabilities: { spatial_subset: false, temporal_subset: true, variable_subset: false }
320
- summary: Storm Events details
322
+ summary: Storm Events details, fatalities, and locations
321
323
  formats: [gzip CSV]
322
- selection: Whole annual archives; filter rows locally after downloading
323
- inputs: Both dates (selects the containing years)
324
+ selection: Whole annual archives of one table; filter rows locally after downloading
325
+ inputs: Both dates (selects the containing years); optionally table
324
326
  reader: pandas
325
327
  guide: docs/providers/noaa-storm-events.md
326
328
  examples:
@@ -358,18 +360,20 @@ datasets:
358
360
  or F rating, injuries, fatalities, loss, start and end coordinates, path
359
361
  length and width, and FIPS codes. Whole files linked from the SPC page:
360
362
  annual from 2008, half-decade for 2000-2007, decade for 1950-1999.
361
- Stable names revised in place; no server-side row, location, or
362
- variable subsetting.
363
- keywords: [tornado, spc, severe weather, storm reports, tracks, ef scale, fujita]
363
+ The table parameter selects SPC's hail and wind databases instead, which
364
+ share the layout and start in 1955; mag is then the stone diameter in
365
+ inches or the wind speed in knots. Stable names revised in place; no
366
+ server-side row, location, or variable subsetting.
367
+ keywords: [tornado, hail, wind, spc, severe weather, storm reports, tracks, ef scale, fujita]
364
368
  protocol: http
365
369
  homepage: https://www.spc.noaa.gov/wcm/#data
366
370
  license: US Government Work (public domain)
367
371
  temporal_extent: { start: "1950-01-01T00:00:00Z" }
368
372
  capabilities: { spatial_subset: false, temporal_subset: true, variable_subset: false }
369
- summary: SPC tornado database
373
+ summary: SPC tornado, hail, and wind databases
370
374
  formats: [CSV]
371
- selection: Whole annual, half-decade, or decade files; filter rows locally after downloading
372
- inputs: Both dates (selects the files covering those years)
375
+ selection: Whole annual, half-decade, or decade files of one table; filter rows locally after downloading
376
+ inputs: Both dates (selects the files covering those years); optionally table
373
377
  reader: pandas
374
378
  guide: docs/providers/noaa-spc-tornado.md
375
379
  examples:
@@ -393,7 +397,7 @@ datasets:
393
397
  - { name: "tz", description: "Time-zone code: 3 is Central Standard Time, 9 is GMT, ? is unknown" }
394
398
  - { name: "st", description: "Two-letter state" }
395
399
  - { name: "stf", description: "State FIPS code" }
396
- - { name: "mag", description: "F scale through January 2007 and EF scale afterwards; -9 is unknown" }
400
+ - { name: "mag", description: "Tornado: F scale through January 2007 and EF scale afterwards, -9 unknown. Hail: size in inches. Wind: speed in knots" }
397
401
  - { name: "inj", units: "count", description: "Injuries" }
398
402
  - { name: "fat", units: "count", description: "Fatalities" }
399
403
  - { name: "loss", description: "Property loss: a 0 to 9 category before 1996, millions of dollars from 1996" }
@@ -405,6 +409,7 @@ datasets:
405
409
  - { name: "len", units: "miles", description: "Path length" }
406
410
  - { name: "wid", units: "yards", description: "Path width" }
407
411
  - { name: "sg", description: "Segment code: 1 a whole track, 2 a state segment, -9 extra county codes" }
412
+ - { name: "mt", description: "Wind only, from 2006: EG estimated gust, MG measured gust, MS measured sustained, ES estimated sustained" }
408
413
  adapter: usdata.providers.noaa.spc:SpcTornadoReports
409
414
 
410
415
  - id: noaa:hurdat2
@@ -1438,13 +1443,14 @@ datasets:
1438
1443
  title: American Community Survey 5-Year Estimates
1439
1444
  description: >-
1440
1445
  Population, housing, income, and demographic estimates for every
1441
- geography down to block group, via the Census Data API. Anonymous for
1442
- light use; an API key lifts rate limits.
1446
+ geography down to block group, via the Census Data API, selected by state
1447
+ and county FIPS code rather than by box. Requires a free API key on every
1448
+ data request; only the dataset and variable metadata are served without one.
1443
1449
  keywords: [population, demographics, housing, income, acs, census]
1444
1450
  protocol: http
1445
1451
  homepage: https://www.census.gov/data/developers/data-sets/acs-5year.html
1446
1452
  license: US Government Work (public domain)
1447
- capabilities: { spatial_subset: true, temporal_subset: true, variable_subset: true }
1453
+ capabilities: { spatial_subset: false, place_subset: true, temporal_subset: true, variable_subset: true }
1448
1454
 
1449
1455
  # ---------------------------------------------------------------- USDA
1450
1456
  - id: usda:cropland-data-layer
@@ -1540,6 +1546,68 @@ datasets:
1540
1546
  temporal_subset: false
1541
1547
  variable_subset: false
1542
1548
 
1549
+ - id: noaa:nws-vtec-events
1550
+ provider: noaa
1551
+ status: available
1552
+ domain: severe-weather
1553
+ since: "0.22"
1554
+ title: NWS Watch, Warning, and Advisory Events by County
1555
+ description: >-
1556
+ National Weather Service watch, warning, and advisory events issued for one county
1557
+ or forecast zone, one row per event with its issuance and expiry, VTEC phenomena and
1558
+ significance, issuing office, and product id, as CSV from the Iowa Environmental
1559
+ Mesonet's archive of NWS products; the NWS API itself keeps no archive. Rows carry no
1560
+ coordinates, so selection is by a named county rather than by box, and a window
1561
+ selects events by when they were issued, not by when they were in effect. A county
1562
+ reaches county-based products (tornado, severe thunderstorm, flash flood); zone-based
1563
+ products need an explicit UGC. Polygons are a separate product, noaa:nws-warnings.
1564
+ keywords: [warnings, watches, advisories, vtec, nws, tornado warning, lead time, county, ugc]
1565
+ protocol: http
1566
+ homepage: https://mesonet.agron.iastate.edu/info/datasets/vtec.html
1567
+ license: Public domain (NWS products; IEM materials are public domain, attribution appreciated)
1568
+ temporal_extent: { start: "1986-01-01T00:00:00Z" }
1569
+ capabilities:
1570
+ spatial_subset: false
1571
+ place_subset: true
1572
+ temporal_subset: true
1573
+ variable_subset: false
1574
+ summary: NWS warnings and watches by county
1575
+ formats: [CSV]
1576
+ selection: Events issued for one county or UGC inside an inclusive UTC window; optionally one event type
1577
+ inputs: Both timestamps; a county location or a ugc; optionally phenomena with significance
1578
+ reader: pandas
1579
+ guide: docs/providers/noaa-nws-vtec-events.md
1580
+ examples:
1581
+ - examples/warning-lead-time/README.md
1582
+ resolution:
1583
+ spatial: "One county, parish, or forecast zone per request, by NWS UGC code"
1584
+ temporal: "Issuance and expiry to the minute"
1585
+ update_frequency: >-
1586
+ Not stated by IEM, which processes the live NWS product stream; events before 2005
1587
+ come from an NWS database dump rather than from VTEC
1588
+ citation: >-
1589
+ National Weather Service watch, warning, and advisory products, as archived and served
1590
+ by the Iowa Environmental Mesonet of Iowa State University, accessed via usdata
1591
+ terms: https://mesonet.agron.iastate.edu/disclaimer.php
1592
+ variables:
1593
+ - { name: vtec_year, description: "Year the event's VTEC event id belongs to" }
1594
+ - { name: iso_issued, units: "ISO 8601 UTC", description: "When the event was issued for this UGC" }
1595
+ - { name: issued, units: "UTC", description: "The same instant as YYYY-MM-DD HH:MM" }
1596
+ - { name: iso_expired, units: "ISO 8601 UTC", description: "When the event expired or was cancelled for this UGC" }
1597
+ - { name: expired, units: "UTC", description: "The same instant as YYYY-MM-DD HH:MM" }
1598
+ - { name: eventid, description: "VTEC event number, unique per office, phenomena, significance, and year; IEM-assigned before VTEC" }
1599
+ - { name: phenomena, description: "Two-letter VTEC phenomena code, such as TO or SV" }
1600
+ - { name: significance, description: "One-letter VTEC significance code, such as W warning, A watch, Y advisory" }
1601
+ - { name: hvtec_nwsli, description: "NWS location identifier of a hydrologic event's forecast point; empty otherwise" }
1602
+ - { name: wfo, description: "Issuing forecast office; the present-day office for events before 2005" }
1603
+ - { name: ugc, description: "The UGC code the row is for" }
1604
+ - { name: product_id, description: "IEM identifier of the issuing text product" }
1605
+ - { name: name, description: "Phenomena and significance in words, such as Tornado Warning" }
1606
+ - { name: ph_name, description: "Phenomena in words" }
1607
+ - { name: sig_name, description: "Significance in words" }
1608
+ - { name: url, description: "Path of the event's page on the IEM site" }
1609
+ adapter: usdata.providers.noaa.nws_vtec:NwsVtecEvents
1610
+
1543
1611
  - id: noaa:nws-warnings
1544
1612
  provider: noaa
1545
1613
  status: planned
@@ -1598,21 +1666,26 @@ datasets:
1598
1666
 
1599
1667
  - id: fema:disaster-declarations
1600
1668
  provider: fema
1601
- status: planned
1669
+ status: available
1602
1670
  domain: natural-hazards
1603
- target: later
1671
+ since: "0.21"
1604
1672
  title: FEMA Disaster Declarations Summaries
1605
1673
  description: >-
1606
- Every federal disaster declaration since 1953, one row per declaration and
1607
- designated area, with incident type, dates, programs declared, and county
1608
- FIPS codes, from the OpenFEMA v2 JSON API (70,402 rows on 2026-09-14; OData
1609
- filters and paging).
1674
+ Every federally declared disaster since 1953, major disaster, emergency, and fire
1675
+ management declarations alike, one row per declaration and designated area, with the
1676
+ incident type and period, the programs declared, and state and county FIPS codes, from
1677
+ the OpenFEMA v2 API as CSV. Rows carry no coordinates, so selection is by named state or
1678
+ county rather than by box, and a window selects declarations whose incident period
1679
+ overlaps it. The dataset is rebuilt every twenty minutes and rows are revised as
1680
+ incidents close.
1610
1681
  keywords:
1611
1682
  - fema
1612
1683
  - disasters
1613
1684
  - declarations
1614
1685
  - tornado
1615
1686
  - impacts
1687
+ - counties
1688
+ - openfema
1616
1689
  protocol: http
1617
1690
  homepage: https://www.fema.gov/openfema-data-page/disaster-declarations-summaries-v2
1618
1691
  license: US Government Work (public domain)
@@ -1620,5 +1693,59 @@ datasets:
1620
1693
  start: "1953-01-01T00:00:00Z"
1621
1694
  capabilities:
1622
1695
  spatial_subset: false
1696
+ place_subset: true
1623
1697
  temporal_subset: true
1624
- variable_subset: true
1698
+ variable_subset: false
1699
+ summary: Federal disaster declarations by county
1700
+ formats: [CSV]
1701
+ selection: >-
1702
+ Declarations whose incident period overlaps an inclusive UTC window, for a named state or
1703
+ county; a county also returns its state's statewide designations
1704
+ inputs: Both dates; optionally a state or county location, or state or fips, and type filters
1705
+ reader: pandas
1706
+ guide: docs/providers/fema-disaster-declarations.md
1707
+ examples:
1708
+ - examples/disaster-declarations/README.md
1709
+ resolution:
1710
+ spatial: "One row per designated area: a county or county equivalent, a tribal area, or a whole state"
1711
+ temporal: "Calendar dates for the declaration and for the start and end of the incident"
1712
+ update_frequency: Every twenty minutes (R/PT20M); a record's lastRefresh moves only when it changes
1713
+ citation: >-
1714
+ Federal Emergency Management Agency (FEMA), OpenFEMA Dataset: Disaster Declarations
1715
+ Summaries - v2. Retrieved from
1716
+ https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries on [date, time]. This
1717
+ product uses the Federal Emergency Management Agency's OpenFEMA API, but is not endorsed
1718
+ by FEMA. The Federal Government or FEMA cannot vouch for the data or analyses derived from
1719
+ these data after the data have been retrieved from the Agency's website(s).
1720
+ terms: https://www.fema.gov/about/openfema/terms-conditions
1721
+ variables:
1722
+ - { name: femaDeclarationString, description: "Declaration type, disaster number, and state code joined, such as DR-4393-NC" }
1723
+ - { name: disasterNumber, description: "Sequentially assigned number designating the declared event" }
1724
+ - { name: state, description: "Two-letter code of the state, district, or territory" }
1725
+ - { name: declarationType, description: "DR major disaster, EM emergency, or FM fire management" }
1726
+ - { name: declarationDate, units: "ISO 8601 UTC", description: "Date the disaster was declared" }
1727
+ - { name: fyDeclared, description: "Fiscal year in which the disaster was declared" }
1728
+ - { name: incidentType, description: "Primary type of incident, such as Fire or Flood" }
1729
+ - { name: declarationTitle, description: "Title for the disaster" }
1730
+ - { name: ihProgramDeclared, description: "Whether the Individuals and Households program was declared" }
1731
+ - { name: iaProgramDeclared, description: "Whether the Individual Assistance program was declared" }
1732
+ - { name: paProgramDeclared, description: "Whether the Public Assistance program was declared" }
1733
+ - { name: hmProgramDeclared, description: "Whether the Hazard Mitigation program was declared" }
1734
+ - { name: incidentBeginDate, units: "ISO 8601 UTC", description: "Date the incident itself began" }
1735
+ - { name: incidentEndDate, units: "ISO 8601 UTC", description: "Date the incident itself ended; empty while open" }
1736
+ - { name: disasterCloseoutDate, units: "ISO 8601 UTC", description: "Date all financial transactions for all programs are completed" }
1737
+ - { name: tribalRequest, description: "Whether a Tribal Nation submitted the request directly to the President" }
1738
+ - { name: fipsStateCode, description: "Two-digit FIPS code of the state, district, or territory" }
1739
+ - { name: fipsCountyCode, description: "Three-digit FIPS code of the county; 000 for a statewide or tribal designation" }
1740
+ - { name: placeCode, description: "FEMA's own location code, 99 plus the county code, covering areas with no FIPS county code" }
1741
+ - { name: designatedArea, description: "Name of the geographic area included in the declaration" }
1742
+ - { name: declarationRequestNumber, description: "Number assigned to the declaration request" }
1743
+ - { name: declarationRequestDate, units: "ISO 8601 UTC", description: "Date the declaration request was made" }
1744
+ - { name: lastIAFilingDate, units: "ISO 8601 UTC", description: "Last date Individual Assistance requests can be filed; after 1998 only" }
1745
+ - { name: incidentId, description: "Identifier of the incident, which may or may not become a declared disaster" }
1746
+ - { name: region, description: "FEMA region, 1 to 10, where the disaster occurred" }
1747
+ - { name: designatedIncidentTypes, description: "Comma-separated codes of every incident type designated for the disaster" }
1748
+ - { name: lastRefresh, units: "ISO 8601 UTC", description: "When the record was last updated in the API data store" }
1749
+ - { name: hash, description: "MD5 hash of the record's fields and values" }
1750
+ - { name: id, description: "Unique id assigned to the record" }
1751
+ adapter: usdata.providers.fema.declarations:DisasterDeclarations
@@ -149,6 +149,9 @@ class Capabilities(BaseModel):
149
149
 
150
150
  ``spatial_subset`` and ``variable_subset`` mean the request narrows the
151
151
  bytes served, so a bbox or a variable list changes the files.
152
+ ``place_subset`` means a named state or county selects what is served, which
153
+ is a separate question: a source keyed by FIPS code honours a place and
154
+ must refuse a bare rectangle, which names no place (ADR 0034).
152
155
  ``temporal_subset`` means the time window chooses which assets are fetched,
153
156
  whether the source crops files to it or serves whole files that cover it.
154
157
  ``partial_fetch`` means selected byte ranges of an object can be fetched on
@@ -157,6 +160,7 @@ class Capabilities(BaseModel):
157
160
  """
158
161
 
159
162
  spatial_subset: bool = False
163
+ place_subset: bool = False
160
164
  temporal_subset: bool = False
161
165
  variable_subset: bool = False
162
166
  partial_fetch: bool = False
@@ -381,18 +385,73 @@ class Dataset(BaseModel):
381
385
  return self.id.split(":", 1)[1]
382
386
 
383
387
 
388
+ class Place(BaseModel):
389
+ """The state or county a ``location`` named, as the bundled Census table identifies it.
390
+
391
+ A rectangle cannot be turned back into the place it was drawn around, so a
392
+ query keeps this beside its ``bbox`` for the sources that are keyed by FIPS
393
+ code rather than by coordinates. See ADR 0034.
394
+ """
395
+
396
+ model_config = ConfigDict(frozen=True)
397
+
398
+ kind: Literal["state", "county"]
399
+ geoid: str = Field(
400
+ pattern=r"^\d{2}(\d{3})?$",
401
+ description="Census GEOID: the two-digit state FIPS code, or the five-digit county one",
402
+ )
403
+ label: str = Field(description="The place as the table names it, such as 'Osage County, OK'")
404
+ state: str = Field(
405
+ pattern=r"^[A-Z]{2}$",
406
+ description=(
407
+ "Two-letter postal code of the state, or of the state a county lies in, such as OK; "
408
+ "some sources key places by it rather than by the state FIPS code"
409
+ ),
410
+ )
411
+
412
+ @model_validator(mode="after")
413
+ def _kind_matches_geoid(self) -> Place:
414
+ if (self.kind == "state") is not (len(self.geoid) == 2):
415
+ raise ValueError(f"a {self.kind} geoid cannot be {self.geoid!r}")
416
+ return self
417
+
418
+ @property
419
+ def state_fips(self) -> str:
420
+ """The two-digit FIPS code of the state, or of the state a county lies in."""
421
+ return self.geoid[:2]
422
+
423
+ @property
424
+ def county_fips(self) -> str | None:
425
+ """The three-digit county FIPS code within its state, or None for a state."""
426
+ return self.geoid[2:] or None
427
+
428
+
384
429
  class Query(BaseModel):
385
430
  """Normalized, provider-agnostic request. Providers translate this into their own terms."""
386
431
 
387
432
  text: str | None = None
388
433
  provider: str | None = None
389
434
  bbox: BBox | None = None
435
+ place: Place | None = Field(
436
+ default=None,
437
+ description=(
438
+ "The state or county the spatial filter named, set only when it was given as a "
439
+ "location; bbox still holds that place's rectangle"
440
+ ),
441
+ )
390
442
  time: TimeRange | None = None
391
443
  variables: list[str] = Field(default_factory=list)
392
444
  params: dict[str, Any] = Field(
393
445
  default_factory=dict, description="Provider-specific passthrough parameters"
394
446
  )
395
447
 
448
+ @model_validator(mode="after")
449
+ def _place_has_its_box(self) -> Query:
450
+ # Most adapters read only bbox, so a place without one would select nothing for them.
451
+ if self.place is not None and self.bbox is None:
452
+ raise ValueError("a query naming a place must carry that place's bbox")
453
+ return self
454
+
396
455
 
397
456
  class Asset(BaseModel):
398
457
  """A single retrievable object (file, granule, or subset request) from a dataset."""
@@ -16,6 +16,7 @@ from usdata.providers.params import (
16
16
  StrList,
17
17
  UpperStrList,
18
18
  choice,
19
+ flag,
19
20
  int_list,
20
21
  int_range,
21
22
  positive_int,
@@ -30,6 +31,7 @@ __all__ = [
30
31
  "StrList",
31
32
  "UpperStrList",
32
33
  "choice",
34
+ "flag",
33
35
  "int_list",
34
36
  "int_range",
35
37
  "load_adapter",
@@ -13,7 +13,7 @@ from typing import Any, ClassVar, Literal, Self, TypeVar
13
13
  from pydantic import BaseModel, ValidationError
14
14
  from pydantic_core import ErrorDetails
15
15
 
16
- from usdata.models import Asset, Dataset, PartialFetch, Provenance, Query
16
+ from usdata.models import Asset, Dataset, PartialFetch, Place, Provenance, Query
17
17
 
18
18
  QueryField = Literal["text", "bbox", "variables", "time"]
19
19
  Params = TypeVar("Params", bound=BaseModel)
@@ -25,6 +25,10 @@ _LABELS: dict[QueryField, str] = {
25
25
  }
26
26
 
27
27
 
28
+ BARE_BOX = "bbox or lat/lon"
29
+ """How ``Provider.place_of`` names the spatial filter a place-keyed source refuses."""
30
+
31
+
28
32
  class NotImplementedProvider(NotImplementedError):
29
33
  """Raised by adapters that are registered but not yet built."""
30
34
 
@@ -179,6 +183,29 @@ class Provider(ABC):
179
183
  message = f"{self.dataset.id} does not support {', '.join(present)}"
180
184
  raise QueryError(f"{message}; {hint}" if hint else message)
181
185
 
186
+ def place_of(self, query: Query, hint: str = "") -> Place | None:
187
+ """The state or county a query names, for a source keyed by place rather than by box.
188
+
189
+ Such a source cannot honour a rectangle: its rows carry FIPS codes and no
190
+ coordinates, and a box cannot be turned back into the places it covers.
191
+ A query whose spatial filter was a ``bbox`` or a ``lat``/``lon`` is
192
+ therefore refused, in the same words for every such source.
193
+
194
+ Args:
195
+ query: The query being listed.
196
+ hint: What to do instead, usually naming the adapter's own place parameters.
197
+
198
+ Returns:
199
+ The place, or None when the query sets no spatial filter at all.
200
+
201
+ Raises:
202
+ QueryError: The query carries a box that names no place.
203
+ """
204
+ if query.place is None and query.bbox is not None:
205
+ message = f"{self.dataset.id} does not support {BARE_BOX}; name a state or county"
206
+ raise QueryError(f"{message} with location, or {hint}" if hint else message)
207
+ return query.place
208
+
182
209
  def utc_window(self, query: Query) -> tuple[datetime, datetime]:
183
210
  """Both time bounds, required, in UTC. Naive bounds are read as UTC."""
184
211
  if query.time is None or query.time.start is None or query.time.end is None:
@@ -0,0 +1 @@
1
+ """FEMA dataset adapters."""