diff --git a/src/api/EpiData.ts b/src/api/EpiData.ts index 1b3dfc5..142d2c5 100644 --- a/src/api/EpiData.ts +++ b/src/api/EpiData.ts @@ -118,6 +118,7 @@ export function loadDataSet( fixedParams: Record, userParams: Record, columns: string[], + api_key = '', columnRenamings: Record = {}, ): Promise { const duplicates = get(expandedDataGroups).filter((d) => d.title == title); @@ -131,7 +132,11 @@ export function loadDataSet( ) .then(() => null); } - const url = new URL(ENDPOINT + `/${endpoint}/`); + let url_string = ENDPOINT + `/${endpoint}/`; + if (api_key !== '') { + url_string += `?api_key=${api_key}`; + } + const url = new URL(url_string); const params = cleanParams(userParams); Object.entries(fixedParams).forEach(([key, value]) => { url.searchParams.set(key, String(value)); @@ -168,10 +173,14 @@ export function loadDataSet( }); } -export function fetchCOVIDcastMeta(): Promise< - { geo_type: string; signal: string; data_source: string; time_type?: string }[] -> { - const url = new URL(ENDPOINT + `/covidcast_meta/`); +export function fetchCOVIDcastMeta( + api_key: string, +): Promise<{ geo_type: string; signal: string; data_source: string; time_type?: string }[]> { + let url_string = ENDPOINT + `/covidcast_meta/`; + if (api_key !== '') { + url_string += `?api_key=${api_key}`; + } + const url = new URL(url_string); url.searchParams.set('format', 'json'); return fetchImpl<{ geo_type: string; signal: string; data_source: string; time_type?: string }[]>(url).catch( (error) => { @@ -190,8 +199,9 @@ export function importCDC({ locations, auth }: { locations: string; auth?: strin { epiweeks: epiRange(firstEpiWeek.cdc, currentEpiWeek), }, - { auth, locations }, + { locations }, ['total', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8'], + auth, ); } @@ -201,12 +211,14 @@ export function importCOVIDcast({ geo_value, signal, time_type = 'day', + api_key, }: { data_source: string; signal: string; time_type?: string; geo_type: string; geo_value: string; + api_key: string; }): Promise { const title = `[API] COVIDcast: ${data_source}:${signal} (${geo_type}:${geo_value})`; return loadDataSet( @@ -221,6 +233,7 @@ export function importCOVIDcast({ }, { data_source, signal, time_type, geo_type, geo_value }, ['value', 'stderr', 'sample_size'], + api_key, ); } @@ -343,7 +356,7 @@ export function importFluView({ { epiweeks: epiRange(firstEpiWeek.fluview, currentEpiWeek), }, - { regions, issues, lag, auth }, + { regions, issues, lag }, [ 'wili', 'ili', @@ -357,6 +370,7 @@ export function importFluView({ 'num_age_4', 'num_age_5', ], + auth, { wili: '%wILI', ili: '%ILI', @@ -395,8 +409,9 @@ export function importGHT({ { epiweeks: epiRange(firstEpiWeek.ght, currentEpiWeek), }, - { auth, locations, query }, + { locations, query }, ['value'], + auth, ); } @@ -456,8 +471,9 @@ export function importQuidel({ auth, locations }: { auth: string; locations: str { epiweeks: epiRange(firstEpiWeek.quidel, currentEpiWeek), }, - { auth, locations }, + { locations }, ['value'], + auth, ); } export function importSensors({ @@ -478,8 +494,9 @@ export function importSensors({ { epiweeks: epiRange(firstEpiWeek.sensors, currentEpiWeek), }, - { auth, names, locations }, + { names, locations }, ['value'], + auth, ); } // twtr @@ -504,8 +521,9 @@ export function importTwitter({ : { epiweeks: epiRange(firstEpiWeek.twitter, currentEpiWeek), }, - { auth, locations, resolution }, + { locations, resolution }, ['num', 'total', 'percent'], + auth, ); } export function importWiki({ diff --git a/src/components/dialogs/dataSources/COVIDcast.svelte b/src/components/dialogs/dataSources/COVIDcast.svelte index 10e9699..074c881 100644 --- a/src/components/dialogs/dataSources/COVIDcast.svelte +++ b/src/components/dialogs/dataSources/COVIDcast.svelte @@ -7,10 +7,13 @@ export let id: string; + let api_key = ''; let data_source = ''; let signal = ''; let geo_type = ''; let geo_value = ''; + let form_key = ''; + let valid_key = true; let dataSources: (LabelValue & { signals: string[] })[] = []; let geoTypes: string[] = []; @@ -23,38 +26,77 @@ } } - onMount(() => { - fetchCOVIDcastMeta().then((res) => { - geoTypes = [...new Set(res.map((d) => d.geo_type))]; - const byDataSource = new Map(); - for (const row of res) { - const ds = byDataSource.get(row.data_source); - if (!ds) { - byDataSource.set(row.data_source, { - label: row.data_source, - value: row.data_source, - signals: [row.signal], - }); - } else if (!ds.signals.includes(row.signal)) { - ds.signals.push(row.signal); + // Helper function; delay invoking "fn" until "ms" milliseconds have passed + const debounce = (fn: Function, ms = 500) => { + let timeoutId: ReturnType; + return function (this: any, ...args: any[]) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => fn.apply(this, args), ms); + }; + }; + + function fetchMetadata() { + fetchCOVIDcastMeta(form_key).then((res) => { + if (res.length == 0) { + valid_key = false; + } else { + valid_key = true; + api_key = form_key; // API key is valid -> use it to fetch data later on + geoTypes = [...new Set(res.map((d) => d.geo_type))]; + const byDataSource = new Map(); + for (const row of res) { + const ds = byDataSource.get(row.data_source); + if (!ds) { + byDataSource.set(row.data_source, { + label: row.data_source, + value: row.data_source, + signals: [row.signal], + }); + } else if (!ds.signals.includes(row.signal)) { + ds.signals.push(row.signal); + } } + byDataSource.forEach((entry) => { + entry.signals.sort(); + }); + dataSources = [...byDataSource.values()].sort((a, b) => a.value.localeCompare(b.value)); } - byDataSource.forEach((entry) => { - entry.signals.sort(); - }); - dataSources = [...byDataSource.values()].sort((a, b) => a.value.localeCompare(b.value)); }); + } + + onMount(() => { + fetchMetadata(); }); export function importDataSet() { - return fetchCOVIDcastMeta().then((res) => { + return fetchCOVIDcastMeta(api_key).then((res) => { const meta = res.filter((row) => row.data_source === data_source && row.signal === signal); const time_type = meta[0].time_type; - return importCOVIDcast({ data_source, signal, geo_type, geo_value, time_type }); + return importCOVIDcast({ data_source, signal, geo_type, geo_value, time_type, api_key }); }); } +
+ +
+ fetchMetadata(), 500)} + /> + {#if !valid_key} +
API key is invalid - ignoring
+ {/if} +
+
@@ -65,3 +107,10 @@ name="geo_values" placeholder="e.g., PA or 42003" /> + +