timelineviz 0.1.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.
@@ -0,0 +1,18 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Coverage / build artifacts
13
+ .coverage
14
+ htmlcov/
15
+ .pytest_cache/
16
+
17
+ # OS
18
+ .DS_Store
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [0.1.0] - 2025-01-01
9
+
10
+ ### Added
11
+
12
+ - Timeline visualisation from CSV / DataFrame timestamp data.
13
+ - Automatic timestamp column detection (columns ending `_utc`).
14
+ - Cluster detection for grouping related timestamps.
15
+ - Prometheus test file parser (`parse_promtest_file`, `parse_promtest_string`).
16
+ - `plot_promtest` step-chart visualiser with self-documenting annotations.
17
+ - `expand_values` helper for expanding Prometheus value notation.
18
+ - CLI entry point `timelineviz` with `--promtest` flag.
19
+ - 113 unit tests with >90 % coverage.
@@ -0,0 +1,63 @@
1
+ # Development Guide
2
+
3
+ Setup, testing, and release instructions for `timelineviz`.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/garrywilliams/timeline_viz.git
9
+ cd timeline_viz
10
+ uv pip install -e ".[dev]"
11
+ ```
12
+
13
+ ## Testing
14
+
15
+ ```bash
16
+ # Run tests with coverage
17
+ pytest
18
+
19
+ # HTML coverage report
20
+ pytest --cov=timelineviz --cov-report=html
21
+ open htmlcov/index.html
22
+ ```
23
+
24
+ Coverage threshold is 90 % (enforced in `pyproject.toml`).
25
+
26
+ ## Project Layout
27
+
28
+ ```
29
+ src/timelineviz/
30
+ __init__.py # Public API re-exports
31
+ _version.py # Single source of truth for version
32
+ timeline.py # CSV/DataFrame visualisation
33
+ promtest.py # Prometheus test file parser + visualiser
34
+ utils.py # Shared helpers
35
+ cli.py # CLI entry point
36
+ py.typed # PEP 561 marker
37
+ tests/
38
+ test_timeline.py
39
+ test_promtest.py
40
+ test_utils.py
41
+ test_cli.py
42
+ ```
43
+
44
+ ## Building
45
+
46
+ ```bash
47
+ uv build
48
+ # outputs dist/timelineviz-x.y.z-py3-none-any.whl
49
+ ```
50
+
51
+ ## Release Process
52
+
53
+ 1. Bump version in `src/timelineviz/_version.py`
54
+ 2. Update `CHANGELOG.md`
55
+ 3. Commit, tag, push:
56
+ ```bash
57
+ git tag v0.1.0
58
+ git push origin main --tags
59
+ ```
60
+ 4. Publish to PyPI:
61
+ ```bash
62
+ uv publish
63
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Garry Williams
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: timelineviz
3
+ Version: 0.1.0
4
+ Summary: Timeline visualisation for CSV data and Prometheus test files
5
+ Project-URL: Homepage, https://github.com/garrywilliams/timeline_viz
6
+ Project-URL: Source, https://github.com/garrywilliams/timeline_viz
7
+ Project-URL: Issues, https://github.com/garrywilliams/timeline_viz/issues
8
+ Project-URL: Changelog, https://github.com/garrywilliams/timeline_viz/blob/main/CHANGELOG.md
9
+ Author: Garry Williams
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: matplotlib,prometheus,promtool,timeline,visualisation
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Scientific/Engineering :: Visualization
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.8
26
+ Requires-Dist: matplotlib>=3.4
27
+ Requires-Dist: numpy>=1.20
28
+ Requires-Dist: pandas>=1.3
29
+ Requires-Dist: python-dateutil>=2.8
30
+ Requires-Dist: pytz>=2021.1
31
+ Requires-Dist: pyyaml>=6.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
34
+ Requires-Dist: pytest>=7.0; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # timelineviz
38
+
39
+ [![PyPI version](https://img.shields.io/pypi/v/timelineviz)](https://pypi.org/project/timelineviz/)
40
+ [![Python](https://img.shields.io/pypi/pyversions/timelineviz)](https://pypi.org/project/timelineviz/)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
42
+
43
+ Timeline visualisation for CSV data and Prometheus test files.
44
+
45
+ ![Example Timeline](images/timeline1.png)
46
+
47
+ ## Features
48
+
49
+ - Plot event timelines from CSV / DataFrame timestamp data
50
+ - Handle time gaps with broken timeline display
51
+ - Auto-detect timestamp columns based on naming patterns
52
+ - **Visualise Prometheus `promtool` unit-test files** — series values, eval checkpoints, and alert checks on a relative time axis
53
+ - Customisable colour schemes
54
+ - CLI and Python API
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install timelineviz
60
+
61
+ # or with uv
62
+ uv add timelineviz
63
+ ```
64
+
65
+ For development:
66
+
67
+ ```bash
68
+ git clone https://github.com/garrywilliams/timeline_viz.git
69
+ cd timeline_viz
70
+ uv pip install -e ".[dev]"
71
+ ```
72
+
73
+ ## Quick Start
74
+
75
+ ### CSV / DataFrame Timelines
76
+
77
+ ```bash
78
+ # Auto-detect timestamp columns
79
+ timelineviz data.csv --detect-timestamps --output-dir timelines
80
+
81
+ # Specify columns explicitly
82
+ timelineviz data.csv --timestamp-columns created_at updated_at completed_at
83
+ ```
84
+
85
+ ```python
86
+ from timelineviz import plot_timeline, plot_multiple_timelines
87
+
88
+ import pandas as pd
89
+ df = pd.read_csv("data.csv")
90
+
91
+ # Single entity
92
+ plot_timeline(df.iloc[0],
93
+ timestamp_columns=['created_at', 'updated_at', 'completed_at'],
94
+ entity_id="12345")
95
+
96
+ # Multiple entities
97
+ plot_multiple_timelines("data.csv",
98
+ timestamp_columns=['created_at', 'updated_at'],
99
+ id_column='entity_id',
100
+ output_dir="timeline_images")
101
+ ```
102
+
103
+ ### Prometheus Test Timelines
104
+
105
+ Visualise `promtool` unit-test YAML files — see series values change over time, where evaluations happen, and when alerts fire.
106
+
107
+ ```bash
108
+ timelineviz my_rules_test.yml --promtest
109
+ timelineviz my_rules_test.yml --promtest --output-dir images --no-show
110
+ ```
111
+
112
+ ```python
113
+ from timelineviz import parse_promtest_file, plot_promtest
114
+
115
+ groups = parse_promtest_file("my_rules_test.yml")
116
+ plot_promtest(groups, output_file="promtest_timeline.png")
117
+ ```
118
+
119
+ ![Promtest Example](images/promtest_example_1.png)
120
+
121
+ Charts are self-documenting — each subplot shows the metric name and raw notation, value labels appear at transition points, eval/alert vertical lines are labelled, and a legend strip at the bottom explains all marker types.
122
+
123
+ > **Full guide:** [PROMTEST.md](PROMTEST.md) — notation reference, worked examples, and all parameters.
124
+
125
+ ## How It Works
126
+
127
+ ### CSV Timelines
128
+
129
+ Timestamps are plotted as labelled points along a horizontal axis. When time gaps exceed a threshold, the timeline is broken into segments with slash markers indicating the breaks.
130
+
131
+ ### Promtest Timelines
132
+
133
+ Prometheus test files define metric series as values over discrete time steps (e.g. one value per minute). The library:
134
+
135
+ 1. Parses the YAML and **expands the compact notation** (`1+2x5` → `1, 3, 5, 7, 9, 11`)
136
+ 2. Plots each `input_series` as a **step chart** on its own subplot
137
+ 3. Draws **vertical markers** at `eval_time` checkpoints
138
+ 4. Shows **alert check points** with firing/pending status
139
+ 5. Labels the x-axis with **relative time offsets** (`0s`, `1m`, `2m`, …)
140
+
141
+ ## API Reference
142
+
143
+ ### CSV Mode
144
+
145
+ | Parameter | Description |
146
+ |-----------|-------------|
147
+ | `timestamp_columns` | Columns containing timestamp data to visualise |
148
+ | `id_column` | Column that uniquely identifies each entity |
149
+ | `threshold_days` | Time gap (in days) that triggers a timeline break |
150
+ | `entity_name` | Type name for titles (e.g. "Patient", "Order") |
151
+ | `label_mappings` | Custom display names for timestamp columns |
152
+ | `color_scheme` | Dictionary of colour overrides |
153
+
154
+ ### Promtest Mode
155
+
156
+ | Parameter | Description |
157
+ |-----------|-------------|
158
+ | `figsize` | Figure dimensions `(width, height)` in inches |
159
+ | `title` | Custom figure title |
160
+ | `color_scheme` | Override colours (see [PROMTEST.md](PROMTEST.md#colour-scheme)) |
161
+ | `output_file` | Save to PNG |
162
+ | `dpi` | Resolution (default 150) |
163
+
164
+ ## License
165
+
166
+ [MIT](LICENSE)
@@ -0,0 +1,265 @@
1
+ # Prometheus Test Visualisation
2
+
3
+ Visualise [promtool unit-test](https://prometheus.io/docs/prometheus/latest/configuration/unit_testing_rules/) YAML files as timeline charts — see how series values evolve, where evaluations happen, and when alerts fire.
4
+
5
+ ## Overview
6
+
7
+ A promtool test file defines metric series as values over discrete time steps and then asserts the results of PromQL expressions or alerting rules at specific points. This module parses those files and produces a multi-panel chart:
8
+
9
+ - **One subplot per `input_series`** — step plot of metric values over relative time
10
+ - **Vertical dashed lines** at `eval_time` checkpoints (red for expression tests, dotted for alert checks)
11
+ - **Alert status markers** — diamonds for FIRING, circles for pending
12
+ - **Gap and stale indicators** — hollow squares for missing samples (`_`), × marks for `stale`
13
+ - **Relative x-axis** — labels like `0s`, `1m`, `2m` rather than real timestamps
14
+
15
+ ## Usage
16
+
17
+ ### CLI
18
+
19
+ ```bash
20
+ # Display interactively
21
+ timelineviz my_rules_test.yml --promtest
22
+
23
+ # Save to file without displaying
24
+ timelineviz my_rules_test.yml --promtest --output-dir images --no-show
25
+
26
+ # Custom size and resolution
27
+ timelineviz my_rules_test.yml --promtest --figsize 18,10 --dpi 300
28
+ ```
29
+
30
+ ### Python API
31
+
32
+ ```python
33
+ from timelineviz import parse_promtest_file, parse_promtest_string, plot_promtest
34
+
35
+ # From a file
36
+ groups = parse_promtest_file("my_rules_test.yml")
37
+ results = plot_promtest(groups, output_file="timeline.png")
38
+
39
+ # From a YAML string (handy in notebooks)
40
+ yaml_str = """
41
+ evaluation_interval: 1m
42
+ tests:
43
+ - interval: 1m
44
+ input_series:
45
+ - series: 'http_requests_total{method="GET"}'
46
+ values: '0+10x15'
47
+ promql_expr_test:
48
+ - expr: rate(http_requests_total[5m])
49
+ eval_time: 10m
50
+ exp_samples:
51
+ - labels: 'http_requests_total{method="GET"}'
52
+ value: 0.1666
53
+ """
54
+ groups = parse_promtest_string(yaml_str)
55
+ plot_promtest(groups)
56
+ ```
57
+
58
+ ### Jupyter Notebook
59
+
60
+ ```python
61
+ from timelineviz import parse_promtest_string, plot_promtest
62
+
63
+ # plot_promtest returns a list of (figure, axes) tuples — one per test group
64
+ results = plot_promtest(groups, show_plot=False)
65
+ fig, axs = results[0]
66
+ fig # renders inline in Jupyter
67
+ ```
68
+
69
+ ## Promtool Notation Reference
70
+
71
+ This section summarises the promtool value notation so charts are easier to interpret.
72
+
73
+ ### Durations
74
+
75
+ Used for `evaluation_interval`, `interval`, and `eval_time`:
76
+
77
+ | Example | Meaning |
78
+ |---------|---------|
79
+ | `1m` | 1 minute |
80
+ | `5m` | 5 minutes |
81
+ | `1h30m` | 1 hour 30 minutes |
82
+ | `2d` | 2 days |
83
+ | `500ms` | 500 milliseconds |
84
+
85
+ ### Series Value Notation
86
+
87
+ Each space-separated token in a `values` string represents one or more time steps:
88
+
89
+ | Token | Expansion | Description |
90
+ |-------|-----------|-------------|
91
+ | `42` | `42` | Single sample |
92
+ | `1+2x3` | `1 3 5 7` | Start at 1, increment by 2, repeat 3 more times (4 total) |
93
+ | `10-3x2` | `10 7 4` | Start at 10, decrement by 3, repeat 2 more times (3 total) |
94
+ | `5x4` | `5 5 5 5 5` | Repeat 5 four more times (5 total) |
95
+ | `_` | *(missing)* | One missing/gap sample |
96
+ | `_x3` | *(missing × 3)* | Three consecutive missing samples |
97
+ | `stale` | *(stale)* | Stale marker |
98
+
99
+ Tokens can be combined freely:
100
+
101
+ ```yaml
102
+ values: '1+0x6 0+0x5'
103
+ # Expands to: 1 1 1 1 1 1 1 0 0 0 0 0 0
104
+ # ^^^^^^^^^^^^^^^ ^^^^^^^^^^^
105
+ # 7 ones 6 zeros
106
+ ```
107
+
108
+ ### How Time Steps Map to the Chart
109
+
110
+ Given `interval: 1m` and `values: '0+1x4'`:
111
+
112
+ | Step | Time | Value |
113
+ |------|------|-------|
114
+ | 0 | 0m | 0 |
115
+ | 1 | 1m | 1 |
116
+ | 2 | 2m | 2 |
117
+ | 3 | 3m | 3 |
118
+ | 4 | 4m | 4 |
119
+
120
+ The chart plots these as a step function with dots at each sample.
121
+
122
+ ## Worked Example
123
+
124
+ Given a test file for an `InstanceDown` alert:
125
+
126
+ ```yaml
127
+ # rules_test.yml
128
+ evaluation_interval: 1m
129
+
130
+ tests:
131
+ - interval: 1m
132
+ input_series:
133
+ - series: 'up{job="api"}'
134
+ values: '1+0x14 0+0x5'
135
+ - series: 'up{job="web"}'
136
+ values: '1x19'
137
+
138
+ alert_rule_test:
139
+ - eval_time: 15m
140
+ alertname: InstanceDown
141
+ exp_alerts:
142
+ - exp_labels:
143
+ job: api
144
+
145
+ promql_expr_test:
146
+ - expr: up == 0
147
+ eval_time: 16m
148
+ exp_samples:
149
+ - labels: 'up{job="api"}'
150
+ value: 0
151
+ ```
152
+
153
+ ```python
154
+ from timelineviz import parse_promtest_file, plot_promtest
155
+
156
+ groups = parse_promtest_file("rules_test.yml")
157
+ plot_promtest(groups, title="InstanceDown Alert Test")
158
+ ```
159
+
160
+ This produces:
161
+
162
+ ![InstanceDown Alert Test](images/promtest_example_1.png)
163
+
164
+ **Reading the chart:**
165
+
166
+ 1. **Top subplot** — `up{job="api"}`: value 1 for 0m–14m, drops to 0 at 15m. The raw notation `'1+0x14 0+0x5'` is shown in the italic subtitle below each series name.
167
+ 2. **Middle subplot** — `up{job="web"}`: constant 1 across all 20 steps.
168
+ 3. **Bottom row** (Alert Checks) — `InstanceDown` is marked FIRING at 15m with a red diamond and boxed label.
169
+ 4. **Vertical markers** — dashed red line labelled `eval: up == 0 @ 16m` for the expression eval, dotted line for the alert check time.
170
+ 5. **Value labels** appear above transition points (where the value changes) so you can read exact values without consulting a y-axis.
171
+ 6. **Legend strip** at the bottom explains all marker types used in the chart.
172
+
173
+
174
+ ## Multi-Series Example
175
+
176
+ A more complex example with gaps, stale markers, and multiple series:
177
+
178
+ ```yaml
179
+ evaluation_interval: 1m
180
+ tests:
181
+ - interval: 1m
182
+ input_series:
183
+ - series: 'http_requests_total{method="GET"}'
184
+ values: '0+10x9'
185
+ - series: 'http_requests_total{method="POST"}'
186
+ values: '0+5x4 _ stale 30+5x2'
187
+ - series: 'error_rate'
188
+ values: '0x4 0.5+0.5x3 2x2'
189
+ promql_expr_test:
190
+ - expr: error_rate > 1
191
+ eval_time: 8m
192
+ exp_samples:
193
+ - labels: 'error_rate'
194
+ value: 2
195
+ ```
196
+
197
+ ![Multi-Series with Gaps & Stale](images/promtest_example_2.png)
198
+
199
+ **Things to notice:**
200
+
201
+ - The POST series has a **missing sample** (hollow square at 5m) and a **stale marker** (× at 6m) before resuming at 30.
202
+ - The error_rate series shows a **gradual ramp** from 0 → 0.5 → 1.0 → 1.5 → 2.0 then holds at 2.
203
+ - The eval line at 8m checks `error_rate > 1` — at that point the value is indeed 2.
204
+ - Each subplot's italic subtitle shows the raw promtool notation, making it easy to cross-reference with your YAML test file.
205
+
206
+ ## API Reference
207
+
208
+ ### Parsing
209
+
210
+ | Function | Description |
211
+ |----------|-------------|
212
+ | `parse_promtest_file(path)` | Parse a YAML file, returns `list[PromTestGroup]` |
213
+ | `parse_promtest_string(yaml_string)` | Parse a YAML string, returns `list[PromTestGroup]` |
214
+ | `parse_duration(s)` | Parse a Prometheus duration (`'5m'`) → `timedelta` |
215
+ | `expand_values(notation)` | Expand series notation (`'1+2x3'`) → `[1.0, 3.0, 5.0, 7.0]` |
216
+
217
+ ### Data Model
218
+
219
+ | Class | Key Fields |
220
+ |-------|------------|
221
+ | `PromTestGroup` | `interval`, `series`, `eval_points`, `alert_checks`, `name` |
222
+ | `SeriesData` | `metric`, `labels`, `values`, `interval`, `raw_values`, `display_name`, `time_offsets` |
223
+ | `EvalPoint` | `expr`, `eval_time`, `expected_results` |
224
+ | `AlertCheck` | `alertname`, `eval_time`, `exp_alerts` |
225
+
226
+ ### Visualisation
227
+
228
+ ```python
229
+ plot_promtest(
230
+ groups, # list[PromTestGroup]
231
+ figsize=None, # (width, height) or auto-sized
232
+ show_plot=True, # display interactively
233
+ output_file=None, # save PNG path
234
+ dpi=150, # resolution
235
+ title=None, # custom figure title
236
+ color_scheme=None, # override PROMTEST_COLOR_SCHEME keys
237
+ )
238
+ # Returns list[(matplotlib.Figure, list[matplotlib.Axes])]
239
+ ```
240
+
241
+ ### Colour Scheme
242
+
243
+ Override any of these keys via the `color_scheme` parameter:
244
+
245
+ ```python
246
+ {
247
+ 'series_colors': ['#0046be', '#e6194b', '#3cb44b', '#f58231',
248
+ '#911eb4', '#42d4f4', '#f032e6', '#bfef45'],
249
+ 'eval_line': '#e6194b', # eval_time vertical lines
250
+ 'alert_pending': '#ffc107', # pending alert markers
251
+ 'alert_firing': '#dc3545', # firing alert markers
252
+ 'grid': '#e0e0e0',
253
+ 'background': '#fafafa',
254
+ 'text': '#333333',
255
+ 'stale_marker': '#999999', # × marks for stale samples
256
+ 'missing_marker': '#cccccc', # □ marks for missing samples
257
+ }
258
+ ```
259
+
260
+ ## Limitations
261
+
262
+ - **No PromQL evaluation** — the chart shows raw input series and where checks happen, but does not compute derived expressions like `rate()` or `avg()`.
263
+ - **Alert state transitions are not computed** — we show whether `exp_alerts` is populated (FIRING) or empty (pending) at each `eval_time`, but we don't simulate the `for` duration logic.
264
+ - **Native histogram notation** is not yet supported — histogram-valued series will raise a parse error.
265
+ - **One figure per test group** — if your YAML has several `tests:` entries, each gets a separate figure.
@@ -0,0 +1,130 @@
1
+ # timelineviz
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/timelineviz)](https://pypi.org/project/timelineviz/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/timelineviz)](https://pypi.org/project/timelineviz/)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+
7
+ Timeline visualisation for CSV data and Prometheus test files.
8
+
9
+ ![Example Timeline](images/timeline1.png)
10
+
11
+ ## Features
12
+
13
+ - Plot event timelines from CSV / DataFrame timestamp data
14
+ - Handle time gaps with broken timeline display
15
+ - Auto-detect timestamp columns based on naming patterns
16
+ - **Visualise Prometheus `promtool` unit-test files** — series values, eval checkpoints, and alert checks on a relative time axis
17
+ - Customisable colour schemes
18
+ - CLI and Python API
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install timelineviz
24
+
25
+ # or with uv
26
+ uv add timelineviz
27
+ ```
28
+
29
+ For development:
30
+
31
+ ```bash
32
+ git clone https://github.com/garrywilliams/timeline_viz.git
33
+ cd timeline_viz
34
+ uv pip install -e ".[dev]"
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### CSV / DataFrame Timelines
40
+
41
+ ```bash
42
+ # Auto-detect timestamp columns
43
+ timelineviz data.csv --detect-timestamps --output-dir timelines
44
+
45
+ # Specify columns explicitly
46
+ timelineviz data.csv --timestamp-columns created_at updated_at completed_at
47
+ ```
48
+
49
+ ```python
50
+ from timelineviz import plot_timeline, plot_multiple_timelines
51
+
52
+ import pandas as pd
53
+ df = pd.read_csv("data.csv")
54
+
55
+ # Single entity
56
+ plot_timeline(df.iloc[0],
57
+ timestamp_columns=['created_at', 'updated_at', 'completed_at'],
58
+ entity_id="12345")
59
+
60
+ # Multiple entities
61
+ plot_multiple_timelines("data.csv",
62
+ timestamp_columns=['created_at', 'updated_at'],
63
+ id_column='entity_id',
64
+ output_dir="timeline_images")
65
+ ```
66
+
67
+ ### Prometheus Test Timelines
68
+
69
+ Visualise `promtool` unit-test YAML files — see series values change over time, where evaluations happen, and when alerts fire.
70
+
71
+ ```bash
72
+ timelineviz my_rules_test.yml --promtest
73
+ timelineviz my_rules_test.yml --promtest --output-dir images --no-show
74
+ ```
75
+
76
+ ```python
77
+ from timelineviz import parse_promtest_file, plot_promtest
78
+
79
+ groups = parse_promtest_file("my_rules_test.yml")
80
+ plot_promtest(groups, output_file="promtest_timeline.png")
81
+ ```
82
+
83
+ ![Promtest Example](images/promtest_example_1.png)
84
+
85
+ Charts are self-documenting — each subplot shows the metric name and raw notation, value labels appear at transition points, eval/alert vertical lines are labelled, and a legend strip at the bottom explains all marker types.
86
+
87
+ > **Full guide:** [PROMTEST.md](PROMTEST.md) — notation reference, worked examples, and all parameters.
88
+
89
+ ## How It Works
90
+
91
+ ### CSV Timelines
92
+
93
+ Timestamps are plotted as labelled points along a horizontal axis. When time gaps exceed a threshold, the timeline is broken into segments with slash markers indicating the breaks.
94
+
95
+ ### Promtest Timelines
96
+
97
+ Prometheus test files define metric series as values over discrete time steps (e.g. one value per minute). The library:
98
+
99
+ 1. Parses the YAML and **expands the compact notation** (`1+2x5` → `1, 3, 5, 7, 9, 11`)
100
+ 2. Plots each `input_series` as a **step chart** on its own subplot
101
+ 3. Draws **vertical markers** at `eval_time` checkpoints
102
+ 4. Shows **alert check points** with firing/pending status
103
+ 5. Labels the x-axis with **relative time offsets** (`0s`, `1m`, `2m`, …)
104
+
105
+ ## API Reference
106
+
107
+ ### CSV Mode
108
+
109
+ | Parameter | Description |
110
+ |-----------|-------------|
111
+ | `timestamp_columns` | Columns containing timestamp data to visualise |
112
+ | `id_column` | Column that uniquely identifies each entity |
113
+ | `threshold_days` | Time gap (in days) that triggers a timeline break |
114
+ | `entity_name` | Type name for titles (e.g. "Patient", "Order") |
115
+ | `label_mappings` | Custom display names for timestamp columns |
116
+ | `color_scheme` | Dictionary of colour overrides |
117
+
118
+ ### Promtest Mode
119
+
120
+ | Parameter | Description |
121
+ |-----------|-------------|
122
+ | `figsize` | Figure dimensions `(width, height)` in inches |
123
+ | `title` | Custom figure title |
124
+ | `color_scheme` | Override colours (see [PROMTEST.md](PROMTEST.md#colour-scheme)) |
125
+ | `output_file` | Save to PNG |
126
+ | `dpi` | Resolution (default 150) |
127
+
128
+ ## License
129
+
130
+ [MIT](LICENSE)