Getting started

The epidatpy package provides access to all the endpoints of the Delphi Epidata API, and can be used to make requests for specific signals on specific dates and in select geographic regions.

Basic usage

Fetching data from the Delphi Epidata API is simple. Suppose we are interested in the covidcast endpoint, which provides access to a wide range of data on COVID-19. Reviewing the endpoint documentation, we see that we need to specify a data source name, a signal name, a geographic level, a time resolution, and the location and times of interest.

The pub_covidcast function lets us access the covidcast endpoint. Here we demonstrate how to fetch the most up-to-date version of the confirmed cumulative COVID cases from the JHU CSSE data source at the national level.


from epidatpy import CovidcastEpidata, EpiDataContext, EpiRange

# Create the client object. Note that due to the arguments below all results
# will be cached to your disk for 7 days, which helps avoid making repeated
# downloads.
epidata = EpiDataContext(use_cache=True, cache_max_age_days=7)

# `pub_covidcast` returns an `EpiDataCall`, which is a not-yet-executed query
# that can be inspected.
apicall = epidata.pub_covidcast(
    data_source="jhu-csse",
    signals="confirmed_cumulative_num",
    geo_type="nation",
    time_type="day",
    geo_values="us",
    time_values=EpiRange(20210405, 20210410),
)
print(apicall)
# The query can be executed and converted to a DataFrame by using the `.df()`
# method:
apicall.df()
EpiDataCall(endpoint=covidcast/, params={'data_source': 'jhu-csse', 'signals': 'confirmed_cumulative_num', 'geo_type': 'nation', 'time_type': 'day', 'geo_values': 'us', 'time_values': '20210405-20210410'})

source signal geo_type geo_value time_type time_value issue lag value stderr sample_size direction missing_value missing_stderr missing_sample_size
0 jhu-csse confirmed_cumulative_num nation us day 2021-04-05 2023-03-10 704 30874278.0 <NA> <NA> <NA> 0 5 5
1 jhu-csse confirmed_cumulative_num nation us day 2021-04-06 2023-03-10 703 30937664.0 <NA> <NA> <NA> 0 5 5
2 jhu-csse confirmed_cumulative_num nation us day 2021-04-07 2023-03-10 702 31013399.0 <NA> <NA> <NA> 0 5 5
3 jhu-csse confirmed_cumulative_num nation us day 2021-04-08 2023-03-10 701 31093208.0 <NA> <NA> <NA> 0 5 5
4 jhu-csse confirmed_cumulative_num nation us day 2021-04-09 2023-03-10 700 31177602.0 <NA> <NA> <NA> 0 5 5
5 jhu-csse confirmed_cumulative_num nation us day 2021-04-10 2023-03-10 699 31247947.0 <NA> <NA> <NA> 0 5 5

# Create the pub_covidcast-specific client object. This you to find what sources
# and signals are available without leaving your REPL.
covidcast = CovidcastEpidata(use_cache=True, cache_max_age_days=7)
# Get a list of all the sources available in the pub_covidcast endpoint.
print(covidcast.source_names())
print(covidcast.signal_names("jhu-csse"))
# Obtain the same data as above with a different interface.
covidcast["jhu-csse", "confirmed_cumulative_num"].call(
    "nation",
    "us",
    EpiRange(20210405, 20210410),
).df()
# See the "Finding data of interest" notebook for more features of this interface.
['chng', 'covid-act-now', 'doctor-visits', 'fb-survey', 'google-symptoms', 'hhs', 'hospital-admissions', 'indicator-combination-cases-deaths', 'jhu-csse', 'safegraph-weekly', 'usa-facts', 'ght', 'google-survey', 'indicator-combination-nmf', 'safegraph-daily', 'nchs-mortality', 'dsew-cpr', 'nssp']
['confirmed_cumulative_num', 'confirmed_7dav_incidence_num', 'confirmed_7dav_incidence_prop', 'confirmed_cumulative_prop', 'confirmed_incidence_num', 'confirmed_incidence_prop', 'deaths_cumulative_num', 'deaths_7dav_incidence_num', 'deaths_7dav_incidence_prop', 'deaths_cumulative_prop', 'deaths_incidence_num', 'deaths_incidence_prop']

