55from dataclasses import Field , InitVar , asdict , dataclass , field , fields
66from functools import cached_property
77from typing import (
8+ TYPE_CHECKING ,
89 Any ,
9- Generic ,
1010 Literal ,
1111 get_args ,
1212 overload ,
1515from pandas import DataFrame
1616
1717from ._model import (
18- CALL_TYPE ,
1918 EpidataFieldInfo ,
2019 EpidataFieldType ,
2120 EpiRangeParam ,
2423 TimeType ,
2524)
2625
26+ if TYPE_CHECKING :
27+ from .request import EpiDataCall
28+
2729
2830@dataclass
2931class WebLink :
@@ -73,10 +75,10 @@ def define_covidcast_fields() -> list[EpidataFieldInfo]:
7375
7476
7577@dataclass
76- class DataSignal ( Generic [ CALL_TYPE ]) :
78+ class DataSignal :
7779 """represents a COVIDcast data signal"""
7880
79- _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], CALL_TYPE ]
81+ _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], EpiDataCall ]
8082
8183 source : str
8284 signal : str
@@ -150,7 +152,7 @@ def call(
150152 as_of : None | str | int = None ,
151153 issues : EpiRangeParam | None = None ,
152154 lag : int | None = None ,
153- ) -> CALL_TYPE :
155+ ) -> EpiDataCall :
154156 """Fetch Delphi's COVID-19 Surveillance Streams"""
155157 if any (v is None for v in (geo_type , geo_values , time_values )):
156158 raise InvalidArgumentException ("`geo_type`, `time_values`, and `geo_values` are all required" )
@@ -179,16 +181,16 @@ def __call__(
179181 as_of : None | str | int = None ,
180182 issues : EpiRangeParam | None = None ,
181183 lag : int | None = None ,
182- ) -> CALL_TYPE :
184+ ) -> EpiDataCall :
183185 """Fetch Delphi's COVID-19 Surveillance Streams"""
184186 return self .call (geo_type , geo_values , time_values , as_of , issues , lag )
185187
186188
187189@dataclass
188- class DataSource ( Generic [ CALL_TYPE ]) :
190+ class DataSource :
189191 """represents a COVIDcast data source"""
190192
191- _create_call : InitVar [Callable [[Mapping [str , EpiRangeParam | None ]], CALL_TYPE ]]
193+ _create_call : InitVar [Callable [[Mapping [str , EpiRangeParam | None ]], EpiDataCall ]]
192194
193195 source : str
194196 db_source : str
@@ -201,7 +203,7 @@ class DataSource(Generic[CALL_TYPE]):
201203
202204 signals : Sequence [DataSignal ] = field (default_factory = list )
203205
204- def __post_init__ (self , _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], CALL_TYPE ]) -> None :
206+ def __post_init__ (self , _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], EpiDataCall ]) -> None :
205207 self .link = [
206208 WebLink (alt = link ["alt" ], href = link ["href" ]) if isinstance (link , dict ) else link for link in self .link
207209 ]
@@ -236,16 +238,14 @@ def signal_df(self) -> DataFrame:
236238
237239
238240@dataclass
239- class CovidcastDataSources ( Generic [ CALL_TYPE ]) :
241+ class CovidcastDataSources :
240242 """COVIDcast data source helper."""
241243
242- sources : Sequence [DataSource [CALL_TYPE ]]
243- _source_by_name : dict [str , DataSource [CALL_TYPE ]] = field (init = False , default_factory = dict )
244- _signals_by_key : OrderedDict [tuple [str , str ], DataSignal [CALL_TYPE ]] = field (
245- init = False , default_factory = OrderedDict
246- )
244+ sources : Sequence [DataSource ]
245+ _source_by_name : dict [str , DataSource ] = field (init = False , default_factory = dict )
246+ _signals_by_key : OrderedDict [tuple [str , str ], DataSignal ] = field (init = False , default_factory = OrderedDict )
247247
248- _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], CALL_TYPE ]
248+ _create_call : Callable [[Mapping [str , EpiRangeParam | None ]], EpiDataCall ]
249249
250250 def __post_init__ (self ) -> None :
251251 self ._source_by_name = {s .source : s for s in self .sources }
@@ -373,12 +373,12 @@ def signal_df(self) -> DataFrame:
373373 return DataSignal .to_df (self ._signals_by_key .values ())
374374
375375 @overload
376- def __getitem__ (self , source : str , / ) -> DataSource [ CALL_TYPE ] : ...
376+ def __getitem__ (self , source : str , / ) -> DataSource : ...
377377
378378 @overload
379- def __getitem__ (self , source_signal : tuple [str , str ], / ) -> DataSignal [ CALL_TYPE ] : ...
379+ def __getitem__ (self , source_signal : tuple [str , str ], / ) -> DataSignal : ...
380380
381- def __getitem__ (self , source_signal : str | tuple [str , str ]) -> DataSource [ CALL_TYPE ] | DataSignal [ CALL_TYPE ] :
381+ def __getitem__ (self , source_signal : str | tuple [str , str ]) -> DataSource | DataSignal :
382382 if isinstance (source_signal , str ):
383383 r = self ._source_by_name .get (source_signal )
384384 assert r is not None
@@ -390,7 +390,7 @@ def __getitem__(self, source_signal: str | tuple[str, str]) -> DataSource[CALL_T
390390 @staticmethod
391391 def create (
392392 meta : list [dict ],
393- create_call : Callable [[Mapping [str , EpiRangeParam | None ]], CALL_TYPE ],
393+ create_call : Callable [[Mapping [str , EpiRangeParam | None ]], EpiDataCall ],
394394 ) -> CovidcastDataSources :
395395 source_fields = fields (DataSource )
396396 sources = [DataSource (_create_call = create_call , ** _limit_fields (k , source_fields )) for k in meta ]
0 commit comments