Skip to content

Commit f217c14

Browse files
committed
enh: update with new column names
1 parent 1c0f07f commit f217c14

12 files changed

Lines changed: 177 additions & 362 deletions

File tree

Makefile

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ format:
2121
$(PY) ruff check --fix epidatpy tests
2222

2323
test:
24-
$(PY) pytest .
24+
$(PY) pytest -m "not live" .
2525

26-
# Live network tests gated on DELPHI_EPIDATA_KEY (skipped when unset).
26+
# Live network tests gated on DELPHI_EPIDATA_KEY (skipped per-test when unset).
2727
test_live:
28-
$(PY) pytest tests/test_epidata_calls.py tests/test_cast_endpoints.py
29-
30-
test_live_cast:
31-
$(PY) pytest tests/test_cast_endpoints.py
28+
$(PY) pytest -m live .
3229

3330
doc:
3431
@pandoc --version >/dev/null 2>&1 || (echo "ERROR: pandoc is required (install via your platform's package manager)"; exit 1)

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ epidata.pub_covidcast(
4040

4141
The CAST API exposes versioned signals (NSSP, pophive, NWSS, ...). Use
4242
`epidata_snapshot` for a single as-of view, `epidata_archive` for the full
43-
version history, or `epidata` to dispatch between them.
43+
report-time history, or `epidata` to dispatch between them.
4444

4545
```py
4646
from epidatpy import EpiDataContext, EpiRange
@@ -50,34 +50,34 @@ epidata = EpiDataContext()
5050
# Source-level metadata (signals, geo_types, available date ranges).
5151
epidata.epidata_meta(source="nssp")
5252

53-
# Latest snapshot of a signal (omit `as_of` to fetch the newest version).
53+
# Latest snapshot of a signal (omit `snapshot_date` to fetch the newest version).
5454
epidata.epidata_snapshot(
5555
source="nssp",
5656
signals="pct_ed_visits_influenza",
5757
geo_type="state",
5858
geo_values="ca,ny",
59-
time_values=EpiRange("2025-01-01", "2025-06-01"),
59+
reference_time=EpiRange("2025-01-01", "2025-06-01"),
6060
).df()
6161

62-
# Full version history, filtered to versions on or before 2025-10-16.
62+
# Full report-time history, filtered to report_times on or before 2025-10-16.
6363
epidata.epidata_archive(
6464
source="nssp",
6565
signals="pct_ed_visits_influenza",
6666
geo_type="state",
67-
version="<2025-10-16",
67+
report_time_query="<2025-10-16",
6868
).df()
6969

70-
# Router: pass `version` (or `as_of="*"`) for archive, `as_of` for snapshot.
70+
# Router: pass `report_time_query` (or `snapshot_date="*"`) for archive, `snapshot_date` for snapshot.
7171
epidata.epidata(
7272
source="nssp",
7373
signals="pct_ed_visits_influenza",
7474
geo_type="state",
75-
version=EpiRange("2025-01-01", "2025-10-16"),
75+
report_time_query=EpiRange("2025-01-01", "2025-10-16"),
7676
).df()
7777
```
7878

79-
`geo_values`, `time_values`, and an `EpiRange` `version` lower bound are
80-
filtered locally after the request.
79+
`geo_values`, `reference_time`, and an `EpiRange` `report_time_query` lower
80+
bound are filtered locally after the request.
8181

8282
## Development
8383

__marimo__/session/test.py.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": "1",
3+
"metadata": {
4+
"marimo_version": "0.23.6",
5+
"script_metadata_hash": null
6+
},
7+
"cells": [
8+
{
9+
"id": "Hbol",
10+
"code_hash": "4db6ef7392eeca00b16df83ee6033d0a",
11+
"outputs": [
12+
{
13+
"type": "data",
14+
"data": {
15+
"text/plain": ""
16+
}
17+
}
18+
],
19+
"console": []
20+
},
21+
{
22+
"id": "MJUe",
23+
"code_hash": "eff7d5dba32b4da32d9a67a519434d3f",
24+
"outputs": [
25+
{
26+
"type": "data",
27+
"data": {
28+
"text/html": "<marimo-ui-element object-id='MJUe-0' random-id='af1f0a84-1ce7-8ec4-6a81-0f7ab8e2d3ed'><marimo-table data-initial-value='[]' data-label='null' data-data='&quot;[{&#92;&quot;&#92;&quot;:79,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-17 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-02-03 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:1.659999966621399},{&#92;&quot;&#92;&quot;:103,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-24 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-04-20 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:1.9199999570846558},{&#92;&quot;&#92;&quot;:167,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-03 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-11-16 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:0.8100000023841858},{&#92;&quot;&#92;&quot;:173,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-10 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-11-23 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:1.340000033378601},{&#92;&quot;&#92;&quot;:185,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-10 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-14 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:2.259999990463257},{&#92;&quot;&#92;&quot;:188,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-02-07 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-21 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:2.8499999046325684},{&#92;&quot;&#92;&quot;:189,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-17 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-21 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:2.8399999141693115},{&#92;&quot;&#92;&quot;:190,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-01-03 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-21 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:2.819999933242798},{&#92;&quot;&#92;&quot;:192,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-02-21 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-28 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:4.179999828338623},{&#92;&quot;&#92;&quot;:193,&#92;&quot;signal&#92;&quot;:&#92;&quot;pct_ed_visits_influenza&#92;&quot;,&#92;&quot;report_time&#92;&quot;:&#92;&quot;2025-02-07 00:00:00&#92;&quot;,&#92;&quot;geo_type&#92;&quot;:&#92;&quot;state&#92;&quot;,&#92;&quot;geo_value&#92;&quot;:&#92;&quot;ak&#92;&quot;,&#92;&quot;fill_method&#92;&quot;:&#92;&quot;source&#92;&quot;,&#92;&quot;reference_time&#92;&quot;:&#92;&quot;2024-12-28 00:00:00&#92;&quot;,&#92;&quot;value&#92;&quot;:4.159999847412109}]&quot;' data-total-rows='7174' data-total-columns='7' data-max-columns='50' data-banner-text='&quot;&quot;' data-pagination='true' data-page-size='10' data-field-types='[[&quot;signal&quot;,[&quot;string&quot;,&quot;string&quot;]],[&quot;report_time&quot;,[&quot;datetime&quot;,&quot;datetime64[us]&quot;]],[&quot;geo_type&quot;,[&quot;string&quot;,&quot;string&quot;]],[&quot;geo_value&quot;,[&quot;string&quot;,&quot;string&quot;]],[&quot;fill_method&quot;,[&quot;string&quot;,&quot;string&quot;]],[&quot;reference_time&quot;,[&quot;datetime&quot;,&quot;datetime64[us]&quot;]],[&quot;value&quot;,[&quot;number&quot;,&quot;Float64&quot;]]]' data-show-filters='true' data-show-download='true' data-show-column-summaries='true' data-show-data-types='true' data-show-page-size-selector='true' data-show-column-explorer='true' data-show-chart-builder='true' data-row-headers='[[&quot;&quot;,[&quot;integer&quot;,&quot;int64&quot;]]]' data-has-stable-row-id='false' data-lazy='false' data-preload='false'></marimo-table></marimo-ui-element>"
29+
}
30+
}
31+
],
32+
"console": []
33+
},
34+
{
35+
"id": "AUnF",
36+
"code_hash": null,
37+
"outputs": [],
38+
"console": []
39+
}
40+
]
41+
}