source signal geo_type geo_value time_type time_value issue lag value stderr sample_size direction missing_value missing_stderr missing_sample_size
0 jhu-csse confirmed_cumulative_num nation us day 2021-04-05 2023-03-10 704 30874278.0 <NA> <NA> <NA> 0 5 5
1 jhu-csse confirmed_cumulative_num nation us day 2021-04-06 2023-03-10 703 30937664.0 <NA> <NA> <NA> 0 5 5
2 jhu-csse confirmed_cumulative_num nation us day 2021-04-07 2023-03-10 702 31013399.0 <NA> <NA> <NA> 0 5 5
3 jhu-csse confirmed_cumulative_num nation us day 2021-04-08 2023-03-10 701 31093208.0 <NA> <NA> <NA> 0 5 5
4 jhu-csse confirmed_cumulative_num nation us day 2021-04-09 2023-03-10 700 31177602.0 <NA> <NA> <NA> 0 5 5
5 jhu-csse confirmed_cumulative_num nation us day 2021-04-10 2023-03-10 699 31247947.0 <NA> <NA> <NA> 0 5 5

Each row represents one observation in the US on one day. The geographical abbreviation is given in the geo_value column, the date in the time_value column. Here value is the requested signal – in this case, the smoothed estimate of the percentage of people with COVID-like illness, based on the symptom surveys, and stderr is its standard error.

The Epidata API makes signals available at different geographic levels, depending on the endpoint. To request signals for all states instead of the entire US, we use the geo_type argument paired with * for the geo_values argument. (Only some endpoints allow for the use of * to access data at all locations. Check the help for a given endpoint to see if it supports *.)


epidata.pub_covidcast(
    data_source="fb-survey",
    signals="smoothed_cli",
    geo_type="state",
    time_type="day",
    geo_values="*",
    time_values=EpiRange(20210405, 20210410),
).df()

source signal geo_type geo_value time_type time_value issue lag value stderr sample_size direction missing_value missing_stderr missing_sample_size
0 fb-survey smoothed_cli state ak day 2021-04-05 2021-04-10 5 0.736883 0.275805 720.0 <NA> 0 0 0
1 fb-survey smoothed_cli state al day 2021-04-05 2021-04-10 5 0.796627 0.137734 3332.1117 <NA> 0 0 0
2 fb-survey smoothed_cli state ar day 2021-04-05 2021-04-10 5 0.561916 0.131108 2354.9911 <NA> 0 0 0
3 fb-survey smoothed_cli state az day 2021-04-05 2021-04-10 5 0.62283 0.105354 4742.2778 <NA> 0 0 0
4 fb-survey smoothed_cli state ca day 2021-04-05 2021-04-10 5 0.444169 0.040576 21382.3806 <NA> 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
301 fb-survey smoothed_cli state vt day 2021-04-10 2021-04-15 5 0.496408 0.237163 789.0011 <NA> 0 0 0
302 fb-survey smoothed_cli state wa day 2021-04-10 2021-04-15 5 0.573955 0.082897 6378.9502 <NA> 0 0 0
303 fb-survey smoothed_cli state wi day 2021-04-10 2021-04-15 5 0.552162 0.093652 4802.9953 <NA> 0 0 0
304 fb-survey smoothed_cli state wv day 2021-04-10 2021-04-15 5 0.726741 0.173248 2034.1066 <NA> 0 0 0
305 fb-survey smoothed_cli state wy day 2021-04-10 2021-04-15 5 1.205129 0.416785 573.7192 <NA> 0 0 0

306 rows × 15 columns

Alternatively, we can fetch the full time series for a subset of states by listing out the desired locations in the geo_value argument and using * in the time_values argument:


epidata.pub_covidcast(
    data_source="fb-survey",
    signals="smoothed_cli",
    geo_type="state",
    time_type="day",
    geo_values="pa,ca,fl",
    time_values="*",
).df()

source signal geo_type geo_value time_type time_value issue lag value stderr sample_size direction missing_value missing_stderr missing_sample_size
0 fb-survey smoothed_cli state ca day 2020-04-06 2020-09-03 150 0.727647 0.136668 3116.6652 <NA> 0 0 0
1 fb-survey smoothed_cli state fl day 2020-04-06 2020-09-03 150 0.605006 0.126229 2657.0001 <NA> 0 0 0
2 fb-survey smoothed_cli state pa day 2020-04-06 2020-09-03 150 0.852422 0.138715 3299.0016 <NA> 0 0 0
3 fb-survey smoothed_cli state ca day 2020-04-07 2020-09-03 149 0.672257 0.073444 9616.9951 <NA> 0 0 0
4 fb-survey smoothed_cli state fl day 2020-04-07 2020-09-03 149 0.705451 0.070535 10420.0016 <NA> 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2434 fb-survey smoothed_cli state fl day 2022-06-26 2022-06-28 2 3.606007 0.197311 7184.0002 <NA> 0 0 0
2435 fb-survey smoothed_cli state pa day 2022-06-26 2022-06-28 2 2.046306 0.195172 4194.0018 <NA> 0 0 0
2436 fb-survey smoothed_cli state ca day 2022-06-27 2022-06-28 1 3.368872 0.1838 7719.148 <NA> 0 0 0
2437 fb-survey smoothed_cli state fl day 2022-06-27 2022-06-28 1 3.740106 0.219306 5990.0001 <NA> 0 0 0
2438 fb-survey smoothed_cli state pa day 2022-06-27 2022-06-28 1 1.942765 0.209353 3460.0016 <NA> 0 0 0

