Skip to content

Commit f431baf

Browse files
authored
Merge pull request #1508 from cmu-delphi/release/delphi-epidata-4.1.25
Release Delphi Epidata 4.1.25
2 parents aa3dedb + 704e898 commit f431baf

39 files changed

+210
-340
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 4.1.24
2+
current_version = 4.1.25
33
commit = False
44
tag = False
55

.git-blame-ignore-revs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ b9ceb400d9248c8271e8342275664ac5524e335d
2020
07ed83e5768f717ab0f9a62a9209e4e2cffa058d
2121
# style(black): format wiki acquisition
2222
923852eafa86b8f8b182d499489249ba8f815843
23+
# lint: trailing whitespace changes
24+
81179c5f144b8f25421e799e823e18cde43c84f9

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
closes|addresses <!--list issues closed or partially-addressed by this PR -->
1+
addresses issue(s) #ISSUE <!--list issue(s) associated with this PR -->
22

33
### Summary:
44

.github/workflows/update_gdocs_data.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ jobs:
2121
restore-keys: |
2222
${{ runner.os }}-pipd-
2323
- name: Install Dependencies
24-
run: pip install -r requirements.dev.txt
24+
run: |
25+
pip -V
26+
python -m pip install pip==22.0.2
27+
pip install -r requirements.dev.txt
2528
- name: Update Docs
2629
run: inv update-gdoc
2730
- name: Create pull request into dev

dev/local/setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = Delphi Development
3-
version = 4.1.24
3+
version = 4.1.25
44

55
[options]
66
packages =

