def parse_JSON(self, JSON_string): """ Parses a *Forecast* instance out of raw JSON data. Only certain properties of the data are used: if these properties are not found or cannot be parsed, an error is issued. :param JSON_string: a raw JSON string :type JSON_string: str :returns: a *Forecast* instance or ``None`` if no data is available :raises: *ParseResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the JSON string embeds an HTTP status error """ if JSON_string is None: raise parse_response_error.ParseResponseError('JSON data is None') d = json.loads(JSON_string) # 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 d and 'cod' in d: if d['cod'] == "404": print( "OWM API: data not found - response payload: " + json.dumps(d), d['cod']) return None elif d['cod'] != "200": raise api_response_error.APIResponseError( "OWM API: error - response payload: " + json.dumps(d), d['cod']) try: place = location.location_from_dictionary(d) except KeyError: raise parse_response_error.ParseResponseError(''.join([ __name__, ': impossible to read location info from JSON data' ])) # Handle the case when no results are found if 'count' in d and d['count'] == "0": weathers = [] elif 'cnt' in d and d['cnt'] == 0: weathers = [] else: if 'list' in d: try: weathers = [weather.weather_from_dictionary(item) \ for item in d['list']] except KeyError: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to read weather ' \ 'info from JSON data']) ) else: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to read weather ' \ 'list from JSON data']) ) current_time = int(round(time.time())) return forecast.Forecast(None, current_time, place, weathers)
def parse_JSON(self, JSON_string): """ Parses a *Station* instance out of raw JSON data. Only certain properties of the data are used: if these properties are not found or cannot be parsed, an error is issued. :param JSON_string: a raw JSON string :type JSON_string: str :returns: a *Station* instance or ``None`` if no data is available :raises: *ParseResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the JSON string embeds an HTTP status error """ if JSON_string is None: raise parse_response_error.ParseResponseError('JSON data is None') d = json.loads(JSON_string) try: name = d['station']['name'] station_ID = d['station']['id'] station_type = d['station']['type'] status = d['station']['status'] lat = d['station']['coord']['lat'] if 'lon' in d['station']['coord']: lon = d['station']['coord']['lon'] elif 'lng' in d['station']['coord']: lon = d['station']['coord']['lng'] else: lon = None if 'distance' in d: distance = d['distance'] else: distance = None except KeyError as e: error_msg = ''.join(( __name__, ': unable to read JSON data', )) raise parse_response_error.ParseResponseError(error_msg) else: if 'last' in d: last_weather = weather.weather_from_dictionary(d['last']) else: last_weather = None return station.Station(name, station_ID, station_type, status, lat, lon, distance, last_weather)
def parse_JSON(self, JSON_string): """ Parses a list of *Weather* instances out of raw JSON data. Only certain properties of the data are used: if these properties are not found or cannot be parsed, an error is issued. :param JSON_string: a raw JSON string :type JSON_string: str :returns: a list of *Weather* instances or ``None`` if no data is available :raises: *ParseResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the JSON string embeds an HTTP status error """ if JSON_string is None: raise parse_response_error.ParseResponseError('JSON data is None') d = json.loads(JSON_string) # 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 d and 'cod' in d: if d['cod'] == "404": print("OWM API: data not found - response payload: " + \ json.dumps(d)) return None elif d['cod'] != "200": raise api_response_error.APIResponseError( "OWM API: error - response payload: " + json.dumps(d), d['cod']) # Handle the case when no results are found if 'cnt' in d and d['cnt'] == "0": return [] else: if 'list' in d: try: return [weather.weather_from_dictionary(item) \ for item in d['list']] except KeyError: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to read ' \ 'weather info from JSON data']) ) else: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to read ' \ 'weather list from JSON data']) )
def parse_JSON(self, JSON_string): """ Parses a *Station* instance out of raw JSON data. Only certain properties of the data are used: if these properties are not found or cannot be parsed, an error is issued. :param JSON_string: a raw JSON string :type JSON_string: str :returns: a *Station* instance or ``None`` if no data is available :raises: *ParseResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the JSON string embeds an HTTP status error """ if JSON_string is None: raise parse_response_error.ParseResponseError('JSON data is None') d = json.loads(JSON_string) try: name = d['station']['name'] station_ID = d['station']['id'] station_type = d['station']['type'] status = d['station']['status'] lat = d['station']['coord']['lat'] if 'lon' in d['station']['coord']: lon = d['station']['coord']['lon'] elif 'lng' in d['station']['coord']: lon = d['station']['coord']['lng'] else: lon = None if 'distance' in d: distance = d['distance'] else: distance = None except KeyError as e: error_msg = ''.join((__name__, ': unable to read JSON data', )) raise parse_response_error.ParseResponseError(error_msg) else: if 'last' in d: last_weather = weather.weather_from_dictionary(d['last']) else: last_weather = None return station.Station(name, station_ID, station_type, status, lat, lon, distance, last_weather)
def parse_JSON(self, JSON_string): """ Parses an *Observation* instance out of raw JSON data. Only certain properties of the data are used: if these properties are not found or cannot be parsed, an error is issued. :param JSON_string: a raw JSON string :type JSON_string: str :returns: an *Observation* instance or ``None`` if no data is available :raises: *ParseResponseError* if it is impossible to find or parse the data needed to build the result, *APIResponseError* if the JSON string embeds an HTTP status error """ if JSON_string is None: raise parse_response_error.ParseResponseError('JSON data is None') d = loads(JSON_string) # 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 d and 'cod' in d: if d['cod'] == "404": print("OWM API: observation data not available - response " \ "payload: " + dumps(d)) return None else: raise api_response_error.APIResponseError( "OWM API: error - response payload: " + dumps(d), d['cod']) try: place = location.location_from_dictionary(d) except KeyError: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to ' \ 'read location info from JSON data'])) try: w = weather.weather_from_dictionary(d) except KeyError: raise parse_response_error.ParseResponseError( ''.join([__name__, ': impossible to ' \ 'read weather info from JSON data'])) current_time = int(round(time())) return observation.Observation(current_time, place, w)
def test_from_dictionary_when_data_fields_are_none(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': None, 'visibility': {'distance': 1000}, 'calc':{ 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 }, 'rain': None, 'snow': None } result1 = weather_from_dictionary(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertEquals(0, len(result1.get_wind())) self.assertEquals(0, len(result1.get_rain())) self.assertEquals(0, len(result1.get_snow())) dict2 = {"station":{ "name":"KPPQ", "type":1, "status":50, "id":1000, "coord":{"lon":-90.47,"lat":39.38} }, "last":{ "main":{ "temp":276.15, "pressure":1031}, "wind":None, "visibility":{ "distance":11265, "prefix":0 }, "calc":{ "dewpoint":273.15 }, "clouds":[ {"distance":427, "condition":"SCT"} ], "dt":1417977300 }, "params":["temp","pressure","wind","visibility"] } result2 = weather_from_dictionary(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertEquals(0, len(result2.get_wind()))
def test_from_dictionary(self): dict1 = {'clouds': {'all': 92}, 'name': 'London', 'coord': {'lat': 51.50853, 'lon': -0.12574}, 'sys': {'country': 'GB', 'sunset': 1378923812, 'sunrise': 1378877413 }, 'weather': [ {'main': 'Clouds', 'id': 804, 'icon': '04d', 'description': 'overcastclouds'} ], 'cod': 200, 'base': 'gdpsstations', 'dt': 1378895177, 'main': { 'pressure': 1022, 'humidity': 75, 'temp_max': 289.82, 'temp': 288.44, 'temp_min': 287.59 }, 'id': 2643743, 'wind': {'gust': 2.57, 'speed': 1.54, 'deg': 31}, 'visibility': {'distance': 1000}, 'calc':{ 'dewpoint': 300.0, 'humidex': 298.0, 'heatindex': 296.0 } } dict2 = {"dt": 1378897200, "temp": {"day": 289.37, "min": 284.88, "max": 289.37, "night": 284.88, "eve": 287.53, "morn": 289.37 }, "pressure": 1025.35, "humidity": 71, "weather": [ {"id": 500, "main": "Rain", "description": "light rain", "icon": "u10d"} ], "speed": 3.76, "deg": 338, "clouds": 48, "rain": 3 } dict3 = {"station":{ "name":"KPPQ", "type":1, "status":50, "id":1000, "coord":{"lon":-90.47,"lat":39.38} }, "last":{ "main":{ "temp":276.15, "pressure":1031}, "wind":{ "speed":3.1, "deg":140 }, "visibility":{ "distance":11265, "prefix":0 }, "calc":{ "dewpoint":273.15 }, "clouds":[ {"distance":427, "condition":"SCT"} ], "dt":1417977300 }, "params":["temp","pressure","wind","visibility"] } result1 = weather_from_dictionary(dict1) self.assertTrue(isinstance(result1, Weather)) self.assertTrue(all(v is not None for v in result1.__dict__.values())) result2 = weather_from_dictionary(dict2) self.assertTrue(isinstance(result2, Weather)) self.assertFalse(all(v is not None for v in result2.__dict__.values())) result3 = weather_from_dictionary(dict3) self.assertTrue(isinstance(result3, Weather))