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 (this is an OWM web API 2.5 bug) """ 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 *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 (this is an OWM web API 2.5 bug) """ 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)) 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 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} } 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 } 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.assertTrue(all(v is not None for v in result2.__dict__.values()))
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 (this is an OWM web API 2.5 bug) """ 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 (this is an OWM web API 2.5 bug) """ 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)) 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 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 (this is an OWM web API 2.5 bug) """ 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)) 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 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 (this is an OWM web API 2.5 bug) """ 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'] lon = d['station']['coord']['lon'] 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 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(result2, Weather))
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(result2, Weather))
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()))