KISTERS Water Time Series API¶
Welcome to the Water Time Series API documentation. This API provides access to time series data from KiWIS and ZRXP files.
General API¶
Time Series¶
TimeSeries is the object representation of the time series data it provides all the attributes and metadata of the time series as well as access to the data itself through the read_data_frame and write_data_frame methods.
-
class
kisters.water.time_series.core.time_series.
TimeSeries
(*args, **kwargs)¶ Bases:
abc.ABC
This class provides the interface of TimeSeries.
-
coverage_from
¶ The date from which the TimeSeries data starts.
Returns: The start date
-
coverage_until
¶ The date until which the TimeSeries data covers.
Returns: The end date
-
id
¶ The id number which fully identifies the TimeSeries.
Returns: The id number
-
metadata
¶ The map containing all the metadata related to this TimeSeries.
Returns: The metadata map
-
name
¶ The full name of the TimeSeries.
Returns: The full name
-
path
¶ The full path to this TimeSeries.
Returns: The path string
-
read_data_frame
(start: Union[str, datetime.datetime] = None, end: Union[str, datetime.datetime] = None, params: Mapping = None, t0: datetime.datetime = None, dispatch_info: str = None, member: str = None, **kwargs) → pandas.core.frame.DataFrame¶ This method returns the TimeSeries data between the start and end dates (both dates included) structured as a pandas DataFrame.
Parameters: - start – The starting date from which the data will be returned, expressed either
- an ISO Datetime string or as a datetime object. If TimeZone is not included, (as) –
- assumes the TimeZone of the TimeSeries. (it) –
- end – The ending date until which the data will be covered (end date included),
- either as an ISO Datetime string or as a datetime object. If TimeZone (expressed) –
- not included, it assumes the TimeZone of the TimeSeries. (is) –
- params – The parameters passed to the backend call.
- ensemble time series only (For) –
- To retrieve all data points of all dispatch_infos and members
- set t0, dispatch_info, member to None including t0, dispatch_info, member as additional columns
- To retrieve a single ensemble member
- t0: the t0 time stamp of the ensemble member dispatch_info: ensemble dispatch_info identifier member: ensemble member identifier
Returns: The DataFrame containing the TimeSeries data
-
read_ensemble_members
(t0_start: datetime.datetime = None, t0_end: datetime.datetime = None)¶ Returns a list of dictionaries with the corresponding t0, member and dispatch_infos as key.
Parameters: - t0_start – The starting date from which the data will be returned.
- t0_end – The ending date until which the data will be covered (end date included).
-
short_name
¶ The short name of the TimeSeries.
Returns: The short name
-
write_data_frame
(data_frame: pandas.core.frame.DataFrame, start: datetime.datetime = None, end: datetime.datetime = None, t0: datetime.datetime = None, dispatch_info: str = None, member: str = None, **kwargs)¶ This methods writes the TimeSeries data from the data_frame into this TimeSeries. If either start or end, cover data missing in the data_frame these date ranges will be deleted. So if you specify an empty DataFrame, you can remove all data between start and end.
Parameters: - data_frame – The TimeSeries data to be written in the form of a pandas DataFrame.
- start – The date from which data will be writen.
- end – The date until which data will be writen (end date included).
- ensemble time series only (For) –
- To write a single ensemble member at once
- t0: the t0 time stamp of the ensemble member dispatch_info: ensemble dispatch_info identifier member: ensemble member identifier start, end will be ignored
-
Time Series Store¶
TimeSeriesStore provides access to time series data from different backends. All TimeSeriesStore implementations provide this methods, to see details on a concrete Store usage go to Stores Backends
-
class
kisters.water.time_series.core.time_series_store.
TimeSeriesStore
¶ Bases:
abc.ABC
-
create_time_series
(path: str, display_name: str, attributes: Mapping = None, params: Mapping[str, Any] = None) → kisters.water.time_series.core.time_series.TimeSeries¶ Create an empty time series.
Parameters: - path – The time series path.
- display_name – The time series name to display.
- attributes – The metadata of the time series.
- params – The additional parameters, which are passed to the backend.
-
create_time_series_from
(copy_from: kisters.water.time_series.core.time_series.TimeSeries, **kwargs) → kisters.water.time_series.core.time_series.TimeSeries¶ Create a time series as a copy from another existing time series e.g. from another system. This function only copies meta data and only if the underlaying backend supports it.
Parameters: copy_from – The time series object to be copied.
-
get_by_filter
(ts_filter: str, params: Mapping[str, Any] = None) → Iterable[kisters.water.time_series.core.time_series.TimeSeries]¶ Get the time series list by filter.
Parameters: - ts_filter – time series path or filter.
- params – the additional parameters, which are passed to the backend.
Returns: The list of the found TimeSeries objects.
Examples
store.get_by_filter("W7AgentTest/20004/S/*")
-
get_by_id
(ts_id: Union[int, str, Iterable[int], Iterable[str]], params: Mapping[str, Any] = None) → Union[kisters.water.time_series.core.time_series.TimeSeries, Iterable[kisters.water.time_series.core.time_series.TimeSeries]]¶ Get the time series by id.
Parameters: - ts_id – List of ids or single id.
- params – The additional parameters, which are passed to the backend.
Returns: The time series or a list of time series if ts_id is a list.
Examples
store.get_by_id(4711) store.get_by_id([4711, 4712])
-
get_by_path
(path: str, params: Mapping[str, Any] = None) → kisters.water.time_series.core.time_series.TimeSeries¶ Get the time series by path.
Parameters: - path – The full qualified time series path.
- params – The additional parameters, which are passed to the backend.
Returns: The TimeSeries object.
Examples
store.get_by_path("W7AgentTest/20003/S/cmd")
-
get_entity
(entity_path: str = None, entity_id: int = None, **kwargs) → kisters.water.time_series.core.entity.Entity¶ Retrieve a single Entity from the backend.
Basic implementation is given based on get_entity_list, but it is recommended to overwrite this method based on the backend specifications. :param entity_path: The entity path. :param entity_id: The entity id. :param **kwargs: Additional arguments dependent on the backend.
Returns: The matching Entity.
-
get_entity_list
(entity_filter: str = None, entities_id: Iterable[int] = None, **kwargs) → Iterable[kisters.water.time_series.core.entity.Entity]¶ Retrieve a list of entities from the backend.
The behaviour depends totally on the backend implementation, this should decide if both entity_filter and entities_id arguments can be given and how they behave if both are given. As a rule of thumb if both arguments are given a double filter should be applied. :param entity_filter: The entity filter. :param entities_id: A list of entities id. :param **kwargs: Additional arguments dependent on the backend.
Returns: The list of Entity objects.
-
get_time_series
(**kwargs)¶
-
get_time_series_list
(**kwargs)¶
-
read_data_frames
(ts_list: Iterable[kisters.water.time_series.core.time_series.TimeSeries], start: Union[str, datetime.datetime] = None, end: Union[str, datetime.datetime] = None, params: Mapping = None, t0: datetime.datetime = None, dispatch_info: str = None, member: str = None) → Mapping[kisters.water.time_series.core.time_series.TimeSeries, pandas.core.frame.DataFrame]¶ Read multiple time series as data frames.
Note: TimeSeriesStore provides a default unoptimized implementation. Override this method if your store can provide a more efficient bulk read method.
-
write_data_frames
(ts_list: Iterable[kisters.water.time_series.core.time_series.TimeSeries], data_frames: Iterable[pandas.core.frame.DataFrame], start: Union[datetime.datetime, Iterable] = None, end: Union[datetime.datetime, Iterable] = None, t0: Union[datetime.datetime, Iterable] = None, dispatch_info: Iterable = None, member: Iterable = None)¶ Write multiple data frames to time series
Note: Override this method if your store can provide a better implementation to bulk write data frames.
-
write_time_series
(ts: kisters.water.time_series.core.time_series.TimeSeries, start: datetime.datetime = None, end: datetime.datetime = None, auto_create: bool = False) → kisters.water.time_series.core.time_series.TimeSeries¶ Write a single time series to the time series back end for the given time range.
Parameters: - ts – The time series to write.
- start – The starting date from which data will be written.
- end – The ending date until which data will be written.
- auto_create – Create the time series if not exists in the back end.
Examples
ts = store1.get_by_id(47122) store2.write_time_series(ts)
-
write_time_series_list
(ts_list: Iterable[kisters.water.time_series.core.time_series.TimeSeries], start: datetime.datetime = None, end: datetime.datetime = None, auto_create: bool = False)¶ Write a time series list to the back end for the given time range.
Parameters: - ts_list – The time series list.
- start – The starting date from which data will be written.
- end – The ending date until which data will be written.
- auto_create – Create the time series if not exists in the back end.
Examples
ts_list = store1.get_by_filter('W7AgentTest/2000*') store2.write_time_series_list(ts_list, datetime(2001, 1, 1), datetime(2002, 1, 1))
-
Stores Backends¶
File Store¶
FileStore class grants access through your own time series data files. Right now, you can have your time series data files in 3 formats, ZRXP, CSV and Pickle.
-
class
kisters.water.time_series.file_io.
FileStore
(root_dir: str, file_format: kisters.water.time_series.file_io.time_series_format.TimeSeriesFormat)¶ FileStore provides a TimeSeriesStore for your local time series data files
Parameters: - root_dir – The path to your time series data folder.
- file_format – The format used by your time series data files.
Examples
from kisters.water.time_series.file_io import FileStore, ZRXPFormat fs = FileStore('tests/data', ZRXPFormat()) ts = fs.get_by_path('validation/inner_consistency1/station1/H')
-
class
kisters.water.time_series.file_io.
CSVFormat
(delimiter: str = ', ', quotechar: str = '"', header_lines: int = 1)¶ CSV formatter class
Example
from kisters.water.time_series.file_io import FileStore, CSVFormat fs = FileStore('tests/data', CSVFormat())
-
class
kisters.water.time_series.file_io.
PickleFormat
¶ Pickle formatter class
Example
from kisters.water.time_series.file_io import FileStore, PickleFormat fs = FileStore('tests/data', PickleFormat())
-
class
kisters.water.time_series.file_io.
ZRXPFormat
¶ ZRXP formatter class
Example
from kisters.water.time_series.file_io import FileStore, ZRXPFormat fs = FileStore('tests/data', ZRXPFormat())
KiWIS Store¶
KiWISStore class grants access to the time series data of the Kisters Web Interoperability Solution backend.
-
class
kisters.water.time_series.kiwis.
KiWISStore
(base_url: str, datasource: int = 0, user: str = None, password: str = None)¶ Bases:
kisters.water.time_series.core.time_series_store.TimeSeriesStore
Connector to KiWIS backend over KiWIS REST API
Parameters: - base_url – Base url of REST API.
- data_source – Optional number identifying the data source.
Examples
from kisters.water.time_series.kiwis import KiWISStore kiwis = KiWISStore('http://kiwis.kisters.de/KiWIS2/KiWIS') kiwis.get_by_path('DWD/07367/Precip/CmdTotal.1h')
-
_get_time_series
(ts_id: int = None, path: str = None, params: Mapping[str, Any] = None) → kisters.water.time_series.core.time_series.TimeSeries¶ Get a time series identified by id or by path and return a TimeSeries
Parameters: - ts_id – The time series id.
- path – The time series path (ignored if ts_id is given).
- params –
The additional parameters, which are passed to the rest api. in addition to the parameters defined by the REST API there are the following keys:
metadata = comma separated list of additional meta information where the values are “site”, “station”, “parameter”.All time series specific information should be specified as is. All station, site and parameter specific information should be prefixed with “station.” etc.
Returns: The found TimeSeries object.
Examples
kiwis.get_by_id(ts_id = 40765010) # There is a special key 'all' which allows to retrieve all metadata keys of the specified object. # But this should be handeld with care, because it is expensive. ts = self.kiwis.get_by_id(ts_id=40765010, params={'metadata': 'station.all'}) # The following statement would retrieve all available information: kiwis.get_by_id(ts_id=40765010, params={'metadata': 'all,parameter.all,station.all,site.all'})
-
_get_time_series_list
(ts_filter: str = None, id_list: Iterable[int] = None, params: Mapping[str, Any] = None) → List[kisters.water.time_series.core.time_series.TimeSeries]¶ Get the time series list and return a list of TimeSeries objects
Parameters: - ts_filter – The ts filter.
- id_list – The id list.
- params –
The additional parameters, which are passed to rest api in addition to the parameters defined by the REST API there are the following keys:
metadata = comma separated list of additional meta information where the values are “site”, “station”, “parameter”.
Returns: The list of TimeSeries objects.
Examples
kiwis.get_by_filter(ts_filter="FR110031fb-e8e7-4381-a942-372aa8141945/CM0514*")
TimeSeriesStoreDecorators¶
The TimeSeriesStoreDecorators allow you to “wrap” a TimeSeriesStore to extend its functionality.
-
class
kisters.water.time_series.store_decorators.
AddMetadataStore
(forward: kisters.water.time_series.core.time_series_store.TimeSeriesStore, metadata: Mapping[str, Any])¶ Bases:
kisters.water.time_series.core.time_series_store.TimeSeriesStore
AddMetadataStore is a TimeSeriesStore decorator which allows to add metadata to TimeSeries inside the original TimeSeriesStore. To add metadata you must provide a Mapping of paths to metadata dictionaries.
Parameters: - forward – The TimeSeriesStore to be decorated.
- metadata – The mapping providing metadata. Keys are the time series paths, and values are the metadata maps for each time series.
Example
import json from kisters.water.file_io import FileStore, ZRXPFormat from kisters.water.store_decorators import AddMetadataStore with open('tests/data/addmetadata.json', 'r') as f: j = json.load(f) store = AddMetadataStore(FileStore('tests/data', ZRXPFormat()), j) ts = store.get_by_path('validation/threshold/05BJ004.HG.datum.O') ts.metadata['THRESHOLDATTR']
-
class
kisters.water.time_series.store_decorators.
CacheStore
(forward: kisters.water.time_series.core.time_series_store.TimeSeriesStore)¶ Bases:
kisters.water.time_series.core.time_series_store.TimeSeriesStore
CacheStore is a TimeSeriesStore decorator which allows to cache the retrieval of TimeSeries inside the original TimeSeriesStore. Also TimeSeries retrieved this way cache the data they contain in memory.
Parameters: forward – The TimeSeriesStore to be decorated. Example
from kisters.water.file_io import FileStore, ZRXPFormat from kisters.water.store_decorators import CacheStore store = CacheStore(FileStore('tests/data', ZRXPFormat())) ts = store.get_by_path('validation/threshold/05BJ004.HG.datum.O')
Examples¶
KiWIS Example¶
Accessing KiWIS data¶
This example demonstrates how to access and plot time series data from KiWIS using Python.
from datetime import datetime
import matplotlib.pyplot as plt
from kisters.water.time_series.kiwis import KiWISStore
# Initialize KiWISStore object with url to location
kiwis = KiWISStore("http://kiwis.kisters.de/KiWIS2/KiWIS")
# Get time series list by path filter
ts_list = kiwis.get_by_filter("123/*/Precip/MMonth.Total")
# Get time series by path
ts = kiwis.get_by_path("DWD/07367/Precip/CmdTotal.1h")
# We can access timeseries metadata as a dict using the metadata attribute
ts_metadata_dict = ts.metadata
# ts_metadata_dict looks like this:
# {
# "from": datetime.datetime(
# 2007, 12, 1, 0, 0, tzinfo=tzoffset(None, 3600)
# ),
# "to": datetime.datetime(
# 2018, 7, 16, 23, 0, tzinfo=tzoffset(None, 3600)
# ),
# "tsPath": "DWD/07367/Precip/CmdTotal.1h",
# "shortName": "CmdTotal.1h",
# "id": 7411042,
# "name": "0 Stundenwerte",
# "dataCoverageFrom": datetime.datetime(
# 2007, 12, 1, 0, 0, tzinfo=tzoffset(None, 3600)
# ),
# "dataCoverageUntil": datetime.datetime(
# 2018, 7, 16, 23, 0, tzinfo=tzoffset(None, 3600)
# ),
# }
# Access the time series data in the form of pandas DataFrame
df = ts.read_data_frame(datetime(2017, 1, 1), ts.coverage_until)
# Plot the data
plt.figure(figsize=(15, 5))
df["Value"].plot(label=ts.name, figsize=(15, 5))
df["Value"].resample("D").sum().plot(label="Daily sum", figsize=(15, 5))
plt.legend(loc=2)
plt.show()
Writing data to KiWIS¶
Currently KiWIS doesn’t allow to write data into or create time series. However, you can use the File Store module to save your data locally.
For example, this code snippet continues from the example above and writes the
time series variable ts
to a ZRX file using the ZRXPFormat.
from kisters.water.time_series.file_io import ZRXPFormat
writer = ZRXPFormat().writer()
writer.write('my_time_series.zrx', [ts])