コード例 #1
0
    def from_dict(cls, the_dict):
        """
        Parses a *COIndex* 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 *COIndex* 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

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        try:
            # -- reference time (strip away Z and T on ISO8601 format)
            t = the_dict['time'].replace('Z', '+00:00').replace('T', ' ')
            reference_time = formatting.ISO8601_to_UNIXtime(t)

            # -- reception time (now)
            reception_time = timestamps.now('unix')

            # -- location
            lon = float(the_dict['location']['longitude'])
            lat = float(the_dict['location']['latitude'])
            place = location.Location(None, lon, lat, None)

            # -- CO samples
            co_samples = the_dict['data']

        except KeyError:
            raise exceptions.ParseAPIResponseError(
                      ''.join([__name__, ': impossible to parse COIndex']))

        return COIndex(reference_time, place, None, co_samples, reception_time)
コード例 #2
0
    def from_dict(cls, the_dict):
        """
        Parses a *Alert* 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 *Alert* 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

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        try:
            alert_id = the_dict['_id']
            t = the_dict['last_update'].split('.')[0].replace('T', ' ') + '+00'
            alert_last_update = formatting.ISO8601_to_UNIXtime(t)
            alert_trigger_id = the_dict['triggerId']
            alert_met_conds = [
                dict(current_value=c['current_value']['min'],
                     condition=Condition.from_dict(c['condition']))
                for c in the_dict['conditions']
            ]
            alert_coords = the_dict['coordinates']
            return Alert(alert_id,
                         alert_trigger_id,
                         alert_met_conds,
                         alert_coords,
                         last_update=alert_last_update)
        except ValueError as e:
            raise exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)
        except KeyError as e:
            raise exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)
コード例 #3
0
    def from_dict(cls, the_dict):
        """
        Parses a *NationalWeatherAlert* 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 *NationalWeatherAlert* 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

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

        try:
            sender = the_dict['sender_name']
            title = the_dict['event']
            description = the_dict['description']
            start_time = the_dict['start']
            end_time = the_dict['end']
        except KeyError:
            raise exceptions.ParseAPIResponseError('Invalid data payload')
        tags = the_dict.get('tags', [])
        return NationalWeatherAlert(sender, title, description, start_time,
                                    end_time, tags)
コード例 #4
0
    def from_dict(cls, the_dict):
        """
        Parses an *UVIndex* 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 the_dict: the input dict
        :type the_dict: dict
        :returns: an *UVIndex* 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')
        try:
            # -- reference time
            reference_time = the_dict['date']

            # -- reception time (now)
            reception_time = timestamps.now('unix')

            # -- location
            lon = float(the_dict['lon'])
            lat = float(the_dict['lat'])
            place = location.Location(None, lon, lat, None)

            # -- UV intensity
            uv_intensity = float(the_dict['value'])
        except KeyError:
            raise exceptions.ParseAPIResponseError(''.join(
                [__name__, ': impossible to parse UV Index']))
        return UVIndex(reference_time, place, uv_intensity, reception_time)
コード例 #5
0
ファイル: one_call.py プロジェクト: Abdulaziz1601/python_bots
    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)
コード例 #6
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)
コード例 #7
0
 def from_dict(cls, the_dict):
     if the_dict is None:
         raise exceptions.ParseAPIResponseError('Data is None')
     try:
         weather_param = the_dict['name']
         operator = the_dict['expression']
         amount = the_dict['amount']
         the_id = the_dict.get('_id', None)
         return Condition(weather_param, operator, amount, id=the_id)
     except KeyError as e:
         raise exceptions.ParseAPIResponseError(
             'Impossible to parse data: %s' % e)