2439 rows × 15 columns

Getting versioned data

The Epidata API stores a historical record of all data, including corrections and updates, which is particularly useful for accurately backtesting forecasting models. To fetch versioned data, we can use the as_of argument:


epidata.pub_covidcast(
    data_source="fb-survey",
    signals="smoothed_cli",
    geo_type="state",
    time_type="day",
    geo_values="pa",
    time_values=EpiRange(20210405, 20210410),
    as_of="2021-06-01",
).df()

source signal geo_type geo_value time_type time_value issue lag value stderr sample_size direction missing_value missing_stderr missing_sample_size
0 fb-survey smoothed_cli state pa day 2021-04-05 2021-04-10 5 0.715758 0.072999 10894.0057 <NA> 0 0 0
1 fb-survey smoothed_cli state pa day 2021-04-06 2021-04-11 5 0.69321 0.070869 10862.0055 <NA> 0 0 0
2 fb-survey smoothed_cli state pa day 2021-04-07 2021-04-12 5 0.685934 0.070654 10790.0054 <NA> 0 0 0
3 fb-survey smoothed_cli state pa day 2021-04-08 2021-04-13 5 0.681511 0.071394 10731.0044 <NA> 0 0 0
4 fb-survey smoothed_cli state pa day 2021-04-09 2021-04-14 5 0.709416 0.072162 10590.0049 <NA> 0 0 0
5 fb-survey smoothed_cli state pa day 2021-04-10 2021-04-15 5 0.77624 0.076037 10492.0055 <NA> 0 0 0

Plotting

Because the output data is a standard Pandas DataFrame, we can easily plot it using any of the available Python libraries:


import matplotlib.pyplot as plt

plt.rcParams["figure.dpi"] = 300

apicall = epidata.pub_covidcast(
    data_source="fb-survey",
    signals="smoothed_cli",
    geo_type="state",
    geo_values="pa,ca,fl",
    time_type="day",
    time_values=EpiRange(20210405, 20210410),
)

fig, ax = plt.subplots(figsize=(6, 5))
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["top"].set_visible(False)

(
    apicall.df()
    .pivot_table(values="value", index="time_value", columns="geo_value")
    .plot(xlabel="Date", ylabel="CLI", ax=ax, linewidth=1.5)
)

plt.title("Smoothed CLI from Facebook Survey", fontsize=16)
plt.subplots_adjust(bottom=0.2)
plt.show()
_images/getting_started_11_0.png

Finding locations of interest

Most data is only available for the US. Select endpoints report other countries at the national and/or regional levels. Endpoint descriptions explicitly state when they cover non-US locations.

For endpoints that report US data, see the geographic coding documentation for available geographic levels.

International data

International data is available via

  • pub_dengue_nowcast (North and South America)

  • pub_ecdc_ili (Europe)

  • pub_kcdc_ili (Korea)

  • pub_nidss_dengue (Taiwan)

  • pub_nidss_flu (Taiwan)

  • pub_paho_dengue (North and South America)

  • pvt_dengue_sensors (North and South America)

Finding data sources and signals of interest

Above we used data from Delphi’s symptom surveys, but the Epidata API includes numerous data streams: medical claims data, cases and deaths, mobility, and many others. This can make it a challenge to find the data stream that you are most interested in.

The Epidata documentation lists all the data sources and signals available through the API for COVID-19 and for other diseases.

Epiweeks and dates

Formatting for epiweeks is YYYYWW and for dates is YYYYMMDD.

Epiweeks use the U.S. CDC definition, which defines the first epiweek each year to be the first week containing January 4th and the start of the week is on Sunday. See this page for a less terse explanation.

When specifying the time_values argument, you can use individual values, comma-separated lists or, a hyphenated range of values to specify single or several dates (or epiweeks). An EpiRange object can be also used to construct a range of epiweeks or dates. Examples include:

  • param = 201530 (A single epiweek)

  • param = '201401,201501,201601' (Several epiweeks)

  • param = '200501-200552' (A range of epiweeks)

  • param = '201440,201501-201510' (Several epiweeks, including a range)

  • param = EpiRange(20070101, 20071231) (A range of dates)