Ejemplo n.º 1
0
    def from_dict(cls, the_dict: dict):
        """
        Parses a *OneCall* instance out of a data dictionary. Only certain properties of the data dictionary
        are used: if these properties are not found or cannot be parsed, an exception is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a *OneCall* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the input dict embeds an HTTP status error

        """

        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')

        # Check if server returned errors: this check overcomes the lack of use
        # of HTTP error status codes by the OWM API 2.5. This mechanism is
        # supposed to be deprecated as soon as the API fully adopts HTTP for
        # conveying errors to the clients
        if 'message' in the_dict and 'cod' in the_dict:
            if the_dict['cod'] == "404":
                return None
            elif the_dict['cod'] == "429":
                raise exceptions.APIResponseError(
                    "OWM API: error - Exceeded call limit", the_dict['cod'])
            else:
                raise exceptions.APIResponseError(
                    "OWM API: error - response payload", the_dict['cod'])

        try:
            current = Weather.from_dict(the_dict["current"])
            minutely = None
            if "minutely" in the_dict:
                minutely = [
                    Weather.from_dict(item) for item in the_dict["minutely"]
                ]
            hourly = None
            if "hourly" in the_dict:
                hourly = [
                    Weather.from_dict(item) for item in the_dict["hourly"]
                ]
            daily = None
            if "daily" in the_dict:
                daily = [Weather.from_dict(item) for item in the_dict["daily"]]

        except KeyError:
            raise exceptions.ParseAPIResponseError(
                f"{__name__}: impossible to read weather info from input data")

        return OneCall(lat=the_dict.get("lat", None),
                       lon=the_dict.get("lon", None),
                       timezone=the_dict.get("timezone", None),
                       current=current,
                       forecast_minutely=minutely,
                       forecast_hourly=hourly,
                       forecast_daily=daily)
