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.get_locale(explicit_locale=None)¶
Extract (Plotly) locale
Infers Plotly locale from plot target settings or returns explicit provided locale.
- Parameters:
explicit_locale (str | None) – Defaults to None. Locale string like “de”, “en-US” or similar. Will be returned instead of what is inferred from plot_target_settings if provided
- Returns:
Extracted locale (like “de_DE”)
- Return type:
str | None
Code example:
>>> get_locale("de_DE") # returns "de-DE" 'de-DE' >>> print(get_locale()) # returns locale from plot target settings of execution or None None
- 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. If time zone information is not defined in object to convert it is assumed that it is in UTC. Please note that column_names and convert_index are not exclusive to enable modifying both at the same time. To enable modifying the value of a series (not the index), please name the series and define the series’ name in column_names.
- 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
plotting¶
Collection of useful functions to ease plotting.
- hdhelpers.plotting.resolve_color(color_str)¶
Resolves Fuseki Colors and returns resulting color string
Non-fuseki (color) strings are returned just as they are.
- Parameters:
color_str (str) – Color string like “#ea1255”, “orange” or “ki.shade” (Fuseki color)
- Returns:
Returns the resolved color string.
- Return type:
str
Code example:
>>> resolve_color("red") 'red' >>> resolve_color("ki.energy") '#eb6962'
- hdhelpers.plotting.set_agnostic_theme(fig)¶
Set Plotly template of figure to a theme agnostic template
This Plotly template should yield good results for both light and dark themed backgrounds.
- Parameters:
fig (plotly Figure object) – Plotly figure object whose template will be set.
- Returns:
Returns None, since the figure object is modified in place
- Return type:
None
Code example:
>>> import plotly.graph_objects as go >>> fig = go.Figure(data=go.Scatter(x=[1, 2, 3], y=[1, 4, 9])) >>> set_agnostic_theme(fig)
- hdhelpers.plotting.set_dt_ticks(fig)¶
Set x datetime tick labels to language agnostic format
Sets the x axes tick format of the Plotly Figure to some isoformat inspired timestamp format, adequately for multiple zoom levels.
Infers Plotly locale from plot target settings or returns explicit provided locale.
- Parameters:
fig (plotly Figure object) – Plotly figure object whose x axes will be modified.
- Returns:
Returns None, since the figure object is modified in place
- Return type:
None
Code example:
>>> import plotly.graph_objects as go >>> fig = go.Figure(data=go.Scatter(x=["2024-01-01", "2024-01-02"], y=[1, 4])) >>> set_dt_ticks(fig)
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