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.
- {time_split-0.5.0 → time_split-0.6.0}/PKG-INFO +4 -7
- {time_split-0.5.0 → time_split-0.6.0}/README.md +1 -1
- {time_split-0.5.0 → time_split-0.6.0}/pyproject.toml +1 -6
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/__init__.py +1 -1
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_docstrings.py +1 -1
- time_split-0.5.0/src/time_split/streamlit/README.md +0 -82
- time_split-0.5.0/src/time_split/streamlit/__init__.py +0 -1
- time_split-0.5.0/src/time_split/streamlit/_logging.py +0 -75
- time_split-0.5.0/src/time_split/streamlit/_support.py +0 -67
- time_split-0.5.0/src/time_split/streamlit/_views.py +0 -125
- time_split-0.5.0/src/time_split/streamlit/config.py +0 -68
- time_split-0.5.0/src/time_split/streamlit/widgets/__init__.py +0 -1
- time_split-0.5.0/src/time_split/streamlit/widgets/data/__init__.py +0 -7
- time_split-0.5.0/src/time_split/streamlit/widgets/data/_data.py +0 -336
- time_split-0.5.0/src/time_split/streamlit/widgets/data/_datasets.py +0 -123
- time_split-0.5.0/src/time_split/streamlit/widgets/data/_sample_data.py +0 -147
- time_split-0.5.0/src/time_split/streamlit/widgets/data/load.py +0 -111
- time_split-0.5.0/src/time_split/streamlit/widgets/data/sample.csv +0 -397
- time_split-0.5.0/src/time_split/streamlit/widgets/display/__init__.py +0 -15
- time_split-0.5.0/src/time_split/streamlit/widgets/display/_aggregate.py +0 -227
- time_split-0.5.0/src/time_split/streamlit/widgets/display/_code.py +0 -175
- time_split-0.5.0/src/time_split/streamlit/widgets/display/_overview.py +0 -51
- time_split-0.5.0/src/time_split/streamlit/widgets/display/_performance.py +0 -176
- time_split-0.5.0/src/time_split/streamlit/widgets/display/_plot_folds.py +0 -92
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/__init__.py +0 -21
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_datetime.py +0 -30
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_duration.py +0 -78
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_expand_limits.py +0 -141
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_schedule.py +0 -135
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_schedule_filter.py +0 -43
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_span.py +0 -122
- time_split-0.5.0/src/time_split/streamlit/widgets/parameters/_splitter_kwargs.py +0 -29
- time_split-0.5.0/src/time_split/streamlit/widgets/ruff.toml +0 -6
- time_split-0.5.0/src/time_split/streamlit/widgets/types.py +0 -351
- {time_split-0.5.0 → time_split-0.6.0}/LICENSE.md +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_datetime_index_like.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_limits.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_process_available.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_schedule.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_span.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_backend/_splitter.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_compat.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_plot.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_progress.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_split.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_to_string.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_frontend/_weight.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/_support.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/_log_progress.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/base.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/pandas/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/pandas/_impl.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/polars/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/polars/_impl.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/sklearn/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/integration/sklearn/_impl.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/py.typed +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/settings.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/__init__.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/_create_explorer_link.py +0 -0
- {time_split-0.5.0 → time_split-0.6.0}/src/time_split/support/types.py +0 -0
- {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.
|
|
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
|
-
|
|
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"
|
|
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](
|
|
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](
|
|
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.
|
|
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.
|
|
@@ -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
|
-
[](https://pypi.python.org/pypi/time-split)
|
|
6
|
-
[](https://pypi.python.org/pypi/time-split)
|
|
7
|
-
[](https://github.com/rsundqvist/time-split/actions?workflow=tests)
|
|
8
|
-
[](https://codecov.io/gh/rsundqvist/time-split)
|
|
9
|
-
[](https://time-split.readthedocs.io/)
|
|
10
|
-
[](https://pypi.python.org/pypi/time-split)
|
|
11
|
-
[](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
|
-
[](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."""
|