diff --git a/CHANGELOG.md b/CHANGELOG.md index faf4b99..5cf9255 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -## [0.0.2] - 2026-XX-XX +## [0.0.3] - 2026-06-23 +- Fixes in modifiy_timezone +- Disarm dependencies to ease compatibility to designer development +- Enhance documentation + +## [0.0.2] - 2026-05-21 - Include helpers for metadata - Include helper function for modify timezone - Publish sphinx documentation on GitHub Pages diff --git a/README.md b/README.md index 8203906..83de197 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ writing component code. Once you are done writing your code, including unit tests, use `./run check` to see if your code quality is sufficient. ### Documentation -Fr documentation we use the tool sphinx. Please apply `./run build_docs` to create the current state of documentation. It will be stored in **docs**. You can open the documentation by opening `docs/index.html`, e.g. with your browser. +For documentation we use the tool sphinx. Please apply `./run build_docs` to create the current state of documentation. It will be stored in **docs**. You can open the documentation by opening `docs/index.html`, e.g. with your browser. ### Build, Release and Publish The first step for publishing a new package version is creating and merging a pull request from develop to main. @@ -96,9 +96,21 @@ To **publish** the build from the `dist` subdirectory to PyPI, 1) tag your main branch with the specified package version -2) use `uv publish --index testpypi --token `. You need a (Test-)PyPI account with a token and you need maintainer/owner access to the [hdhelpers (Test-)PyPI project](https://pypi.org/project/hdhelpers/). +2) use `uv publish --index testpypi --token `. You need a Test-PyPI account with a token and you need maintainer/owner access to the [hdhelpers Test-PyPI project](https://test.pypi.org/project/hdhelpers/). -3) After publishing please communicate to the hetida designer team so upgrade there dependencies. +3) verifiy that package can be installed by using: +```bash +uv run --with 'hdhelpers==' + --refresh-package hdhelpers + --default-index https://test.pypi.org/simple/ + --index https://test.pypi.org/simple/ + --no-project + -- python -c "import hdhelpers; print(hdhelpers.__version__)" +``` + +4) use `uv publish dist/*` to upload the package on [hdhelpers PyPI project](https://pypi.org/project/hdhelpers/). + +5) After publishing please communicate to the hetida designer team so upgrade there dependencies. The hetida designer docker compose setup installs hdhelpers from [PyPI](https://pypi.org) as it does with any dependency listed in `runtime/requirements.in`. ### Notes diff --git a/docs/_sources/first_steps.rst.txt b/docs/_sources/first_steps.rst.txt index 46e7dbf..fd7d6e0 100644 --- a/docs/_sources/first_steps.rst.txt +++ b/docs/_sources/first_steps.rst.txt @@ -5,8 +5,8 @@ First steps How to get metadata with hdhelpers? =================================== -Let's say we want to plot a timeseries with data points. -In hetida designer this series can be represented as json for *direct provisioning* : +Let's say we want to retrieve the metadata of a timeseries. +In hetida designer this series can be represented as json for *direct provisioning* .. code-block:: json @@ -34,7 +34,7 @@ In hetida designer this series can be represented as json for *direct provisioni } } -We can retrieve the name and unit for example with the following code +We can retrieve the name and unit of the series with the following code .. code-block:: python @@ -43,7 +43,7 @@ We can retrieve the name and unit for example with the following code def main(*, series): # entrypoint function for this component # ***** DO NOT EDIT LINES ABOVE ***** - # write your function code here. + name = get_series_name(series) unit = get_series_unit(series) @@ -54,36 +54,14 @@ We can retrieve the name and unit for example with the following code How to use hdhelpers for plotting? (tbd) ======================================== -Let's say we want to plot a timeseries with data points. -In hetida designer this series can be represented as json for *direct provisioning* : +Let's say we want to plot the same timeseries above using hdhelpers functionalities. +For example, we want to: +- plot the timeseries in a corresponding timezone, +- set the limits of the x-axis corresponding to the metadata, +- define the label of the y-axis corresponding to the metadata, +- and use standard colors for plotting. -.. code-block:: json - - { - "__hd_wrapped_data_object__":"SERIES", - "__metadata__": { - "single_metric_dataset_metadata": { - "ref_interval_end_timestamp":"2020-01-01T08:20:00.000Z", - "ref_interval_start_timestamp": "2020-01-01T08:10:00.000Z" - }, - "single_metric_metadata": { - "structured_metadata": { - "metric": { - "short_display_name": "Water Level", - "unit": "cm" - } - } - } - }, - "__data__": { - "2020-01-01T08:10:00+00:00": 1, - "2020-01-01T08:15:00+00:00": 2, - "2020-01-01T08:16:00+00:00": 3, - "2020-01-01T08:17:00+00:00": 4, - } - } - -Our component code might look like this to plot this series: +Our component code might look like this to plot the timeseries accordingly: .. code-block:: python @@ -94,7 +72,7 @@ Our component code might look like this to plot this series: def main(*, series): # entrypoint function for this component # ***** DO NOT EDIT LINES ABOVE ***** - # write your function code here. + series = modify_timezone(series) colors = get_colors_from_plot_target_settings() @@ -108,72 +86,15 @@ Our component code might look like this to plot this series: return {"plot": plotly_fig_to_json_dict(fig=fig)} -First, we use *modify_timezone* to set the timezone. Since our goal is just to make sure that the timestamps are -timezone aware, not to convert it to a specific timezone, we do not pass a value for the `timezone` parameter. That way, -if there is a `plot_target_timezone` set in the hetida designer's `plot_target_settings` context variable, that timezone -will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive. - -With the timezone-corrected data in place, we turn it into a plotly Scatter Figure object called `fig`, that we can then -style to our liking. We want to customize said scatter plot by coloring the markers. To find a fitting color, we use -`get_colors_from_plot_target_settings`, which returns the `plot_target_style` property of the `plot_target_settings` -context variable. It contains a set of colors with specific purposes, such as `background_color`, and the -`status_colors` object, which in turn contains the four status colors: `success_color`, `error_color`, `warn_color`, and -`info_color`. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, -we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the `warn_color` for -`fig`'s `marker["color"]` property, which determines the plot's marker and line color. - -Now, we use `get_and_pad_start_and_end_timestamp` for precise control over the x-axis range. We do not set `start` and -`end` explicitly because we want to parse them from the series metadata, which reflects the chosen interval for which -plotting data was requested. This way, we can see that there is missing data from 8:18 to 8:20, where normally Plotly -would not have included that time range in the plot. We do not pass a `timezone` for the same reasons as with -`modify_timezone`. We also set a `start_padding`, so the markers of the first data point is not cut in half by the edge -of the plot. With start and end parsed, we can update `fig`'s x-axis range. - -Next, we use `get_y_axis_label` so our y-axis can be labeled with the series metadata. With the above input series, -title and unit will be parsed from the series metadata, but in case the component is ever run without series metadata, -we provide a `default_title`, but we leave the `default_unit` at its empty default value. Then, we update `fig` with our -title. - -Lastly, we use `plotly_fig_to_json_dict` to apply standardized stylings and serialize the plotly figure into a json -dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not -have to set any for this example. - -As a result we get the following plot: - -Further Explanation -=================== - -* `use_platform_defaults=True` sets the following flags to `True`, which are by default `False`: -* `hide_legend` sets the plotly layout parameter `showlegend=False` to hide the plot's legend -* `hide_x_title` sets the plotly xaxes parameter `title_text=''` to hide the x-axis title -* `remove_plotly_bar` sets the plotly figure's `displayModeBar` setting to `False` to remove the plotly bar from the plot -* `update_x_axes_tickformat` sets the plotly xaxes parameter `tickformat` to the `datetime_tick_format` property the hetida platform writes into the hetida designer's `plot_target_settings` context variable (unless the property is `None`) -* `use_default_standoff` sets the plotly yaxes parameter `title_standoff=5` -* `use_muplot_axes_color` sets the plotly xaxes and yaxes parameter `color` to the `axes_label_color` property the hetida platform writes into the hetida designer's `plot_target_settings` context variable (unless the property is `None`) -* `use_muplot_grid` makes the plotly grid visible and colors it in according to the `grid_color` property the hetida platform writes into the hetida designer's `plot_target_settings` context variable (unless the property is `None`) -* `use_muplot_line_and_markers` sets the plotly traces to the following style, which matches the hetida platform's µplots: +Explanation +----------- -.. code-block:: json +- *modify_timezone*: We use `modify_timezone` function to set the timezone. Since our goal is just to make sure that the timestamps are timezone aware, not to convert it to a specific timezone, we do not pass a value for the `timezone` parameter. That way, if there is a `plot_target_timezone` set in the hetida designer's `plot_target_settings` context variable, that timezone will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive. - { - "marker": {"size": 3}, - "line": {"width": 1}, - "mode": "lines+markers", - "marker_symbol": "circle", - } +- *get_colors_from_plot_target_settings*: To use a (global) standard color, we use `get_colors_from_plot_target_settings`, which returns the `plot_target_style` property of the `plot_target_settings` context variable. It contains a set of colors with specific purposes, such as `background_color`, and the `status_colors` object, which in turn contains the four status colors: `success_color`, `error_color`, `warn_color`, and `info_color`. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the `warn_color` for `fig`'s `marker["color"]` property, which determines the plot's marker and line color. + +- *get_and_pad_start_and_end_timestamp*: We use `get_and_pad_start_and_end_timestamp` for precise control over the x-axis range. We do not set `start` and `end` explicitly because we want to parse them from the metadata, which reflects the chosen interval for which the data was requested. This way, we can see that there is missing data from 8:18 to 8:20. In the default behaviour of plotly this time range would not have been included possibly hiding missing data. Note: (1) We do not pass a `timezone` for the same reasons as with `modify_timezone`. (2) We also set a `start_padding`, so the markers of the first data point is not cut in half by the edge of the plot. + +- *get_y_axis_label*: We use `get_y_axis_label` so our y-axis can be labeled by using information from the metadata. With the above input series, title and unit will be parsed from the metadata. In case the metadata does not contain the mentioned information, we provide a `default_title`, and `default_unit` to configure the axis label in such cases. -* `use_platform_background` sets the plotly layout parameter `paper_bgcolor` to the `background_color` property the - hetida platform writes into the hetida designer's `plot_target_settings` context variable (unless the property is - `None`) and it sets `plot_bgcolor=rgba(0,0,0,0)` so the "paper background" is visible through the "plot background" -* `plotly_fig_to_json_dict` has four more boolean parameters: - * `add_config_settings` sets the plotly figure's locale to - the `plot_target_locale` property the hetida platform writes into the hetida designer's `plot_target_settings` context - variable (unless the property is `None`) - * `remove_plotly_icon` sets the plotly figure's `displaylogo` setting to - `False` to remove the plotly logo from the plot - * `use_minimum_margin` sets the plotly layout parameter - `margin={"autoexpand": True, "l": 0, "r": 0, "b": 0, "t": 0, "pad": 0}` to minimize the plot's margins - * `use_platform_colorway` sets the plotly layout parameter `colorway` to the `line_colors` property the hetida platform - writes into the hetida designer's `plot_target_settings` context variable (unless the property is `None`). Note that in - Plotly, explicitly set line colors have higher priority than those in the colorway, so setting this parameter to `False` - is rarely necessary. * `use_simple_white_template` sets the plotly layout parameter `template=simple_white` +- *plotly_fig_to_json_dict*: We use `plotly_fig_to_json_dict` to apply standardized stylings and serialize the plotly figure into a json dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not have to set any for this example. diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt index d74199d..e902d3a 100644 --- a/docs/_sources/index.rst.txt +++ b/docs/_sources/index.rst.txt @@ -14,10 +14,10 @@ hdhelpers is a package designed for and included in the standard installation of 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) +* 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). .. _hetida designer: https://github.com/hetida/hetida-designer .. _hetida platform: https://hetida.io/ diff --git a/docs/first_steps.html b/docs/first_steps.html index 146c434..f0b36ca 100644 --- a/docs/first_steps.html +++ b/docs/first_steps.html @@ -44,8 +44,8 @@

