Skip to content

Commit

Permalink
Merge pull request #1119 from cmu-delphi/release/delphi-epidata-0.4.8
Browse files Browse the repository at this point in the history
Release Delphi Epidata 0.4.8
  • Loading branch information
krivard authored Apr 4, 2023
2 parents a5e25d4 + 6b2923c commit 5da6d3f
Show file tree
Hide file tree
Showing 48 changed files with 184 additions and 519 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.4.7
current_version = 0.4.8
commit = False
tag = False

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ jobs:
docker build -t delphi_web_epidata -f ./devops/Dockerfile .
cd ../../../
# MODULE_NAME specifies the location of the `app` variable, the actual WSGI application object to run.
# see https://github.com/tiangolo/meinheld-gunicorn-docker#module_name
- name: Start services
run: |
docker network create --driver bridge delphi-net
docker run --rm -d -p 13306:3306 --network delphi-net --name delphi_database_epidata --cap-add=sys_nice delphi_database_epidata
docker run --rm -d -p 10080:80 --env "SQLALCHEMY_DATABASE_URI=mysql+mysqldb://user:pass@delphi_database_epidata:3306/epidata" --env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --network delphi-net --name delphi_web_epidata delphi_web_epidata
docker run --rm -d -p 10080:80 --env "MODULE_NAME=delphi.epidata.server.main" --env "SQLALCHEMY_DATABASE_URI=mysql+mysqldb://user:pass@delphi_database_epidata:3306/epidata" --env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --network delphi-net --name delphi_web_epidata delphi_web_epidata
docker ps
- run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/performance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
run: |
cd delphi-admin/load-testing/locust
docker build -t locust .
export CSV=v4-requests-small.csv
export CSV=v4-requests-as_of.csv
touch output_stats.csv && chmod 666 output_stats.csv
touch output_stats_history.csv && chmod 666 output_stats_history.csv
touch output_failures.csv && chmod 666 output_failures.csv
Expand Down
18 changes: 9 additions & 9 deletions deploy.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
"add-header-comment": true
},

"// common",
{
"type": "move",
"src": "src/common/",
"dst": "[[package]]/common/",
"match": "^.*\\.(py)$",
"add-header-comment": true
},

"// server",
{
"type": "move",
Expand Down Expand Up @@ -47,15 +56,6 @@
"add-header-comment": true
},

"// acquisition - common",
{
"type": "move",
"src": "src/acquisition/common/",
"dst": "[[package]]/acquisition/common/",
"match": "^.*\\.(py)$",
"add-header-comment": true
},

