time-split 0.5.0__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. {time_split-0.5.0 → time_split-0.6.0}/PKG-INFO +4 -7
  2. {time_split-0.5.0 → time_split-0.6.0}/README.md +1 -1
  3. {time_split-0.5.0 → time_split-0.6.0}/pyproject.toml +1 -6
  4. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/__init__.py +1 -1
  5. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_docstrings.py +1 -1
  6. time_split-0.5.0/src/time_split/streamlit/README.md +0 -82
  7. time_split-0.5.0/src/time_split/streamlit/__init__.py +0 -1
  8. time_split-0.5.0/src/time_split/streamlit/_logging.py +0 -75
  9. time_split-0.5.0/src/time_split/streamlit/_support.py +0 -67
  10. time_split-0.5.0/src/time_split/streamlit/_views.py +0 -125
  11. time_split-0.5.0/src/time_split/streamlit/config.py +0 -68
  12. time_split-0.5.0/src/time_split/streamlit/widgets/__init__.py +0 -1
  13. time_split-0.5.0/src/time_split/streamlit/widgets/data/__init__.py +0 -7
  14. time_split-0.5.0/src/time_split/streamlit/widgets/data/_data.py +0 -336
  15. time_split-0.5.0/src/time_split/streamlit/widgets/data/_datasets.py +0 -123
  16. time_split-0.5.0/src/time_split/streamlit/widgets/data/_sample_data.py +0 -147
  17. time_split-0.5.0/src/time_split/streamlit/widgets/data/load.py +0 -111
  18. time_split-0.5.0/src/time_split/streamlit/widgets/data/sample.csv +0 -397
  19. time_split-0.5.0/src/time_split/streamlit/widgets/display/__init__.py +0 -15
  20. time_split-0.5.0/src/time_split/streamlit/widgets/display/_aggregate.py +0 -227
  21. time_split-0.5.0/src/time_split/streamlit/widgets/display/_code.py +0 -175
  22. time_split-0.5.0/src/time_split/streamlit/widgets/display/_overview.py +0 -51
  23. time_split-0.5.0/src/time_split/streamlit/widgets/display/_performance.py +0 -176
  24. time_split-0.5.0/src/time_split/streamlit/widgets/display/_plot_folds.py +0 -92
  25. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/__init__.py +0 -21
  26. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_datetime.py +0 -30
  27. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_duration.py +0 -78
  28. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_expand_limits.py +0 -141
  29. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_schedule.py +0 -135
  30. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_schedule_filter.py +0 -43
  31. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_span.py +0 -122
  32. time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_splitter_kwargs.py +0 -29
  33. time_split-0.5.0/src/time_split/streamlit/widgets/ruff.toml +0 -6
  34. time_split-0.5.0/src/time_split/streamlit/widgets/types.py +0 -351
  35. {time_split-0.5.0 → time_split-0.6.0}/LICENSE.md +0 -0
  36. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/__init__.py +0 -0
  37. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_datetime_index_like.py +0 -0
  38. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_limits.py +0 -0
  39. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_process_available.py +0 -0
  40. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_schedule.py +0 -0
  41. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_span.py +0 -0
  42. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_splitter.py +0 -0
  43. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_compat.py +0 -0
  44. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/__init__.py +0 -0
  45. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_plot.py +0 -0
  46. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_progress.py +0 -0
  47. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_split.py +0 -0
  48. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_to_string.py +0 -0
  49. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_weight.py +0 -0
  50. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_support.py +0 -0
  51. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/__init__.py +0 -0
  52. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/_log_progress.py +0 -0
  53. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/base.py +0 -0
  54. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/pandas/__init__.py +0 -0
  55. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/pandas/_impl.py +0 -0
  56. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/polars/__init__.py +0 -0
  57. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/polars/_impl.py +0 -0
  58. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/sklearn/__init__.py +0 -0
  59. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/sklearn/_impl.py +0 -0
  60. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/py.typed +0 -0
  61. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/settings.py +0 -0
  62. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/__init__.py +0 -0
  63. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/_create_explorer_link.py +0 -0
  64. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/types.py +0 -0
  65. {time_split-0.5.0 → time_split-0.6.0}/src/time_split/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: time-split
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Time-based k-fold validation splits for heterogeneous data.
5
5
  Home-page: https://github.com/rsundqvist/time-split