epidatpy/_endpoints.py

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
ParamType,
2626
StringParam,
2727
)
28-
from ._parse import parse_api_date, parse_user_date_or_week, validate_version_query
28+
from ._parse import parse_api_date, parse_user_date_or_week, validate_report_time_query
2929

3030

3131
def get_wildcard_equivalent_dates(time_value: EpiRangeParam, time_type: Literal["day", "week"]) -> EpiRangeParam:
@@ -1532,24 +1532,24 @@ def epidata_snapshot(
15321532
signals: StringParam,
15331533
geo_type: str,
15341534
geo_values: StringParam = "*",
1535-
time_values: EpiRangeParam = "*",
1535+
reference_time: EpiRangeParam = "*",
15361536
fill_method: str | None = None,
1537-
as_of: str | date | None = None,
1537+
snapshot_date: str | date | None = None,
15381538
) -> CALL_TYPE:
1539-
"""Fetch a snapshot of CAST-API signals as they appeared at `as_of`.
1539+
"""Fetch a snapshot of CAST-API signals as they appeared on `snapshot_date`.
15401540
1541-
`as_of=None` returns the latest available version. `geo_values` and
1542-
`time_values` are filtered locally after the API call.
1541+
`snapshot_date=None` returns the latest available version. `geo_values`
1542+
and `reference_time` are filtered locally after the API call.
15431543
"""
1544-
if as_of is None:
1545-
snapshot_date: str | None = None
1546-
elif isinstance(as_of, date):
1547-
snapshot_date = as_of.strftime("%Y-%m-%d")
1544+
if snapshot_date is None:
1545+
snapshot_date_str: str | None = None
1546+
elif isinstance(snapshot_date, date):
1547+
snapshot_date_str = snapshot_date.strftime("%Y-%m-%d")
15481548
else:
1549-
parsed = parse_api_date(as_of)
1549+
parsed = parse_api_date(snapshot_date)
15501550
if parsed is None:
1551-
raise InvalidArgumentException(f"Invalid `as_of` value: {as_of!r}")
1552-
snapshot_date = parsed.strftime("%Y-%m-%d")
1551+
raise InvalidArgumentException(f"Invalid `snapshot_date` value: {snapshot_date!r}")
1552+
snapshot_date_str = parsed.strftime("%Y-%m-%d")
15531553
signal_str = signals if isinstance(signals, str) else ",".join(signals)
15541554

15551555
return self._create_call(
@@ -1559,11 +1559,11 @@ def epidata_snapshot(
15591559
"signal": signal_str,
15601560
"geo_type": geo_type,
15611561
"fill_method": fill_method,
1562-
"snapshot_date": snapshot_date,
1562+
"snapshot_date": snapshot_date_str,
15631563
},
15641564
_cast_signal_fields(),
15651565
api_version="cast",
1566-
post_filter=(geo_values, time_values, None),
1566+
post_filter=(geo_values, reference_time, None),
15671567
)
15681568

15691569
def epidata_archive(
@@ -1572,18 +1572,18 @@ def epidata_archive(
15721572
signals: StringParam,
15731573
geo_type: str,
15741574
geo_values: StringParam = "*",
1575-
time_values: EpiRangeParam = "*",
1575+
reference_time: EpiRangeParam = "*",
15761576
fill_method: str | None = None,
1577-
version: str | date | EpiRange | None = "*",
1577+
report_time_query: str | date | EpiRange | None = "*",
15781578
) -> CALL_TYPE:
1579-
"""Fetch the full version history of CAST-API signals.
1579+
"""Fetch the full report-time history of CAST-API signals.
15801580
1581-
`version` accepts an exact date, an operator-prefixed string
1581+
`report_time_query` accepts an exact date, an operator-prefixed string
15821582
(e.g. ``"<2025-10-16"``), or an :class:`EpiRange`. ``"*"`` (default)
1583-
requests all versions. `geo_values`, `time_values`, and the EpiRange
1584-
lower bound are filtered locally after the API call.
1583+
requests all report times. `geo_values`, `reference_time`, and the
1584+
EpiRange lower bound are filtered locally after the API call.
15851585
"""
1586-
version_query = validate_version_query(version)
1586+
report_time_query_str = validate_report_time_query(report_time_query)
15871587