"// acquisition - fluview",
{
"type": "move",
Expand Down
3 changes: 3 additions & 0 deletions dev/local/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ web:
cd -

@# Run the web server
@# MODULE_NAME specifies the location of the `app` variable, the actual WSGI application object to run.
@# see https://github.com/tiangolo/meinheld-gunicorn-docker#module_name
@docker run --rm -p 127.0.0.1:10080:80 \
$(M1) \
--env "MODULE_NAME=delphi.epidata.server.main" \
--env "SQLALCHEMY_DATABASE_URI=$(sqlalchemy_uri)" \
--env "FLASK_SECRET=abc" --env "FLASK_PREFIX=/epidata" --env "LOG_DEBUG" \
--network delphi-net --name delphi_web_epidata \
Expand Down
2 changes: 1 addition & 1 deletion dev/local/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = Delphi Development
version = 0.4.7
version = 0.4.8

[options]
packages =
Expand Down
10 changes: 6 additions & 4 deletions devops/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ LABEL org.opencontainers.image.source=https://github.com/cmu-delphi/delphi-epida

COPY ./devops/gunicorn_conf.py /app
COPY ./devops/start_wrapper.sh /
COPY ./src/server/ /app/app/
COPY --from=builder ./src/build/lib/ /app/app/lib/
RUN mkdir -p /app/delphi/epidata
COPY ./src/server /app/delphi/epidata/server
COPY ./src/common /app/delphi/epidata/common
COPY --from=builder ./src/build/lib/ /app/delphi/epidata/lib/

COPY requirements.api.txt /app/requirements_also.txt

RUN ln -s -f /usr/share/zoneinfo/America/New_York /etc/localtime \
&& rm -rf /app/app/__pycache__ /app/app/*.php \
&& chmod -R o+r /app/app \
&& rm -rf /app/delphi/epidata/__pycache__ \
&& chmod -R o+r /app/delphi/epidata \
&& chmod 755 /start_wrapper.sh \
&& pip install --no-cache-dir -r /tmp/requirements.txt -r requirements_also.txt
# the file /tmp/requirements.txt is created in the parent docker definition. (see:
Expand Down
8 changes: 5 additions & 3 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (5.2.5)
activesupport (6.0.6.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
Expand All @@ -15,7 +16,7 @@ GEM
colorator (1.1.0)
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.8)
concurrent-ruby (1.2.0)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.2)
Expand Down Expand Up @@ -209,7 +210,7 @@ GEM
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
minitest (5.17.0)
multipart-post (2.1.1)
nokogiri (1.13.10)
mini_portile2 (~> 2.8.0)
Expand Down Expand Up @@ -255,6 +256,7 @@ GEM
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
wdm (0.1.1)
zeitwerk (2.6.6)

PLATFORMS
ruby
Expand Down
8 changes: 6 additions & 2 deletions docs/symptom-survey/publications.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ Pandemic"](https://www.pnas.org/topic/548) in *PNAS*:

Research publications using the survey data include:

- Taube JC, Susswein Z, Bansal S (2023). [Spatiotemporal Trends in Self-Reported
Mask-Wearing Behavior in the United States: Analysis of a Large
Cross-sectional Survey](https://doi.org/10.2196/42128). *JMIR Public Health
and Surveillance* 9:e42128.
- Rebecca L. Weintraub et al (2023). [Identifying COVID-19 Vaccine Deserts and
Ways to Reduce Them: A Digital Tool to Support Public Health
Decision-Making](https://doi.org/10.2105/AJPH.2022.307198). *American Journal
of Public Health*.
of Public Health* 113 (4), 363-367.
- Anzalone AJ, Sun J, Vinson AJ, Beasley WH, Hillegass WB, Murray K, et al.
(2023). [Community risks for SARS-CoV-2 infection among fully vaccinated US
adults by rurality: A retrospective cohort study from the National COVID
Expand All @@ -38,7 +42,7 @@ Research publications using the survey data include:
- Rufino, J., Baquero, C., Frey, D. et al (2023). [Using survey data to estimate
the impact of the omicron variant on vaccine efficacy against COVID-19
infection](https://doi.org/10.1038/s41598-023-27951-3). *Scientific Reports*
13, 900 (2023).
13, 900.
- Rader, B., Astley, C.M., Sewalk, K. et al (2022). [Spatial modeling of vaccine
deserts as barriers to controlling
SARS-CoV-2](https://doi.org/10.1038/s43856-022-00183-8). *Communications
Expand Down
6 changes: 3 additions & 3 deletions integrations/acquisition/covidcast/delete_batch.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
geo_id,value,stderr,sample_size,issue,time_value,geo_type,signal,source
d_nonlatest,0,0,0,1,0,county,sig,src
d_latest, 0,0,0,3,0,county,sig,src
d_justone, 0,0,0,1,0,county,sig,src
d_nonlatest,0,0,0,1,0,msa,sig,src
d_latest, 0,0,0,3,0,msa,sig,src
d_justone, 0,0,0,1,0,msa,sig,src
14 changes: 5 additions & 9 deletions integrations/acquisition/covidcast/test_csv_uploading.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import date
import os
import unittest
from unittest.mock import MagicMock
import argparse

# third party
import mysql.connector
Expand All @@ -14,7 +14,7 @@
# first party
from delphi_utils import Nans
from delphi.epidata.client.delphi_epidata import Epidata
from delphi.epidata.acquisition.covidcast.csv_to_database import main
from delphi.epidata.acquisition.covidcast.csv_to_database import main, get_argument_parser
import delphi.operations.secrets as secrets

# py3tester coverage target (equivalent to `import *`)
Expand Down Expand Up @@ -92,16 +92,12 @@ def test_uploading(self):

# make some fake data files
data_dir = 'covid/data'
source_receiving_dir = data_dir + '/receiving/src-name'
indicator_dir = 'src-name'
source_receiving_dir = data_dir + '/receiving/' + indicator_dir
log_file_directory = "/var/log/"
os.makedirs(source_receiving_dir, exist_ok=True)
os.makedirs(log_file_directory, exist_ok=True)
# TODO: use an actual argparse object for the args instead of a MagicMock
args = MagicMock(
log_file=log_file_directory +
"output.log",
data_dir=data_dir,
specific_issue_date=False)
args = get_argument_parser().parse_args(["--log_file", log_file_directory + "output.log", "--data_dir", data_dir, "--indicator_name", indicator_dir])
uploader_column_rename = {"geo_id": "geo_value", "val": "value", "se": "stderr", "missing_val": "missing_value", "missing_se": "missing_stderr"}


Expand Down
31 changes: 16 additions & 15 deletions integrations/client/test_delphi_epidata.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
# third party
import delphi.operations.secrets as secrets
from delphi.epidata.acquisition.covidcast.covidcast_meta_cache_updater import main as update_covidcast_meta_cache
from delphi.epidata.acquisition.covidcast.test_utils import CovidcastBase, CovidcastTestRow
from delphi.epidata.acquisition.covidcast.test_utils import CovidcastBase, CovidcastTestRow, FIPS, MSA
from delphi.epidata.client.delphi_epidata import Epidata
from delphi_utils import Nans


# py3tester coverage target
__test_target__ = 'delphi.epidata.client.delphi_epidata'
# all the Nans we use here are just one value, so this is a shortcut to it:
Expand Down Expand Up @@ -219,10 +218,10 @@ def test_geo_value(self):
# insert placeholder data: three counties, three MSAs
N = 3
rows = [
CovidcastTestRow.make_default_row(geo_type="county", geo_value=str(i)*5, value=i)
CovidcastTestRow.make_default_row(geo_type="fips", geo_value=FIPS[i], value=i)
for i in range(N)
] + [
CovidcastTestRow.make_default_row(geo_type="msa", geo_value=str(i)*5, value=i*10)
CovidcastTestRow.make_default_row(geo_type="msa", geo_value=MSA[i], value=i*10)
for i in range(N)
]
self._insert_rows(rows)
Expand All @@ -241,26 +240,28 @@ def fetch(geo):
self.assertEqual(request['message'], 'success')
self.assertEqual(request['epidata'], counties)
# test fetch a specific region
request = fetch('11111')
request = fetch([FIPS[0]])
self.assertEqual(request['message'], 'success')
self.assertEqual(request['epidata'], [counties[1]])
self.assertEqual(request['epidata'], [counties[0]])
# test fetch a specific yet not existing region
request = fetch('55555')
self.assertEqual(request['message'], 'no results')
self.assertEqual(request['message'], 'Invalid geo_value(s) 55555 for the requested geo_type fips')
# test fetch a multiple regions
request = fetch(['11111', '22222'])
request = fetch([FIPS[0], FIPS[1]])
self.assertEqual(request['message'], 'success')
self.assertEqual(request['epidata'], [counties[1], counties[2]])
self.assertEqual(request['epidata'], [counties[0], counties[1]])
# test fetch a multiple regions in another variant
request = fetch(['00000', '22222'])
request = fetch([FIPS[0], FIPS[2]])
self.assertEqual(request['message'], 'success')
self.assertEqual(request['epidata'], [counties[0], counties[2]])
# test fetch a multiple regions but one is not existing
request = fetch(['11111', '55555'])
self.assertEqual(request['message'], 'success')
self.assertEqual(request['epidata'], [counties[1]])
request = fetch([FIPS[0], '55555'])
self.assertEqual(request['message'], 'Invalid geo_value(s) 55555 for the requested geo_type fips')
# test fetch a multiple regions but specify no region
request = fetch([])
self.assertEqual(request['message'], 'geo_value is empty for the requested geo_type fips!')
# test fetch a region with no results
request = fetch([FIPS[3]])
self.assertEqual(request['message'], 'no results')

def test_covidcast_meta(self):
Expand Down Expand Up @@ -325,10 +326,10 @@ def test_async_epidata(self):
# insert placeholder data: three counties, three MSAs
N = 3
rows = [
CovidcastTestRow.make_default_row(geo_type="county", geo_value=str(i)*5, value=i)
CovidcastTestRow.make_default_row(geo_type="fips", geo_value=FIPS[i-1], value=i)
for i in range(N)
] + [
CovidcastTestRow.make_default_row(geo_type="msa", geo_value=str(i)*5, value=i*10)
CovidcastTestRow.make_default_row(geo_type="msa", geo_value=MSA[i-1], value=i*10)
for i in range(N)
]
self._insert_rows(rows)
Expand Down
33 changes: 17 additions & 16 deletions integrations/server/test_covidcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# first party
from delphi_utils import Nans
from delphi.epidata.acquisition.covidcast.test_utils import CovidcastBase, CovidcastTestRow
from delphi.epidata.acquisition.covidcast.test_utils import CovidcastBase, CovidcastTestRow, FIPS, MSA
from delphi.epidata.client.delphi_epidata import Epidata

# use the local instance of the Epidata API
Expand All @@ -37,23 +37,22 @@ def _insert_placeholder_set_one(self):

def _insert_placeholder_set_two(self):
rows = [
CovidcastTestRow.make_default_row(geo_type='county', geo_value=str(i)*5, value=i*1., stderr=i*10., sample_size=i*100.)
CovidcastTestRow.make_default_row(geo_type='msa', geo_value=MSA[i-1], value=i*1., stderr=i*10., sample_size=i*100.)
for i in [1, 2, 3]
] + [
# geo value intended to overlap with counties above
CovidcastTestRow.make_default_row(geo_type='msa', geo_value=str(i-3)*5, value=i*1., stderr=i*10., sample_size=i*100.)
CovidcastTestRow.make_default_row(geo_type='fips', geo_value=FIPS[i-4], value=i*1., stderr=i*10., sample_size=i*100.)
for i in [4, 5, 6]
]
self._insert_rows(rows)
return rows

def _insert_placeholder_set_three(self):
rows = [
CovidcastTestRow.make_default_row(geo_type='county', geo_value='11111', time_value=2000_01_01+i, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03, lag=2-i)
CovidcastTestRow.make_default_row(time_value=2000_01_01+i, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03, lag=2-i)
for i in [1, 2, 3]
] + [
# time value intended to overlap with 11111 above, with disjoint geo values
CovidcastTestRow.make_default_row(geo_type='county', geo_value=str(i)*5, time_value=2000_01_01+i-3, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03, lag=5-i)
# time value intended to overlap with the time values above, with disjoint geo values
CovidcastTestRow.make_default_row(geo_value=MSA[i-3], time_value=2000_01_01+i-3, value=i*1., stderr=i*10., sample_size=i*100., issue=2000_01_03, lag=5-i)
for i in [4, 5, 6]
]
self._insert_rows(rows)
Expand Down Expand Up @@ -295,7 +294,7 @@ def test_signal_wildcard(self):
})

def test_geo_value(self):
"""test different variants of geo types: single, *, multi."""
"""test whether geo values are valid for specific geo types"""

# insert placeholder data
rows = self._insert_placeholder_set_two()
Expand All @@ -308,26 +307,28 @@ def fetch(geo_value):
return response

# test fetch a specific region
r = fetch('11111')
r = fetch(MSA[0])
self.assertEqual(r['message'], 'success')
self.assertEqual(r['epidata'], expected[0:1])
# test fetch a specific yet not existing region
r = fetch('55555')
self.assertEqual(r['message'], 'no results')
r = fetch('11111')
self.assertEqual(r['message'], 'Invalid geo_value(s) 11111 for the requested geo_type msa')
# test fetch multiple regions
r = fetch('11111,22222')
r = fetch(f'{MSA[0]},{MSA[1]}')
self.assertEqual(r['message'], 'success')
self.assertEqual(r['epidata'], expected[0:2])
# test fetch multiple noncontiguous regions
r = fetch('11111,33333')
r = fetch(f'{MSA[0]},{MSA[2]}')
self.assertEqual(r['message'], 'success')
self.assertEqual(r['epidata'], [expected[0], expected[2]])
# test fetch multiple regions but one is not existing
r = fetch('11111,55555')
self.assertEqual(r['message'], 'success')
self.assertEqual(r['epidata'], expected[0:1])
r = fetch(f'{MSA[0]},11111')
self.assertEqual(r['message'], 'Invalid geo_value(s) 11111 for the requested geo_type msa')
# test fetch empty region
r = fetch('')
self.assertEqual(r['message'], 'geo_value is empty for the requested geo_type msa!')
# test a region that has no results
r = fetch(MSA[3])
self.assertEqual(r['message'], 'no results')

def test_location_timeline(self):
Expand Down
Loading

0 comments on commit 5da6d3f

Please sign in to comment.