hdhelpers¶
Introduction¶
hdhelpers is a package designed for and included in the standard installation of the hetida designer.
It contains functions that streamline plotting components, especially those that are used in the hetida platform, by
accessing series metadata that complies with the hetida platform metadata scheme,
aditional helper functions like adjusting the timezone of timestamps, series, and dataframes,
accessing metadata that the hetida platform writes into the hetida designer’s plot_target_settings context variable (tbd),
providing toggleable standardized styling options and json serialization for plotly plots (tbd).
Further Information¶
Functions¶
metadata¶
Collection of functions to access metadata information from timeseries objects. Metadata information can follow varying conventions as the package glom is used to extract the requested information.
- hdhelpers.metadata.get_display_names(multitsframe)¶
Gets display names of the MTSF metrics from the metadata
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
- Returns:
Dictionary of metrics containing the display names. If the display name of the metrics is not present it returns the result of
hdhelpers.metadata.get_names().- Return type:
defaultdict[str, defaultdict[str, str | None]]
- Raises:
TypeError – If multitsframe is not a DataFrame.
Code example:
>>> attr = { "by_metric": { "metric1": {"metric": {"display_name": "display_name_of_metric1"}}, ... "metric2": {"metric": {"name": "name_of_metric2"}}}} >>> dataframe.attrs = attr >>> result = get_display_names(dataframe) >>> result["metric1"]["value"] 'display_name_of_metric1' >>> result["metric2"]["value"] 'name_of_metric2'
Lets try another MTSF format:
>>> attr = { "dataset_metadata": {"metric_key": "external_id"}, ... "metrics": [{"external_id": "ruhr-temperature", ... "name": "Ruhr temperature [°C]", ... "display_name": "temperature [°C]", ... "short_display_name": "[°C]", ... "value_dimensions": [{"column": "temp", "measurement": "temperature", "unit": "°C"}]}]} >>> dataframe.attrs = attr >>> result = get_display_names(dataframe) >>> result["ruhr-temperature"]["value"] 'temperature [°C]'
- hdhelpers.metadata.get_measurements(multitsframe)¶
Gets measurement (type) of the MTSF metrics from the metadata
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
- Returns:
Dictionary of metrics containing the measurement (type) of the MTSF metrics. If the short measurement (type) of the MTSF metrics is not present it returns None.
- Return type:
defaultdict[str, defaultdict[str, str | None]]
- Raises:
TypeError – If multitsframe is not a DataFrame.
Code example:
>>> attr = { "dataset_metadata": {"metric_key": "external_id"}, ... "metrics": [{"external_id": "column_name", "value_dimensions": [{"column": "temp", "measurement": "temperature"}]}]} >>> dataframe.attrs = attr >>> result = get_measurements(dataframe) >>> result["column_name"]["temp"] 'temperature'
- hdhelpers.metadata.get_metric_info(multitsframe, metric_info)¶
Gets a dictionary of metadata associated to metrics.
In contrast to metadata associated to concrete value dimensions, this function abstracts access to metadata associated to the underlying metric.
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
metric_info (str | Spec) – Name of information to retrieve. Note that metric_info is interpreted as a glom Spec.
- Returns:
Dictionary, where keys are the entries of the metrics metadata specified via “metric_key” in “dataset_metadata” and values are the entries specified via “metric_info” in the metrics metadata
- Return type:
defaultdict[str, Any]
Code example:
>>> multitsframe.attrs = { ... "dataset_metadata": { ... "metric_key": "id" ... }, ... "metrics": [ ... { ... "id": "first", ... "external_id": "external_first", ... "unit": "m", ... "display_name": "first display name", ... "value_dimensions": [ ... { ... "column": "temp", ... "unit": "C", ... "measurement": "temperature" ... } ... ] ... }, ... { ... "id": "second", ... "name": "second name", ... "external_id": "external_second", ... "value_dimensions": [ ... { ... "column": "temp", ... "unit": "C" ... } ... ] ... } ... ] ... } >>> result = get_metric_info(multitsframe, "external_id") >>> result["first"] 'external_first' >>> result["second"] 'external_second' >>> result["not-given"] is None True
- hdhelpers.metadata.get_names(multitsframe)¶
Gets names of the MTSF metrics from the metadata
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
- Returns:
Dictionary of metrics containing the names. If the name is not present for a metric the corresponding value is None.
- Return type:
dict[str, str | None]
- Raises:
TypeError – If multitsframe is not a DataFrame.
Code example:
>>> attr = { "by_metric": { "metric1": {"metric": {"name": "name_of_metric1"}}, ... "metric2": {"metric": {"name": None }} }} >>> dataframe.attrs = attr >>> result = get_names(dataframe) >>> result["metric1"]["value"] 'name_of_metric1' >>> result["metric2"]["value"] is None True
Lets try another MTSF format:
>>> attr = { "dataset_metadata": {"metric_key": "external_id"}, ... "metrics": [{"external_id": "ruhr-temperature", ... "name": "Ruhr temperature [°C]", ... "display_name": "temperature [°C]", ... "short_display_name": "[°C]", ... "value_dimensions": [{"column": "temp", "measurement": "temperature", "unit": "°C"}]}]} >>> dataframe.attrs = attr >>> result = get_names(dataframe) >>> result["ruhr-temperature"]["value"] 'Ruhr temperature [°C]'
- hdhelpers.metadata.get_queried_interval(data)¶
Get queried interval from metadata
- Parameters:
data (pd.Series | pd.DataFrame) – Series or Dataframe with metadata following the convention
- Returns:
Tuple of available start and end date of requested interval.
- Return type:
tuple[datetime.datetime | None, datetime.datetime | None]
- Raises:
ValueError – If metadata of data is not None and not convertible to a datetime-object (ISO-format is expected).
TypeError – If data is not a Series or Dataframe.
Code example:
>>> attr = { ... "dataset_metadata": { ... "ref_interval_start_timestamp": "2025-11-05T13:28:00Z", ... "ref_interval_end_timestamp": "2025-11-06T13:28:00Z" ... } ... } >>> series.attrs = attr >>> start, end = get_queried_interval(series) >>> start.isoformat() '2025-11-05T13:28:00+00:00' >>> end.isoformat() '2025-11-06T13:28:00+00:00'
- hdhelpers.metadata.get_series_display_name(series)¶
Gets display name of the series from metadata
- Parameters:
series (pd.Series) – Series with metadata following the convention.
- Returns:
Returns the display name of the value. If the display name of the metric is not present it returns the display name of the value. If the metric display name is not present it returns the result of
hdhelpers.metadata.get_series_name().- Return type:
str | None
- Raises:
TypeError – If series is not a Series.
Code example:
>>> attr = { "by_metric": { "series": {"metric": {"display_name": "display_name_of_series"}}}} >>> series.attrs = attr >>> get_series_display_name(series) 'display_name_of_series'
- hdhelpers.metadata.get_series_info(series, value_dim_info)¶
Gets an arbitrary series info
Since a series has only one value dimension named “value”, this information is equivalent to information on the metric.
- Parameters:
series (pd.Series) – Series with metadata following the convention.
value_dim_info (str | Spec) – Name of information to retrieve. Note that value_dim_info is interpreted as a glom Spec.
- Returns:
Retrieved information defined by value_dim_info
- Return type:
Any
Code example:
>>> attr = { "by_metric": { "series": {"value_dimensions": {"value": {"unit": "m"}}}}} >>> series.attrs = attr >>> get_series_info(series, "unit") 'm' >>> get_series_info(series, "not-given") is None True
- hdhelpers.metadata.get_series_measurement(series)¶
Gets measurement (type) of the Series from metadata
- Parameters:
series (pd.Series) – Series with metadata following the convention.
- Returns:
Returns the measurement (type) of the value. If “measurement” is not given in the metadata, None is returned.
- Return type:
str | None
- Raises:
TypeError – If series is not a Series.
Code example:
>>> attr = { "by_metric": { "series": { "metric": {"measurement": "temperature"}}}} >>> series.attrs = attr >>> get_series_measurement(series) 'temperature'
- hdhelpers.metadata.get_series_name(series)¶
Gets name of the series from metadata
- Parameters:
series (pd.Series) – Series with metadata following the convention.
- Returns:
Returns the name of the value. If the name of the metric is not present it returns the name of the value. If the value name is not present it returns None.
- Return type:
str | None
- Raises:
TypeError – If series is not a Series.
Let’s test what happens if series has name in value_dimensions:
>>> attr = { "by_metric": { "series": {"value_dimensions": {"value": {"name": "value_name_of_series"}}}}} >>> series.attrs = attr >>> get_series_name(series) 'value_name_of_series'
Let’s test what happens if series has name in metric:
>>> attr = { "by_metric": { "series": {"metric": {"name": "name_of_series_1"}}}} >>> series.attrs = attr >>> get_series_name(series) 'name_of_series_1'
Let’s test what happens if series has name in metric and value_dimensions:
>>> attr = { "single_metric_metadata": { "structured_metadata": {"metric": {"name": "name_of_series_2"}}, ... "value_dimensions": {"value": {"name": "value_name_of_series"}}}} >>> series.attrs = attr >>> get_series_name(series) 'name_of_series_2'
- hdhelpers.metadata.get_series_short_display_name(series)¶
Gets short display name of the Series from metadata
- Parameters:
series (pd.Series) – Series with metadata following the convention.
- Returns:
Returns the short display name of the value. If the short display name of the metric is not present it returns the short display name of the value. If the metric short display name is not present it returns the result of
hdhelpers.metadata.get_series_display_name().- Return type:
str | None
- Raises:
TypeError – If series is not a Series.
Code example:
>>> attr = { "by_metric": { "series": { "metric": {"short_display_name": "short_display_name_of_series"}}}} >>> series.attrs = attr >>> get_series_short_display_name(series) 'short_display_name_of_series'
- hdhelpers.metadata.get_series_unit(series)¶
Gets name of the series from metadata
- Parameters:
series (pd.Series) – Series with metadata following the convention.
- Returns:
Returns the unit of series. If the unit of the series is not present it returns None.
- Return type:
str | None
- Raises:
TypeError – If series is not a Series.
Let’s test what happens if series has no attr:
>>> series.attrs = {} >>> get_series_unit(series) is None True
Let’s test what happens if series has attr but no entry for unit:
>>> attr = { "by_metric": { "series": {"value_dimensions": {"value": {"unit":None}}}}} >>> series.attrs = attr >>> get_series_unit(series) is None True
Let’s test what happens if series has unit in attr:
>>> attr = { "by_metric": { "series": {"value_dimensions": {"value": {"unit":"m/s"}}}}} >>> series.attrs = attr >>> get_series_unit(series) 'm/s'
- hdhelpers.metadata.get_short_display_names(multitsframe)¶
Gets short display names of the MTSF metrics from the metadata
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
- Returns:
Dictionary of metrics containing the short display names. If the short display name of the metrics is not present it returns the result of
hdhelpers.metadata.get_display_names().- Return type:
defaultdict[str, defaultdict[str, str | None]]
- Raises:
TypeError – If multitsframe is not a DataFrame.
Code example:
>>> attr = { "by_metric": { "metric1": {"metric": {"short_display_name": "short_display_name_of_metric1"}}, ... "metric2": {"metric": {"name": "name_of_metric2"}}, ... "metric3": {"metric": {"name": None}} }} >>> dataframe.attrs = attr >>> result = get_short_display_names(dataframe) >>> result["metric1"]["value"] 'short_display_name_of_metric1' >>> result["metric2"]["value"] 'name_of_metric2' >>> result["metric3"]["value"] is None True
Lets try another MTSF format:
>>> attr = { "dataset_metadata": {"metric_key": "external_id"}, ... "metrics": [{"external_id": "ruhr-temperature", ... "name": "Ruhr temperature [°C]", ... "display_name": "temperature [°C]", ... "short_display_name": "temp. [°C]", ... "value_dimensions": [{"column": "temp", "measurement": "temperature", "unit": "°C"}]}]} >>> dataframe.attrs = attr >>> result = get_short_display_names(dataframe) >>> result["ruhr-temperature"]["value"] 'temp. [°C]'
- hdhelpers.metadata.get_units(multitsframe)¶
Gets unit of value dimensions in MTSF metrics from Metadata
- Parameters:
multitsframe (pd.DataFrame) – MTSF with metadata following the convention.
- Returns:
Dictionary of metrics containing the names of the value dimensions. If the short display name of the value_dimension is not present it returns the result of get_value_dimension_info().
- Return type:
dict[str, dict[str | None] | None]
- Raises:
TypeError – If multitsframe is not a DataFrame.
Code example:
>>> attr = { ... "by_metric": { ... "metric1": { ... "value_dimensions": { ... "value_dim_1": { ... "unit": "m" ... } ... } ... }, ... "metric3": { ... "value_dimensions": { ... "value_dim_1": { ... "unit": None, ... } ... } ... } ... } ... } >>> dataframe.attrs = attr >>> result = get_units(dataframe) >>> result["metric1"]['value_dim_1'] 'm' >>> result["metric3"]['value_dim_1'] is None True >>> result["metric2"]['value_dim_1'] is None True
helpers¶
Collection of useful functions to ease some operations in hetida designer code.
- hdhelpers.helpers.modify_timezone(object_to_convert, to_timezone=None, column_names=None, convert_index=True)¶
Converts time information of pandas objects to a certain timezone
This function is applicable to index and/or columns of pd.Series or pd.DataFrame as well as for single pd.Timestamp objects.
- Parameters:
object_to_convert (pd.Timestamp | pd.Series | pd.DataFrame) – Timestamp, Series or DataFrame where timezone is modified
to_timezone (str | None) – Timezone to convert to, e.g. for German time use “Europe/Berlin”. See possible timezone strings in pandas’ tz_convert method or pytz all_timezones list. If to_timezone is not defined, the global timezone from plot_target_settings is used. .
column_names (str | None) – List of column_names to modify. For pd.Series the default behaviour is modifying the index and for pd.DataFrame the default behaviour is modifying the column “timestamp”. This option is not applicable in case object_to_convert is a pd.Timestamp.
convert_index (bool | None) – Boolean that controls whether the index of pd.Dataframe or pd.Series should be transformed. Note that for a pd.Series setting this option to true results in the same output as using column_names=None. This option is not applicable in case object_to_convert is a pd.Timestamp.
- Returns:
Returns the modified timezone object.
- Return type:
pd.Timestamp | pd.Series | pd.DataFrame
- Raises:
TypeError – If object_to_convert is not a pd.Series, pd.Timestamp, pd.DataFrame.
Code example:
>>> from hdhelpers.helpers import modify_timezone >>> modified_timezone = modify_timezone(pd.to_datetime("2025-01-01T01:00:00+05:00"), to_timezone="Europe/Berlin") >>> int(modified_timezone.utcoffset().total_seconds()) 3600
exceptions¶
- exception hdhelpers.exceptions.HelperException(*args, error_code='', extra_information=None, **kwargs)¶
Bases:
ExceptionException to re-raise exceptions with error code raised in the code of the hdhelpers package.
- Parameters:
args (Any)
error_code (int | str)
extra_information (dict | None)
kwargs (Any)
- Return type:
None
- exception hdhelpers.exceptions.InsufficientPlottingData(*args, error_code='', extra_information=None, **kwargs)¶
Bases:
HelperExceptionA plot component has insufficient data to generate a meaningful plot
This exception class should be used when custom plots generated by hetida designer are integrated in other frontends. This allows the frontend to handle the case of e.g. no data to show in a sensible way, surpressing an empty plot and showing an adequate message instead.
- Parameters:
args (Any)
error_code (int | str)
extra_information (dict | None)
kwargs (Any)
- Return type:
None