15881588
signal_str = signals if isinstance(signals, str) else ",".join(signals)
15891589

@@ -1594,11 +1594,15 @@ def epidata_archive(
15941594
"signal": signal_str,
15951595
"geo_type": geo_type,
15961596
"fill_method": fill_method,
1597-
"version_query": version_query,
1597+
"report_time_query": report_time_query_str,
15981598
},
15991599
_cast_signal_fields(),
16001600
api_version="cast",
1601-
post_filter=(geo_values, time_values, version if isinstance(version, EpiRange) else None),
1601+
post_filter=(
1602+
geo_values,
1603+
reference_time,
1604+
report_time_query if isinstance(report_time_query, EpiRange) else None,
1605+
),
16021606
)
16031607

16041608
def epidata(
@@ -1607,50 +1611,51 @@ def epidata(
16071611
signals: StringParam,
16081612
geo_type: str,
16091613
geo_values: StringParam = "*",
1610-
time_values: EpiRangeParam = "*",
1614+
reference_time: EpiRangeParam = "*",
16111615
fill_method: str | None = None,
1612-
as_of: str | date | None = None,
1613-
version: str | date | EpiRange | None = None,
1616+
snapshot_date: str | date | None = None,
1617+
report_time_query: str | date | EpiRange | None = None,
16141618
) -> CALL_TYPE:
16151619
"""Router for CAST-API queries.
16161620
1617-
Dispatches to :meth:`epidata_archive` when ``version`` is supplied or
1618-
``as_of == "*"``; otherwise to :meth:`epidata_snapshot`. ``version`` and
1619-
``as_of`` are mutually exclusive.
1621+
Dispatches to :meth:`epidata_archive` when ``report_time_query`` is
1622+
supplied or ``snapshot_date == "*"``; otherwise to
1623+
:meth:`epidata_snapshot`. ``report_time_query`` and ``snapshot_date``
1624+
are mutually exclusive.
16201625
"""
1621-
if version is not None and as_of is not None:
1622-
raise InvalidArgumentException("`version` and `as_of` are mutually exclusive")
1626+
if report_time_query is not None and snapshot_date is not None:
1627+
raise InvalidArgumentException("`report_time_query` and `snapshot_date` are mutually exclusive")
16231628

1624-
if version is not None or as_of == "*":
1629+
if report_time_query is not None or snapshot_date == "*":
16251630
return self.epidata_archive(
16261631
source=source,
16271632
signals=signals,
16281633
geo_type=geo_type,
16291634
geo_values=geo_values,
1630-
time_values=time_values,
1635+
reference_time=reference_time,
16311636
fill_method=fill_method,
1632-
version=version if version is not None else "*",
1637+
report_time_query=report_time_query if report_time_query is not None else "*",
16331638
)
16341639
return self.epidata_snapshot(
16351640
source=source,
16361641
signals=signals,
16371642
geo_type=geo_type,
16381643
geo_values=geo_values,
1639-
time_values=time_values,
1644+
reference_time=reference_time,
16401645
fill_method=fill_method,
1641-
as_of=as_of,
1646+
snapshot_date=snapshot_date,
16421647
)
16431648

16441649

16451650
def _cast_signal_fields() -> Sequence[EpidataFieldInfo]:
16461651
"""Fields for CAST snapshot/archive responses; extras are skipped if absent."""
16471652
return [
16481653
EpidataFieldInfo("signal", EpidataFieldType.text),
1649-
EpidataFieldInfo("version", EpidataFieldType.date),
1654+
EpidataFieldInfo("report_time", EpidataFieldType.date),
16501655
EpidataFieldInfo("geo_type", EpidataFieldType.text),
16511656
EpidataFieldInfo("geo_value", EpidataFieldType.text),
16521657
EpidataFieldInfo("fill_method", EpidataFieldType.text),
1653-
EpidataFieldInfo("time_value", EpidataFieldType.date),
1658+
EpidataFieldInfo("reference_time", EpidataFieldType.date),
16541659
EpidataFieldInfo("value", EpidataFieldType.float),
16551660
# Source-specific extras (skipped per-response if not present):
16561661
EpidataFieldInfo("age_group", EpidataFieldType.text), # pophive

epidatpy/_model.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def add_endpoint_to_url(url: str, endpoint: str) -> str:
137137

138138
ApiVersion = Literal["classic", "cast"]
139139

140-
# (geo_values, time_values, version) — passed straight to cast_filter.
140+
# (geo_values, reference_time, report_time) — passed straight to cast_filter.
141141
CastPostFilter = tuple[
142142
Union[str, Sequence[str]],
143143
Union[str, "EpiRangeParam"],
@@ -268,13 +268,13 @@ def _parse_row(
268268
def cast_filter(
269269
df: DataFrame,
270270
geo_values: str | Sequence[str] = "*",
271-
time_values: str | EpiRangeParam = "*",
272-
version: str | EpiRange | None = None,
271+
reference_time: str | EpiRangeParam = "*",
272+
report_time: str | EpiRange | None = None,
273273
) -> DataFrame:
274274
"""Local post-filter for CAST-API responses.
275275
276276
The CAST endpoints return data that's only weakly filtered server-side.
277-
Apply geo, time, and EpiRange version-lower-bound filters locally.
277+
Apply geo, reference_time, and EpiRange report_time-lower-bound filters locally.
278278
"""
279279
from pandas import to_datetime
280280

@@ -288,11 +288,11 @@ def cast_filter(
288288
wanted = [str(g).strip().lower() for g in geo_values]
289289
df = df[df["geo_value"].str.lower().isin(wanted)]
290290

291-
if time_values != "*" and "time_value" in df.columns:
292-
df = _filter_by_timeset(df, "time_value", time_values, to_datetime)
291+
if reference_time != "*" and "reference_time" in df.columns:
292+
df = _filter_by_timeset(df, "reference_time", reference_time, to_datetime)
293293

294-
if isinstance(version, EpiRange) and "version" in df.columns:
295-
df = _filter_by_timeset(df, "version", version, to_datetime)
294+
if isinstance(report_time, EpiRange) and "report_time" in df.columns:
295+
df = _filter_by_timeset(df, "report_time", report_time, to_datetime)
296296

297297
return df
298298

0 commit comments

Comments
 (0)