Exemplo n.º 1
0
    def __init__(self) -> None:
        """ Initiate DataFrames """
        self.df = get_data_daily_reports()
        self.df_time_series = get_data_time_series()
        self.df_US_time_series = get_US_time_series()
        self.lookup_table = get_data_lookup_table()

        concerned_columns = ['Confirmed', 'Deaths', 'Recovered', 'Active']
        self.df_grp_by_country = self.df.groupby(
            'Country_Region')[concerned_columns].sum()
        self.df_grp_by_country[concerned_columns] = self.df_grp_by_country[
            concerned_columns].astype(int)

        self.datetime = max(self.df['Last_Update'].tolist())
        self.timestamp = datetime.strptime(self.datetime,
                                           '%Y-%m-%d %H:%M:%S').timestamp()

        self.scheme = {'data': None, 'dt': self.datetime, 'ts': self.timestamp}
Exemplo n.º 2
0
class CovidAPIv2:
    """ Covid-19 API v2 model and its methods
        SCHEMA: {
            "data": Any,
            "dt": str = "{datetime}",
            "ts": int = "{timestamp}
        }
    """
    def __init__(self) -> None:
        """ Initiate DataFrames """
        self.lookup_table = get_data_lookup_table()
        self.scheme = {'data': None, 'dt': None, 'ts': None}

    def wrap_data(func) -> Dict[str, Any]:
        """ Wrap a result in a schemed data """
        @wraps(func)
        def wrapper(self, *args, **kwargs) -> Dict[str, Any]:
            packed_data = self.scheme
            packed_data['data'] = []
            try:
                packed_data['data'] = func(self, *args, **kwargs)
            except Exception as e:
                print(e)
            finally:
                time_format = '%m-%d-%Y'
                packed_data['dt'] = datetime.utcnow().strftime(time_format)
                packed_data['ts'] = datetime.strptime(packed_data['dt'],
                                                      time_format).timestamp()
            return packed_data

        return wrapper

    @wrap_data
    def get_current(self) -> Dict[str, Any]:
        """ Current data from all locations (Lastest date) """
        concerned_columns = ['Confirmed', 'Deaths', 'Recovered', 'Active']
        self.df = get_data_daily_reports()  # Get base data
        self.df_grp_by_country = self.df.groupby(
            'Country_Region')[concerned_columns].sum()
        self.df_grp_by_country[concerned_columns] = self.df_grp_by_country[
            concerned_columns].astype(int)

        df_grp_by_country = self.df_grp_by_country.sort_values(by='Confirmed',
                                                               ascending=False)
        df_grp_by_country = df_grp_by_country.reset_index()
        df_grp_by_country.columns = [
            'location', 'confirmed', 'deaths', 'recovered', 'active'
        ]

        data = [v for v in df_grp_by_country.to_dict('index').values()]

        return data

    @wrap_data
    def get_current_US(self) -> Dict[str, Any]:
        """ Get current data for USA's situation """
        self.df_US = get_data_daily_reports_us()  # Get base data

        concerned_columns = [
            'Confirmed', 'Deaths', 'Recovered', 'Active', 'People_Tested',
            'People_Hospitalized'
        ]
        df = self.df_US.groupby([
            'Province_State'
        ])[concerned_columns].sum().sort_values(by='Confirmed',
                                                ascending=False)
        df = df[concerned_columns].astype(int)
        df = df.reset_index()
        df.columns = ['Province_State'] + concerned_columns

        data = [v for v in df.to_dict('index').values()]

        return data

    @wrap_data
    def get_country(self, country_name: str) -> Dict[str, Any]:
        """ Get a country data from its name or ISO 2 """
        all_country_data = self.get_current()['data']

        # Check input
        if not isinstance(country_name, str) or not country_name.isalpha():
            return {}

        # Search for a given country
        country_name = country_name.lower()
        country_name_from_code = self.lookup_table.get(country_name.upper(),
                                                       '').lower()

        data = [
            country_data for country_data in all_country_data
            if country_data['location'].lower() in
            [country_name, country_name_from_code]
        ]
        data = data[0] if data else {}

        return data

    @wrap_data
    def get_confirmed(self) -> Dict[str, Any]:
        """ Summation of all confirmed cases """
        self.df = get_data_daily_reports()  # Get base data
        data = int(self.df['Confirmed'].sum())

        return data

    @wrap_data
    def get_deaths(self) -> Dict[str, Any]:
        """ Summation of all deaths """
        self.df = get_data_daily_reports()  # Get base data
        data = int(self.df['Deaths'].sum())

        return data

    @wrap_data
    def get_recovered(self) -> Dict[str, Any]:
        """ Summation of all recovers """
        self.df = get_data_daily_reports()  # Get base data
        data = int(self.df['Recovered'].sum())

        return data

    @wrap_data
    def get_active(self) -> Dict[str, Any]:
        """ Summation of all actives """
        self.df = get_data_daily_reports()  # Get base data
        data = int(self.df['Active'].sum())

        return data

    @wrap_data
    def get_total(self) -> Dict[str, Any]:
        """ Summation of Confirmed, Deaths, Recovered, Active """
        self.df = get_data_daily_reports()  # Get base data
        data = {
            'confirmed': int(self.df['Confirmed'].sum()),
            'deaths': int(self.df['Deaths'].sum()),
            'recovered': int(self.df['Recovered'].sum()),
            'active': int(self.df['Active'].sum())
        }

        return data

    def __extract_time_series(self, time_series: Dict) -> List[Dict]:
        """ Extract time series from a given case """
        def __unpack_inner_time_series(
                time_series: Dict[str, Any]) -> Dict[str, Any]:
            for data in time_series.values():
                excluded_cols = [
                    'Province/State', 'Country/Region', 'Lat', 'Long'
                ]
                temp_dict = {}
                temp_dict['Province/State'] = data['Province/State']
                temp_dict['Country/Region'] = data['Country/Region']
                temp_dict['Coordinates'] = {
                    'Lat': float(data['Lat']),
                    'Long': float(data['Long'])
                }

                temp_time_series_dict = {
                    k: int(v)
                    for k, v in data.items() if k not in excluded_cols
                }
                temp_dict['TimeSeries'] = [{
                    'date': k,
                    'value': v
                } for k, v in temp_time_series_dict.items()]

                yield temp_dict

        # Extract the time series data
        time_series_data = []
        for data in __unpack_inner_time_series(time_series):
            time_series_data.append(data)

        return time_series_data

    def __extract_US_time_series(self, time_series: Dict[str,
                                                         Any]) -> List[Dict]:
        """ Extract USA time series """
        def __unpack_US_inner_time_series(
                time_series: Dict[str, Any]) -> Dict[str, Any]:
            for data in time_series.values():
                excluded_cols = [
                    'UID', 'iso2', 'iso3', 'code3', 'FIPS', 'Admin2',
                    'Province_State', 'Country_Region', 'Lat', 'Long_',
                    'Combined_Key', 'Population'
                ]
                temp_dict = {}
                temp_dict['Province_State'] = data['Province_State']
                temp_dict['Country_Region'] = data['Country_Region']
                temp_dict['Info'] = {
                    'UID': data['UID'],
                    'iso2': data['iso2'],
                    'iso3': data['iso3'],
                    'code3': data['code3'],
                    'FIPS': data['FIPS'],
                    'Admin2': data['Admin2']
                }
                temp_dict['Coordinates'] = {
                    'Lat': float(data['Lat']),
                    'Long': float(data['Long_'])
                }

                temp_time_series_dict = {
                    k: int(v)
                    for k, v in data.items() if k not in excluded_cols
                }
                temp_dict['TimeSeries'] = [{
                    'date': k,
                    'value': v
                } for k, v in temp_time_series_dict.items()]

                yield temp_dict

        # Extract the time series data
        time_series_data = []
        for data in __unpack_US_inner_time_series(time_series):
            time_series_data.append(data)

        return time_series_data

    def __extract_time_series_global(
            self, dataframe_dict: Dict[str, pd.DataFrame]) -> List[Dict]:
        """ Extract time series for global case
            Iterating all cases from all time series
        """
        global_df_list = []

        for key, df in dataframe_dict.items():
            df_temp = pd.DataFrame(
                df.iloc[:, 4:].astype('int32').sum(axis=0)
            )  # Slice to select time series data (exclude country info)
            df_temp.columns = [
                key
            ]  # A dataframe with one column named by a key (case), rows are time series
            global_df_list.append(df_temp)

        # Combine DataFrames
        global_dict = pd.concat(global_df_list, axis=1, sort=False).T.to_dict()
        data = [{k: v} for k, v in global_dict.items()]

        return data

    @wrap_data
    def get_time_series(self, case: str) -> Dict[str, Any]:
        """ Get time series data from a given case
            1.) global
            2.) confirmed, deaths, recovered
        """
        self.df_time_series = get_data_time_series()  # Get base data

        if case not in ['global']:
            raw_data = self.df_time_series[case].T.to_dict()
            data = self.__extract_time_series(raw_data)
        else:
            raw_data = self.df_time_series
            data = self.__extract_time_series_global(raw_data)

        return data