docs/api/covidcast-signals/covid-act-now.md

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ grand_parent: COVIDcast Main Endpoint
1515
* **Time type:** day (see [date format docs](../covidcast_times.md))
1616
* **License:** [CC BY-NC](../covidcast_licensing.md#creative-commons-attribution-noncommercial)
1717

18-
The COVID Act Now (CAN) data source provides COVID-19 testing statistics, such as positivity rates and total tests performed.
19-
The county-level positivity rates and test totals are pulled directly from CAN.
20-
While CAN provides this data potentially from multiple sources, we only use data sourced from the
18+
The [COVID Act Now (CAN)](https://covidactnow.org/) data source provides COVID-19 testing statistics, such as positivity rates and total tests performed.
19+
The county-level positivity rates and test totals are pulled directly from CAN using [their API](https://covidactnow.org/data-api).
20+
While CAN provides this data potentially from multiple sources, we only use data that CAN sources from the
2121
[CDC's COVID-19 Integrated County View](https://covid.cdc.gov/covid-data-tracker/#county-view).
2222

23+
Delphi's mirror of the CAN data was deactivated in December 2021 (last issue 2021-12-10) in favor of the [DSEW CPR data](./dsew-cpr.md), which reports the same information under the `covid_naat_pct_positive_7dav` signal.
24+
2325

2426
| Signal | Description |
2527
|--------------------------------|----------------------------------------------------------------|
@@ -34,9 +36,9 @@ While CAN provides this data potentially from multiple sources, we only use data
3436

3537
## Estimation
3638

37-
The quantities received from CAN / CDC are the county-level positivity rate and total tests,
38-
which are based on the counts of PCR specimens tested.
39-
In particular, they are also already smoothed with a 7-day-average.
39+
We receive county-level positivity rate and total tests from CAN, originating from the CDC.
40+
These quantiles are based on the counts of PCR specimens tested.
41+
They are also already smoothed with a 7-day-average.
4042

4143
For a fixed location $$i$$ and time $$t$$, let $$Y_{it}$$ denote the number of PCR specimens
4244
tested that have a positive result. Let $$N_{it}$$ denote the total number of PCR specimens tested.
@@ -79,38 +81,41 @@ $$
7981

8082
### Smoothing
8183

82-
No additional smoothing is done to avoid double-smoothing, since the data pulled from CAN / CDC
84+
No additional smoothing is done to avoid double-smoothing, since the CAN data
8385
is already smoothed with a 7-day-average.
8486

8587
## Limitations
8688

87-
Estimates for geographical levels beyond counties may be inaccurate due to how aggregations
88-
are done on smoothed values instead of the raw values. Ideally we would aggregate raw values
89+
Estimates for geographical levels beyond counties may be inaccurate because our aggregations
90+
are performed on smoothed values instead of the raw values.
91+
Ideally we would aggregate raw values
8992
then smooth, but the raw values are not accessible in this case.
9093

91-
The positivity rate here should not be interpreted as the population positivity rate as
94+
The reported test positivity rate should not be interpreted as the population positivity rate as
9295
the testing performed are typically not randomly sampled, especially for early data
9396
with lower testing volumes.
9497

9598
A few counties, most notably in California, are also not covered by this data source.
9699

97-
Entries with zero total tests performed are also suppressed, even if it was actually the case that
100+
Entries with zero total tests performed are suppressed, even if it was actually the case that
98101
no tests were performed for the day.
99102

100103
## Lag and Backfill
101104

102105
The lag for these signals varies depending on the reporting patterns of individual counties.
103106
Most counties have their latest data report with a lag of 2 days, while others can take 9 days
104-
or more in the case of California counties.
107+
or more, as is the case with California counties.
105108

106-
These signals are also backfilled as backlogged test results could get assigned to older 7-day timeframes.
107-
Most recent test positivity rates do not change substantially with backfill (having a median delta of close to 0).
108-
However, most recent total tests performed is expected to increase in later data revisions (having a median increase of 7%).
109+
Revisions are sometimes made to the data. For example, backlogged test results can get assigned to past dates.
110+
The majority of recent test positivity rates do not change substantially with backfill (having a median delta of close to 0).
111+
However, the majority of recent total tests performed is expected to increase in later data revisions (having a median increase of 7%).
109112
Values more than 5 days in the past are expected to remain fairly static (with total tests performed
110113
having a median increase of 1% of less), as most major revisions have already occurred.
111114

112115
## Source and Licensing
113116

114-
County-level testing data is scraped by CAN from the
117+
County-level testing data is scraped by [CAN](https://covidactnow.org/) from the
115118
[CDC's COVID-19 Integrated County View](https://covid.cdc.gov/covid-data-tracker/#county-view),
116119
and made available through [CAN's API](https://covidactnow.org/tools).
120+
121+
The data is made available under a [CC BY-NC](../covidcast_licensing.md#creative-commons-attribution-noncommercial) license.

docs/api/covidcast-signals/hhs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Department of Health & Human Services
3-
parent: Data Sources and Signals
3+
parent: Inactive Signals
44
grand_parent: COVIDcast Main Endpoint
55
---
66

docs/epidata_development.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ $ [sudo] make test pdb=1
4949
$ [sudo] make test test=repos/delphi/delphi-epidata/integrations/acquisition
5050
```
5151

52-
You can read the commands executed by the Makefile [here](../dev/local/Makefile).
52+
You can read the commands executed by the Makefile [here](https://github.com/cmu-delphi/delphi-epidata/blob/dev/dev/local/Makefile).
5353

5454
## Rapid Iteration and Bind Mounts
5555

@@ -87,8 +87,8 @@ You can test your changes manually by:
8787

8888
What follows is a worked demonstration based on the `fluview` endpoint. Before
8989
starting, make sure that you have the `delphi_database_epidata`,
90-
`delphi_web_epidata`, and `delphi_redis` containers running; if you don't, see
91-
the Makefile instructions above.
90+
`delphi_web_epidata`, and `delphi_redis` containers running (with `docker ps`);
91+
if you don't, see the Makefile instructions above.
9292

9393
First, let's insert some fake data into the `fluview` table:
9494

docs/symptom-survey/publications.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Pandemic"](https://www.pnas.org/topic/548) in *PNAS*:
2626

2727
Research publications using the survey data include:
2828

29+
- C.K. Ettman, E. Badillo-Goicoechea, E.A. Stuart (2024). [Financial
30+
strain, schooling modality and mental health of US adults living
31+
with children during the COVID-19 pandemic](https://doi.org/10.1136/jech-2023-221672).
32+
*Journal of Epidemiology & Community Health*.
2933
- K. Sasse, R. Mahabir, O. Gkountouna, A. Crooks, A. Croitoru (2024).
3034
[Understanding the determinants of vaccine hesitancy in the United
3135
States: A comparison of social surveys and social media](https://doi.org/10.1371/journal.pone.0301488).
@@ -41,7 +45,7 @@ Research publications using the survey data include:
4145
- Z. Yang, R. Krishnan, and B. Li (2024). [The interplay between individual
4246
mobility, health risk, and economic choice: A holistic model for COVID-19
4347
policy intervention](https://doi.org/10.1287/ijds.2023.0013). *INFORMS
44-
Journal on Data Science*.
48+
Journal on Data Science* 3 (1), 6-27.
4549
- A. Srivastava, J. M. Ramirez, S. Díaz-Aranda, J. Aguilar, A. F. Anta, A. Ortega,
4650
and R. E. Lillo (2024). [Nowcasting temporal trends using indirect surveys](https://doi.org/10.1609/aaai.v38i20.30242).
4751
In *Proceedings of the 38th AAAI Conference on Artificial Intelligence* 38,

integrations/client/test_delphi_epidata.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
# standard library
44
import time
5+
import json
56
from json import JSONDecodeError
6-
from requests.models import Response
77
from unittest.mock import MagicMock, patch
88

99
# first party
@@ -306,6 +306,26 @@ def test_sandbox(self, get, post):
306306
Epidata.debug = False
307307
Epidata.sandbox = False
308308

309+
@patch('requests.get')
310+
def test_version_check(self, get):
311+
"""Test that the _version_check() function correctly logs a version discrepancy."""
312+
class MockJson:
313+
def __init__(self, content, status_code):
314+
self.content = content
315+
self.status_code = status_code
316+
def raise_for_status(self): pass
317+
def json(self): return json.loads(self.content)
318+
get.reset_mock()
319+
get.return_value = MockJson(b'{"info": {"version": "0.0.1"}}', 200)
320+
321+
Epidata._version_check()
322+
323+
captured = self.capsys.readouterr()
324+
output = captured.err.splitlines()
325+
self.assertEqual(len(output), 1)
326+
self.assertIn("Client version not up to date", output[0])
327+
self.assertIn("\'latest_version\': \'0.0.1\'", output[0])
328+
309329
def test_geo_value(self):
310330
"""test different variants of geo types: single, *, multi."""
311331

src/acquisition/covid_hosp/common/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
# first party
1313
import delphi.operations.secrets as secrets
14-
from delphi.epidata.common.logger import get_structured_logger
14+
from delphi_utils import get_structured_logger
1515

1616
Columndef = namedtuple("Columndef", "csv_name sql_name dtype")
1717

src/acquisition/covidcast/csv_importer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313
import pandas as pd
1414

1515
# first party
16-
from delphi_utils import Nans
16+
from delphi_utils import get_structured_logger, Nans
1717
from delphi.utils.epiweek import delta_epiweeks
1818
from delphi.epidata.common.covidcast_row import CovidcastRow
19-
from delphi.epidata.common.logger import get_structured_logger
2019

2120
DataFrameRow = NamedTuple('DFRow', [
2221
('geo_id', str),

src/acquisition/covidcast/csv_to_database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from delphi.epidata.acquisition.covidcast.csv_importer import CsvImporter, PathDetails
1212
from delphi.epidata.acquisition.covidcast.database import Database, DBLoadStateException
1313
from delphi.epidata.acquisition.covidcast.file_archiver import FileArchiver
14-
from delphi.epidata.common.logger import get_structured_logger
14+
from delphi_utils import get_structured_logger
1515

1616

1717
def get_argument_parser():

src/acquisition/covidcast/database.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
# first party
1616
import delphi.operations.secrets as secrets
17-
from delphi.epidata.common.logger import get_structured_logger
17+
from delphi_utils import get_structured_logger
1818
from delphi.epidata.common.covidcast_row import CovidcastRow
1919

2020

@@ -117,28 +117,28 @@ def insert_or_update_batch(self, cc_rows: List[CovidcastRow], batch_size=2**20,
117117
get_structured_logger("insert_or_update_batch").fatal(err_msg)
118118
raise DBLoadStateException(err_msg)
119119

120-
# NOTE: `value_update_timestamp` is hardcoded to "NOW" (which is appropriate) and
120+
# NOTE: `value_update_timestamp` is hardcoded to "NOW" (which is appropriate) and
121121
# `is_latest_issue` is hardcoded to 1 (which is temporary and addressed later in this method)
122122
insert_into_loader_sql = f'''
123123
INSERT INTO `{self.load_table}`
124124
(`source`, `signal`, `time_type`, `geo_type`, `time_value`, `geo_value`,
125-
`value_updated_timestamp`, `value`, `stderr`, `sample_size`, `issue`, `lag`,
125+
`value_updated_timestamp`, `value`, `stderr`, `sample_size`, `issue`, `lag`,
126126
`is_latest_issue`, `missing_value`, `missing_stderr`, `missing_sample_size`)
127127
VALUES
128-
(%s, %s, %s, %s, %s, %s,
129-
UNIX_TIMESTAMP(NOW()), %s, %s, %s, %s, %s,
128+
(%s, %s, %s, %s, %s, %s,
129+
UNIX_TIMESTAMP(NOW()), %s, %s, %s, %s, %s,
130130
1, %s, %s, %s)
131131
'''
132132

133133
# all load table entries are already marked "is_latest_issue".
134134
# if an entry in the load table is NOT in the latest table, it is clearly now the latest value for that key (so we do nothing (thanks to INNER join)).
135135
# if an entry *IS* in both load and latest tables, but latest table issue is newer, unmark is_latest_issue in load.
136136
fix_is_latest_issue_sql = f'''
137-
UPDATE
138-
`{self.load_table}` JOIN `{self.latest_view}`
139-
USING (`source`, `signal`, `geo_type`, `geo_value`, `time_type`, `time_value`)
140-
SET `{self.load_table}`.`is_latest_issue`=0
141-
WHERE `{self.load_table}`.`issue` < `{self.latest_view}`.`issue`
137+
UPDATE
138+
`{self.load_table}` JOIN `{self.latest_view}`
139+
USING (`source`, `signal`, `geo_type`, `geo_value`, `time_type`, `time_value`)
140+
SET `{self.load_table}`.`is_latest_issue`=0
141+
WHERE `{self.load_table}`.`issue` < `{self.latest_view}`.`issue`
142142
'''
143143

144144
# TODO: consider handling cc_rows as a generator instead of a list

src/acquisition/covidcast/file_archiver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import shutil
77

88
# first party
9-
from delphi.epidata.common.logger import get_structured_logger
9+
from delphi_utils import get_structured_logger
1010

1111
class FileArchiver:
1212
"""Archives files by moving and compressing."""

src/client/delphi_epidata.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Epidata <- (function() {
1515
# API base url
1616
BASE_URL <- getOption('epidata.url', default = 'https://api.delphi.cmu.edu/epidata/')
1717

18-
client_version <- '4.1.24'
18+
client_version <- '4.1.25'
1919

2020
auth <- getOption("epidata.auth", default = NA)
2121

src/client/delphi_epidata.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
}
2323
})(this, function (exports, fetchImpl, jQuery) {
2424
const BASE_URL = "https://api.delphi.cmu.edu/epidata/";
25-
const client_version = "4.1.24";
25+
const client_version = "4.1.25";
2626

2727
// Helper function to cast values and/or ranges to strings
2828
function _listitem(value) {

src/client/delphi_epidata.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from aiohttp import ClientSession, TCPConnector, BasicAuth
2020

21-
__version__ = "4.1.24"
21+
__version__ = "4.1.25"
2222

2323
_HEADERS = {"user-agent": "delphi_epidata/" + __version__ + " (Python)"}
2424

@@ -43,8 +43,6 @@ class Epidata:
4343
BASE_URL = "https://api.delphi.cmu.edu/epidata"
4444
auth = None
4545

46-
client_version = __version__
47-
4846
debug = False # if True, prints extra logging statements
4947
sandbox = False # if True, will not execute any queries
5048

@@ -54,6 +52,25 @@ def log(evt, **kwargs):
5452
kwargs['timestamp'] = time.strftime("%Y-%m-%d %H:%M:%S %z")
5553
return sys.stderr.write(str(kwargs) + "\n")
5654

55+
# Check that this client's version matches the most recent available. This
56+
# is intended to run just once per program execution, on initial module load.
57+
# See the bottom of this file for the ultimate call to this method.
58+
@staticmethod
59+
def _version_check():
60+
try:
61+
request = requests.get('https://pypi.org/pypi/delphi-epidata/json', timeout=5)
62+
latest_version = request.json()['info']['version']
63+
except Exception as e:
64+
Epidata.log("Error getting latest client version", exception=str(e))
65+
return
66+
67+
if latest_version != __version__:
68+
Epidata.log(
69+
"Client version not up to date",
70+
client_version=__version__,
71+
latest_version=latest_version
72+
)
73+
5774
# Helper function to cast values and/or ranges to strings
5875
@staticmethod
5976
def _listitem(value):
@@ -692,3 +709,10 @@ async def async_make_calls(param_combos):
692709
future = asyncio.ensure_future(async_make_calls(param_list))
693710
responses = loop.run_until_complete(future)
694711
return responses
712+
713+
714+
715+
# This should only run once per program execution, on initial module load,
716+
# as a result of how Python's module system works:
717+
# https://docs.python.org/3/reference/import.html#the-module-cache
718+
Epidata._version_check()

src/client/packaging/npm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "delphi_epidata",
33
"description": "Delphi Epidata API Client",
44
"authors": "Delphi Group",
5-
"version": "4.1.24",
5+
"version": "4.1.25",
66
"license": "MIT",
77
"homepage": "https://github.com/cmu-delphi/delphi-epidata",
88
"bugs": {

src/client/packaging/pypi/.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 4.1.24
2+
current_version = 4.1.25
33
commit = False
44
tag = False
55

src/client/packaging/pypi/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
All notable future changes to the `delphi_epidata` python client will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/).
55

6+
## [4.1.25] - 2024-07-29
7+
8+
### Includes
9+
- https://github.com/cmu-delphi/delphi-epidata/pull/1456
10+
- https://github.com/cmu-delphi/delphi-epidata/pull/1497
11+
12+
### Changed
13+
- Added a one-time check which logs a warning when the newest client version does not match the client version in use.
14+
615
## [4.1.24] - 2024-07-09
716

817
### Includes

0 commit comments

Comments
 (0)