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)
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)
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']))
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)