kutop 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.
kutop-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kutop contributors
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.
kutop-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: kutop
3
+ Version: 0.1.0
4
+ Summary: A modern, like-btop Kubernetes resource dashboard for the terminal.
5
+ Author: kutop contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ken-jo/kutop
8
+ Project-URL: Repository, https://github.com/ken-jo/kutop
9
+ Project-URL: Issues, https://github.com/ken-jo/kutop/issues
10
+ Keywords: kubernetes,tui,monitoring,dashboard,textual,btop,kutop,kubetop
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: textual==8.2.7
15
+ Requires-Dist: rich==15.0.0
16
+ Provides-Extra: profiles
17
+ Requires-Dist: pyyaml>=6; extra == "profiles"
18
+ Dynamic: license-file
19
+
20
+ # kutop
21
+
22
+ [![CI](https://github.com/ken-jo/kutop/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ken-jo/kutop/actions/workflows/ci.yml)
23
+ [![Release](https://github.com/ken-jo/kutop/actions/workflows/release.yml/badge.svg)](https://github.com/ken-jo/kutop/actions/workflows/release.yml)
24
+ [![GitHub release](https://img.shields.io/github/v/release/ken-jo/kutop?include_prereleases&sort=semver&logo=github)](https://github.com/ken-jo/kutop/releases)
25
+ [![PyPI](https://img.shields.io/pypi/v/kutop?logo=pypi&logoColor=white)](https://pypi.org/project/kutop/)
26
+ [![Wheel](https://img.shields.io/pypi/wheel/kutop?logo=python&logoColor=white)](https://pypi.org/project/kutop/)
27
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue?logo=python&logoColor=white)](pyproject.toml)
28
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
29
+ [![Issues](https://img.shields.io/github/issues/ken-jo/kutop)](https://github.com/ken-jo/kutop/issues)
30
+ [![Stars](https://img.shields.io/github/stars/ken-jo/kutop?style=social)](https://github.com/ken-jo/kutop/stargazers)
31
+ [![Last commit](https://img.shields.io/github/last-commit/ken-jo/kutop)](https://github.com/ken-jo/kutop/commits/master)
32
+
33
+ A modern, like-btop **Kubernetes resource dashboard** for the terminal, built
34
+ with [Textual](https://textual.textualize.io/). It attaches to any cluster /
35
+ namespace, shows live CPU/MEM trend sparklines, an aggregate counter bar, and
36
+ per-pod usage-vs-limit gauges — so you can read the state of a cluster in a few
37
+ seconds. Workload-specific behaviour (pod ordering, timezone, thresholds, alert
38
+ sources, health probes) is injected declaratively via **profiles**, keeping the
39
+ core generic.
40
+
41
+ ```
42
+ NODES 2/2 │ PODS(R/P/F) 18/1/0 │ RESTARTS 7 │ OOM 1 │ WARN 2 │ ALERTS 3
43
+ CPU OVERALL ▁▂▃▅▆▇█ 62% 5.1/16 MEM OVERALL ▃▄▅▆▇█ 74% 47/64Gi
44
+ ◆ worker-pool node-a │
45
+ ● api-0 (1/1) ███████░░░ 70% STS
46
+ ● worker-9 OOMKilled (0/1) █████████░ 95% Deploy
47
+ ```
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ python -m pip install kutop
53
+ python -m pip install "kutop[profiles]" # optional: enables --profile YAML loading
54
+ python -m pip install "kutop[profiles] @ git+https://github.com/ken-jo/kutop.git"
55
+ python -m pip install -e ".[profiles]" # local development from this directory
56
+ ```
57
+
58
+ The project name, PyPI distribution, and Python package namespace are `kutop`.
59
+ The `kubetop` command and `python -m kubetop` remain available only as
60
+ compatibility aliases:
61
+
62
+ ```bash
63
+ kutop --version
64
+ kubetop --version
65
+ python -m kutop --version
66
+ python -m kubetop --version
67
+ ```
68
+
69
+ The PyPI name `kubetop` belongs to a different package. Pinned deps:
70
+ `textual==8.2.7`, `rich==15.0.0`. Python 3.9+.
71
+
72
+ Other package managers after a tagged release:
73
+
74
+ ```bash
75
+ brew install ken-jo/tap/kutop
76
+
77
+ curl -fsSL https://ken-jo.github.io/kutop/apt/kutop.gpg \
78
+ | sudo gpg --dearmor -o /usr/share/keyrings/kutop-archive-keyring.gpg
79
+ echo "deb [signed-by=/usr/share/keyrings/kutop-archive-keyring.gpg] https://ken-jo.github.io/kutop/apt stable main" \
80
+ | sudo tee /etc/apt/sources.list.d/kutop.list
81
+ sudo apt update
82
+ sudo apt install kutop
83
+ ```
84
+
85
+ Release setup for PyPI, Homebrew, and apt is documented in
86
+ [`docs/release.md`](docs/release.md).
87
+
88
+ ## Run
89
+
90
+ ```bash
91
+ kutop # generic view, namespace 'default'
92
+ kutop demo-ns 3 # namespace demo-ns, 3s refresh
93
+ kutop ns-a,ns-b # multiple namespaces (comma list)
94
+ kutop --profile example # load a profile (ordering / tz / thresholds)
95
+ python -m kutop demo-ns 3 # module form
96
+ python -m kubetop demo-ns 3 # legacy module alias
97
+ kutop --context demo-context demo-ns # pick a kubeconfig context
98
+ kutop --allow-destructive # enable pod delete (still confirm-gated)
99
+ kutop --dump-config # print the full annotated config skeleton
100
+ kutop --self-test # headless smoke test (no cluster), exits 0
101
+ kutop --snapshot out.svg # render one frame to SVG and exit
102
+ kutop --snapshot out.svg --detail full # wider diagnostic capture
103
+ ```
104
+
105
+ Positional `namespaces`/`interval` only seed the first run; your in-app choices
106
+ are saved to `~/.config/kutop/config.yaml` and win on the next launch. Existing
107
+ `~/.config/kubetop` and legacy `~/.config/ktop` configs are migrated on first
108
+ load; named profiles are also resolved from those legacy profile directories.
109
+
110
+ ## Keybindings
111
+
112
+ | Key | Action |
113
+ |-----|--------|
114
+ | `q` | quit |
115
+ | `r` | refresh now |
116
+ | `o` | options / settings (tabbed: View, Columns, Panels, Thresholds, Cluster) |
117
+ | `Tab` / `b` | toggle the control sidebar |
118
+ | `/` | search / filter pods by name |
119
+ | `s` / `S` | cycle sort column / flip sort direction (or click a column header) |
120
+ | `g` | group pods under their node |
121
+ | `l` | live logs for the focused pod (`kubectl logs -f`) |
122
+ | `d` | describe the focused pod |
123
+ | `x` | delete the focused pod (only with `--allow-destructive`, then confirm) |
124
+ | `e` / `v` | toggle the Events / PVC panels |
125
+ | `a` / `h` | toggle the Alerts / Health panels (profile-driven) |
126
+ | `R` | reload `~/.config/kutop/config.yaml` live |
127
+
128
+ The **NODE/POD column is resizable**: drag the `│` handle on its header to widen
129
+ or narrow it (the width persists). Click any column header to sort by it.
130
+
131
+ ## Screenshots
132
+
133
+ `kutop` can render a headless SVG frame for README images, reviews, and visual
134
+ QA. It uses live cluster data when reachable and falls back to a generic
135
+ synthetic frame when not.
136
+
137
+ ![kutop wide detail screenshot](docs/kutop-wide.svg)
138
+
139
+ ```bash
140
+ kutop --snapshot /tmp/kutop.svg
141
+ kutop --snapshot /tmp/kutop-wide.svg --detail wide
142
+ kutop --snapshot /tmp/kutop-full.svg --detail full
143
+ kutop --snapshot /tmp/kutop-full.svg --detail full --size 220x54
144
+ ```
145
+
146
+ The detail presets are one-shot column layouts:
147
+
148
+ | Detail | Default size | Use |
149
+ |--------|--------------|-----|
150
+ | `normal` | `140x40` | Same visible columns as the interactive default |
151
+ | `wide` | `160x44` | Prioritises namespace, readiness, phase, reason, owner, node, and key resources |
152
+ | `full` | `220x54` | Enables every table column and the PVC panel; increase `--size` for far-right columns |
153
+
154
+ ## Profiles
155
+
156
+ A profile externalises everything that would otherwise be hardcoded. See
157
+ [`kutop/profiles/example.yaml`](kutop/profiles/example.yaml) for a fully
158
+ commented template:
159
+
160
+ ```yaml
161
+ name: my-stack
162
+ namespaces: [team-a, team-b]
163
+ timezone: "" # "" -> host local tz; or an IANA name
164
+ ordering:
165
+ - { prefix: ingress-, weight: 10 }
166
+ - { prefix: api-, weight: 20 }
167
+ thresholds:
168
+ cpu_warn: 75
169
+ cpu_crit: 90
170
+ mem_warn: 80
171
+ mem_crit: 92
172
+ # alertmanager_url: "/api/v1/namespaces/monitoring/services/<svc>:9093/proxy/api/v2/alerts"
173
+ ```
174
+
175
+ Profiles resolve by name from `~/.config/kutop/profiles/<name>.yaml` and the
176
+ packaged `kutop/profiles/` directory, or by explicit path. Without a profile
177
+ the core runs fully (alphabetical ordering, local timezone, generic thresholds).
178
+
179
+ ## Alerts & health (no port-forward)
180
+
181
+ The Alerts and Health panels are opt-in and profile-driven. A `/`-prefixed URL
182
+ in `alertmanager_url` / `health_probes[].url` is fetched via `kubectl get --raw`
183
+ through the Kubernetes **API-server proxy** — so it uses your kubeconfig auth
184
+ with no localhost port-forward. Health is a self-contained plugin
185
+ (`kutop/plugins/health.py`); the core does not depend on it.
186
+
187
+ ## How it works
188
+
189
+ * kubectl calls run in a background thread worker; the UI thread never blocks,
190
+ and a refresh is skipped while one is in flight (no thrashing on slow clusters).
191
+ * Node/pod CPU & memory come from `kubectl top` + `kubectl get -o json`.
192
+ * PVC usage comes from the kubelet summary API
193
+ (`/api/v1/nodes/<node>/proxy/stats/summary`) because metrics-server does not
194
+ expose it — a node whose summary call fails is skipped, others still report.
195
+ * OOMKilled / CrashLoopBackOff / Pending pods are highlighted distinctly; node
196
+ rows lead with the nodegroup (EKS/GKE/AKS label), then the short instance name.
197
+
198
+ ## License
199
+
200
+ MIT. See [LICENSE](LICENSE).
kutop-0.1.0/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # kutop
2
+
3
+ [![CI](https://github.com/ken-jo/kutop/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ken-jo/kutop/actions/workflows/ci.yml)
4
+ [![Release](https://github.com/ken-jo/kutop/actions/workflows/release.yml/badge.svg)](https://github.com/ken-jo/kutop/actions/workflows/release.yml)
5
+ [![GitHub release](https://img.shields.io/github/v/release/ken-jo/kutop?include_prereleases&sort=semver&logo=github)](https://github.com/ken-jo/kutop/releases)
6
+ [![PyPI](https://img.shields.io/pypi/v/kutop?logo=pypi&logoColor=white)](https://pypi.org/project/kutop/)
7
+ [![Wheel](https://img.shields.io/pypi/wheel/kutop?logo=python&logoColor=white)](https://pypi.org/project/kutop/)
8
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue?logo=python&logoColor=white)](pyproject.toml)
9
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
10
+ [![Issues](https://img.shields.io/github/issues/ken-jo/kutop)](https://github.com/ken-jo/kutop/issues)
11
+ [![Stars](https://img.shields.io/github/stars/ken-jo/kutop?style=social)](https://github.com/ken-jo/kutop/stargazers)
12
+ [![Last commit](https://img.shields.io/github/last-commit/ken-jo/kutop)](https://github.com/ken-jo/kutop/commits/master)
13
+
14
+ A modern, like-btop **Kubernetes resource dashboard** for the terminal, built
15
+ with [Textual](https://textual.textualize.io/). It attaches to any cluster /
16
+ namespace, shows live CPU/MEM trend sparklines, an aggregate counter bar, and
17
+ per-pod usage-vs-limit gauges — so you can read the state of a cluster in a few
18
+ seconds. Workload-specific behaviour (pod ordering, timezone, thresholds, alert
19
+ sources, health probes) is injected declaratively via **profiles**, keeping the
20
+ core generic.
21
+
22
+ ```
23
+ NODES 2/2 │ PODS(R/P/F) 18/1/0 │ RESTARTS 7 │ OOM 1 │ WARN 2 │ ALERTS 3
24
+ CPU OVERALL ▁▂▃▅▆▇█ 62% 5.1/16 MEM OVERALL ▃▄▅▆▇█ 74% 47/64Gi
25
+ ◆ worker-pool node-a │
26
+ ● api-0 (1/1) ███████░░░ 70% STS
27
+ ● worker-9 OOMKilled (0/1) █████████░ 95% Deploy
28
+ ```
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ python -m pip install kutop
34
+ python -m pip install "kutop[profiles]" # optional: enables --profile YAML loading
35
+ python -m pip install "kutop[profiles] @ git+https://github.com/ken-jo/kutop.git"
36
+ python -m pip install -e ".[profiles]" # local development from this directory
37
+ ```
38
+
39
+ The project name, PyPI distribution, and Python package namespace are `kutop`.
40
+ The `kubetop` command and `python -m kubetop` remain available only as
41
+ compatibility aliases:
42
+
43
+ ```bash
44
+ kutop --version
45
+ kubetop --version
46
+ python -m kutop --version
47
+ python -m kubetop --version
48
+ ```
49
+
50
+ The PyPI name `kubetop` belongs to a different package. Pinned deps:
51
+ `textual==8.2.7`, `rich==15.0.0`. Python 3.9+.
52
+
53
+ Other package managers after a tagged release:
54
+
55
+ ```bash
56
+ brew install ken-jo/tap/kutop
57
+
58
+ curl -fsSL https://ken-jo.github.io/kutop/apt/kutop.gpg \
59
+ | sudo gpg --dearmor -o /usr/share/keyrings/kutop-archive-keyring.gpg
60
+ echo "deb [signed-by=/usr/share/keyrings/kutop-archive-keyring.gpg] https://ken-jo.github.io/kutop/apt stable main" \
61
+ | sudo tee /etc/apt/sources.list.d/kutop.list
62
+ sudo apt update
63
+ sudo apt install kutop
64
+ ```
65
+
66
+ Release setup for PyPI, Homebrew, and apt is documented in
67
+ [`docs/release.md`](docs/release.md).
68
+
69
+ ## Run
70
+
71
+ ```bash
72
+ kutop # generic view, namespace 'default'
73
+ kutop demo-ns 3 # namespace demo-ns, 3s refresh
74
+ kutop ns-a,ns-b # multiple namespaces (comma list)
75
+ kutop --profile example # load a profile (ordering / tz / thresholds)
76
+ python -m kutop demo-ns 3 # module form
77
+ python -m kubetop demo-ns 3 # legacy module alias
78
+ kutop --context demo-context demo-ns # pick a kubeconfig context
79
+ kutop --allow-destructive # enable pod delete (still confirm-gated)
80
+ kutop --dump-config # print the full annotated config skeleton
81
+ kutop --self-test # headless smoke test (no cluster), exits 0
82
+ kutop --snapshot out.svg # render one frame to SVG and exit
83
+ kutop --snapshot out.svg --detail full # wider diagnostic capture
84
+ ```
85
+
86
+ Positional `namespaces`/`interval` only seed the first run; your in-app choices
87
+ are saved to `~/.config/kutop/config.yaml` and win on the next launch. Existing
88
+ `~/.config/kubetop` and legacy `~/.config/ktop` configs are migrated on first
89
+ load; named profiles are also resolved from those legacy profile directories.
90
+
91
+ ## Keybindings
92
+
93
+ | Key | Action |
94
+ |-----|--------|
95
+ | `q` | quit |
96
+ | `r` | refresh now |
97
+ | `o` | options / settings (tabbed: View, Columns, Panels, Thresholds, Cluster) |
98
+ | `Tab` / `b` | toggle the control sidebar |
99
+ | `/` | search / filter pods by name |
100
+ | `s` / `S` | cycle sort column / flip sort direction (or click a column header) |
101
+ | `g` | group pods under their node |
102
+ | `l` | live logs for the focused pod (`kubectl logs -f`) |
103
+ | `d` | describe the focused pod |
104
+ | `x` | delete the focused pod (only with `--allow-destructive`, then confirm) |
105
+ | `e` / `v` | toggle the Events / PVC panels |
106
+ | `a` / `h` | toggle the Alerts / Health panels (profile-driven) |
107
+ | `R` | reload `~/.config/kutop/config.yaml` live |
108
+
109
+ The **NODE/POD column is resizable**: drag the `│` handle on its header to widen
110
+ or narrow it (the width persists). Click any column header to sort by it.
111
+
112
+ ## Screenshots
113
+
114
+ `kutop` can render a headless SVG frame for README images, reviews, and visual
115
+ QA. It uses live cluster data when reachable and falls back to a generic
116
+ synthetic frame when not.
117
+
118
+ ![kutop wide detail screenshot](docs/kutop-wide.svg)
119
+
120
+ ```bash
121
+ kutop --snapshot /tmp/kutop.svg
122
+ kutop --snapshot /tmp/kutop-wide.svg --detail wide
123
+ kutop --snapshot /tmp/kutop-full.svg --detail full
124
+ kutop --snapshot /tmp/kutop-full.svg --detail full --size 220x54
125
+ ```
126
+
127
+ The detail presets are one-shot column layouts:
128
+
129
+ | Detail | Default size | Use |
130
+ |--------|--------------|-----|
131
+ | `normal` | `140x40` | Same visible columns as the interactive default |
132
+ | `wide` | `160x44` | Prioritises namespace, readiness, phase, reason, owner, node, and key resources |
133
+ | `full` | `220x54` | Enables every table column and the PVC panel; increase `--size` for far-right columns |
134
+
135
+ ## Profiles
136
+
137
+ A profile externalises everything that would otherwise be hardcoded. See
138
+ [`kutop/profiles/example.yaml`](kutop/profiles/example.yaml) for a fully
139
+ commented template:
140
+
141
+ ```yaml
142
+ name: my-stack
143
+ namespaces: [team-a, team-b]
144
+ timezone: "" # "" -> host local tz; or an IANA name
145
+ ordering:
146
+ - { prefix: ingress-, weight: 10 }
147
+ - { prefix: api-, weight: 20 }
148
+ thresholds:
149
+ cpu_warn: 75
150
+ cpu_crit: 90
151
+ mem_warn: 80
152
+ mem_crit: 92
153
+ # alertmanager_url: "/api/v1/namespaces/monitoring/services/<svc>:9093/proxy/api/v2/alerts"
154
+ ```
155
+
156
+ Profiles resolve by name from `~/.config/kutop/profiles/<name>.yaml` and the
157
+ packaged `kutop/profiles/` directory, or by explicit path. Without a profile
158
+ the core runs fully (alphabetical ordering, local timezone, generic thresholds).
159
+
160
+ ## Alerts & health (no port-forward)
161
+
162
+ The Alerts and Health panels are opt-in and profile-driven. A `/`-prefixed URL
163
+ in `alertmanager_url` / `health_probes[].url` is fetched via `kubectl get --raw`
164
+ through the Kubernetes **API-server proxy** — so it uses your kubeconfig auth
165
+ with no localhost port-forward. Health is a self-contained plugin
166
+ (`kutop/plugins/health.py`); the core does not depend on it.
167
+
168
+ ## How it works
169
+
170
+ * kubectl calls run in a background thread worker; the UI thread never blocks,
171
+ and a refresh is skipped while one is in flight (no thrashing on slow clusters).
172
+ * Node/pod CPU & memory come from `kubectl top` + `kubectl get -o json`.
173
+ * PVC usage comes from the kubelet summary API
174
+ (`/api/v1/nodes/<node>/proxy/stats/summary`) because metrics-server does not
175
+ expose it — a node whose summary call fails is skipped, others still report.
176
+ * OOMKilled / CrashLoopBackOff / Pending pods are highlighted distinctly; node
177
+ rows lead with the nodegroup (EKS/GKE/AKS label), then the short instance name.
178
+
179
+ ## License
180
+
181
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,14 @@
1
+ """Compatibility namespace for the old kubetop import name.
2
+
3
+ New code should import :mod:`kutop`. This module keeps legacy imports such as
4
+ ``import kubetop.config`` working by exposing kutop's package path.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import kutop as _kutop
10
+ from kutop import __version__
11
+
12
+ __path__ = _kutop.__path__
13
+
14
+ __all__ = ["__version__"]
@@ -0,0 +1,9 @@
1
+ """Run kutop through the legacy ``python -m kubetop`` alias."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from kutop.cli import main
6
+
7
+
8
+ if __name__ == "__main__":
9
+ raise SystemExit(main())
@@ -0,0 +1,3 @@
1
+ """kutop - a modern, like-btop Kubernetes resource dashboard."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Enable ``python -m kutop``."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())