Skip to content

Commit 8048bc8

Browse files
committed
Merge latest dev changes
2 parents 91dc867 + 2ede365 commit 8048bc8

File tree

2 files changed

+98
-31
lines changed

2 files changed

+98
-31
lines changed

src/api/EpiData.ts

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export function loadDataSet(
118118
fixedParams: Record<string, unknown>,
119119
userParams: Record<string, unknown>,
120120
columns: string[],
121+
api_key = '',
121122
columnRenamings: Record<string, string> = {},
122123
): Promise<DataGroup | null> {
123124
const duplicates = get(expandedDataGroups).filter((d) => d.title == title);
@@ -131,7 +132,11 @@ export function loadDataSet(
131132
)
132133
.then(() => null);
133134
}
134-
const url = new URL(ENDPOINT + `/${endpoint}/`);
135+
let url_string = ENDPOINT + `/${endpoint}/`;
136+
if (api_key !== '') {
137+
url_string += `?api_key=${api_key}`;
138+
}
139+
const url = new URL(url_string);
135140
const params = cleanParams(userParams);
136141
Object.entries(fixedParams).forEach(([key, value]) => {
137142
url.searchParams.set(key, String(value));
@@ -168,10 +173,14 @@ export function loadDataSet(
168173
});
169174
}
170175