コード例 #8
0
 def get_geotiff(self, path, params=None, headers=None):
     builder = HttpRequestBuilder(self.root_uri, self.api_key, self.config, has_subdomains=self.admits_subdomains)\
         .with_path(path)\
         .with_api_key()\
         .with_language()\
         .with_query_params(params if params is not None else dict())\
         .with_headers(headers if headers is not None else dict())\
         .with_header('Accept', ImageTypeEnum.GEOTIFF.mime_type)
     url, params, headers, proxies = builder.build()
     try:
         resp = requests.get(url, stream=True, params=params, headers=headers, proxies=proxies,
                             timeout=self.config['connection']['timeout_secs'],
                             verify=self.config['connection']['verify_ssl_certs'])
     except requests.exceptions.SSLError as e:
         raise exceptions.InvalidSSLCertificateError(str(e))
     except requests.exceptions.ConnectionError as e:
         raise exceptions.InvalidSSLCertificateError(str(e))
     except requests.exceptions.Timeout:
         raise exceptions.TimeoutError('API call timeouted')
     HttpClient.check_status_code(resp.status_code, resp.text)
     try:
         return resp.status_code, resp.content
     except:
         raise exceptions.ParseAPIResponseError('Impossible to parse'
                                                       'API response data')
コード例 #9
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'
                ]))
コード例 #10
0
    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']))
コード例 #11
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)
コード例 #12
0
    def from_dict(cls, the_dict):
        """
        Parses a *Location* 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 *Location* 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

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        country = None
        if 'sys' in the_dict and 'country' in the_dict['sys']:
            country = the_dict['sys']['country']
        if 'city' in the_dict:
            data = the_dict['city']
        else:
            data = the_dict
        if 'name' in data:
            name = data['name']
        else:
            name = None
        if 'id' in data:
            ID = int(data['id'])
        else:
            ID = None
        if 'coord' in data:
            lon = data['coord'].get('lon', 0.0)
            lat = data['coord'].get('lat', 0.0)
        elif 'station' in data and 'coord' in data['station']:
            if 'lon' in data['station']['coord']:
                lon = data['station']['coord'].get('lon', 0.0)
            elif 'lng' in data['station']['coord']:
                lon = data['station']['coord'].get('lng', 0.0)
            else:
                lon = 0.0
            lat = data['station']['coord'].get('lat', 0.0)
        else:
            raise KeyError("Impossible to read geographical coordinates from JSON")
        if 'country' in data:
            country = data['country']
        return Location(name, lon, lat, ID, country)
コード例 #13
0
ファイル: station.py プロジェクト: mohsen20100/pyowm
    def from_dict(cls, the_dict):
        """
        Parses a *Station* 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 *Station* 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

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        id = the_dict.get('ID', None) or the_dict.get('id', None)
        external_id = the_dict.get('external_id', None)
        lon = the_dict.get('longitude', None)
        lat = the_dict.get('latitude', None)
        alt = the_dict.get('altitude', None)
        name = the_dict.get('name', None)
        rank = the_dict.get('rank', None)
        created_at = the_dict.get('created_at', None)
        updated_at = the_dict.get('updated_at', None)
        return Station(id, created_at, updated_at, external_id, name, lon, lat, alt, rank)
コード例 #14
0
ファイル: http_client.py プロジェクト: csparpa/pyowm
    def get_geotiff(self, path, params=None, headers=None):
        # check URL fromt the metaimage: if it looks like a complete URL, use that one (I know, it's a hack...)
        try:
            partial_path = path.split(self.root_uri)[1].lstrip('/')
        except:
            partial_path = ''  # fallback so that a 404 is issued

        builder = HttpRequestBuilder(self.root_uri, self.api_key, self.config, has_subdomains=self.admits_subdomains)\
            .with_path(partial_path)\
            .with_api_key()\
            .with_language()\
            .with_query_params(params if params is not None else dict())\
            .with_headers(headers if headers is not None else dict())\
            .with_header('Accept', ImageTypeEnum.GEOTIFF.mime_type)
        url, params, headers, proxies = builder.build()
        try:
            resp = self.http.get(
                url,
                stream=True,
                params=params,
                headers=headers,
                proxies=proxies,
                timeout=self.config['connection']['timeout_secs'],
                verify=self.config['connection']['verify_ssl_certs'])
        except requests.exceptions.SSLError as e:
            raise exceptions.InvalidSSLCertificateError(str(e))
        except requests.exceptions.ConnectionError as e:
            raise exceptions.InvalidSSLCertificateError(str(e))
        except requests.exceptions.Timeout:
            raise exceptions.TimeoutError('API call timeouted')
        HttpClient.check_status_code(resp.status_code, resp.text)
        try:
            return resp.status_code, resp.content
        except:
            raise exceptions.ParseAPIResponseError('Impossible to parse'
                                                   'API response data')
