stui-terminal 0.1.0rc2__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.
- stui_terminal-0.1.0rc2/.github/workflows/ci.yml +30 -0
- stui_terminal-0.1.0rc2/.github/workflows/publish.yml +107 -0
- stui_terminal-0.1.0rc2/AGENTS.md +11 -0
- stui_terminal-0.1.0rc2/CHANGELOG.md +29 -0
- stui_terminal-0.1.0rc2/CONTRIBUTING.md +44 -0
- stui_terminal-0.1.0rc2/LICENSE +21 -0
- stui_terminal-0.1.0rc2/MANIFEST.in +13 -0
- stui_terminal-0.1.0rc2/PKG-INFO +258 -0
- stui_terminal-0.1.0rc2/README.md +236 -0
- stui_terminal-0.1.0rc2/RELEASE_NOTES_v0.1.0rc1.md +83 -0
- stui_terminal-0.1.0rc2/RELEASE_NOTES_v0.1.0rc2.md +92 -0
- stui_terminal-0.1.0rc2/assets/model_demo.svg +178 -0
- stui_terminal-0.1.0rc2/docs/announcement-drafts.md +92 -0
- stui_terminal-0.1.0rc2/docs/publishing.md +139 -0
- stui_terminal-0.1.0rc2/examples/basic.py +14 -0
- stui_terminal-0.1.0rc2/examples/counter.py +20 -0
- stui_terminal-0.1.0rc2/examples/model_demo.py +43 -0
- stui_terminal-0.1.0rc2/pyproject.toml +50 -0
- stui_terminal-0.1.0rc2/setup.cfg +4 -0
- stui_terminal-0.1.0rc2/src/stui/__init__.py +40 -0
- stui_terminal-0.1.0rc2/src/stui/__main__.py +4 -0
- stui_terminal-0.1.0rc2/src/stui/api.py +187 -0
- stui_terminal-0.1.0rc2/src/stui/app.py +343 -0
- stui_terminal-0.1.0rc2/src/stui/cli.py +52 -0
- stui_terminal-0.1.0rc2/src/stui/elements.py +103 -0
- stui_terminal-0.1.0rc2/src/stui/runtime.py +293 -0
- stui_terminal-0.1.0rc2/src/stui/session_state.py +57 -0
- stui_terminal-0.1.0rc2/src/stui/widgets/__init__.py +3 -0
- stui_terminal-0.1.0rc2/src/stui/widgets/slider.py +132 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/PKG-INFO +258 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/SOURCES.txt +46 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/dependency_links.txt +1 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/entry_points.txt +2 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/requires.txt +9 -0
- stui_terminal-0.1.0rc2/src/stui_terminal.egg-info/top_level.txt +1 -0
- stui_terminal-0.1.0rc2/tests/test_app_smoke.py +74 -0
- stui_terminal-0.1.0rc2/tests/test_button.py +48 -0
- stui_terminal-0.1.0rc2/tests/test_callbacks.py +163 -0
- stui_terminal-0.1.0rc2/tests/test_cli.py +61 -0
- stui_terminal-0.1.0rc2/tests/test_keys.py +62 -0
- stui_terminal-0.1.0rc2/tests/test_phase2_elements.py +68 -0
- stui_terminal-0.1.0rc2/tests/test_phase2_widgets.py +122 -0
- stui_terminal-0.1.0rc2/tests/test_runtime.py +89 -0
- stui_terminal-0.1.0rc2/tests/test_runtime_hardening.py +218 -0
- stui_terminal-0.1.0rc2/tests/test_session_state.py +29 -0
- stui_terminal-0.1.0rc2/tests/test_slider.py +27 -0
- stui_terminal-0.1.0rc2/tests/test_static_policy.py +87 -0
- stui_terminal-0.1.0rc2/tests/test_widget_edge_cases.py +127 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
name: Python ${{ matrix.python-version }}
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.11", "3.12"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check out repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install package
|
|
27
|
+
run: python -m pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: python -m pytest
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
publish_to_testpypi:
|
|
10
|
+
description: "Publish to TestPyPI after the testpypi environment is configured"
|
|
11
|
+
required: true
|
|
12
|
+
type: boolean
|
|
13
|
+
default: false
|
|
14
|
+
publish_to_pypi:
|
|
15
|
+
description: "Publish to real PyPI after the pypi environment is configured"
|
|
16
|
+
required: true
|
|
17
|
+
type: boolean
|
|
18
|
+
default: false
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
name: Build and check distributions
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Check out repository
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.11"
|
|
36
|
+
|
|
37
|
+
- name: Install build tools
|
|
38
|
+
run: python -m pip install --upgrade build twine
|
|
39
|
+
|
|
40
|
+
- name: Build sdist and wheel
|
|
41
|
+
run: python -m build
|
|
42
|
+
|
|
43
|
+
- name: Check distributions
|
|
44
|
+
run: python -m twine check dist/*
|
|
45
|
+
|
|
46
|
+
- name: Upload distributions
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: python-distributions
|
|
50
|
+
path: dist/*
|
|
51
|
+
if-no-files-found: error
|
|
52
|
+
|
|
53
|
+
publish-testpypi:
|
|
54
|
+
name: Publish to TestPyPI
|
|
55
|
+
needs: build
|
|
56
|
+
if: >-
|
|
57
|
+
${{
|
|
58
|
+
github.event_name == 'workflow_dispatch' &&
|
|
59
|
+
inputs.publish_to_testpypi &&
|
|
60
|
+
startsWith(github.ref, 'refs/tags/v')
|
|
61
|
+
}}
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
environment: testpypi
|
|
64
|
+
permissions:
|
|
65
|
+
contents: read
|
|
66
|
+
id-token: write
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- name: Download distributions
|
|
70
|
+
uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: python-distributions
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
- name: Publish distributions to TestPyPI
|
|
76
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
77
|
+
with:
|
|
78
|
+
repository-url: https://test.pypi.org/legacy/
|
|
79
|
+
packages-dir: dist/
|
|
80
|
+
skip-existing: true
|
|
81
|
+
|
|
82
|
+
publish-pypi:
|
|
83
|
+
name: Publish to PyPI
|
|
84
|
+
needs: build
|
|
85
|
+
if: >-
|
|
86
|
+
${{
|
|
87
|
+
github.event_name == 'workflow_dispatch' &&
|
|
88
|
+
inputs.publish_to_pypi &&
|
|
89
|
+
startsWith(github.ref, 'refs/tags/v')
|
|
90
|
+
}}
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
environment: pypi
|
|
93
|
+
permissions:
|
|
94
|
+
contents: read
|
|
95
|
+
id-token: write
|
|
96
|
+
|
|
97
|
+
steps:
|
|
98
|
+
- name: Download distributions
|
|
99
|
+
uses: actions/download-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: python-distributions
|
|
102
|
+
path: dist/
|
|
103
|
+
|
|
104
|
+
- name: Publish distributions to PyPI
|
|
105
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
106
|
+
with:
|
|
107
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# stui Agent Notes
|
|
2
|
+
|
|
3
|
+
- Always run `python3.11 -m pytest` after code changes.
|
|
4
|
+
- Keep the public API small and Streamlit-inspired, not Streamlit-compatible.
|
|
5
|
+
- Do not add browser, server, websocket, or port-forwarding code.
|
|
6
|
+
- Do not depend on Streamlit at runtime.
|
|
7
|
+
- Do not copy GPL slider code or depend on packages such as `textual-slider`.
|
|
8
|
+
- Prefer Textual first-party widgets where they exist.
|
|
9
|
+
- Keep the MVP implementation readable and direct before adding abstractions.
|
|
10
|
+
- Keep public docs honest: `stui` is not official Streamlit, not affiliated with Streamlit, and not a Streamlit compatibility layer.
|
|
11
|
+
- When working alongside other agents, do not revert edits you did not make.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This project is currently pre-1.0, so APIs may change while the MVP is being
|
|
6
|
+
shaped.
|
|
7
|
+
|
|
8
|
+
## 0.1.0rc2 - 2026-05-09
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Updated install documentation for the future PyPI distribution name,
|
|
13
|
+
`stui-terminal`.
|
|
14
|
+
- Clarified that the distribution name is `stui-terminal`, while the import
|
|
15
|
+
package and CLI remain `stui`.
|
|
16
|
+
- Preserved editable local development install instructions for contributors.
|
|
17
|
+
|
|
18
|
+
## 0.1.0rc1 - 2026-05-08
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Initial terminal-native `stui` MVP with top-to-bottom script reruns.
|
|
23
|
+
- Public APIs for text output, alerts, button, slider, text input, checkbox,
|
|
24
|
+
and session state.
|
|
25
|
+
- Textual terminal renderer with keyboard-first widget interactions.
|
|
26
|
+
- CLI entrypoints for `stui run ...` and `python -m stui run ...`.
|
|
27
|
+
- Example apps for the basic demo, counter, and model-parameter playground.
|
|
28
|
+
- Test suite, static policy checks, CI workflow, contributor guide, and release
|
|
29
|
+
candidate documentation.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping with `stui`. The project is still an MVP, so the best
|
|
4
|
+
contributions keep the surface area small, readable, and easy to test.
|
|
5
|
+
|
|
6
|
+
## Local Setup
|
|
7
|
+
|
|
8
|
+
Use Python 3.11 or newer:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
python3.11 -m pip install -e ".[dev]"
|
|
12
|
+
python3.11 -m pytest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Development Guidelines
|
|
16
|
+
|
|
17
|
+
- Keep the public API small and Streamlit-inspired, not Streamlit-compatible.
|
|
18
|
+
- Do not add browser, server, websocket, or port-forwarding code.
|
|
19
|
+
- Do not depend on Streamlit at runtime.
|
|
20
|
+
- Prefer Textual first-party widgets where they exist.
|
|
21
|
+
- Do not copy GPL slider code or depend on packages such as `textual-slider`.
|
|
22
|
+
- Keep MVP code direct before adding abstractions.
|
|
23
|
+
- Keep examples local and deterministic; avoid network calls unless the project
|
|
24
|
+
explicitly grows that capability later.
|
|
25
|
+
|
|
26
|
+
## Tests
|
|
27
|
+
|
|
28
|
+
Run the full test suite after code changes:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
python3.11 -m pytest
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Documentation-only edits should still be checked for accuracy against the
|
|
35
|
+
current API and examples.
|
|
36
|
+
|
|
37
|
+
## Public Claims
|
|
38
|
+
|
|
39
|
+
Please keep README and release notes honest:
|
|
40
|
+
|
|
41
|
+
- Say `stui` is inspired by Streamlit, not compatible with it.
|
|
42
|
+
- Say `stui` is not official Streamlit and is not affiliated with Streamlit.
|
|
43
|
+
- Avoid implying production hardening, broad widget coverage, browser support,
|
|
44
|
+
or long-term API stability before those things exist.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MarMar Labs
|
|
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,13 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include RELEASE_NOTES_v0.1.0rc1.md
|
|
5
|
+
include RELEASE_NOTES_v0.1.0rc2.md
|
|
6
|
+
include CONTRIBUTING.md
|
|
7
|
+
include AGENTS.md
|
|
8
|
+
include pyproject.toml
|
|
9
|
+
recursive-include assets *.svg
|
|
10
|
+
recursive-include docs *.md
|
|
11
|
+
recursive-include examples *.py
|
|
12
|
+
recursive-include tests *.py
|
|
13
|
+
recursive-include .github/workflows *.yml
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stui-terminal
|
|
3
|
+
Version: 0.1.0rc2
|
|
4
|
+
Summary: A tiny Streamlit-inspired terminal UI experiment.
|
|
5
|
+
Author: MarMar Labs
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/marmar9615-cloud/stui-terminal
|
|
8
|
+
Project-URL: Repository, https://github.com/marmar9615-cloud/stui-terminal
|
|
9
|
+
Project-URL: Issues, https://github.com/marmar9615-cloud/stui-terminal/issues
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: rich>=13.7
|
|
14
|
+
Requires-Dist: textual>=0.89
|
|
15
|
+
Requires-Dist: typer>=0.12
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
18
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
19
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
20
|
+
Requires-Dist: twine>=5.1; extra == "dev"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# stui
|
|
24
|
+
|
|
25
|
+
[](https://github.com/marmar9615-cloud/stui-terminal/actions/workflows/ci.yml)
|
|
26
|
+
|
|
27
|
+
`stui` is a tiny Streamlit-inspired framework for building terminal-native
|
|
28
|
+
Python apps. Write a short script, run it in your terminal, and get a Textual UI
|
|
29
|
+
with stateful controls.
|
|
30
|
+
|
|
31
|
+
It is built for local tools, demos, data scripts, model debug panels, SSH
|
|
32
|
+
sessions, and headless environments where opening a browser, binding a port, or
|
|
33
|
+
running a dashboard server is unnecessary ceremony. The public API is
|
|
34
|
+
deliberately small and readable.
|
|
35
|
+
|
|
36
|
+
`stui` is not official Streamlit, is not affiliated with Streamlit, and is not a
|
|
37
|
+
Streamlit compatibility layer. The API intentionally feels familiar, but this
|
|
38
|
+
project keeps its own smaller surface area.
|
|
39
|
+
|
|
40
|
+
## Preview
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
┌─ stui ───────────────────────────────────────────┐
|
|
46
|
+
│ stui demo │
|
|
47
|
+
│ │
|
|
48
|
+
│ x │
|
|
49
|
+
│ [██░░░░░░░░░░░░] 10 │
|
|
50
|
+
│ │
|
|
51
|
+
│ [ Increment ] │
|
|
52
|
+
│ │
|
|
53
|
+
│ x = 10 │
|
|
54
|
+
│ count = 0 │
|
|
55
|
+
│ │
|
|
56
|
+
│ q Quit r Rerun tab Focus next │
|
|
57
|
+
└──────────────────────────────────────────────────┘
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
Use Python 3.11 or newer.
|
|
63
|
+
|
|
64
|
+
Install the PyPI distribution named `stui-terminal`:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python3.11 -m pip install stui-terminal
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The PyPI distribution name is `stui-terminal`, but the import package and CLI
|
|
71
|
+
are both `stui`:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import stui as st
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For local development from a checkout, use an editable install with the dev
|
|
78
|
+
extra:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python3.11 -m venv .venv
|
|
82
|
+
. .venv/bin/activate
|
|
83
|
+
python3.11 -m pip install -e ".[dev]"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For runtime-only local use, install without the dev extra:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python3.11 -m pip install -e .
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Quickstart
|
|
93
|
+
|
|
94
|
+
Install from PyPI, then run your app:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python3.11 -m pip install stui-terminal
|
|
98
|
+
stui run app.py
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Or set up the project from source and run the basic example:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/marmar9615-cloud/stui-terminal.git
|
|
105
|
+
cd stui-terminal
|
|
106
|
+
python3.11 -m venv .venv
|
|
107
|
+
. .venv/bin/activate
|
|
108
|
+
python3.11 -m pip install -e ".[dev]"
|
|
109
|
+
stui run examples/basic.py
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
You can also run through the module entry point:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python3.11 -m stui run examples/counter.py
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Scripts use the public `stui` API:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
import stui as st
|
|
122
|
+
|
|
123
|
+
st.title("stui demo")
|
|
124
|
+
|
|
125
|
+
if "count" not in st.session_state:
|
|
126
|
+
st.session_state.count = 0
|
|
127
|
+
|
|
128
|
+
value = st.slider("value", 0, 100, 25)
|
|
129
|
+
|
|
130
|
+
if st.button("Increment"):
|
|
131
|
+
st.session_state.count += 1
|
|
132
|
+
|
|
133
|
+
st.write("value =", value)
|
|
134
|
+
st.write("count =", st.session_state.count)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
More examples:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
stui run examples/counter.py
|
|
141
|
+
stui run examples/model_demo.py
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Why terminal-native?
|
|
145
|
+
|
|
146
|
+
Some useful Python apps do not need a browser runtime. `stui` keeps the
|
|
147
|
+
interface inside the terminal so it can fit naturally into:
|
|
148
|
+
|
|
149
|
+
- SSH sessions, remote machines, and headless boxes.
|
|
150
|
+
- Internal tools where opening ports or managing local server URLs is friction.
|
|
151
|
+
- Offline or locked-down environments where browser access is limited.
|
|
152
|
+
- Model, data, and DevOps workflows that already start from a shell.
|
|
153
|
+
|
|
154
|
+
That also keeps the boundary simple: `stui` does not start a web server, use
|
|
155
|
+
websockets, require port-forwarding, or depend on Streamlit at runtime.
|
|
156
|
+
|
|
157
|
+
## Commands
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Install the project for local development.
|
|
161
|
+
python3.11 -m venv .venv
|
|
162
|
+
. .venv/bin/activate
|
|
163
|
+
python3.11 -m pip install -e ".[dev]"
|
|
164
|
+
|
|
165
|
+
# Run the smoke-size example app.
|
|
166
|
+
stui run examples/basic.py
|
|
167
|
+
|
|
168
|
+
# Run the stateful counter example.
|
|
169
|
+
stui run examples/counter.py
|
|
170
|
+
|
|
171
|
+
# Run the deterministic model-parameter demo.
|
|
172
|
+
stui run examples/model_demo.py
|
|
173
|
+
|
|
174
|
+
# Run the test suite.
|
|
175
|
+
python3.11 -m pytest
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Keyboard Shortcuts
|
|
179
|
+
|
|
180
|
+
- `q`: quit the app
|
|
181
|
+
- `r`: rerun the script
|
|
182
|
+
- `tab`: focus the next widget
|
|
183
|
+
- `enter`: press the focused button
|
|
184
|
+
- `left` or `h`: decrease the focused slider
|
|
185
|
+
- `right` or `l`: increase the focused slider
|
|
186
|
+
- `home`: set the focused slider to its minimum value
|
|
187
|
+
- `end`: set the focused slider to its maximum value
|
|
188
|
+
|
|
189
|
+
## Current API
|
|
190
|
+
|
|
191
|
+
The current public API is intentionally small:
|
|
192
|
+
|
|
193
|
+
- `st.title(body, *, key=None)`: render a title.
|
|
194
|
+
- `st.header(body, *, key=None)`: render a section header.
|
|
195
|
+
- `st.text(body)`: render plain text.
|
|
196
|
+
- `st.markdown(body)`: render Markdown-flavored text.
|
|
197
|
+
- `st.divider()`: render a horizontal divider.
|
|
198
|
+
- `st.info(body)`, `st.success(body)`, `st.warning(body)`, `st.error(body)`: render status messages.
|
|
199
|
+
- `st.write(*args)`: render simple text output.
|
|
200
|
+
- `st.button(label, key=None, help=None, disabled=False, on_click=None, args=None, kwargs=None)`: render a button and return `True` for the run where it was pressed.
|
|
201
|
+
- `st.slider(label, min_value=0, max_value=100, value=None, step=1, *, key=None, help=None, disabled=False, on_change=None, args=None, kwargs=None)`: render a numeric slider and return its current value.
|
|
202
|
+
- `st.text_input(label, value="", *, key=None, placeholder=None, disabled=False, on_change=None, args=None, kwargs=None)`: render a single-line text input and return its current value.
|
|
203
|
+
- `st.checkbox(label, value=False, *, key=None, disabled=False, on_change=None, args=None, kwargs=None)`: render a checkbox and return its current value.
|
|
204
|
+
- `st.session_state`: persist values across reruns with dict-style or attribute-style access.
|
|
205
|
+
- `st.rerun()`: request a script rerun.
|
|
206
|
+
|
|
207
|
+
Import the API as:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
import stui as st
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Examples
|
|
214
|
+
|
|
215
|
+
### Counter
|
|
216
|
+
|
|
217
|
+
`examples/counter.py` shows a minimal stateful app with increment, decrement, and
|
|
218
|
+
reset controls.
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
stui run examples/counter.py
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Model Demo
|
|
225
|
+
|
|
226
|
+
`examples/model_demo.py` shows a small model-parameter playground using text
|
|
227
|
+
input, checkbox, sliders, status messages, session state, and deterministic
|
|
228
|
+
scoring. It is intentionally local and fake: there are no network calls or model
|
|
229
|
+
dependencies.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
stui run examples/model_demo.py
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Limitations
|
|
236
|
+
|
|
237
|
+
- No browser, web server, websocket, or port-forwarding runtime.
|
|
238
|
+
- No Streamlit dependency and no promise of Streamlit compatibility.
|
|
239
|
+
- No charts, tables, dataframes, forms, columns, sidebars, or file upload yet.
|
|
240
|
+
- Slider input supports numeric values only.
|
|
241
|
+
- Layout is currently linear and script-driven.
|
|
242
|
+
- The app reruns the script as interactions change state, so examples should keep top-level work lightweight.
|
|
243
|
+
- Error handling is still early and meant for development feedback.
|
|
244
|
+
- The package is an MVP and has not stabilized a long-term compatibility policy.
|
|
245
|
+
|
|
246
|
+
## Roadmap
|
|
247
|
+
|
|
248
|
+
- Add small text output helpers such as `caption`.
|
|
249
|
+
- Add common controls such as `selectbox`, `radio`, and number inputs.
|
|
250
|
+
- Add simple display primitives for tables and progress.
|
|
251
|
+
- Improve focus behavior, accessibility hints, and keyboard discoverability.
|
|
252
|
+
- Expand example coverage for data scripts, model controls, DevOps panels, and internal tools.
|
|
253
|
+
- Keep the implementation clean-room, readable, and based on Textual first-party widgets where possible.
|
|
254
|
+
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the local development workflow and
|
|
258
|
+
project boundaries.
|