class CovidAPIv2Integrator:
    """ Covid-19 API v2 methods
        SCHEMA: {
            "data": Any,
            "dt": str = "{datetime}",
            "ts": int = "{timestamp}
        }
    """
    def __init__(self) -> None:
        """ Initiate DataFrames """
        self.lookup_table = get_data_lookup_table()
        self.scheme = {
            'data': None,
            'dt': None,
            'ts': None
        }
    
    def wrap_data(func) -> ResponseModel:
        """ Wrap a result in a schemed data """
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            packed_data = self.scheme
            packed_data['data'] = []
            try:
                packed_data['data'] = func(self, *args, **kwargs)
            except Exception as e:
                print(e)
            finally:
                time_format = '%m-%d-%Y'
                packed_data['dt'] = datetime.utcnow().strftime(time_format)
                packed_data['ts'] = datetime.strptime(packed_data['dt'], time_format).timestamp()
                reponse_model = ResponseModel(**packed_data)
            return reponse_model
        return wrapper
    
    #######################################################################################
    # GET - Current
    #######################################################################################
    @wrap_data
    def get_current(self) -> List[CurrentModel]:
        """ Current data from all locations (Lastest date) """
        concerned_columns = ['Confirmed', 'Deaths', 'Recovered', 'Active']
        self.df = get_data_daily_reports() # Get base data
        self.df_grp_by_country = self.df.groupby('Country_Region')[concerned_columns].sum()
        self.df_grp_by_country[concerned_columns] = self.df_grp_by_country[concerned_columns].astype(int)

        df_grp_by_country = self.df_grp_by_country.sort_values(by='Confirmed', ascending=False)
        df_grp_by_country = df_grp_by_country.reset_index()
        df_grp_by_country.columns = ['location', 'confirmed', 'deaths', 'recovered', 'active']

        data = [CurrentModel(**v) for v in df_grp_by_country.to_dict('index').values()]

        return data
    
    #######################################################################################
    # GET - Current US
    #######################################################################################
    @wrap_data
    def get_current_US(self) -> List[CurrentUSModel]:
        """ Get current data for USA's situation """
        self.df_US = get_data_daily_reports_us() # Get base data

        concerned_columns = ['Confirmed', 'Deaths', 'Recovered', 'Active']
        df = self.df_US.groupby(['Province_State'])[concerned_columns].sum().sort_values(by='Confirmed', ascending=False)
        df = df[concerned_columns].astype(int)
        df = df.reset_index()
        df.columns = ['Province_State'] + concerned_columns

        data = [CurrentUSModel(**v) for v in df.to_dict('index').values()]

        return data
    
    #######################################################################################
    # GET - Country
    #######################################################################################
    @wrap_data
    def get_country(self, country_name: str) -> Dict[str, Any]:
        """ Get a country data from its name or ISO 2 """
        all_country_data = self.get_current().data

        # Check input
        if not isinstance(country_name, str) or not country_name.isalpha():
            return {}

        # Search for a given country
        country_name = country_name.lower()
        country_name_from_code = self.lookup_table.get(country_name.upper(), '').lower()

        data = [country_data for country_data in all_country_data if country_data.location.lower() in [country_name, country_name_from_code]]
        data = data[0] if data else {}

        return data
    
    #######################################################################################
    # GET - Confirm
    #######################################################################################
    @wrap_data
    def get_confirmed(self) -> ConfirmedModel:
        """ Summation of all confirmed cases """
        self.df = get_data_daily_reports() # Get base data
        data = ConfirmedModel(
            confirmed=int(self.df['Confirmed'].sum())
        )
        return data

    #######################################################################################
    # GET - Deaths
    #######################################################################################
    @wrap_data
    def get_deaths(self) -> DeathsModel:
        """ Summation of all deaths """
        self.df = get_data_daily_reports() # Get base data
        data = DeathsModel(
            deaths=int(self.df['Deaths'].sum())
        )
        return data
    
    #######################################################################################
    # GET - Recovered
    #######################################################################################
    @wrap_data
    def get_recovered(self) -> RecoveredModel:
        """ Summation of all recovers """
        self.df = get_data_daily_reports() # Get base data
        data = RecoveredModel(
            recovered=int(self.df['Recovered'].sum())
        )
        return data
    
    #######################################################################################
    # GET - Active
    #######################################################################################
    @wrap_data
    def get_active(self) -> ActiveModel:
        """ Summation of all actives """
        self.df = get_data_daily_reports() # Get base data
        data = ActiveModel(
            active=int(self.df['Active'].sum())
        )
        return data
    
    #######################################################################################
    # GET - Total
    #######################################################################################
    @wrap_data
    def get_total(self) -> TotalModel:
        """ Summation of Confirmed, Deaths, Recovered, Active """
        self.df = get_data_daily_reports() # Get base data
        data = TotalModel(
            confirmed=int(self.df['Confirmed'].sum()),
            deaths=int(self.df['Deaths'].sum()),
            recovered=int(self.df['Recovered'].sum()),
            active=int(self.df['Active'].sum())
        )
        return data
    
    #######################################################################################
    # GET - Timeseries
    #######################################################################################
    @wrap_data
    def get_time_series(self, case: str) -> List[Any]:
        """ Get time series data from a given case
            1.) global
            2.) confirmed, deaths, recovered
        """
        self.df_time_series = get_data_time_series() # Get base data

        if case not in ['global']:
            raw_data = self.df_time_series[case].T.to_dict()
            data = self.__extract_time_series(raw_data)
        else:
            raw_data = self.df_time_series
            data = self.__extract_time_series_global(raw_data)

        return data