コード例 #15
0
    def from_dict(cls, the_dict):
        """
        Parses a *Weather* 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 *Weather* 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')
        # -- times
        reference_time = 0
        if 'dt' in the_dict:
            reference_time = the_dict['dt']
        elif 'dt' in the_dict['last']:
            reference_time = the_dict['last']['dt']

        if 'sunset' in the_dict:
            sunset_time = the_dict['sunset']
        elif 'sys' in the_dict and 'sunset' in the_dict['sys']:
            sunset_time = the_dict['sys']['sunset']
        else:
            sunset_time = None

        if 'sunrise' in the_dict:
            sunrise_time = the_dict['sunrise']
        elif 'sys' in the_dict and 'sunrise' in the_dict['sys']:
            sunrise_time = the_dict['sys']['sunrise']
        else:
            sunrise_time = None

        # -- calc
        dewpoint = None
        humidex = None
        heat_index = None
        if 'calc' in the_dict:
            if 'dewpoint' in the_dict['calc']:
                dewpoint = the_dict['calc']['dewpoint']

            if 'humidex' in the_dict['calc']:
                humidex = the_dict['calc']['humidex']

            if 'heatindex' in the_dict['calc']:
                heat_index = the_dict['calc']['heatindex']

        elif 'last' in the_dict:
            if 'calc' in the_dict['last']:
                if 'dewpoint' in the_dict['last']['calc']:
                    dewpoint = the_dict['last']['calc']['dewpoint']

                if 'humidex' in the_dict['last']['calc']:
                    humidex = the_dict['last']['calc']['humidex']

                if 'heatindex' in the_dict['last']['calc']:
                    heat_index = the_dict['last']['calc']['heatindex']

        if 'dew_point' in the_dict and dewpoint is None:
            dewpoint = the_dict.get('dew_point', None)

        # -- visibility
        visibility_distance = None
        if 'visibility' in the_dict:
            if isinstance(the_dict['visibility'], int):
                visibility_distance = the_dict['visibility']
            elif 'distance' in the_dict['visibility']:
                visibility_distance = the_dict['visibility']['distance']
        elif 'last' in the_dict and 'visibility' in the_dict['last']:
            if isinstance(the_dict['last']['visibility'], int) or isinstance(
                    the_dict['last']['visibility'], float):
                visibility_distance = the_dict['last']['visibility']
            elif 'distance' in the_dict['last']['visibility']:
                visibility_distance = the_dict['last']['visibility'][
                    'distance']

        # -- clouds
        clouds = 0
        if 'clouds' in the_dict:
            if isinstance(the_dict['clouds'], int) or isinstance(
                    the_dict['clouds'], float):
                clouds = the_dict['clouds']
            elif 'all' in the_dict['clouds']:
                clouds = the_dict['clouds']['all']

        # -- precipitation workaround
        if 'precipitation' in the_dict and 'rain' not in the_dict:
            the_dict['rain'] = the_dict['precipitation']

        # -- rain
        rain = dict()
        if 'rain' in the_dict:
            if isinstance(the_dict['rain'], int) or isinstance(
                    the_dict['rain'], float):
                rain = {'all': the_dict['rain']}
            else:
                if the_dict['rain'] is not None:
                    rain = the_dict['rain'].copy()

        # -- wind
        wind = dict()
        if 'wind' in the_dict and the_dict['wind'] is not None:
            wind = the_dict['wind'].copy()
        elif 'last' in the_dict:
            if 'wind' in the_dict['last'] and the_dict['last'][
                    'wind'] is not None:
                wind = the_dict['last']['wind'].copy()
        else:
            if 'speed' in the_dict:
                wind['speed'] = the_dict['speed']
            elif 'wind_speed' in the_dict:
                wind['speed'] = the_dict.get('wind_speed', 0)

            if 'deg' in the_dict:
                wind['deg'] = the_dict['deg']
            elif 'wind_deg' in the_dict:
                wind['deg'] = the_dict.get('wind_deg', 0)

            if 'wind_gust' in the_dict:
                wind['gust'] = the_dict.get('wind_gust', 0)

        # -- humidity
        if 'humidity' in the_dict:
            humidity = the_dict['humidity']
        elif 'main' in the_dict and 'humidity' in the_dict['main']:
            humidity = the_dict['main']['humidity']
        elif 'last' in the_dict and 'main' in the_dict[
                'last'] and 'humidity' in the_dict['last']['main']:
            humidity = the_dict['last']['main']['humidity']
        else:
            humidity = 0

        # -- snow
        snow = dict()
        if 'snow' in the_dict:
            if isinstance(the_dict['snow'], int) or isinstance(
                    the_dict['snow'], float):
                snow = {'all': the_dict['snow']}
            else:
                if the_dict['snow'] is not None:
                    snow = the_dict['snow'].copy()

        # -- pressure
        atm_press = None
        if 'pressure' in the_dict:
            atm_press = the_dict['pressure']
        elif 'main' in the_dict and 'pressure' in the_dict['main']:
            atm_press = the_dict['main']['pressure']
        elif 'last' in the_dict:
            if 'main' in the_dict['last']:
                atm_press = the_dict['last']['main']['pressure']

        sea_level_press = None
        if 'main' in the_dict and 'sea_level' in the_dict['main']:
            sea_level_press = the_dict['main']['sea_level']

        pressure = {'press': atm_press, 'sea_level': sea_level_press}

        # -- temperature
        temperature = dict()
        if 'temp' in the_dict:
            if isinstance(the_dict['temp'], int) or isinstance(
                    the_dict['temp'], float):
                temperature = {'temp': the_dict.get('temp', None)}
            elif the_dict['temp'] is not None:
                temperature = the_dict['temp'].copy()
        elif 'main' in the_dict and 'temp' in the_dict['main']:
            temp_dic = the_dict['main']

            temperature = {
                'temp': temp_dic['temp'],
                'temp_kf': temp_dic.get('temp_kf', None),
                'temp_max': temp_dic.get('temp_max', None),
                'temp_min': temp_dic.get('temp_min', None),
                'feels_like': temp_dic.get('feels_like', None)
            }
        elif 'last' in the_dict:
            if 'main' in the_dict['last']:
                temperature = dict(temp=the_dict['last']['main']['temp'])

        # add feels_like to temperature if present
        if 'feels_like' in the_dict:
            feels_like = the_dict['feels_like']
            if isinstance(feels_like, int) or isinstance(feels_like, float):
                temperature['feels_like'] = the_dict.get('feels_like', None)
            elif isinstance(feels_like, dict):
                for label, temp in feels_like.items():
                    temperature[f'feels_like_{label}'] = temp

        # -- weather status info
        if 'weather' in the_dict:
            status = the_dict['weather'][0]['main']
            detailed_status = the_dict['weather'][0]['description']
            weather_code = the_dict['weather'][0]['id']
            weather_icon_name = the_dict['weather'][0]['icon']
        else:
            status = ''
            detailed_status = ''
            weather_code = 0
            weather_icon_name = ''

        # -- timezone
        if 'timezone' in the_dict:
            utc_offset = the_dict['timezone']
        else:
            utc_offset = None

        # -- UV index
        uvi = the_dict.get('uvi', None)

        return Weather(reference_time,
                       sunset_time,
                       sunrise_time,
                       clouds,
                       rain,
                       snow,
                       wind,
                       humidity,
                       pressure,
                       temperature,
                       status,
                       detailed_status,
                       weather_code,
                       weather_icon_name,
                       visibility_distance,
                       dewpoint,
                       humidex,
                       heat_index,
                       utc_offset=utc_offset,
                       uvi=uvi)
コード例 #16
0
    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)