Source code for sondera.clients.smhi.smhistrang

"""
Client for SMHI Strång API
https://opendata.smhi.se/apidocs/strang/

model data and not observation, so will not use the station and dataclasses
simply return the data as either pd.Series or xarray
https://opendata.smhi.se/apidocs/strang/get_points.html <-- pandas.Series
https://opendata.smhi.se/apidocs/strang/get_multipoint.html <-- xarray (api returns the full field)

Todo:
Multipoint

"""
from typing import Union
import datetime

import pandas as pd

from ..parameters import ParametersStrang as Parameters
from .common import _make_request


[docs] class StrangClient: # Fixed to version 1 _api_url = 'https://opendata-download-metanalys.smhi.se/api/category/strang1g/version/1/geotype' def __init__(self): self.Parameters = Parameters self._api_url_template_point = (self._api_url + '/point/lon/{longitude}' '/lat/{latitude}' '/parameter/{parameter}' '/data.json?' '?from={from}' '&to={to}' '&interval={interval}')
[docs] def get_data_point(self, parameter: Union[Parameters, int], lon: float, lat: float, date_from: Union[pd.Timestamp, datetime.datetime, str], date_to: Union[pd.Timestamp, datetime.datetime, str], agg_interval: str, ) -> pd.Series: """ Get Strång data for a single latitude-longitude coordinate. Parameters ---------- parameter : int or ParametersStrang enum The parameter for the radiation data type. lon : float Longitude in decimal degrees. lat : float Latitude in decimal degrees. date_from : str, datetime or pandas.Timestamp Retrieve data starting from this datetime. date_to : str, datetime or pandas.Timestamp Retrieve data up to this datetime. agg_interval : str Aggregation interval. Valid values are 'hourly', 'daily' and 'monthly'. Returns ------- A pandas Series of values returned by Strång API Notes ----- https://strang.smhi.se/ https://opendata.smhi.se/apidocs/strang/ """ if isinstance(parameter, int): try: parameter = self.Parameters(parameter) except ValueError as error: raise # format date string if passed time is not string # "UTC. For example 2020-01-02T10:00:00Z" # TODO support timezone, strftime now doesnt do this correctly if datetime is localized? # datetimeobject.isoformat() ? if isinstance(date_from, str): date_from_f = date_from else: date_from_f = date_from.strftime('%Y-%m-%dT%H:%M:%SZ') if isinstance(date_to, str): date_to_f = date_to else: date_to_f = date_to.strftime('%Y-%m-%dT%H:%M:%SZ') api_vars = {'parameter': parameter.value, 'longitude': lon, 'latitude': lat, 'from': date_from_f, 'to': date_to_f, 'interval': agg_interval} # Get data api_url = self._api_url_template_point.format(**api_vars) api_get_result = _make_request(api_url) api_df = pd.DataFrame(api_get_result.json()) api_df['datetime'] = pd.to_datetime(api_df['date_time']) data_series = api_df.set_index('datetime')['value'] data_series.name = parameter.name return data_series
[docs] def get_data_multipoint(self): raise NotImplementedError # requires xarray heavy dependence
[docs] def get_data_multipoint_period(self): # Get multipoint data for a range of times (provided as sequence of timestamps) # Resample timestamps to hourly if provided with higher freq raise NotImplementedError # requires xarray heavy dependence