Repository navigation
Expand file tree
/
Copy pathget.py
More file actions
119 lines (90 loc) · 3.44 KB
/
Copy pathget.py
File metadata and controls
119 lines (90 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from typing import Iterable, Dict, Union, List
from json import dumps
from requests import get
from http import HTTPStatus
StructureType = Dict[str, Union[dict, str]]
FiltersType = Iterable[str]
APIResponseType = Union[List[StructureType], str]
def get_paginated_dataset(filters: FiltersType, structure: StructureType,
as_csv: bool = False) -> APIResponseType:
"""
Extracts paginated data by requesting all of the pages
and combining the results.
Parameters
----------
filters: Iterable[str]
API filters. See the API documentations for additional
information.
structure: Dict[str, Union[dict, str]]
Structure parameter. See the API documentations for
additional information.
as_csv: bool
Return the data as CSV. [default: ``False``]
Returns
-------
Union[List[StructureType], str]
Comprehensive list of dictionaries containing all the data for
the given ``filters`` and ``structure``.
"""
endpoint = "https://api.coronavirus.data.gov.uk/v1/data"
api_params = {
"filters": str.join(";", filters),
"structure": dumps(structure, separators=(",", ":")),
"format": "json" if not as_csv else "csv"
}
data = list()
page_number = 1
while True:
# Adding page number to query params
api_params["page"] = page_number
response = get(endpoint, params=api_params, timeout=10)
if response.status_code >= HTTPStatus.BAD_REQUEST:
raise RuntimeError(f'Request failed: {response.text}')
elif response.status_code == HTTPStatus.NO_CONTENT:
break
if as_csv:
csv_content = response.content.decode()
# Removing CSV header (column names) where page
# number is greater than 1.
if page_number > 1:
data_lines = csv_content.split("\n")[1:]
csv_content = str.join("\n", data_lines)
data.append(csv_content.strip())
page_number += 1
continue
current_data = response.json()
page_data: List[StructureType] = current_data['data']
data.extend(page_data)
# The "next" attribute in "pagination" will be `None`
# when we reach the end.
if current_data["pagination"]["next"] is None:
break
page_number += 1
if not as_csv:
return data
# Concatenating CSV pages
return str.join("\n", data)
if __name__ == "__main__":
query_filters = [
f"areaType=overview"
]
query_structure = {
"date": "date",
#"name": "areaName",
#"code": "areaCode",
"newCases": "newCasesByPublishDate",
"cumulativeCases": "cumCasesByPublishDate",
"newDeaths": "newDeaths28DaysByPublishDate",
"cumulativeDeaths": "cumDeaths28DaysByPublishDate"
}
json_data = get_paginated_dataset(query_filters, query_structure)
print("JSON:")
print(f"Length:", len(json_data))
print("Data (first 3 items):", json_data[:3])
print("---" * 10)
csv_data = get_paginated_dataset(query_filters, query_structure, as_csv=True)
csv_lines = csv_data.split("\n")
print(csv_data)
##print("CSV:")
##print(f"Length:", len(csv_lines))
##print("Data (first 3 lines):", csv_lines[:3])