Navigation

First steps

How to get metadata with hdhelpers?

-

Let’s say we want to plot a timeseries with data points. -In hetida designer this series can be represented as json for direct provisioning :

+

Let’s say we want to retrieve the metadata of a timeseries. +In hetida designer this series can be represented as json for direct provisioning

{
     "__hd_wrapped_data_object__":"SERIES",
     "__metadata__": {
@@ -71,13 +71,13 @@ 

How to get metadata with hdhelpers?}

-

We can retrieve the name and unit for example with the following code

+

We can retrieve the name and unit of the series with the following code

from hdhelpers.metadata import get_series_name, get_series_unit
 
 def main(*, series):
     # entrypoint function for this component
     # ***** DO NOT EDIT LINES ABOVE *****
-    # write your function code here.
+
     name = get_series_name(series)
     unit = get_series_unit(series)
 
@@ -87,34 +87,13 @@ 

How to get metadata with hdhelpers?

How to use hdhelpers for plotting? (tbd)

-

Let’s say we want to plot a timeseries with data points. -In hetida designer this series can be represented as json for direct provisioning :

-
{
-    "__hd_wrapped_data_object__":"SERIES",
-    "__metadata__": {
-        "single_metric_dataset_metadata": {
-            "ref_interval_end_timestamp":"2020-01-01T08:20:00.000Z",
-            "ref_interval_start_timestamp": "2020-01-01T08:10:00.000Z"
-        },
-        "single_metric_metadata": {
-            "structured_metadata": {
-                "metric": {
-                    "short_display_name": "Water Level",
-                    "unit": "cm"
-                }
-            }
-        }
-    },
-    "__data__": {
-        "2020-01-01T08:10:00+00:00": 1,
-        "2020-01-01T08:15:00+00:00": 2,
-        "2020-01-01T08:16:00+00:00": 3,
-        "2020-01-01T08:17:00+00:00": 4,
-    }
-}
-
-
-

Our component code might look like this to plot this series:

+

Let’s say we want to plot the same timeseries above using hdhelpers functionalities. +For example, we want to: +- plot the timeseries in a corresponding timezone, +- set the limits of the x-axis corresponding to the metadata, +- define the label of the y-axis corresponding to the metadata, +- and use standard colors for plotting.

+

Our component code might look like this to plot the timeseries accordingly:

from hdhelpers.plotting import get_and_pad_start_and_end_timestamp, get_y_axis_label, plotly_fig_to_json_dict
 from hdhelpers.helpers import modify_timezone
 import plotly.graph_objects as go
@@ -122,7 +101,7 @@ 

How to use hdhelpers for plotting? (tbd)def main(*, series): # entrypoint function for this component # ***** DO NOT EDIT LINES ABOVE ***** - # write your function code here. + series = modify_timezone(series) colors = get_colors_from_plot_target_settings() @@ -137,77 +116,17 @@

How to use hdhelpers for plotting? (tbd)return {"plot": plotly_fig_to_json_dict(fig=fig)}

-

First, we use modify_timezone to set the timezone. Since our goal is just to make sure that the timestamps are -timezone aware, not to convert it to a specific timezone, we do not pass a value for the timezone parameter. That way, -if there is a plot_target_timezone set in the hetida designer’s plot_target_settings context variable, that timezone -will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive.

-

With the timezone-corrected data in place, we turn it into a plotly Scatter Figure object called fig, that we can then -style to our liking. We want to customize said scatter plot by coloring the markers. To find a fitting color, we use -get_colors_from_plot_target_settings, which returns the plot_target_style property of the plot_target_settings -context variable. It contains a set of colors with specific purposes, such as background_color, and the -status_colors object, which in turn contains the four status colors: success_color, error_color, warn_color, and -info_color. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, -we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the warn_color for -fig’s marker[“color”] property, which determines the plot’s marker and line color.

-

Now, we use get_and_pad_start_and_end_timestamp for precise control over the x-axis range. We do not set start and -end explicitly because we want to parse them from the series metadata, which reflects the chosen interval for which -plotting data was requested. This way, we can see that there is missing data from 8:18 to 8:20, where normally Plotly -would not have included that time range in the plot. We do not pass a timezone for the same reasons as with -modify_timezone. We also set a start_padding, so the markers of the first data point is not cut in half by the edge -of the plot. With start and end parsed, we can update fig’s x-axis range.

-

Next, we use get_y_axis_label so our y-axis can be labeled with the series metadata. With the above input series, -title and unit will be parsed from the series metadata, but in case the component is ever run without series metadata, -we provide a default_title, but we leave the default_unit at its empty default value. Then, we update fig with our -title.

-

Lastly, we use plotly_fig_to_json_dict to apply standardized stylings and serialize the plotly figure into a json -dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not -have to set any for this example.

-

As a result we get the following plot:

-

-
-

Further Explanation

+
+

Explanation

    -
  • use_platform_defaults=True sets the following flags to True, which are by default False:

  • -
  • hide_legend sets the plotly layout parameter showlegend=False to hide the plot’s legend

  • -
  • hide_x_title sets the plotly xaxes parameter title_text=’’ to hide the x-axis title

  • -
  • remove_plotly_bar sets the plotly figure’s displayModeBar setting to False to remove the plotly bar from the plot

  • -
  • update_x_axes_tickformat sets the plotly xaxes parameter tickformat to the datetime_tick_format property the hetida platform writes into the hetida designer’s plot_target_settings context variable (unless the property is None)

  • -
  • use_default_standoff sets the plotly yaxes parameter title_standoff=5

  • -
  • use_muplot_axes_color sets the plotly xaxes and yaxes parameter color to the axes_label_color property the hetida platform writes into the hetida designer’s plot_target_settings context variable (unless the property is None)

  • -
  • use_muplot_grid makes the plotly grid visible and colors it in according to the grid_color property the hetida platform writes into the hetida designer’s plot_target_settings context variable (unless the property is None)

  • -
  • use_muplot_line_and_markers sets the plotly traces to the following style, which matches the hetida platform’s µplots:

  • -
-
{
-    "marker": {"size": 3},
-    "line": {"width": 1},
-    "mode": "lines+markers",
-    "marker_symbol": "circle",
-}
-
-
-
    -
  • use_platform_background sets the plotly layout parameter paper_bgcolor to the background_color property the -hetida platform writes into the hetida designer’s plot_target_settings context variable (unless the property is -None) and it sets plot_bgcolor=rgba(0,0,0,0) so the “paper background” is visible through the “plot background”

  • -
  • -
    plotly_fig_to_json_dict has four more boolean parameters:
      -
    • add_config_settings sets the plotly figure’s locale to -the plot_target_locale property the hetida platform writes into the hetida designer’s plot_target_settings context -variable (unless the property is None)

    • -
    • remove_plotly_icon sets the plotly figure’s displaylogo setting to -False to remove the plotly logo from the plot

    • -
    • use_minimum_margin sets the plotly layout parameter -margin={“autoexpand”: True, “l”: 0, “r”: 0, “b”: 0, “t”: 0, “pad”: 0} to minimize the plot’s margins

    • -
    • use_platform_colorway sets the plotly layout parameter colorway to the line_colors property the hetida platform -writes into the hetida designer’s plot_target_settings context variable (unless the property is None). Note that in -Plotly, explicitly set line colors have higher priority than those in the colorway, so setting this parameter to False -is rarely necessary. * use_simple_white_template sets the plotly layout parameter template=simple_white

    • -
    -
    -
    -
  • +
  • modify_timezone: We use modify_timezone function to set the timezone. Since our goal is just to make sure that the timestamps are timezone aware, not to convert it to a specific timezone, we do not pass a value for the timezone parameter. That way, if there is a plot_target_timezone set in the hetida designer’s plot_target_settings context variable, that timezone will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive.

  • +
  • get_colors_from_plot_target_settings: To use a (global) standard color, we use get_colors_from_plot_target_settings, which returns the plot_target_style property of the plot_target_settings context variable. It contains a set of colors with specific purposes, such as background_color, and the status_colors object, which in turn contains the four status colors: success_color, error_color, warn_color, and info_color. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the warn_color for fig’s marker[“color”] property, which determines the plot’s marker and line color.

  • +
  • get_and_pad_start_and_end_timestamp: We use get_and_pad_start_and_end_timestamp for precise control over the x-axis range. We do not set start and end explicitly because we want to parse them from the metadata, which reflects the chosen interval for which the data was requested. This way, we can see that there is missing data from 8:18 to 8:20. In the default behaviour of plotly this time range would not have been included possibly hiding missing data. Note: (1) We do not pass a timezone for the same reasons as with modify_timezone. (2) We also set a start_padding, so the markers of the first data point is not cut in half by the edge of the plot.

  • +
  • get_y_axis_label: We use get_y_axis_label so our y-axis can be labeled by using information from the metadata. With the above input series, title and unit will be parsed from the metadata. In case the metadata does not contain the mentioned information, we provide a default_title, and default_unit to configure the axis label in such cases.

  • +
  • plotly_fig_to_json_dict: We use plotly_fig_to_json_dict to apply standardized stylings and serialize the plotly figure into a json dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not have to set any for this example.

+
@@ -222,8 +141,10 @@

Table of Contents

diff --git a/docs/index.html b/docs/index.html index 8db7833..fb8af20 100644 --- a/docs/index.html +++ b/docs/index.html @@ -47,10 +47,10 @@

Introductionhetida 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)

  • +
  • 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).