171-
export function fetchCOVIDcastMeta(): Promise<
172-
{ geo_type: string; signal: string; data_source: string; time_type?: string }[]
173-
> {
174-
const url = new URL(ENDPOINT + `/covidcast_meta/`);
176+
export function fetchCOVIDcastMeta(
177+
api_key: string,
178+
): Promise<{ geo_type: string; signal: string; data_source: string; time_type?: string }[]> {
179+
let url_string = ENDPOINT + `/covidcast_meta/`;
180+
if (api_key !== '') {
181+
url_string += `?api_key=${api_key}`;
182+
}
183+
const url = new URL(url_string);
175184
url.searchParams.set('format', 'json');
176185
return fetchImpl<{ geo_type: string; signal: string; data_source: string; time_type?: string }[]>(url).catch(
177186
(error) => {
@@ -190,8 +199,9 @@ export function importCDC({ locations, auth }: { locations: string; auth?: strin
190199
{
191200
epiweeks: epiRange(firstEpiWeek.cdc, currentEpiWeek),
192201
},
193-
{ auth, locations },
202+
{ locations },
194203
['total', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8'],
204+
auth,
195205
);
196206
}
197207

@@ -201,12 +211,14 @@ export function importCOVIDcast({
201211
geo_value,
202212
signal,
203213
time_type = 'day',
214+
api_key,
204215
}: {
205216
data_source: string;
206217
signal: string;
207218
time_type?: string;
208219
geo_type: string;
209220
geo_value: string;
221+
api_key: string;
210222
}): Promise<DataGroup | null> {
211223
const title = `[API] COVIDcast: ${data_source}:${signal} (${geo_type}:${geo_value})`;
212224
return loadDataSet(
@@ -221,6 +233,7 @@ export function importCOVIDcast({
221233
},
222234
{ data_source, signal, time_type, geo_type, geo_value },
223235
['value', 'stderr', 'sample_size'],
236+
api_key,
224237
);
225238
}
226239

@@ -343,7 +356,7 @@ export function importFluView({
343356
{
344357
epiweeks: epiRange(firstEpiWeek.fluview, currentEpiWeek),
345358
},
346-
{ regions, issues, lag, auth },
359+
{ regions, issues, lag },
347360
[
348361
'wili',
349362
'ili',
@@ -357,6 +370,7 @@ export function importFluView({
357370
'num_age_4',
358371
'num_age_5',
359372
],
373+
auth,
360374
{
361375
wili: '%wILI',
362376
ili: '%ILI',
@@ -395,8 +409,9 @@ export function importGHT({
395409
{
396410
epiweeks: epiRange(firstEpiWeek.ght, currentEpiWeek),
397411
},
398-
{ auth, locations, query },
412+
{ locations, query },
399413
['value'],
414+
auth,
400415
);
401416
}
402417

@@ -456,8 +471,9 @@ export function importQuidel({ auth, locations }: { auth: string; locations: str
456471
{
457472
epiweeks: epiRange(firstEpiWeek.quidel, currentEpiWeek),
458473
},
459-
{ auth, locations },
474+
{ locations },
460475
['value'],
476+
auth,
461477
);
462478
}
463479
export function importSensors({
@@ -478,8 +494,9 @@ export function importSensors({
478494
{
479495
epiweeks: epiRange(firstEpiWeek.sensors, currentEpiWeek),
480496
},
481-
{ auth, names, locations },
497+
{ names, locations },
482498
['value'],
499+
auth,
483500
);
484501
}
485502
// twtr
@@ -504,8 +521,9 @@ export function importTwitter({
504521
: {
505522
epiweeks: epiRange(firstEpiWeek.twitter, currentEpiWeek),
506523
},
507-
{ auth, locations, resolution },
524+
{ locations, resolution },
508525
['num', 'total', 'percent'],
526+
auth,
509527
);
510528
}
511529
export function importWiki({

src/components/dialogs/dataSources/COVIDcast.svelte

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
99
export let id: string;
1010
11+
let api_key = '';
1112
let data_source = $formSelections.covidcast.dataSource;
1213
let signal = $formSelections.covidcast.signal;
1314
let geo_type = $formSelections.covidcast.geoType;
1415
let geo_value = $formSelections.covidcast.geoValue;
16+
let form_key = '';
17+
let valid_key = true;
1518
1619
let dataSources: (LabelValue & { signals: string[] })[] = [];
1720
let geoTypes: string[] = [];
@@ -25,38 +28,77 @@
2528
}
2629
}
2730
28-
onMount(() => {
29-
fetchCOVIDcastMeta().then((res) => {
30-
geoTypes = [...new Set(res.map((d) => d.geo_type))];
31-
const byDataSource = new Map<string, LabelValue & { signals: string[] }>();
32-
for (const row of res) {
33-
const ds = byDataSource.get(row.data_source);
34-
if (!ds) {
35-
byDataSource.set(row.data_source, {
36-
label: row.data_source,
37-
value: row.data_source,
38-
signals: [row.signal],
39-
});
40-
} else if (!ds.signals.includes(row.signal)) {
41-
ds.signals.push(row.signal);
31+
// Helper function; delay invoking "fn" until "ms" milliseconds have passed
32+
const debounce = (fn: Function, ms = 500) => {
33+
let timeoutId: ReturnType<typeof setTimeout>;
34+
return function (this: any, ...args: any[]) {
35+
clearTimeout(timeoutId);
36+
timeoutId = setTimeout(() => fn.apply(this, args), ms);
37+
};
38+
};
39+
40+
function fetchMetadata() {
41+
fetchCOVIDcastMeta(form_key).then((res) => {
42+
if (res.length == 0) {
43+
valid_key = false;
44+
} else {
45+
valid_key = true;
46+
api_key = form_key; // API key is valid -> use it to fetch data later on
47+
geoTypes = [...new Set(res.map((d) => d.geo_type))];
48+
const byDataSource = new Map<string, LabelValue & { signals: string[] }>();
49+
for (const row of res) {
50+
const ds = byDataSource.get(row.data_source);
51+
if (!ds) {
52+
byDataSource.set(row.data_source, {
53+
label: row.data_source,
54+
value: row.data_source,
55+
signals: [row.signal],
56+
});
57+
} else if (!ds.signals.includes(row.signal)) {
58+
ds.signals.push(row.signal);
59+
}
4260
}
61+
byDataSource.forEach((entry) => {
62+
entry.signals.sort();
63+
});
64+
dataSources = [...byDataSource.values()].sort((a, b) => a.value.localeCompare(b.value));
4365
}
44-
byDataSource.forEach((entry) => {
45-
entry.signals.sort();
46-
});
47-
dataSources = [...byDataSource.values()].sort((a, b) => a.value.localeCompare(b.value));
4866
});
67+
}
68+
69+
onMount(() => {
70+
fetchMetadata();
4971
});
5072
5173
export function importDataSet() {
52-
return fetchCOVIDcastMeta().then((res) => {
74+
return fetchCOVIDcastMeta(api_key).then((res) => {
5375
const meta = res.filter((row) => row.data_source === data_source && row.signal === signal);
5476
const time_type = meta[0].time_type;
55-
return importCOVIDcast({ data_source, signal, geo_type, geo_value, time_type });
77+
return importCOVIDcast({ data_source, signal, geo_type, geo_value, time_type, api_key });
5678
});
5779
}
5880
</script>
5981

82+
<div>
83+
<label class="uk-form-label" for="{id}-apikey">
84+
<a href="https://cmu-delphi.github.io/delphi-epidata/api/api_keys.html">API Key</a> (optional)
85+
</label>
86+
<div class="uk-form-controls">
87+
<input
88+
id="{id}-apikey"
89+
type="text"
90+
class="uk-input"
91+
class:uk-form-danger={!valid_key}
92+
name="api_key"
93+
required={false}
94+
bind:value={form_key}
95+
on:input={debounce(() => fetchMetadata(), 500)}
96+
/>
97+
{#if !valid_key}
98+
<div class="invalid">API key is invalid - ignoring</div>
99+
{/if}
100+
</div>
101+
</div>
60102
<SelectField
61103
id="{id}-r"
62104
label="Data Source"
@@ -85,3 +127,10 @@
85127
name="geo_values"
86128
placeholder="e.g., PA or 42003"
87129
/>
130+
131+
<style>
132+
.invalid {
133+
color: red;
134+
font-size: 0.75rem;
135+
}
136+
</style>

0 commit comments

Comments
 (0)