Ejemplo n.º 2
0
    def from_dict(cls, the_dict):
        """
        Parses a *Forecast* instance out of a raw data dictionary. Only certain properties of the data are used: if
        these properties are not found or cannot be parsed, an error is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a *Forecast* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the input dictionary embeds an HTTP status error

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('JSON data is None')
        # Check if server returned errors: this check overcomes the lack of use
        # of HTTP error status codes by the OWM API 2.5. This mechanism is
        # supposed to be deprecated as soon as the API fully adopts HTTP for
        # conveying errors to the clients
        if 'message' in the_dict and 'cod' in the_dict:
            if the_dict['cod'] == "404":
                print("OWM API: data not found - response payload",
                      the_dict['cod'])
                return None
            elif the_dict['cod'] != "200":
                raise exceptions.APIResponseError(
                    "OWM API: error - response payload", the_dict['cod'])
        try:
            place = location.Location.from_dict(the_dict)
        except KeyError:
            raise exceptions.ParseAPIResponseError(''.join([
                __name__, ': impossible to read location info from JSON data'
            ]))
        # Handle the case when no results are found
        if 'count' in the_dict and the_dict['count'] == "0":
            weathers = []
        elif 'cnt' in the_dict and the_dict['cnt'] == 0:
            weathers = []
        else:
            if 'list' in the_dict:
                try:
                    weathers = [weather.Weather.from_dict(item) \
                                for item in the_dict['list']]
                except KeyError:
                    raise exceptions.ParseAPIResponseError(''.join([
                        __name__,
                        ': impossible to read weather info from JSON data'
                    ]))
            else:
                raise exceptions.ParseAPIResponseError(''.join([
                    __name__,
                    ': impossible to read weather list from JSON data'
                ]))
        current_time = int(time.time())
        return Forecast(None, current_time, place, weathers)
Ejemplo n.º 3
0
    def from_dict_of_lists(cls, the_dict):
        """
        Parses a list of *Weather* instances out of an input dict. Only certain properties of the data are used: if
        these properties are not found or cannot be parsed, an error is issued.

        :param the_dict: the input dict
        :type the_dict: dict
        :returns: a list of *Weather* instances or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the data needed to build the result,
            *APIResponseError* if the input dict an HTTP status error

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        # Check if server returned errors: this check overcomes the lack of use
        # of HTTP error status codes by the OWM API 2.5. This mechanism is
        # supposed to be deprecated as soon as the API fully adopts HTTP for
        # conveying errors to the clients
        if 'message' in the_dict and 'cod' in the_dict:
            if the_dict['cod'] == "404":
                print("OWM API: data not found - response payload: " + \
                      json.dumps(the_dict))
                return None
            elif the_dict['cod'] != "200":
                raise exceptions.APIResponseError(
                    "OWM API: error - response payload: " +
                    json.dumps(the_dict), the_dict['cod'])
        # Handle the case when no results are found
        if 'cnt' in the_dict and the_dict['cnt'] == "0":
            return []
        else:
            if 'list' in the_dict:
                try:
                    return [
                        Weather.from_dict(item) for item in the_dict['list']
                    ]
                except KeyError:
                    raise exceptions.ParseAPIResponseError(''.join([
                        __name__,
                        ': impossible to read weather info from input data'
                    ]))
            else:
                raise exceptions.ParseAPIResponseError(''.join([
                    __name__,
                    ': impossible to read weather list from input data'
                ]))
    def from_dict_of_lists(self, the_dict):
        """
        Parses a list of *Observation* instances out of raw input dict containing a list. Only certain properties of
        the data are used: if these properties are not found or cannot be parsed, an error is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a `list` of *Observation* instances or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the OWM API returns an HTTP status error

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('JSON data is None')
        if 'cod' in the_dict:
            # Check if server returned errors: this check overcomes the lack of use
            # of HTTP error status codes by the OWM API 2.5. This mechanism is
            # supposed to be deprecated as soon as the API fully adopts HTTP for
            # conveying errors to the clients
            if the_dict['cod'] == "200" or the_dict['cod'] == 200:
                pass
            else:
                if the_dict['cod'] == "404" or the_dict['cod'] == 404:
                    print("OWM API: data not found")
                    return None
                else:
                    raise exceptions.APIResponseError(
                        "OWM API: error - response payload", the_dict['cod'])

        # Handle the case when no results are found
        if 'count' in the_dict and the_dict['count'] == "0":
            return []
        if 'cnt' in the_dict and the_dict['cnt'] == 0:
            return []
        if 'list' in the_dict:
            return [Observation.from_dict(item) for item in the_dict['list']]

        # no way out..
        raise exceptions.ParseAPIResponseError(''.join(
            [__name__, ': impossible to read JSON data']))
Ejemplo n.º 5
0
    def from_dict(cls, the_dict):
        """
        Parses an *Observation* instance out of a data dictionary. Only certain properties of the data dictionary
        are used: if these properties are not found or cannot be parsed, an exception is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: an *Observation* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the input dict embeds an HTTP status error

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('JSON data is None')

        # Check if server returned errors: this check overcomes the lack of use
        # of HTTP error status codes by the OWM API 2.5. This mechanism is
        # supposed to be deprecated as soon as the API fully adopts HTTP for
        # conveying errors to the clients
        if 'message' in the_dict and 'cod' in the_dict:
            if the_dict['cod'] != "404":
                raise exceptions.APIResponseError(
                    "OWM API: error - response payload", the_dict['cod'])
            print("OWM API: observation data not available")
            return None
        try:
            place = location.Location.from_dict(the_dict)
        except KeyError:
            raise exceptions.ParseAPIResponseError(''.join([
                __name__, ': impossible to read location info from JSON data'
            ]))
        try:
            w = weather.Weather.from_dict(the_dict)
        except KeyError:
            raise exceptions.ParseAPIResponseError(''.join(
                [__name__,
                 ': impossible to read weather info from JSON data']))
        current_time = int(time.time())
        return Observation(current_time, place, w)
    def from_dict(cls, d):
        """
        Parses a *StationHistory* instance out of a data dictionary. Only certain properties of the data dictionary
        are used: if these properties are not found or cannot be parsed, an exception is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a *StationHistory* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the input dict embeds an HTTP status error

        """
        if d is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        # Check if server returned errors: this check overcomes the lack of use
        # of HTTP error status codes by the OWM API but it's supposed to be
        # deprecated as soon as the API implements a correct HTTP mechanism for
        # communicating errors to the clients. In addition, in this specific
        # case the OWM API responses are the very same either when no results
        # are found for a station and when the station does not exist!
        measurements = {}
        try:
            if 'cod' in d:
                if d['cod'] != "200":
                    raise exceptions.APIResponseError(
                        "OWM API: error - response payload: " + str(d),
                        d['cod'])
            if str(d['cnt']) == "0":
                return None
            else:
                for item in d['list']:
                    if 'temp' not in item:
                        temp = None
                    elif isinstance(item['temp'], dict):
                        temp = item['temp']['v']
                    else:
                        temp = item['temp']
                    if 'humidity' not in item:
                        hum = None
                    elif isinstance(item['humidity'], dict):
                        hum = item['humidity']['v']
                    else:
                        hum = item['humidity']
                    if 'pressure' not in item:
                        pres = None
                    elif isinstance(item['pressure'], dict):
                        pres = item['pressure']['v']
                    else:
                        pres = item['pressure']
                    if 'rain' in item and isinstance(item['rain']['today'],
                                                     dict):
                        rain = item['rain']['today']['v']
                    else:
                        rain = None
                    if 'wind' in item and isinstance(item['wind']['speed'],
                                                     dict):
                        wind = item['wind']['speed']['v']
                    else:
                        wind = None
                    measurements[item['dt']] = {
                        "temperature": temp,
                        "humidity": hum,
                        "pressure": pres,
                        "rain": rain,
                        "wind": wind
                    }
        except KeyError:
            raise exceptions.ParseAPIResponseError(
                __name__ + ': impossible to read input data')
        current_time = int(time.time())
        return StationHistory(None, None, current_time, measurements)