6
6
  Author: Richard Sundqvist
@@ -19,13 +19,10 @@ Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Programming Language :: Python :: 3 :: Only
21
21
  Provides-Extra: plotting
22
- Provides-Extra: streamlit
23
- Requires-Dist: croniter ; extra == "streamlit"
24
- Requires-Dist: matplotlib ; extra == "plotting" or extra == "streamlit"
22
+ Requires-Dist: matplotlib ; extra == "plotting"
25
23
  Requires-Dist: pandas (>=2.0.3)
26
24
  Requires-Dist: rics (>=4.1.1)
27
- Requires-Dist: seaborn ; extra == "plotting" or extra == "streamlit"
28
- Requires-Dist: streamlit ; extra == "streamlit"
25
+ Requires-Dist: seaborn ; extra == "plotting"
29
26
  Project-URL: Bug Tracker, https://github.com/rsundqvist/time-split/issues
30
27
  Project-URL: Changelog, https://github.com/rsundqvist/time-split/blob/master/CHANGELOG.md
31
28
  Project-URL: Documentation, https://time-split.readthedocs.io
@@ -73,7 +70,7 @@ strong non-stationary characteristics.
73
70
 
74
71
  ## Experimenting with parameters
75
72
  The **Time Fold Explorer** application
76
- (available [here](http://20.240.208.202/time-split/?data=1554942900-1557610200&schedule=0+0+%2A+%2A+MON%2CFRI&n_splits=2&step=2&show_removed=True))
73
+ (available [here](https://time-split.streamlit.app/?data=1554942900-1557610200&schedule=0+0+%2A+%2A+MON%2CFRI&n_splits=2&step=2&show_removed=True))
77
74
  is designed to help evaluate the effects of different
78
75
  [parameters](https://time-split.readthedocs.io/en/stable/#parameter-overview).
79
76
  To start it locally using
@@ -39,7 +39,7 @@ strong non-stationary characteristics.
39
39
 
40
40
  ## Experimenting with parameters
41
41
  The **Time Fold Explorer** application
42
- (available [here](http://20.240.208.202/time-split/?data=1554942900-1557610200&schedule=0+0+%2A+%2A+MON%2CFRI&n_splits=2&step=2&show_removed=True))
42
+ (available [here](https://time-split.streamlit.app/?data=1554942900-1557610200&schedule=0+0+%2A+%2A+MON%2CFRI&n_splits=2&step=2&show_removed=True))
43
43
  is designed to help evaluate the effects of different
44
44
  [parameters](https://time-split.readthedocs.io/en/stable/#parameter-overview).
45
45
  To start it locally using
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "time-split"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "Time-based k-fold validation splits for heterogeneous data."
5
5
  authors = ["Richard Sundqvist <richard.sundqvist@live.se>"]
6
6
 
@@ -40,13 +40,8 @@ rics = ">=4.1.1"
40
40
  matplotlib = { version = "*", optional = true }
41
41
  seaborn = { version = "*", optional = true }
42
42
 
43
- # explorer
44
- streamlit = { version = "*", optional = true }
45
- croniter = { version = "*", optional = true }
46
-
47
43
  [tool.poetry.extras]
48
44
  plotting = ["matplotlib", "seaborn"]
49
- streamlit = ["matplotlib", "seaborn", "streamlit", "croniter"]
50
45
 
51
46
  [tool.poetry.group.manual-extras.dependencies]
52
47
  # Extras that must be available for docs + tests go here. Doc/test-only deps go in their respective groups.
@@ -11,6 +11,6 @@ __all__ = [
11
11
  "__version__", # Make MyPy happy
12
12
  ]
13
13
 
14
- __version__ = "0.5.0"
14
+ __version__ = "0.6.0"
15
15
 
16
16
  _logging.getLogger(__name__).addHandler(_logging.NullHandler())
@@ -17,7 +17,7 @@ def docs(__func: Callable[P, T], /) -> Callable[P, T]:
17
17
  __func.__doc__ = __func.__doc__.format(**_DOCSTRINGS)
18
18
 
19
19
  if isinstance(__func, type):
20
- __func.__init__ = deprecated_params(__func.__init__)
20
+ __func.__init__ = deprecated_params(__func.__init__) # type: ignore[misc]
21
21
  else:
22
22
  __func = deprecated_params(__func)
23
23
 
@@ -1,82 +0,0 @@
1
- # Time Split <!-- omit in toc -->
2
- Time-based k-fold validation splits for heterogeneous data.
3
-
4
- -----------------
5
- [![PyPI - Version](https://img.shields.io/pypi/v/time-split.svg)](https://pypi.python.org/pypi/time-split)
6
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/time-split.svg)](https://pypi.python.org/pypi/time-split)
7
- [![Tests](https://github.com/rsundqvist/time-split/workflows/tests/badge.svg)](https://github.com/rsundqvist/time-split/actions?workflow=tests)
8
- [![Codecov](https://codecov.io/gh/rsundqvist/time-split/branch/master/graph/badge.svg)](https://codecov.io/gh/rsundqvist/time-split)
9
- [![Read the Docs](https://readthedocs.org/projects/time-split/badge/)](https://time-split.readthedocs.io/)
10
- [![PyPI - License](https://img.shields.io/pypi/l/time-split.svg)](https://pypi.python.org/pypi/time-split)
11
- [![Docker Image Size (tag)](https://img.shields.io/docker/image-size/rsundqvist/time-split/latest?logo=docker&label=time-split)](https://hub.docker.com/r/rsundqvist/time-split/)
12
-
13
- <div align="center">
14
- <img alt="Plotted folds on a two-by-two grid."
15
- title="Examples" height="300" width="1200"
16
- src="https://raw.githubusercontent.com/rsundqvist/time-split/master/docs/2x2-examples.jpg"><br>
17
- </div>
18
-
19
- Folds plotted on a two-by-two grid. See the
20
- [examples](https://time-split.readthedocs.io/en/stable/auto_examples/index.html) page for more.
21
-
22
- # About this image
23
- The **Time Fold Explorer** application
24
- (available [here](http://20.240.208.202/time-split/?data=1554942900-1557610200&schedule=0+0+%2A+%2A+MON%2CFRI&n_splits=2&step=2&show_removed=True))
25
- is designed to help evaluate the effects of different
26
- [parameters](https://time-split.readthedocs.io/en/stable/#parameter-overview).
27
- To start it locally using
28
- [![Docker Image Size (tag)](https://img.shields.io/docker/image-size/rsundqvist/time-split/latest?logo=docker&label=time-split)](https://hub.docker.com/r/rsundqvist/time-split/)
29
- Docker, run
30
- ```sh
31
- docker run -p 8501:8501 rsundqvist/time-split
32
- ```
33
- in the terminal. You may use
34
- [`create_explorer_link()`](https://time-split.readthedocs.io/en/stable/generated/time_split.support.html#time_split.support.create_explorer_link)
35
- to build application URLs with preselected splitting parameters.
36
-
37
- # Custom datasets
38
- To bundle datasets, mount a configuration file (determined by
39
- [`DATASETS_CONFIG_PATH='/home/streamlit/datasets.toml'`](https://time-split.readthedocs.io/en/stable/generated/time_split.streamlit.config.html#time_split.streamlit.config.DATASETS_CONFIG_PATH)
40
- ). The `DatasetConfig` struct has the following keys:
41
-
42
- * `label`: Name shown in the UI. Defaults to section header (i.e. *"my-dataset"* below).
43
- * `path`: Required. First argument to the `pandas` read function.
44
- * `index`: Required. Must be datetime-like.
45
- * `aggregations`: Optional. Determines function to use in the `📈 Aggregations per fold` tab.
46
- * `description`: Optional. The first line will be used as the summary in the UI.
47
- * `read_function_kwargs`: Keyword arguments for the `pandas` read function used (as determined by the `path`).
48
-
49
- Additional dependencies are required for remote filesystems. You may use `EXTRA_PIP_PACKAGES=s3fs` to install
50
- dependencies for the S3 paths used below.
51
-
52
- ```toml
53
- [my-dataset]
54
- label = "Dataset name"
55
- path = "s3://my-bucket/data/title_basics.csv"
56
- index = "from"
57
- aggregations = { runtimeMinutes = "min", isAdult = "mean" }
58
- description = """This is the summary.
59
-
60
- Simplified version of the [Title basics](https://developer.imdb.com/non-commercial-datasets/#titlebasicstsvgz) IMDB
61
- dataset. The description supports Markdown syntax.
62
- """
63
- [my-dataset.read_function_kwargs]
64
- # Valid options depend on the read function used.
65
- ```
66
-
67
- Multiple datasets may be configured in their own top-level sections. Labels must be unique.
68
-
69
- # Environment variables
70
- See [time_split.streamlit.config](https://time-split.readthedocs.io/en/stable/generated/time_split.streamlit.config.html)
71
- for configurable values. Use `true|false` for boolean variables. Documentation for the underlying framework (Streamlit)
72
- is available
73
- [here](https://docs.streamlit.io/develop/concepts/configuration/options/).
74
-
75
- ## User choice
76
- Users may *lower* some configured values by using the Performance tweaker widget in the `❔ About tab` of application. To
77
- set a lower default, add a `DEFAULT_`-prefix to the regular name.
78
- ```bash
79
- PLOT_AGGREGATIONS_PER_FOLD=true
80
- DEFAULT_PLOT_AGGREGATIONS_PER_FOLD=false
81
- ```
82
- This will disable the (expensive) per-column fold aggregation figures, but users who need them can turn them back on.
@@ -1 +0,0 @@
1
- """Reusable components used by the **Time Fold Explorer** application."""
@@ -1,75 +0,0 @@
1
- import logging
2
- from typing import Any
3
-
4
- import pandas as pd
5
- import streamlit as st
6
- from rics.collections.dicts import flatten_dict
7
- from streamlit.runtime.scriptrunner import get_script_run_ctx
8
-
9
- from time_split.streamlit import config
10
- from time_split.streamlit.widgets.types import QueryParams
11
-
12
- LOGGER = logging.getLogger("time_split.streamlit")
13
-
14
-
15
- def log_perf(
16
- message: str,
17
- df: pd.DataFrame | dict[str, pd.DataFrame],
18
- seconds: float,
19
- *,
20
- extra: dict[str, Any],
21
- level: int = logging.INFO,
22
- ) -> str:
23
- if isinstance(df, dict):
24
- frames: dict[str, Any] = {key: _get_frame_extras(df) for key, df in df.items()}
25
- frames["__sum__"] = pd.DataFrame.from_dict(frames, orient="index").sum().to_dict()
26
- frames["n_frames"] = len(df)
27
- frame_extras = flatten_dict(frames)
28
- else:
29
- frame_extras = _get_frame_extras(df)
30
-
31
- remote_ip, session_id = get_session_data()
32
- extra = extra | {
33
- "session_id": session_id,
34
- "remote_ip": remote_ip,
35
- "duration_ms": int(1000 * seconds),
36
- **frame_extras,
37
- **config.get_values(),
38
- **QueryParams.get().to_dict(prefix="query."),
39
- }
40
- message = message.format_map(extra)
41
- LOGGER.log(level, message.replace("`", "") + f" | {extra=}", extra=extra)
42
- return message
43
-
44
-
45
- def _get_frame_extras(df: pd.DataFrame) -> dict[str, int]:
46
- return {"size": df.size, "rows": len(df), "columns": len(df.columns)}
47
-
48
-
49
- class StreamlitLoggingHandler(logging.Handler):
50
- def emit(self, record: logging.LogRecord) -> None:
51
- message = record.getMessage()
52
-
53
- if record.levelno >= logging.ERROR:
54
- st.error(message, icon="🚨")
55
- elif record.levelno >= logging.WARNING:
56
- st.warning(message, icon="⚠️")
57
- elif record.levelno >= logging.INFO:
58
- st.info(message, icon="ℹ️")
59
- else:
60
- st.code(record.levelname + ": " + record.getMessage())
61
-
62
-
63
- def get_session_data() -> tuple[str, str]:
64
- ctx = get_script_run_ctx(suppress_warning=True)
65
- if ctx is None:
66
- return "", ""
67
-
68
- return _get_session_data(ctx.session_id), ctx.session_id
69
-
70
-
71
- def _get_session_data(session_id: str) -> str:
72
- from streamlit.runtime import get_instance
73
-
74
- client = get_instance().get_client(session_id)
75
- return client.request.remote_ip # type: ignore[no-any-return, union-attr]
@@ -1,67 +0,0 @@
1
- from pprint import pformat
2
- from typing import Never
3
-
4
- import pandas as pd
5
- import streamlit as st
6
-
7
- from time_split.streamlit import config
8
- from time_split.streamlit.widgets.display._code import CodeWidget
9
- from time_split.types import DatetimeIndexSplitterKwargs
10
-
11
-
12
- def enforce_max_splits(
13
- all_splits: int, kwargs: DatetimeIndexSplitterKwargs, limits: tuple[pd.Timestamp, pd.Timestamp]
14
- ) -> None:
15
- """Check the number of splits against the configured limit, rising if exceeded."""
16
- if all_splits > config.MAX_SPLITS:
17
- _too_many_splits(all_splits, kwargs, limits)
18
-
19
-
20
- @st.experimental_dialog("🚨 Too many splits")
21
- def _too_many_splits(
22
- all_splits: int,
23
- kwargs: DatetimeIndexSplitterKwargs,
24
- limits: tuple[pd.Timestamp, pd.Timestamp],
25
- ) -> Never:
26
- st.error(f"Maximum number of splits ({config.MAX_SPLITS}) exceeded.", icon="🚨")
27
- st.write("Number of splits is restricted for performance reasons.")
28
- strings = CodeWidget("string").convert({**kwargs, "available": limits})
29
- st.code("kwargs = " + pformat(strings, indent=0, width=40, depth=2))
30
- st.write(
31
- f"The arguments above produces `len(splits)={all_splits} > {config.MAX_SPLITS}=MAX_SPLITS`."
32
- " Try using different parameters to reduce the number of folds."
33
- )
34
- st.stop()
35
-
36
-
37
- def get_about() -> str:
38
- from time_split import __version__
39
-
40
- return f"""## Time Fold Explorer
41
- This applications is designed to help experiment with `time-split` splitting parameters.
42
-
43
- See https://time-split.readthedocs.io/ for library documentation.
44
-
45
- #### 🚀 Getting started
46
- 1. Use the `⚙️ Configure data` menu to select a datetime range or a dataset.
47
- 2. Use the sidebar widgets to control how the data is split.
48
- 3. Use the `📊 Folds` and `📈 Aggregations per fold` tabs to explore the effects.
49
-
50
- Please visit the [GitHub page](https://github.com/rsundqvist/time-split) for questions or feedback.
51
-
52
- #### ⚙️ Server configuration
53
- These values cannot be changed.
54
-
55
- {config.get_server_config_info()}
56
-
57
- See https://hub.docker.com/repository/docker/rsundqvist/time-split/ to spawn custom servers.
58
-
59
- ### Server `time-split` version
60
- The server is using version `{__version__}`. To install this version, run
61
-
62
- ```bash
63
- pip install time-split=={__version__}
64
- ```
65
-
66
- in your favorite terminal. You may then copy one of the snippets from the `📊 Folds` tab to get started.
67
- """ # noqa: S608 # This is not SQL.
@@ -1,125 +0,0 @@
1
- from pprint import pformat
2
- from typing import Any
3
-
4
- import pandas as pd
5
- import streamlit as st
6
-
7
- from time_split._compat import fmt_sec
8
- from time_split.streamlit import config
9
- from time_split.streamlit.widgets.display import CodeWidget, FoldOverviewWidget, PlotFoldsWidget
10
- from time_split.streamlit.widgets.types import QueryParams
11
- from time_split.support import create_explorer_link
12
- from time_split.types import DatetimeIndexSplitterKwargs, DatetimeSplits, DatetimeTypes
13
-
14
-
15
- def primary(
16
- *,
17
- df: pd.DataFrame,
18
- plot_folds_widget: PlotFoldsWidget,
19
- split_kwargs: DatetimeIndexSplitterKwargs,
20
- limits: tuple[DatetimeTypes, DatetimeTypes],
21
- dataset: str | None,
22
- # Overview params
23
- fold_overview_widget: FoldOverviewWidget,
24
- splits: DatetimeSplits,
25
- all_splits: DatetimeSplits,
26
- ) -> None:
27
- st.header("Folds", divider="rainbow")
28
-
29
- with st.container(border=True):
30
- left, right = st.columns([20, 4])
31
- with right, st.container(border=True):
32
- st.subheader("Plot preferences", divider=True)
33
- plot_kwargs = plot_folds_widget.select()
34
- with left:
35
- plot_folds_widget.plot(split_kwargs, df, **plot_kwargs)
36
-
37
- with st.container(border=True):
38
- left, right = st.columns([20, 4])
39
- with left:
40
- st.subheader(
41
- "Code snippets",
42
- divider="rainbow",
43
- help=(
44
- "The [integration](https://time-split.readthedocs.io/en/stable/generated/time_split.integration.html)"
45
- " modules accept the same parameters as `time_fold.split()`."
46
- ),
47
- )
48
- with right, st.popover("🤝 Show permalink", use_container_width=True):
49
- show_permalink(
50
- split_kwargs=split_kwargs,
51
- plot_kwargs=plot_kwargs,
52
- limits=limits if dataset is None else dataset,
53
- )
54
-
55
- left, mid, right = st.columns([10, 10, 4])
56
-
57
- with right:
58
- with st.container(border=True):
59
- st.subheader(
60
- "Type preferences",
61
- divider=True,
62
- help="The `time-split` package uses Pandas types internally. May not work for `📝 Free form` input.",
63
- )
64
- code_widget = CodeWidget.select()
65
-
66
- st.write(
67
- """
68
- * Click [here](https://time-split.readthedocs.io/en/stable/generated/time_split.html#time_split.split) for `split()` docs.
69
- * Click [here](https://time-split.readthedocs.io/en/stable/generated/time_split.html#time_split.plot) for `plot()` docs.
70
- """
71
- )
72
-
73
- used, avail = fold_overview_widget.get_data_utilization(splits, limits)
74
- st.caption(
75
- f"Using `{fmt_sec(used)}` of `{fmt_sec(avail)}` (`{used / avail :.1%}`) of the available data range."
76
- )
77
-
78
- with left:
79
- code_widget.show_split_code(split_kwargs, limits=limits)
80
- fold_overview_widget.show_overview(splits, all_splits=all_splits)
81
- with mid:
82
- code_widget.show_plot_code(split_kwargs, plot_kwargs=plot_kwargs, limits=limits)
83
-
84
-
85
- def show_permalink(
86
- *,
87
- split_kwargs: DatetimeIndexSplitterKwargs,
88
- plot_kwargs: dict[str, Any],
89
- limits: tuple[DatetimeTypes, DatetimeTypes] | str,
90
- ) -> None:
91
- permalink_kwargs = {**split_kwargs, **plot_kwargs, "data": limits}
92
- permalink_kwargs.pop("bar_labels") # Not supported
93
-
94
- host = config.PERMALINK_BASE_URL
95
- if host == "":
96
- host = "http://localhost:8501"
97
- st.warning(f"May not be accurate; {config.PERMALINK_BASE_URL=} not set.", icon="⚠️")
98
-
99
- link = create_explorer_link(host, **permalink_kwargs)
100
- st.header("Share this link", divider=True)
101
- with st.container(border=True):
102
- st.write(f"[{link}]({link})")
103
-
104
- convert = CodeWidget("string").convert
105
-
106
- st.header(
107
- "Parameters",
108
- divider=True,
109
- help="Input parameters are extracted from the URL in the address bar of your browser."
110
- " Output parameters are used to generate the new link above.",
111
- )
112
- with st.container(border=True):
113
- left, right = st.columns(2)
114
- with left:
115
- st.write("Input parameters.")
116
- st.code(pformat(convert(QueryParams.get().to_dict(filter=False)), width=35))
117
-
118
- with right:
119
- st.write("Output parameters.")
120
- st.code(pformat(convert(permalink_kwargs.copy()), width=35))
121
- doc = "https://time-split.readthedocs.io/en/stable/generated/time_split.support.html#time_split.support.create_explorer_link"
122
- st.caption(
123
- f"Parameters may be [converted]({doc}) to equivalent values. "
124
- "Note that `data` is called `available` by core library."
125
- )
@@ -1,68 +0,0 @@
1
- """Configuration namespace.
2
-
3
- Values in this module are treated as hard limits by the server.
4
- """
5
-
6
- from os import environ as _environ
7
-
8
-
9
- def _read_bool(key: str, default: bool) -> bool:
10
- value = _environ.get(key, "").lower()
11
- return value != "false" if default is True else value == "true"
12
-
13
-
14
- # Configurable by application users
15
- PLOT_RAW_TIMESERIES: bool = _read_bool("PLOT_AGGREGATIONS_PER_FOLD", True)
16
- """Enable plot in the `🔍 Show raw data` tab."""
17
- PLOT_AGGREGATIONS_PER_FOLD: bool = _read_bool("PLOT_AGGREGATIONS_PER_FOLD", True)
18
- """Enable plots in the `📈 Aggregations per fold` tab."""
19
- FIGURE_DPI: int = int(_environ.get("FIGURE_DPI", 200))
20
- """Controls figure fidelity. Higher values look better, but is a lot slower."""
21
- MAX_SPLITS = int(_environ.get("MAX_SPLITS", 100))
22
- """Upper fold count limit. Prevents figures from getting too large."""
23
-
24
- # Server configuration
25
- RAW_DATA_SAMPLES: int = int(_environ.get("RAW_DATA_SAMPLES", 1000))
26
- """Maximum number of display and plot in `🔍 Show raw data` tab."""
27
- DATASETS_CONFIG_PATH: str = _environ.get("DATASETS_CONFIG_PATH") or "datasets.toml"
28
- """Determines where to look for the dataset configuration TOML. Disable the dataset view if not found."""
29
- REQUIRE_DATASETS: bool = _read_bool("REQUIRE_DATASETS", False)
30
- """If set, the server will refuse to start if not the ``DATASETS_CONFIG_PATH`` file does not exist."""
31
- DATASET_CACHE_TTL: int = int(_environ.get("DATASET_CACHE_TTL", 60 * 60))
32
- """Cache timeout in seconds. Default is one hour."""
33
- PROCESS_QUERY_PARAMS: bool = _environ.get("PROCESS_QUERY_PARAMS", "").lower() != "false"
34
- """Abort if parameters are given when ``False``. See :class:`~.widgets.types.QueryParams` for details."""
35
- PERMALINK_BASE_URL: str = _environ.get("PERMALINK_BASE_URL", "")
36
- """Public base address for the application. Used to create permalinks."""
37
-
38
-
39
- def get_values() -> dict[str, int | bool]:
40
- """Get config values as a dict."""
41
- return {
42
- "FIGURE_DPI": FIGURE_DPI,
43
- "PLOT_RAW_TIMESERIES": PLOT_RAW_TIMESERIES,
44
- "PLOT_AGGREGATIONS_PER_FOLD": PLOT_AGGREGATIONS_PER_FOLD,
45
- "MAX_SPLITS": MAX_SPLITS,
46
- }
47
-
48
-
49
- def get_descriptions() -> dict[str, str]:
50
- """Get config key descriptions."""
51
- return {
52
- "FIGURE_DPI": "Controls figure fidelity. Higher values look better, but are slower to draw.",
53
- "PLOT_RAW_TIMESERIES": "Enable plot in the `🔍 Show raw data` tab.",
54
- "PLOT_AGGREGATIONS_PER_FOLD": "Enable plots in the `📈 Aggregations per fold` tab.",
55
- "MAX_SPLITS": "Upper fold count limit. Prevents figures from getting too large.",
56
- }
57
-
58
-
59
- def get_server_config_info() -> str:
60
- """Get the readonly server configuration."""
61
- description = get_descriptions()
62
-
63
- return f"""
64
- * `{MAX_SPLITS=}`: {description['MAX_SPLITS']}
65
- * `{PLOT_RAW_TIMESERIES=}`: {description['PLOT_RAW_TIMESERIES']}
66
- * `{PLOT_AGGREGATIONS_PER_FOLD=}`: {description['PLOT_AGGREGATIONS_PER_FOLD']}
67
- * `{FIGURE_DPI=}`: {description['FIGURE_DPI']}
68
- """
@@ -1 +0,0 @@
1
- """Streamlit components library."""
@@ -1,7 +0,0 @@
1
- """Widgets for interacting with datasets."""
2
-
3
- from ._data import DataWidget
4
- from ._datasets import DatasetWidget
5
- from ._sample_data import SampleDataWidget
6
-
7
- __all__ = ["DataWidget", "DatasetWidget", "SampleDataWidget"]