Skip to content

Commit 601a634

Browse files
committed
refactor: async is gone, consolidate df code
1 parent ea7c9e4 commit 601a634

File tree

2 files changed

+35
-43
lines changed

2 files changed

+35
-43
lines changed

epidatpy/_model.py

-40
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
from datetime import date
33
from enum import Enum
44
from typing import (
5-
Any,
6-
Dict,
75
Final,
86
List,
97
Mapping,
@@ -18,10 +16,8 @@
1816
from urllib.parse import urlencode
1917

2018
from epiweeks import Week
21-
from pandas import CategoricalDtype, DataFrame, Series
2219

2320
from ._parse import (
24-
fields_to_predicate,
2521
parse_api_date,
2622
parse_api_date_or_week,
2723
parse_api_week,
@@ -257,39 +253,3 @@ def _parse_row(
257253
if not self.meta:
258254
return row
259255
return {k: self._parse_value(k, v, disable_date_parsing) for k, v in row.items()}
260-
261-
def _as_df(
262-
self,
263-
rows: Sequence[Mapping[str, Union[str, float, int, date, None]]],
264-
fields: Optional[Sequence[str]] = None,
265-
disable_date_parsing: Optional[bool] = False,
266-
) -> DataFrame:
267-
pred = fields_to_predicate(fields)
268-
columns: List[str] = [info.name for info in self.meta if pred(info.name)]
269-
df = DataFrame(rows, columns=columns or None)
270-
271-
data_types: Dict[str, Any] = {}
272-
for info in self.meta:
273-
if not pred(info.name) or df[info.name].isnull().all():
274-
continue
275-
if info.type == EpidataFieldType.bool:
276-
data_types[info.name] = bool
277-
elif info.type == EpidataFieldType.categorical:
278-
data_types[info.name] = CategoricalDtype(
279-
categories=Series(info.categories) if info.categories else None, ordered=True
280-
)
281-
elif info.type == EpidataFieldType.int:
282-
data_types[info.name] = int
283-
elif info.type in (
284-
EpidataFieldType.date,
285-
EpidataFieldType.epiweek,
286-
EpidataFieldType.date_or_epiweek,
287-
):
288-
data_types[info.name] = int if disable_date_parsing else "datetime64[ns]"
289-
elif info.type == EpidataFieldType.float:
290-
data_types[info.name] = float
291-
else:
292-
data_types[info.name] = str
293-
if data_types:
294-
df = df.astype(data_types)
295-
return df

epidatpy/request.py

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from datetime import date
22
from typing import (
3+
Any,
4+
Dict,
35
Final,
46
List,
57
Mapping,
@@ -9,7 +11,7 @@
911
cast,
1012
)
1113

12-
from pandas import DataFrame
14+
from pandas import CategoricalDtype, DataFrame, Series
1315
from requests import Response, Session
1416
from requests.auth import HTTPBasicAuth
1517
from tenacity import retry, stop_after_attempt
@@ -21,13 +23,15 @@
2123
from ._model import (
2224
AEpiDataCall,
2325
EpidataFieldInfo,
26+
EpidataFieldType,
2427
EpiDataFormatType,
2528
EpiDataResponse,
2629
EpiRange,
2730
EpiRangeParam,
2831
OnlySupportsClassicFormatException,
2932
add_endpoint_to_url,
3033
)
34+
from ._parse import fields_to_predicate
3135

3236
# Make the linter happy about the unused variables
3337
__all__ = ["Epidata", "EpiDataCall", "EpiDataContext", "EpiRange", "CovidcastEpidata"]
@@ -140,8 +144,36 @@ def df(
140144
if self.only_supports_classic:
141145
raise OnlySupportsClassicFormatException()
142146
self._verify_parameters()
143-
r = self.json(fields, disable_date_parsing=disable_date_parsing)
144-
return self._as_df(r, fields, disable_date_parsing=disable_date_parsing)
147+
rows = self.json(fields, disable_date_parsing=disable_date_parsing)
148+
pred = fields_to_predicate(fields)
149+
columns: List[str] = [info.name for info in self.meta if pred(info.name)]
150+
df = DataFrame(rows, columns=columns or None)
151+
152+
data_types: Dict[str, Any] = {}
153+
for info in self.meta:
154+
if not pred(info.name) or df[info.name].isnull().all():
155+
continue
156+
if info.type == EpidataFieldType.bool:
157+
data_types[info.name] = bool
158+
elif info.type == EpidataFieldType.categorical:
159+
data_types[info.name] = CategoricalDtype(
160+
categories=Series(info.categories) if info.categories else None, ordered=True
161+
)
162+
elif info.type == EpidataFieldType.int:
163+
data_types[info.name] = "Int64"
164+
elif info.type in (
165+
EpidataFieldType.date,
166+
EpidataFieldType.epiweek,
167+
EpidataFieldType.date_or_epiweek,
168+
):
169+
data_types[info.name] = "Int64" if disable_date_parsing else "datetime64[ns]"
170+
elif info.type == EpidataFieldType.float:
171+
data_types[info.name] = "Float64"
172+
else:
173+
data_types[info.name] = "string"
174+
if data_types:
175+
df = df.astype(data_types)
176+
return df
145177

146178

147179
class EpiDataContext(AEpiDataEndpoints[EpiDataCall]):

0 commit comments

Comments
 (0)