@@ -60,7 +60,6 @@

Further InformationFirst steps diff --git a/docs/searchindex.js b/docs/searchindex.js index 21c714c..7ee22af 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({"alltitles":{"First steps":[[0,null]],"Functions":[[1,"functions"]],"Further Explanation":[[0,"further-explanation"]],"Further Information":[[1,"further-information"]],"How to get metadata with hdhelpers?":[[0,"how-to-get-metadata-with-hdhelpers"]],"How to use hdhelpers for plotting? (tbd)":[[0,"how-to-use-hdhelpers-for-plotting-tbd"]],"Introduction":[[1,"introduction"]],"exceptions":[[1,"module-hdhelpers.exceptions"]],"hdhelpers":[[1,null]],"helpers":[[1,"module-hdhelpers.helpers"]],"metadata":[[1,"module-hdhelpers.metadata"]]},"docnames":["first_steps","index"],"envversion":{"sphinx":66,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["first_steps.rst","index.rst"],"indexentries":{"get_display_names() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_display_names",false]],"get_measurements() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_measurements",false]],"get_metric_info() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_metric_info",false]],"get_names() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_names",false]],"get_queried_interval() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_queried_interval",false]],"get_series_display_name() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_display_name",false]],"get_series_info() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_info",false]],"get_series_measurement() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_measurement",false]],"get_series_name() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_name",false]],"get_series_short_display_name() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_short_display_name",false]],"get_series_unit() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_series_unit",false]],"get_short_display_names() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_short_display_names",false]],"get_units() (in module hdhelpers.metadata)":[[1,"hdhelpers.metadata.get_units",false]],"hdhelpers.exceptions":[[1,"module-hdhelpers.exceptions",false]],"hdhelpers.helpers":[[1,"module-hdhelpers.helpers",false]],"hdhelpers.metadata":[[1,"module-hdhelpers.metadata",false]],"helperexception":[[1,"hdhelpers.exceptions.HelperException",false]],"insufficientplottingdata":[[1,"hdhelpers.exceptions.InsufficientPlottingData",false]],"modify_timezone() (in module hdhelpers.helpers)":[[1,"hdhelpers.helpers.modify_timezone",false]],"module":[[1,"module-hdhelpers.exceptions",false],[1,"module-hdhelpers.helpers",false],[1,"module-hdhelpers.metadata",false]]},"objects":{"hdhelpers":[[1,0,0,"-","exceptions"],[1,0,0,"-","helpers"],[1,0,0,"-","metadata"]],"hdhelpers.exceptions":[[1,1,1,"","HelperException"],[1,1,1,"","InsufficientPlottingData"]],"hdhelpers.helpers":[[1,2,1,"","modify_timezone"]],"hdhelpers.metadata":[[1,2,1,"","get_display_names"],[1,2,1,"","get_measurements"],[1,2,1,"","get_metric_info"],[1,2,1,"","get_names"],[1,2,1,"","get_queried_interval"],[1,2,1,"","get_series_display_name"],[1,2,1,"","get_series_info"],[1,2,1,"","get_series_measurement"],[1,2,1,"","get_series_name"],[1,2,1,"","get_series_short_display_name"],[1,2,1,"","get_series_unit"],[1,2,1,"","get_short_display_names"],[1,2,1,"","get_units"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function"},"terms":{"000z":0,"00z":1,"01t01":1,"01t08":0,"05t13":1,"06t13":1,"5s":0,"A":1,"All":0,"As":0,"DO":0,"For":1,"How":1,"If":1,"In":[0,1],"It":[0,1],"NOT":0,"Our":0,"That":0,"The":0,"Then":0,"This":[0,1],"To":0,"We":0,"With":0,"__data__":0,"__hd_wrapped_data_object__":0,"__metadata__":0,"abov":0,"abstract":1,"access":1,"accord":0,"activ":0,"add_config_set":0,"adequ":1,"adit":1,"adjust":1,"all_timezon":1,"allow":1,"also":0,"ani":[0,1],"anoth":1,"appli":0,"applic":1,"arbitrari":1,"arg":1,"associ":1,"attr":1,"autoexpand":0,"avail":1,"awar":0,"axes_label_color":0,"axi":0,"b":0,"background":0,"background_color":0,"bar":0,"base":1,"becaus":0,"behaviour":1,"berlin":1,"bool":1,"boolean":[0,1],"by_metr":1,"c":1,"call":0,"can":[0,1],"case":[0,1],"certain":1,"chosen":0,"circl":0,"class":1,"cm":0,"code":[0,1],"collect":1,"color":0,"colorway":0,"column":1,"column_nam":1,"communic":0,"compli":1,"compon":[0,1],"concret":1,"contain":[0,1],"context":[0,1],"contrast":1,"control":[0,1],"convent":1,"convert":[0,1],"convert_index":1,"convey":0,"correct":0,"correspond":1,"current":0,"custom":[0,1],"cut":0,"danger":0,"data":[0,1],"datafram":1,"dataset_metadata":1,"date":1,"datetim":1,"datetime_tick_format":0,"def":0,"default":[0,1],"default_titl":0,"default_unit":0,"defaultdict":1,"defin":1,"deprec":[],"design":[0,1],"detail":0,"determin":0,"dict":[0,1],"dictionari":1,"dimens":1,"direct":0,"display":1,"display_nam":1,"display_name_of_metric1":1,"display_name_of_seri":1,"displaylogo":0,"displaymodebar":0,"e":1,"eas":1,"edg":0,"edit":0,"empti":[0,1],"end":[0,1],"entri":1,"entrypoint":0,"equival":1,"error":1,"error_cod":1,"error_color":0,"especi":1,"europ":1,"ever":0,"exampl":[0,1],"expect":1,"explan":1,"explicit":0,"external_first":1,"external_id":1,"external_second":1,"extra_inform":1,"extract":1,"fals":0,"fig":0,"figur":0,"find":0,"first":1,"fit":0,"flag":0,"follow":[0,1],"format":1,"four":0,"frontend":1,"full_titl":0,"function":0,"g":1,"generat":1,"german":1,"get":1,"get_and_pad_start_and_end_timestamp":0,"get_colors_from_plot_target_set":0,"get_display_nam":1,"get_measur":1,"get_metric_info":1,"get_nam":1,"get_queried_interv":1,"get_series_display_nam":1,"get_series_info":1,"get_series_measur":1,"get_series_nam":[0,1],"get_series_short_display_nam":1,"get_series_unit":[0,1],"get_short_display_nam":1,"get_unit":1,"get_value_dimension_info":1,"get_y_axis_label":0,"given":1,"global":1,"glom":1,"go":0,"goal":0,"graph_object":0,"grid":0,"grid_color":0,"half":0,"handl":1,"happen":1,"hardwir":0,"helper":0,"helperexcept":1,"hetida":[0,1],"hide":0,"hide_legend":0,"hide_x_titl":0,"higher":0,"id":1,"import":[0,1],"includ":[0,1],"index":[0,1],"info":1,"info_color":0,"input":0,"instal":1,"instead":1,"insuffici":1,"insufficientplottingdata":1,"int":1,"integr":1,"intend":0,"interpret":1,"interv":[0,1],"iso":1,"isoformat":1,"json":[0,1],"just":0,"keep":0,"key":1,"kwarg":1,"l":0,"label":0,"last":0,"layout":0,"leav":0,"legend":0,"let":[0,1],"level":0,"like":[0,1],"line":0,"line_color":0,"list":1,"local":0,"logo":0,"look":0,"m":1,"magnitud":0,"main":0,"make":0,"margin":0,"marker":0,"marker_symbol":0,"match":0,"meaning":1,"measur":1,"messag":[0,1],"method":1,"metric":[0,1],"metric1":1,"metric2":1,"metric3":1,"metric_info":1,"metric_key":1,"might":0,"minim":0,"miss":0,"mode":0,"modifi":1,"modified_timezon":1,"modify_timezon":[0,1],"modifyng":[],"mtsf":1,"multitsfram":1,"naiv":0,"name":[0,1],"name_of_metric1":1,"name_of_metric2":1,"name_of_series_1":1,"name_of_series_2":1,"necessari":0,"next":0,"none":[0,1],"normal":0,"note":[0,1],"now":0,"object":[0,1],"object_to_convert":1,"one":1,"onli":1,"oper":1,"option":[0,1],"order":0,"otherwis":0,"output":1,"packag":1,"pad":0,"panda":1,"paper":0,"paper_bgcolor":0,"paramet":[0,1],"pars":0,"pass":0,"pd":1,"place":0,"platform":[0,1],"plot":1,"plot_bgcolor":0,"plot_target_local":0,"plot_target_set":[0,1],"plot_target_styl":0,"plot_target_timezon":0,"plotly_fig_to_json_dict":0,"point":0,"possibl":1,"potenti":0,"precis":0,"present":1,"prioriti":0,"properti":0,"provid":[0,1],"provis":0,"purpos":0,"pytz":1,"queri":1,"r":0,"rais":1,"rang":0,"rare":0,"re":1,"reason":0,"ref_interval_end_timestamp":[0,1],"ref_interval_start_timestamp":[0,1],"reflect":0,"remov":0,"remove_plotly_bar":0,"remove_plotly_icon":0,"repres":0,"request":[0,1],"result":[0,1],"retriev":[0,1],"return":[0,1],"rgba":0,"ruhr":1,"run":0,"s":[0,1],"said":0,"say":0,"scatter":0,"scheme":1,"second":1,"see":[0,1],"sensibl":1,"seri":[0,1],"serial":[0,1],"set":[0,1],"short":1,"short_display_nam":[0,1],"short_display_name_of_metric1":1,"short_display_name_of_seri":1,"show":1,"showlegend":0,"simple_whit":0,"sinc":[0,1],"singl":1,"single_metric_dataset_metadata":0,"single_metric_metadata":[0,1],"size":0,"soon":[],"spec":1,"specif":0,"specifi":1,"standard":[0,1],"start":[0,1],"start_pad":0,"status":0,"status_color":0,"step":1,"str":1,"streamlin":1,"string":1,"structured_metadata":[0,1],"style":[0,1],"success_color":0,"sure":0,"surpress":1,"t":0,"tbd":1,"temp":1,"temperatur":1,"templat":0,"test":1,"tickformat":0,"time":[0,1],"timeseri":[0,1],"timestamp":[0,1],"timezon":[0,1],"titl":0,"title_standoff":0,"title_text":0,"to_datetim":1,"to_timezon":1,"toggleabl":1,"total_second":1,"trace":0,"transform":1,"tri":1,"true":[0,1],"tupl":1,"turn":0,"type":1,"typeerror":1,"tz_convert":1,"underlying":1,"unit":[0,1],"unless":0,"updat":0,"update_layout":0,"update_x_axes_tickformat":0,"update_xax":0,"use":1,"use_default_standoff":0,"use_minimum_margin":0,"use_muplot_axes_color":0,"use_muplot_grid":0,"use_muplot_line_and_mark":0,"use_platform_background":0,"use_platform_colorway":0,"use_platform_default":0,"use_simple_white_templ":0,"utc":0,"utcoffset":1,"valu":[0,1],"value_dim_1":1,"value_dim_info":1,"value_dimens":1,"value_name_of_seri":1,"valueerror":1,"vari":1,"variabl":[0,1],"via":1,"visibl":0,"want":0,"warn_color":0,"water":0,"way":[0,1],"well":1,"whether":1,"width":0,"will":0,"without":0,"write":[0,1],"x":0,"xax":0,"y":0,"yax":0,"yaxis_titl":0,"\u00b5plot":0},"titles":["First steps","hdhelpers"],"titleterms":{"Further":[0,1],"How":0,"except":1,"explan":0,"first":0,"function":1,"get":0,"hdhelper":[0,1],"helper":1,"inform":1,"introduct":1,"metadata":[0,1],"plot":0,"step":0,"tbd":0,"use":0}}) \ No newline at end of file +Search.setIndex({"alltitles":{"Explanation":[[0,"explanation"]],"First steps":[[0,null]],"Functions":[[1,"functions"]],"Further Information":[[1,"further-information"]],"How to get metadata with hdhelpers?":[[0,"how-to-get-metadata-with-hdhelpers"]],"How to use hdhelpers for plotting? (tbd)":[[0,"how-to-use-hdhelpers-for-plotting-tbd"]],"Introduction":[[1,"introduction"]],"exceptions":[[1,"module-hdhelpers.exceptions"]],"hdhelpers":[[1,null]],"helpers":[[1,"module-hdhelpers.helpers"]],"metadata":[[1,"module-hdhelpers.metadata"]]},"docnames":["first_steps","index"],"envversion":{"sphinx":66,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["first_steps.rst","index.rst"],"indexentries":{},"objects":{"hdhelpers":[[1,0,0,"-","exceptions"],[1,0,0,"-","helpers"],[1,0,0,"-","metadata"]],"hdhelpers.exceptions":[[1,1,1,"","HelperException"],[1,1,1,"","InsufficientPlottingData"]],"hdhelpers.helpers":[[1,2,1,"","modify_timezone"]],"hdhelpers.metadata":[[1,2,1,"","get_display_names"],[1,2,1,"","get_measurements"],[1,2,1,"","get_metric_info"],[1,2,1,"","get_names"],[1,2,1,"","get_queried_interval"],[1,2,1,"","get_series_display_name"],[1,2,1,"","get_series_info"],[1,2,1,"","get_series_measurement"],[1,2,1,"","get_series_name"],[1,2,1,"","get_series_short_display_name"],[1,2,1,"","get_series_unit"],[1,2,1,"","get_short_display_names"],[1,2,1,"","get_units"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function"},"terms":{"000z":0,"00z":1,"01t01":1,"01t08":0,"05t13":1,"06t13":1,"5s":0,"A":1,"All":0,"As":[],"DO":0,"For":[0,1],"How":1,"If":1,"In":[0,1],"It":[0,1],"NOT":0,"Our":0,"That":0,"The":0,"Then":[],"This":[0,1],"To":0,"We":0,"With":0,"__data__":0,"__hd_wrapped_data_object__":0,"__metadata__":0,"abov":0,"abstract":1,"access":1,"accord":0,"activ":0,"add_config_set":[],"adequ":1,"adit":1,"adjust":1,"all_timezon":1,"allow":1,"also":0,"ani":[0,1],"anoth":1,"appli":0,"applic":1,"arbitrari":1,"arg":1,"associ":1,"attr":1,"autoexpand":[],"avail":1,"awar":0,"axes_label_color":[],"axi":0,"b":[],"background":[],"background_color":0,"bar":[],"base":1,"becaus":0,"behaviour":[0,1],"berlin":1,"bool":1,"boolean":1,"by_metr":1,"c":1,"call":[],"can":[0,1],"case":[0,1],"certain":1,"chosen":0,"circl":[],"class":1,"cm":0,"code":[0,1],"collect":1,"color":0,"colorway":[],"column":1,"column_nam":1,"communic":0,"compli":1,"compon":[0,1],"concret":1,"configur":0,"contain":[0,1],"context":[0,1],"contrast":1,"control":[0,1],"convent":1,"convert":[0,1],"convert_index":1,"convey":0,"correct":[],"correspond":[0,1],"current":0,"custom":1,"cut":0,"danger":0,"data":[0,1],"datafram":1,"dataset_metadata":1,"date":1,"datetim":1,"datetime_tick_format":[],"def":0,"default":[0,1],"default_titl":0,"default_unit":0,"defaultdict":1,"defin":[0,1],"deprec":[],"design":[0,1],"detail":0,"determin":0,"dict":[0,1],"dictionari":1,"dimens":1,"direct":0,"display":1,"display_nam":1,"display_name_of_metric1":1,"display_name_of_seri":1,"displaylogo":[],"displaymodebar":[],"doe":0,"e":1,"eas":1,"edg":0,"edit":0,"empti":1,"end":[0,1],"entri":1,"entrypoint":0,"equival":1,"error":1,"error_cod":1,"error_color":0,"especi":1,"europ":1,"ever":[],"exampl":[0,1],"expect":1,"explan":[],"explicit":0,"external_first":1,"external_id":1,"external_second":1,"extra_inform":1,"extract":1,"fals":[],"fig":0,"figur":0,"find":[],"first":1,"fit":[],"flag":0,"follow":[0,1],"format":1,"four":0,"frontend":1,"full_titl":0,"function":0,"g":1,"generat":1,"german":1,"get":1,"get_and_pad_start_and_end_timestamp":0,"get_colors_from_plot_target_set":0,"get_display_nam":1,"get_measur":1,"get_metric_info":1,"get_nam":1,"get_queried_interv":1,"get_series_display_nam":1,"get_series_info":1,"get_series_measur":1,"get_series_nam":[0,1],"get_series_short_display_nam":1,"get_series_unit":[0,1],"get_short_display_nam":1,"get_unit":1,"get_value_dimension_info":1,"get_y_axis_label":0,"given":1,"global":[0,1],"glom":1,"go":0,"goal":0,"graph_object":0,"grid":[],"grid_color":[],"half":0,"handl":1,"happen":1,"hardwir":0,"helper":0,"helperexcept":1,"hetida":[0,1],"hide":0,"hide_legend":[],"hide_x_titl":[],"higher":[],"id":1,"import":[0,1],"includ":[0,1],"index":[0,1],"info":1,"info_color":0,"inform":0,"input":0,"instal":1,"instead":1,"insuffici":1,"insufficientplottingdata":1,"int":1,"integr":1,"intend":0,"interpret":1,"interv":[0,1],"iso":1,"isoformat":1,"json":[0,1],"just":0,"keep":0,"key":1,"kwarg":1,"l":[],"label":0,"last":[],"layout":[],"leav":[],"legend":[],"let":[0,1],"level":0,"like":[0,1],"limit":0,"line":0,"line_color":[],"list":1,"local":[],"logo":[],"look":0,"m":1,"magnitud":0,"main":0,"make":0,"margin":[],"marker":0,"marker_symbol":[],"match":[],"meaning":1,"measur":1,"mention":0,"messag":[0,1],"method":1,"metric":[0,1],"metric1":1,"metric2":1,"metric3":1,"metric_info":1,"metric_key":1,"might":0,"minim":[],"miss":0,"mode":[],"modifi":1,"modified_timezon":1,"modify_timezon":[0,1],"modifyng":[],"mtsf":1,"multitsfram":1,"naiv":0,"name":[0,1],"name_of_metric1":1,"name_of_metric2":1,"name_of_series_1":1,"name_of_series_2":1,"necessari":[],"next":[],"none":1,"normal":[],"note":[0,1],"now":[],"object":[0,1],"object_to_convert":1,"one":1,"onli":1,"oper":1,"option":[0,1],"order":0,"otherwis":0,"output":1,"packag":1,"pad":[],"panda":1,"paper":[],"paper_bgcolor":[],"paramet":[0,1],"pars":0,"pass":0,"pd":1,"place":[],"platform":1,"plot":1,"plot_bgcolor":[],"plot_target_local":[],"plot_target_set":[0,1],"plot_target_styl":0,"plot_target_timezon":0,"plotly_fig_to_json_dict":0,"point":0,"possibl":[0,1],"potenti":0,"precis":0,"present":1,"prioriti":[],"properti":0,"provid":[0,1],"provis":0,"purpos":0,"pytz":1,"queri":1,"r":[],"rais":1,"rang":0,"rare":[],"re":1,"reason":0,"ref_interval_end_timestamp":[0,1],"ref_interval_start_timestamp":[0,1],"reflect":0,"remov":[],"remove_plotly_bar":[],"remove_plotly_icon":[],"repres":0,"request":[0,1],"result":1,"retriev":[0,1],"return":[0,1],"rgba":[],"ruhr":1,"run":[],"s":[0,1],"said":[],"say":0,"scatter":0,"scheme":1,"second":1,"see":[0,1],"sensibl":1,"seri":[0,1],"serial":[0,1],"set":[0,1],"short":1,"short_display_nam":[0,1],"short_display_name_of_metric1":1,"short_display_name_of_seri":1,"show":1,"showlegend":[],"simple_whit":[],"sinc":[0,1],"singl":1,"single_metric_dataset_metadata":0,"single_metric_metadata":[0,1],"size":[],"soon":[],"spec":1,"specif":0,"specifi":1,"standard":[0,1],"start":[0,1],"start_pad":0,"status":0,"status_color":0,"step":1,"str":1,"streamlin":1,"string":1,"structured_metadata":[0,1],"style":[0,1],"success_color":0,"sure":0,"surpress":1,"t":[],"tbd":1,"temp":1,"temperatur":1,"templat":[],"test":1,"tickformat":[],"time":[0,1],"timeseri":[0,1],"timestamp":[0,1],"timezon":[0,1],"titl":0,"title_standoff":[],"title_text":[],"to_datetim":1,"to_timezon":1,"toggleabl":1,"total_second":1,"trace":[],"transform":1,"tri":1,"true":1,"tupl":1,"turn":0,"type":1,"typeerror":1,"tz_convert":1,"underlying":1,"unit":[0,1],"unless":[],"updat":[],"update_layout":0,"update_x_axes_tickformat":[],"update_xax":0,"use":1,"use_default_standoff":[],"use_minimum_margin":[],"use_muplot_axes_color":[],"use_muplot_grid":[],"use_muplot_line_and_mark":[],"use_platform_background":[],"use_platform_colorway":[],"use_platform_default":[],"use_simple_white_templ":[],"utc":0,"utcoffset":1,"valu":[0,1],"value_dim_1":1,"value_dim_info":1,"value_dimens":1,"value_name_of_seri":1,"valueerror":1,"vari":1,"variabl":[0,1],"via":1,"visibl":[],"want":0,"warn_color":0,"water":0,"way":[0,1],"well":1,"whether":1,"width":[],"will":0,"without":[],"write":1,"wwe":[],"x":0,"xax":[],"y":0,"yax":[],"yaxis_titl":0,"\u00b5plot":[]},"titles":["First steps","hdhelpers"],"titleterms":{"Further":1,"How":0,"except":1,"explan":0,"first":0,"function":1,"get":0,"hdhelper":[0,1],"helper":1,"inform":1,"introduct":1,"metadata":[0,1],"plot":0,"step":0,"tbd":0,"use":0}}) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 30a3c6b..ce5e6a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ exclude = [ [project] name = "hdhelpers" -version = "0.0.2" +version = "0.0.3" description = "Streamlines metadata & timezone handling, and plotting in hetida designer components" readme = "README.md" maintainers = [ @@ -32,11 +32,11 @@ maintainers = [ requires-python = ">=3.12" dependencies = [ - "pandas>=2,<3", - "plotly>=6,<7", - "pydantic>=2,<3", + "pandas", + "plotly", + "pydantic", "glom>25,<26", - "numpy>=2.3.3", + "numpy", ] license = "MIT" license-files = ["LICENSE"] diff --git a/sphinx/source/first_steps.rst b/sphinx/source/first_steps.rst index 986d589..fd7d6e0 100644 --- a/sphinx/source/first_steps.rst +++ b/sphinx/source/first_steps.rst @@ -86,32 +86,15 @@ Our component code might look like this to plot the timeseries accordingly: return {"plot": plotly_fig_to_json_dict(fig=fig)} -# Explanation -- *modify_timezone*: We use `modify_timezone` function to set the timezone. Since our goal is just to make sure that the timestamps are -timezone aware, not to convert it to a specific timezone, we do not pass a value for the `timezone` parameter. That way, -if there is a `plot_target_timezone` set in the hetida designer's `plot_target_settings` context variable, that timezone -will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive. - -- *get_colors_from_plot_target_settings*: To use a (global) standard color, we use `get_colors_from_plot_target_settings`, -which returns the `plot_target_style` property of the `plot_target_settings` -context variable. It contains a set of colors with specific purposes, such as `background_color`, and the -`status_colors` object, which in turn contains the four status colors: `success_color`, `error_color`, `warn_color`, and -`info_color`. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, -we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the `warn_color` for -`fig`'s `marker["color"]` property, which determines the plot's marker and line color. - -- *get_and_pad_start_and_end_timestamp*: We use `get_and_pad_start_and_end_timestamp` for precise control over the x-axis range. We do not set `start` and -`end` explicitly because we want to parse them from the metadata, which reflects the chosen interval for which -the data was requested. This way, we can see that there is missing data from 8:18 to 8:20. In the default behaviour of plotly -this time range would not have been included possibly hiding missing data. -Note: (1) We do not pass a `timezone` for the same reasons as with `modify_timezone`. -(2) We also set a `start_padding`, so the markers of the first data point is not cut in half by the edge -of the plot. - -- *get_y_axis_label*: We use `get_y_axis_label` so our y-axis can be labeled by using information from the metadata. With the above input series, -title and unit will be parsed from the metadata. In case the metadata does not contain the mentioned information, -we provide a `default_title`, and `default_unit` to configure the axis label in such cases. - -- *plotly_fig_to_json_dict*: Wwe use `plotly_fig_to_json_dict` to apply standardized stylings and serialize the plotly figure into a json -dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not -have to set any for this example. +Explanation +----------- + +- *modify_timezone*: We use `modify_timezone` function to set the timezone. Since our goal is just to make sure that the timestamps are timezone aware, not to convert it to a specific timezone, we do not pass a value for the `timezone` parameter. That way, if there is a `plot_target_timezone` set in the hetida designer's `plot_target_settings` context variable, that timezone will be used. Otherwise, the timestamps keep their current timezone or are converted to UTC if they are timezone naive. + +- *get_colors_from_plot_target_settings*: To use a (global) standard color, we use `get_colors_from_plot_target_settings`, which returns the `plot_target_style` property of the `plot_target_settings` context variable. It contains a set of colors with specific purposes, such as `background_color`, and the `status_colors` object, which in turn contains the four status colors: `success_color`, `error_color`, `warn_color`, and `info_color`. The status colors have no hardwired use in a plot, but are intended to convey a message. In our example, we want to communicate that the order of magnitude of our data is potentially dangerous, so we use the `warn_color` for `fig`'s `marker["color"]` property, which determines the plot's marker and line color. + +- *get_and_pad_start_and_end_timestamp*: We use `get_and_pad_start_and_end_timestamp` for precise control over the x-axis range. We do not set `start` and `end` explicitly because we want to parse them from the metadata, which reflects the chosen interval for which the data was requested. This way, we can see that there is missing data from 8:18 to 8:20. In the default behaviour of plotly this time range would not have been included possibly hiding missing data. Note: (1) We do not pass a `timezone` for the same reasons as with `modify_timezone`. (2) We also set a `start_padding`, so the markers of the first data point is not cut in half by the edge of the plot. + +- *get_y_axis_label*: We use `get_y_axis_label` so our y-axis can be labeled by using information from the metadata. With the above input series, title and unit will be parsed from the metadata. In case the metadata does not contain the mentioned information, we provide a `default_title`, and `default_unit` to configure the axis label in such cases. + +- *plotly_fig_to_json_dict*: We use `plotly_fig_to_json_dict` to apply standardized stylings and serialize the plotly figure into a json dict. All the standardized styling options are active by default, as detailed in [Styling Flags](#flags), so we do not have to set any for this example. diff --git a/src/hdhelpers/__init__.py b/src/hdhelpers/__init__.py index e737311..7e1b713 100644 --- a/src/hdhelpers/__init__.py +++ b/src/hdhelpers/__init__.py @@ -5,7 +5,7 @@ from .plot_target_settings import StatusColors # do not edit line of __version__ as it is automatically modified by running ./run build_package -__version__ = "0.0.2" +__version__ = "0.0.3" # function can be automated with from hdhelpers import * __all__ = [ diff --git a/src/hdhelpers/helpers/timezone_handling.py b/src/hdhelpers/helpers/timezone_handling.py index f43d441..003213b 100644 --- a/src/hdhelpers/helpers/timezone_handling.py +++ b/src/hdhelpers/helpers/timezone_handling.py @@ -1,3 +1,4 @@ +import datetime import logging from functools import singledispatch @@ -19,8 +20,9 @@ def _convert_to_optional_timezone(object_to_convert, to_timezone: str | None): ) -@_convert_to_optional_timezone.register(pd.Timestamp | pd.DatetimeIndex) +@_convert_to_optional_timezone.register(pd.Timestamp | pd.DatetimeIndex | datetime.datetime) def _[T: (pd.Timestamp, pd.DatetimeIndex)](object_to_convert: T, to_timezone: str | None) -> T: + object_to_convert = pd.to_datetime(object_to_convert) if to_timezone is None: if object_to_convert.tz is None: return object_to_convert.tz_localize("UTC") @@ -41,7 +43,7 @@ def _(object_to_convert: pd.Series, to_timezone: str | None) -> pd.Series: return object_to_convert.dt.tz_convert(to_timezone) -def modify_timezone[T: (pd.Timestamp, pd.Series, pd.DataFrame)]( # noqa: PLR0912 +def modify_timezone[T: (pd.Timestamp, datetime.datetime, pd.Series, pd.DataFrame)]( # noqa: PLR0912 object_to_convert: T, to_timezone: str | None = None, column_names: list[str] | None = None, @@ -73,9 +75,11 @@ def modify_timezone[T: (pd.Timestamp, pd.Series, pd.DataFrame)]( # noqa: PLR091 3600 """ - if not isinstance(object_to_convert, pd.Timestamp | pd.Series | pd.DataFrame): + if not isinstance( + object_to_convert, pd.Timestamp | pd.Series | pd.DataFrame | datetime.datetime + ): raise TypeError( - f"object_to_convert is {type(object_to_convert)} not pd.Series | pd.DataFrame" + f"object_to_convert is {type(object_to_convert)} not pd.Timestamp | pd.Series | pd.DataFrame | datetime.datetime" ) if column_names is None: column_names = [] @@ -86,9 +90,12 @@ def modify_timezone[T: (pd.Timestamp, pd.Series, pd.DataFrame)]( # noqa: PLR091 if plot_target_settings.plot_target_timezone is not None: to_timezone = plot_target_settings.plot_target_timezone - if isinstance(object_to_convert, pd.Timestamp): + if isinstance(object_to_convert, pd.Timestamp | datetime.datetime): return _convert_to_optional_timezone(object_to_convert, to_timezone) + if object_to_convert.empty: + return object_to_convert + if isinstance(object_to_convert, pd.Series): new_object = object_to_convert.to_frame(name=object_to_convert.name) else: @@ -99,7 +106,7 @@ def modify_timezone[T: (pd.Timestamp, pd.Series, pd.DataFrame)]( # noqa: PLR091 new_object.index = _convert_to_optional_timezone( pd.to_datetime(new_object.index), to_timezone ) - msg = f"Converted index to datetime starting with {object_to_convert.index[0]}" + msg = f"Converted index to datetime starting with {object_to_convert.index.min()}" logger.debug(msg=msg) elif isinstance(new_object, pd.DataFrame) and "timestamp" in new_object.columns: new_object["timestamp"] = _convert_to_optional_timezone( diff --git a/tests/helpers/test_timezone_handling.py b/tests/helpers/test_timezone_handling.py index 322a5d9..808a034 100644 --- a/tests/helpers/test_timezone_handling.py +++ b/tests/helpers/test_timezone_handling.py @@ -97,6 +97,18 @@ def test_modify_timezone_wrong_tzname(series_summer): _ = modify_timezone(series_summer, to_timezone="Europe/Berlin2") +def test_empty_series(): + data = pd.Series() + modified_data = modify_timezone(data, to_timezone="Europe/Berlin") + assert modified_data.empty + + +def test_empty_dataframe(): + data = pd.DataFrame() + modified_data = modify_timezone(data, to_timezone="Europe/Berlin", column_names=["timestamp"]) + assert modified_data.empty + + def test_named_series(series_summer): data = pd.Series(series_summer.index) data.name = "timestamp" @@ -182,3 +194,9 @@ def test_modify_timestamp(): pd.to_datetime("2023-03-25 23:00", utc=True), to_timezone="Europe/Berlin" ) assert modified_timestamp.utcoffset() == datetime.timedelta(seconds=3600) + + +def test_modify_timestamp_datetime(): + example_date = pd.to_datetime("2023-03-25 23:00", utc=True) + modified_timestamp = modify_timezone(example_date.to_pydatetime(), to_timezone="Europe/Berlin") + assert modified_timestamp.utcoffset() == datetime.timedelta(seconds=3600) diff --git a/uv.lock b/uv.lock index 0a8a16e..78341af 100644 --- a/uv.lock +++ b/uv.lock @@ -263,7 +263,7 @@ wheels = [ [[package]] name = "hdhelpers" -version = "0.0.2" +version = "0.0.3" source = { editable = "." } dependencies = [ { name = "glom" }, @@ -288,10 +288,10 @@ dev = [ [package.metadata] requires-dist = [ { name = "glom", specifier = ">25,<26" }, - { name = "numpy", specifier = ">=2.3.3" }, - { name = "pandas", specifier = ">=2,<3" }, - { name = "plotly", specifier = ">=6,<7" }, - { name = "pydantic", specifier = ">=2,<3" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "plotly" }, + { name = "pydantic" }, ] [package.metadata.requires-dev]