Skip to content

Commit ac23a9c

Browse files
committed
implement covid_survey endpoints
- explicitly define the tables - give data dictionary in the ddl - introduce integration tests, which, among other things, test the privacy filter - implement API endpoints for the new tables
1 parent 10e805a commit ac23a9c

5 files changed

+437
-1
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""Integration tests for the `covid_survey_county_weekly` endpoint."""
2+
3+
# standard library
4+
import unittest
5+
6+
# third party
7+
import mysql.connector
8+
import requests
9+
10+
11+
# use the local instance of the Epidata API
12+
BASE_URL = 'http://delphi_web_epidata/epidata/api.php'
13+
14+
15+
class CovidSurveyCountyWeeklyTests(unittest.TestCase):
16+
"""Tests the `covid_survey_county_weekly` endpoint."""
17+
18+
def setUp(self):
19+
"""Perform per-test setup."""
20+
21+
# connect to the `epidata` database and clear the
22+
# `covid_survey_county_weekly` table
23+
cnx = mysql.connector.connect(
24+
user='user',
25+
password='pass',
26+
host='delphi_database_epidata',
27+
database='epidata')
28+
cur = cnx.cursor()
29+
cur.execute('truncate table covid_survey_county_weekly')
30+
cnx.commit()
31+
cur.close()
32+
33+
# make connection and cursor available to test cases
34+
self.cnx = cnx
35+
self.cur = cnx.cursor()
36+
37+
def tearDown(self):
38+
"""Perform per-test teardown."""
39+
self.cur.close()
40+
self.cnx.close()
41+
42+
def test_round_trip(self):
43+
"""Make a simple round-trip with some sample data."""
44+
45+
# insert dummy data
46+
self.cur.execute('''
47+
insert into covid_survey_county_weekly values
48+
(0, 202014, '42003', 1.5, 2.5, 3.5, 4.5, 5678.5)
49+
''')
50+
self.cnx.commit()
51+
52+
# make the request
53+
response = requests.get(BASE_URL, params={
54+
'source': 'covid_survey_county_weekly',
55+
'counties': '42003',
56+
'epiweeks': 202014,
57+
})
58+
response.raise_for_status()
59+
response = response.json()
60+
61+
# assert that the right data came back
62+
self.assertEqual(response, {
63+
"result": 1,
64+
"epidata": [{
65+
'epiweek': 202014,
66+
'county': '42003',
67+
'ili': 1.5,
68+
'ili_stdev': 2.5,
69+
'cli': 3.5,
70+
'cli_stdev': 4.5,
71+
'denominator': 5678.5,
72+
}],
73+
"message": "success",
74+
})
75+
76+
def test_privacy_filtering(self):
77+
"""Don't return rows with too small of a denominator."""
78+
79+
# shared constants
80+
request_params = {
81+
'source': 'covid_survey_county_weekly',
82+
'counties': '42003',
83+
'epiweeks': 202014,
84+
}
85+
86+
with self.subTest(name='filtered'):
87+
88+
# insert dummy data
89+
self.cur.execute('''
90+
insert into covid_survey_county_weekly values
91+
(0, 202014, '42003', 1.5, 2.5, 3.5, 4.5, 99.5)
92+
''')
93+
self.cnx.commit()
94+
95+
# make the request
96+
response = requests.get(BASE_URL, params=request_params)
97+
response.raise_for_status()
98+
response = response.json()
99+
100+
# assert that no data came back
101+
self.assertEqual(response, {
102+
"result": -2,
103+
"message": "no results",
104+
})
105+
106+
with self.subTest(name='unfiltered'):
107+
108+
# amend the denominator
109+
self.cur.execute('''
110+
update covid_survey_county_weekly set denominator = 100.5
111+
''')
112+
self.cnx.commit()
113+
114+
# make the request
115+
response = requests.get(BASE_URL, params=request_params)
116+
response.raise_for_status()
117+
response = response.json()
118+
119+
# assert that the right data came back
120+
self.assertEqual(response, {
121+
"result": 1,
122+
"epidata": [{
123+
'epiweek': 202014,
124+
'county': '42003',
125+
'ili': 1.5,
126+
'ili_stdev': 2.5,
127+
'cli': 3.5,
128+
'cli_stdev': 4.5,
129+
'denominator': 100.5,
130+
}],
131+
"message": "success",
132+
})
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""Integration tests for the `covid_survey_hrr_daily` endpoint."""
2+
3+
# standard library
4+
import unittest
5+
6+
# third party
7+
import mysql.connector
8+
import requests
9+
10+
11+
# use the local instance of the Epidata API
12+
BASE_URL = 'http://delphi_web_epidata/epidata/api.php'
13+
14+
15+
class CovidSurveyHrrDailyTests(unittest.TestCase):
16+
"""Tests the `covid_survey_hrr_daily` endpoint."""
17+
18+
def setUp(self):
19+
"""Perform per-test setup."""
20+
21+
# connect to the `epidata` database and clear the `covid_survey_hrr_daily`
22+
# table
23+
cnx = mysql.connector.connect(
24+
user='user',
25+
password='pass',
26+
host='delphi_database_epidata',
27+
database='epidata')
28+
cur = cnx.cursor()
29+
cur.execute('truncate table covid_survey_hrr_daily')
30+
cnx.commit()
31+
cur.close()
32+
33+
# make connection and cursor available to test cases
34+
self.cnx = cnx
35+
self.cur = cnx.cursor()
36+
37+
def tearDown(self):
38+
"""Perform per-test teardown."""
39+
self.cur.close()
40+
self.cnx.close()
41+
42+
def test_round_trip(self):
43+
"""Make a simple round-trip with some sample data."""
44+
45+
# insert dummy data
46+
self.cur.execute('''
47+
insert into covid_survey_hrr_daily values
48+
(0, '2020-04-08', 123, 1.5, 2.5, 3.5, 4.5, 5678.5)
49+
''')
50+
self.cnx.commit()
51+
52+
# make the request
53+
response = requests.get(BASE_URL, params={
54+
'source': 'covid_survey_hrr_daily',
55+
'hrrs': 123,
56+
'dates': 20200408,
57+
})
58+
response.raise_for_status()
59+
response = response.json()
60+
61+
# assert that the right data came back
62+
self.assertEqual(response, {
63+
"result": 1,
64+
"epidata": [{
65+
'date': '2020-04-08',
66+
'hrr': 123,
67+
'ili': 1.5,
68+
'ili_stdev': 2.5,
69+
'cli': 3.5,
70+
'cli_stdev': 4.5,
71+
'denominator': 5678.5,
72+
}],
73+
"message": "success",
74+
})
75+
76+
def test_privacy_filtering(self):
77+
"""Don't return rows with too small of a denominator."""
78+
79+
# shared constants
80+
request_params = {
81+
'source': 'covid_survey_hrr_daily',
82+
'hrrs': 123,
83+
'dates': 20200408,
84+
}
85+
86+
with self.subTest(name='filtered'):
87+
88+
# insert dummy data
89+
self.cur.execute('''
90+
insert into covid_survey_hrr_daily values
91+
(0, '2020-04-08', 123, 1.5, 2.5, 3.5, 4.5, 99.5)
92+
''')
93+
self.cnx.commit()
94+
95+
# make the request
96+
response = requests.get(BASE_URL, params=request_params)
97+
response.raise_for_status()
98+
response = response.json()
99+
100+
# assert that no data came back
101+
self.assertEqual(response, {
102+
"result": -2,
103+
"message": "no results",
104+
})
105+
106+
with self.subTest(name='unfiltered'):
107+
108+
# amend the denominator
109+
self.cur.execute('''
110+
update covid_survey_hrr_daily set denominator = 100.5
111+
''')
112+
self.cnx.commit()
113+
114+
# make the request
115+
response = requests.get(BASE_URL, params=request_params)
116+
response.raise_for_status()
117+
response = response.json()
118+
119+
# assert that the right data came back
120+
self.assertEqual(response, {
121+
"result": 1,
122+
"epidata": [{
123+
'date': '2020-04-08',
124+
'hrr': 123,
125+
'ili': 1.5,
126+
'ili_stdev': 2.5,
127+
'cli': 3.5,
128+
'cli_stdev': 4.5,
129+
'denominator': 100.5,
130+
}],
131+
"message": "success",
132+
})
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Stores a subset of data from the COVID-19 survey, aggregated by weeks and
3+
counties.
4+
5+
+-------------+------------+------+-----+---------+----------------+
6+
| Field | Type | Null | Key | Default | Extra |
7+
+-------------+------------+------+-----+---------+----------------+
8+
| id | int(11) | NO | PRI | NULL | auto_increment |
9+
| epiweek | int(11) | NO | MUL | NULL | |
10+
| county | varchar(5) | NO | | NULL | |
11+
| ili | double | NO | | NULL | |
12+
| ili_stdev | double | NO | | NULL | |
13+
| cli | double | NO | | NULL | |
14+
| cli_stdev | double | NO | | NULL | |
15+
| denominator | double | NO | | NULL | |
16+
+-------------+------------+------+-----+---------+----------------+
17+
18+
id:
19+
unique identifier for each record
20+
epiweek:
21+
the epidemiological week during which the survey was submitted
22+
county:
23+
assumed fips 6-4 county code
24+
ili:
25+
estimated percent of sample experiencing influenza-like illness (ILI)
26+
ili_stdev:
27+
standard deviation for the ILI estimate
28+
cli:
29+
estimated percent of sample experiencing codid-19-like illness (CLI)
30+
cli_stdev:
31+
standard deviation for the CLI estimate
32+
denominator:
33+
estimated sample size
34+
*/
35+
36+
CREATE TABLE `covid_survey_county_weekly` (
37+
`id` int(11) NOT NULL AUTO_INCREMENT,
38+
`epiweek` int(11) NOT NULL,
39+
`county` varchar(5) NOT NULL,
40+
`ili` double NOT NULL,
41+
`ili_stdev` double NOT NULL,
42+
`cli` double NOT NULL,
43+
`cli_stdev` double NOT NULL,
44+
`denominator` double NOT NULL,
45+
PRIMARY KEY (`id`),
46+
UNIQUE KEY (`epiweek`, `county`),
47+
KEY (`county`, `epiweek`)
48+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

src/ddl/covid_survey_hrr_daily.sql

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Stores a subset of data from the COVID-19 survey, aggregated by days and
3+
Hospital Referral Regions (HRRs).
4+
5+
+-------------+---------+------+-----+---------+----------------+
6+
| Field | Type | Null | Key | Default | Extra |
7+
+-------------+---------+------+-----+---------+----------------+
8+
| id | int(11) | NO | PRI | NULL | auto_increment |
9+
| date | date | NO | MUL | NULL | |
10+
| hrr | int(11) | NO | | NULL | |
11+
| ili | double | NO | | NULL | |
12+
| ili_stdev | double | NO | | NULL | |
13+
| cli | double | NO | | NULL | |
14+
| cli_stdev | double | NO | | NULL | |
15+
| denominator | double | NO | | NULL | |
16+
+-------------+---------+------+-----+---------+----------------+
17+
18+
id:
19+
unique identifier for each record
20+
date:
21+
the date on which the survey was submitted
22+
hrr:
23+
assumed hospital referral region (HRR) identifier
24+
ili:
25+
estimated percent of sample experiencing influenza-like illness (ILI)
26+
ili_stdev:
27+
standard deviation for the ILI estimate
28+
cli:
29+
estimated percent of sample experiencing codid-19-like illness (CLI)
30+
cli_stdev:
31+
standard deviation for the CLI estimate
32+
denominator:
33+
estimated sample size
34+
*/
35+
36+
CREATE TABLE `covid_survey_hrr_daily` (
37+
`id` int(11) NOT NULL AUTO_INCREMENT,
38+
`date` date NOT NULL,
39+
`hrr` int(11) NOT NULL,
40+
`ili` double NOT NULL,
41+
`ili_stdev` double NOT NULL,
42+
`cli` double NOT NULL,
43+
`cli_stdev` double NOT NULL,
44+
`denominator` double NOT NULL,
45+
PRIMARY KEY (`id`),
46+
UNIQUE KEY (`date`, `hrr`),
47+
KEY (`hrr`, `date`)
48+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

0 commit comments

Comments
 (0)