py-sparcli 0.3.0__py3-none-any.whl
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.
- py_sparcli-0.3.0.dist-info/METADATA +257 -0
- py_sparcli-0.3.0.dist-info/RECORD +61 -0
- py_sparcli-0.3.0.dist-info/WHEEL +4 -0
- py_sparcli-0.3.0.dist-info/licenses/LICENSE +21 -0
- sparcli/__init__.py +184 -0
- sparcli/core/__init__.py +92 -0
- sparcli/core/border.py +160 -0
- sparcli/core/color.py +306 -0
- sparcli/core/cursor.py +59 -0
- sparcli/core/geometry.py +141 -0
- sparcli/core/markup.py +215 -0
- sparcli/core/render.py +245 -0
- sparcli/core/style.py +128 -0
- sparcli/core/terminal.py +127 -0
- sparcli/core/text.py +143 -0
- sparcli/core/theme.py +117 -0
- sparcli/core/width.py +244 -0
- sparcli/errors.py +38 -0
- sparcli/input/__init__.py +42 -0
- sparcli/input/calc.py +214 -0
- sparcli/input/confirm.py +188 -0
- sparcli/input/datepicker.py +298 -0
- sparcli/input/editor.py +189 -0
- sparcli/input/event.py +551 -0
- sparcli/input/field.py +90 -0
- sparcli/input/fuzzy.py +401 -0
- sparcli/input/guard.py +103 -0
- sparcli/input/history.py +160 -0
- sparcli/input/line_edit.py +229 -0
- sparcli/input/number.py +232 -0
- sparcli/input/outcome.py +107 -0
- sparcli/input/password.py +233 -0
- sparcli/input/prompt.py +134 -0
- sparcli/input/select.py +336 -0
- sparcli/input/shortcut.py +123 -0
- sparcli/input/text.py +564 -0
- sparcli/input/textarea.py +242 -0
- sparcli/input/validate.py +67 -0
- sparcli/output/__init__.py +56 -0
- sparcli/output/alert.py +107 -0
- sparcli/output/badge.py +82 -0
- sparcli/output/box.py +196 -0
- sparcli/output/columns.py +157 -0
- sparcli/output/compose.py +111 -0
- sparcli/output/diff.py +229 -0
- sparcli/output/kv.py +175 -0
- sparcli/output/layout.py +77 -0
- sparcli/output/list.py +274 -0
- sparcli/output/live.py +129 -0
- sparcli/output/multiprogress.py +73 -0
- sparcli/output/pager.py +83 -0
- sparcli/output/panel.py +125 -0
- sparcli/output/progress.py +233 -0
- sparcli/output/rule.py +134 -0
- sparcli/output/spinner.py +138 -0
- sparcli/output/table/__init__.py +17 -0
- sparcli/output/table/plan.py +198 -0
- sparcli/output/table/render.py +302 -0
- sparcli/output/table/table.py +351 -0
- sparcli/output/tree.py +157 -0
- sparcli/py.typed +0 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py-sparcli
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Styled CLI output and interactive input widgets, dependency-free
|
|
5
|
+
Project-URL: Homepage, https://github.com/cgroening/py-sparcli
|
|
6
|
+
Project-URL: Repository, https://github.com/cgroening/py-sparcli
|
|
7
|
+
Project-URL: Documentation, https://github.com/cgroening/py-sparcli#readme
|
|
8
|
+
Project-URL: Changelog, https://github.com/cgroening/py-sparcli/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Issues, https://github.com/cgroening/py-sparcli/issues
|
|
10
|
+
Author: Corvin Gröning
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: ansi,cli,color,prompt,terminal
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: Terminals
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# sparcli
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/py-sparcli/) [](https://pypi.org/project/py-sparcli/) [](LICENSE) [](https://peps.python.org/pep-0561/)
|
|
30
|
+
|
|
31
|
+
Styled CLI output and interactive input widgets for Python, built directly on ANSI escape codes with no third-party dependencies.
|
|
32
|
+
|
|
33
|
+
sparcli is a native Python port of the Rust library of the same name. It renders styled text, tables, panels, trees and progress bars, and drives single-input prompts (text, password, number, confirm, select, fuzzy, date and more) – all from the standard library alone. It is meant for small, lightweight CLI tools: a single accent color, muted defaults, rounded borders, and graceful behavior under `NO_COLOR` or when output is piped. Heavy, full-screen retained TUIs are out of scope.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Highlights
|
|
42
|
+
|
|
43
|
+
- Output: styled text, inline markup, tables (colspan, rowspan, striping, wrapping, titles), panels, alerts, rules, lists, trees, key-value lists, badges, progress bars, spinners, multi-progress, diffs, columns, live in-place display, pager, and the composition helpers `align`, `pad` and `vstack`.
|
|
44
|
+
- Input: confirm, text (validation, character filters, history, ghost autocomplete, dropdown), password, number (with a calculator), textarea, single and multi select, an inline fuzzy select, and a calendar date picker.
|
|
45
|
+
- A unified `Theme` for input and output, set once and overridable per call.
|
|
46
|
+
- Robust by design: prompts never raise on input, a RAII terminal guard restores the terminal, and results come back as values rather than exceptions.
|
|
47
|
+
- Zero dependencies: pure Python, standard library only, typed under strict basedpyright.
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install py-sparcli
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The distribution is named `py-sparcli`, but the import package is `sparcli`:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import sparcli
|
|
59
|
+
from sparcli import Panel, Table, TextInput
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
sparcli requires Python 3.12 or newer.
|
|
63
|
+
|
|
64
|
+
## Feature overview
|
|
65
|
+
|
|
66
|
+
| Category | Components |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| Text and style | `Style`, `Color`, `Attribute`, `Span`, `Line`, `Text`, `markup` |
|
|
69
|
+
| Framing and layout | `Panel`, `Rule`, `Columns`, `align`, `pad`, `vstack`, `BorderType`, `Align`, `Edges`, `Title` |
|
|
70
|
+
| Data widgets | `Table` (`Column`, `Cell`), `List` (`Marker`), `Tree` (`TreeNode`), `KeyValue`, `Diff`, `Badge`, `Alert` (`AlertKind`) |
|
|
71
|
+
| Progress and live | `Spinner` (`SpinnerStyle`), `ProgressBar` (`ProgressStyle`, `Thresholds`), `MultiProgress`, `Live`, `Pager` |
|
|
72
|
+
| Input prompts | `TextInput`, `PasswordInput`, `NumberInput`, `Confirm`, `Select`, `FuzzySelect`, `DatePicker`, `Textarea` |
|
|
73
|
+
| Prompt support | `Outcome`, `History`, `Shortcut`, `validate`, `event` |
|
|
74
|
+
| Theming and terminal | `Theme`, `theme`, `set_theme`, `color_support`, `is_input_tty`, `is_output_tty`, `term_width` |
|
|
75
|
+
|
|
76
|
+
## Output example
|
|
77
|
+
|
|
78
|
+
Every output widget exposes `print()` to write to stdout, `print_to(writer)` to capture the result, and `render(max_width)` to lay it out as a composable block. When stdout is not a terminal (a pipe, a file, or with `NO_COLOR` set), no escape codes are emitted.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from sparcli import Alert, Table
|
|
82
|
+
|
|
83
|
+
Alert.success("Build finished.").print()
|
|
84
|
+
|
|
85
|
+
Table().columns(["Name", "Status"]).row(["web-1", "online"]).row(
|
|
86
|
+
["db-1", "online"]
|
|
87
|
+
).striped(True).print()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
╭───────────────────╮
|
|
92
|
+
│ ✔ Build finished. │
|
|
93
|
+
╰───────────────────╯
|
|
94
|
+
╭───────┬────────╮
|
|
95
|
+
│ Name │ Status │
|
|
96
|
+
├───────┼────────┤
|
|
97
|
+
│ web-1 │ online │
|
|
98
|
+
│ db-1 │ online │
|
|
99
|
+
╰───────┴────────╯
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
A `Panel` frames content with a rounded border and an optional title. A left-aligned title reads as part of the frame: one connecting border glyph sits before it, never a flush corner - unless the title is too wide for the frame, in which case it is truncated into the border rather than widening the panel.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from sparcli import Panel
|
|
106
|
+
|
|
107
|
+
Panel("All systems nominal.").title("Status").print()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
╭─ Status ─────────────╮
|
|
112
|
+
│ All systems nominal. │
|
|
113
|
+
╰──────────────────────╯
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Input example
|
|
117
|
+
|
|
118
|
+
Prompts return an `Outcome` – a submitted value, a cancellation, or a fired shortcut – and never raise on input. They require an interactive terminal; without one, `run()` raises `NoTerminalError`. Each prompt also has a `frame()` method that renders its static opening frame without a TTY, which is how the previews below are produced.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from sparcli import Select
|
|
122
|
+
|
|
123
|
+
outcome = Select(
|
|
124
|
+
"Environment", options=["staging", "production", "local"]
|
|
125
|
+
).run()
|
|
126
|
+
if outcome.is_submitted:
|
|
127
|
+
print(f"selected option #{outcome.value}")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Its opening frame, with the cursor on the second row:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
Environment
|
|
134
|
+
staging
|
|
135
|
+
‣ production
|
|
136
|
+
local
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Text prompts chain validators and filters fluently:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from sparcli import Confirm, TextInput
|
|
143
|
+
from sparcli import validate
|
|
144
|
+
|
|
145
|
+
name = TextInput("Your name?").validate(validate.non_empty()).run()
|
|
146
|
+
if name.is_submitted:
|
|
147
|
+
if Confirm("Continue?").run().submitted_or(False):
|
|
148
|
+
print(f"Hello, {name.value}!")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Theming
|
|
152
|
+
|
|
153
|
+
A single process-wide theme drives both output widgets and input prompts. Set it once; per-call widget options still override individual values.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from sparcli import Color, Theme, set_theme, theme
|
|
157
|
+
|
|
158
|
+
set_theme(
|
|
159
|
+
Theme(
|
|
160
|
+
accent=Color.rgb(180, 142, 173),
|
|
161
|
+
unicode=True, # set False for ASCII-only glyphs
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
# Read the active theme anywhere:
|
|
166
|
+
active = theme()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Output components
|
|
170
|
+
|
|
171
|
+
The `output_readme.py` example composes a hero panel, a three-column dashboard and a progress bar:
|
|
172
|
+
|
|
173
|
+

|
|
174
|
+
|
|
175
|
+
Captured with `NO_COLOR=1` the same collage renders as plain text:
|
|
176
|
+
|
|
177
|
+
```text
|
|
178
|
+
╭───────────────────────────────── sparcli ──────────────────────────────────╮
|
|
179
|
+
│ A dependency-free Python library for styled output │
|
|
180
|
+
│ and input - panels, tables, trees, lists and more. │
|
|
181
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
182
|
+
|
|
183
|
+
Overview │ 1. Compose widgets side by side │ host localhost
|
|
184
|
+
╭─────────┬────────┬────────╮ │ 2. Capture, pad and align them │ port 8080
|
|
185
|
+
│ Service │ Status │ Uptime │ │ 3. Render to any UTF-8 terminal │ scheme https
|
|
186
|
+
├─────────┼────────┼────────┤ │ │
|
|
187
|
+
│ api │ OK │ 99.98% │ │ project/ │ [ DONE ] [ INFO ]
|
|
188
|
+
├─────────┼────────┼────────┤ │ ├── api/ │
|
|
189
|
+
│ auth │ OK │ 99.91% │ │ │ ├── routes.py │ [ WARN ] [ FAIL ]
|
|
190
|
+
├─────────┼────────┼────────┤ │ │ └── auth.py │
|
|
191
|
+
│ billing │ WARN │ 97.4% │ │ └── worker.py │
|
|
192
|
+
╰─────────┴────────┴────────╯ │ │
|
|
193
|
+
|
|
194
|
+
Building [███████████████████████████░░] 92% (92/100)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Input widgets
|
|
198
|
+
|
|
199
|
+
The `prompt_readme.py` example stacks the static opening frame of every prompt into a single dashboard, produced entirely through `frame()` with no TTY:
|
|
200
|
+
|
|
201
|
+

|
|
202
|
+
|
|
203
|
+
The same dashboard as plain text:
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
╭───────────────────── sparcli - input widgets ─────────────────────╮
|
|
207
|
+
│ Interactive prompts - confirm, select, text, password, │
|
|
208
|
+
│ number, textarea, fuzzy and date. │
|
|
209
|
+
╰─────────────────────────────────────────────────────────────────────╯
|
|
210
|
+
|
|
211
|
+
Deploy to production? [Yes] No │ Environment │ Release date
|
|
212
|
+
│ staging │ May 2026
|
|
213
|
+
Service api-gateway │ ‣ production │ Mo Tu We Th Fr Sa Su
|
|
214
|
+
Password ******* │ local │ 1 2 3
|
|
215
|
+
Replicas 3 │ │ 4 5 6 7 8 9 10
|
|
216
|
+
Email you@example.com │ Targets │ 11 12 13 14 15 16 17
|
|
217
|
+
│ ‣ ◉ web │ 18 19 20 21 22 23 24
|
|
218
|
+
Notes │ ◯ api │ 25 26 27 28 29 30 31
|
|
219
|
+
first line │ ◉ worker │
|
|
220
|
+
second line │ ◯ db │ Language ru
|
|
221
|
+
│ │ ‣ Rust
|
|
222
|
+
│ │ Ruby
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Running the examples
|
|
226
|
+
|
|
227
|
+
The `examples/` directory holds five runnable programs. The static ones are deterministic and pipe-friendly:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
python examples/output_gallery.py # every static output widget
|
|
231
|
+
python examples/output_dynamic.py # spinner, progress, multi-progress, live, pager
|
|
232
|
+
python examples/prompts.py # every interactive prompt (needs a real TTY)
|
|
233
|
+
python examples/output_readme.py # the output showcase collage
|
|
234
|
+
python examples/prompt_readme.py # the input showcase, via frame()
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The `prompts.py` example needs an interactive terminal; run without one it prints a notice and exits. The `output_dynamic.py` animations collapse to a single final frame off a terminal, so it stays clean when piped or redirected.
|
|
238
|
+
|
|
239
|
+
## NO_COLOR and non-terminal behavior
|
|
240
|
+
|
|
241
|
+
sparcli honors the common terminal environment variables:
|
|
242
|
+
|
|
243
|
+
- `NO_COLOR` disables all color: styled spans are written as plain text with no escape codes.
|
|
244
|
+
- `CLICOLOR_FORCE` forces color even when output is not a terminal.
|
|
245
|
+
- `SPARCLI_NO_TTY` forces "no terminal" behavior, used for deterministic captures and tests.
|
|
246
|
+
|
|
247
|
+
When stdout is not a TTY (a pipe or a file), color is disabled automatically unless `CLICOLOR_FORCE` is set, and the in-place engines print only their final frame. Every text showcase in this README is real captured output, produced with `NO_COLOR=1 SPARCLI_NO_TTY=1`; the two screenshots are the same collages captured in color.
|
|
248
|
+
|
|
249
|
+
## Documentation
|
|
250
|
+
|
|
251
|
+
- `docs/DEVELOPMENT.md` covers building, testing, linting and contributing.
|
|
252
|
+
- `CHANGELOG.md` records release notes.
|
|
253
|
+
- Every public class and function carries a docstring; browse the source under `sparcli/` for the complete reference.
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT – see `LICENSE`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
sparcli/__init__.py,sha256=4l96WE29V9B2o1lnB1nTONFlFUaj85wMB2XabdB3p_w,3111
|
|
2
|
+
sparcli/errors.py,sha256=J9oA_C2cabOS6WEfPyhggLpywC3QosheKvbquUTGExQ,1082
|
|
3
|
+
sparcli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
sparcli/core/__init__.py,sha256=eF_mAlmLpt_b57lnbUhX97ESnol-88gZu0oYan4TvCY,1901
|
|
5
|
+
sparcli/core/border.py,sha256=auFHD2swLaWj9nSSHlA7MKUF8dlgpx-szikKeZrkP7w,3300
|
|
6
|
+
sparcli/core/color.py,sha256=nHY84InmfblDQlofsmNNPqNP2dX374DvENXXAe3wM0I,9053
|
|
7
|
+
sparcli/core/cursor.py,sha256=kQWnOckhl_1k678vJiPJJg_9WCXlsplC8KVYaHc6lUA,1559
|
|
8
|
+
sparcli/core/geometry.py,sha256=1E6kEnYfvOQ7P7fkrnKOUG-Z2PV2xsfEeGMK6lgQhFQ,3847
|
|
9
|
+
sparcli/core/markup.py,sha256=ike_O9UU6nVCVvT4hI3dSz7ABdkZVUsJhJv-Zhj0gJ8,6807
|
|
10
|
+
sparcli/core/render.py,sha256=ZeGiJHIbw99nl3Kf25NIoifSR-MuxiaHwXrCHmmi1_U,7775
|
|
11
|
+
sparcli/core/style.py,sha256=MhvgrgH9vqJKE6YlpGOGP_RUtFO_agzunEphYcgrYvA,3831
|
|
12
|
+
sparcli/core/terminal.py,sha256=EuEXXVtlcFnNWPZnUOReHRk13aTtv-bjyHhVVOZBGn8,3576
|
|
13
|
+
sparcli/core/text.py,sha256=phL6pselVJ2N3UteYC8TNi5CHoIK-qx4TBXiN7NPOQk,4281
|
|
14
|
+
sparcli/core/theme.py,sha256=Cd0rJkiIaz8jU_omxBBBU-X635iYOezD0KGnT_z0Xho,3540
|
|
15
|
+
sparcli/core/width.py,sha256=nD0vHRdnpB2KqdbVPX4kEwZ6HRflyP0MrNVjL6SfREw,6752
|
|
16
|
+
sparcli/input/__init__.py,sha256=xqv2oLV2eGUr_zBGwe6cnjn56IGJVGJFgYN3VpRjg7o,1261
|
|
17
|
+
sparcli/input/calc.py,sha256=LXdBOJpTpOnxecQpBPl2BVcdMMAKT15zn8p4qedGEWs,6029
|
|
18
|
+
sparcli/input/confirm.py,sha256=npaEw0qbYL5MxTod3RWN8RZsbHIKXg_jsHKJmip1ntc,6056
|
|
19
|
+
sparcli/input/datepicker.py,sha256=g6Qu_n3yx-5nw-55czv-semS94QR3r7ejteIiNpLQkc,9812
|
|
20
|
+
sparcli/input/editor.py,sha256=hW5Evx3jbRfq_pbbKxmqPKedV0DZ58rxILUjFnbFJ-0,5618
|
|
21
|
+
sparcli/input/event.py,sha256=PnYKrLkwqNLp0tjoqZT16ycmN5-T0k9DP7eD7QX2uRc,16395
|
|
22
|
+
sparcli/input/field.py,sha256=FqYwS0mFzihawBod5v-abGERfUCPv9b402KTBda8HuU,2762
|
|
23
|
+
sparcli/input/fuzzy.py,sha256=i8ntXjtyw64KelpElpe1_elCT_HuH0iLZsHAUfZkNRc,13939
|
|
24
|
+
sparcli/input/guard.py,sha256=OMR4IoBj37ExS4y11WDAnPcj4aG7xpV_ljH7Hln7x54,3379
|
|
25
|
+
sparcli/input/history.py,sha256=BX85aRf3vGIs1_wJUT6SuABkvkD5xwbyWZ8QEUuA5IY,4974
|
|
26
|
+
sparcli/input/line_edit.py,sha256=-g5n9mJsaqszpNQSHP6RSlw2mNVFCdpRTLpdaGnHcTM,8063
|
|
27
|
+
sparcli/input/number.py,sha256=d7h4_Tl9GWr1esR12Dh8WydgE6aOie-xmlXfK50riz0,7892
|
|
28
|
+
sparcli/input/outcome.py,sha256=VhjJrkb7g_VBaYI99tA8v9jJN_Ydiys0S54fl0cIamA,3139
|
|
29
|
+
sparcli/input/password.py,sha256=Z0JIq2esHn_xZ01xu5DBeesOBBfOSXTSwcmghZbw1fY,8041
|
|
30
|
+
sparcli/input/prompt.py,sha256=BxoqD9V2H8HvQObbMOfztmq5x23iP4z8mfv-juQ4jM4,4128
|
|
31
|
+
sparcli/input/select.py,sha256=UIVvukpIY7bFMvatpYfwGENa1x0QzkqCADCcQhgQisA,11582
|
|
32
|
+
sparcli/input/shortcut.py,sha256=3T05n-j8GXJ2ZZ7BBW3ddOMAjNwsGO0xWM9GGXaL_ik,3572
|
|
33
|
+
sparcli/input/text.py,sha256=cfafZnHJeHYtndjzEqFn09LHNMlhp3xoArVYrh1dkVk,20173
|
|
34
|
+
sparcli/input/textarea.py,sha256=4oMfdbM02mWS80zk_EsiI9fYFYr1jFZcqRTEe3MyV0I,8130
|
|
35
|
+
sparcli/input/validate.py,sha256=Icu1bsfe-TY4ktIH6i1s5HWtm1N-gjs-gHzRngSmG8M,1956
|
|
36
|
+
sparcli/output/__init__.py,sha256=1fKmxfM_3CG8z8dYGPoPh6NbSkz4prZsxMZkeuVfJhE,1467
|
|
37
|
+
sparcli/output/alert.py,sha256=0zyvtiJu9x0A8jRAsr3rIKNXufkRWjnCfzuiCqk8DAQ,3310
|
|
38
|
+
sparcli/output/badge.py,sha256=5BneIDDEjJqPDDsm2zXURfZseD9cH7_adM7WQfirw6M,2543
|
|
39
|
+
sparcli/output/box.py,sha256=wdPzlntqyPQ_DdF9EJsd-io43d0YBs35ipHJlSnyecU,6891
|
|
40
|
+
sparcli/output/columns.py,sha256=-nSQdYy-vX4ZXXnhJv29-Gy5g-V8c5NU8lnANIRBgJQ,5334
|
|
41
|
+
sparcli/output/compose.py,sha256=JTIPXW2Rs1lh3sWMoYXq17OnU4W4m1HETj9TsUHyJEg,3140
|
|
42
|
+
sparcli/output/diff.py,sha256=3MAYcwE2ppilFvtRzF-x71bFAwn2tXvw_ED6rPR5708,7333
|
|
43
|
+
sparcli/output/kv.py,sha256=z7TdjzoatKev2TKHKuL0-EMSTMy2eHNIel0FcYohbYU,6011
|
|
44
|
+
sparcli/output/layout.py,sha256=HhGeXSwnJgsn7-375aprkcLNJSked9LWZpmCvH_iSD8,2179
|
|
45
|
+
sparcli/output/list.py,sha256=6etUeKwgneFocWFDin0ROSyxS2QK99r0ahoBxev89h0,8939
|
|
46
|
+
sparcli/output/live.py,sha256=XD22DZUtJZsBoUu_xGAkq8S5WQ8ZbpFhReQ2kDl7Y2w,4379
|
|
47
|
+
sparcli/output/multiprogress.py,sha256=mgazp4o954QlF64MrdUvt7M5UG9ivAXR_P8ERAp9PIE,2403
|
|
48
|
+
sparcli/output/pager.py,sha256=einC15rM_Ub0qvw3dxkZpgLK-yuJaEADmpBjx3pf1QE,2554
|
|
49
|
+
sparcli/output/panel.py,sha256=BhvX8ibw0Sh3HsPPpEBY006E6orCrl7v0XmTAIwNo0Y,4184
|
|
50
|
+
sparcli/output/progress.py,sha256=7J_gzehD4Geyke1VyyirzgndePxP7GzCWdogpmG8aSA,7508
|
|
51
|
+
sparcli/output/rule.py,sha256=_XTNBV3F5WEOyLA7P4enyPBVUHdG9NvmJv-eE8DWxRA,4703
|
|
52
|
+
sparcli/output/spinner.py,sha256=-Sqe6LXUQrrSc2OMQL7HZdgQP6brnl_oI6bxUxNIDHM,4359
|
|
53
|
+
sparcli/output/tree.py,sha256=VgCrGtGm1i06nk9O6vjkvR-1J8H1Tc7mpgJuigqjpiY,5169
|
|
54
|
+
sparcli/output/table/__init__.py,sha256=aW7WOp7VWtsKgz1qdoCDfHN4adr9lDaWLO8OlUxpsGs,535
|
|
55
|
+
sparcli/output/table/plan.py,sha256=CZITOVJL8RlBpw3lgWcVmp65O25dOOwGXP3Bqq6Prjg,6206
|
|
56
|
+
sparcli/output/table/render.py,sha256=lwNAltYtylOmMTJOAoiT7K1CL_Eq3ZZ5dmNM2ZYig2s,11113
|
|
57
|
+
sparcli/output/table/table.py,sha256=0S9L3U7DuXtJ24YFle5YbCGNbCLRXMGa5wSYnmL8Eac,11234
|
|
58
|
+
py_sparcli-0.3.0.dist-info/METADATA,sha256=H-lnH5wYUKq2T8nMX3Ms44fF6T331-OWE7SaVBAlTfY,13008
|
|
59
|
+
py_sparcli-0.3.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
60
|
+
py_sparcli-0.3.0.dist-info/licenses/LICENSE,sha256=KGU4zmBB5SJOxn_dfYTxKVB-tRV94wl3vVLe8HiQ_X8,1072
|
|
61
|
+
py_sparcli-0.3.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Corvin Gröning
|
|
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.
|
sparcli/__init__.py
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sparcli
|
|
3
|
+
=======
|
|
4
|
+
|
|
5
|
+
Styled CLI output and interactive input widgets, built directly on ANSI escape
|
|
6
|
+
codes with no third-party dependencies.
|
|
7
|
+
|
|
8
|
+
The public API is re-exported flat from this package: import widgets and types
|
|
9
|
+
directly (``from sparcli import Panel, TextInput``). Grouped helpers stay
|
|
10
|
+
reachable as submodules (``sparcli.width``, ``sparcli.terminal``,
|
|
11
|
+
``sparcli.markup``).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from sparcli.core import (
|
|
15
|
+
DEFAULT_ACCENT,
|
|
16
|
+
Align,
|
|
17
|
+
Attribute,
|
|
18
|
+
BorderChars,
|
|
19
|
+
BorderType,
|
|
20
|
+
Color,
|
|
21
|
+
ColorName,
|
|
22
|
+
ColorSupport,
|
|
23
|
+
Edges,
|
|
24
|
+
Line,
|
|
25
|
+
Modifier,
|
|
26
|
+
Position,
|
|
27
|
+
Renderable,
|
|
28
|
+
Rendered,
|
|
29
|
+
Span,
|
|
30
|
+
Style,
|
|
31
|
+
Text,
|
|
32
|
+
Theme,
|
|
33
|
+
Title,
|
|
34
|
+
VAlign,
|
|
35
|
+
color_support,
|
|
36
|
+
into_line,
|
|
37
|
+
into_span,
|
|
38
|
+
into_text,
|
|
39
|
+
is_input_tty,
|
|
40
|
+
is_output_tty,
|
|
41
|
+
set_theme,
|
|
42
|
+
term_height,
|
|
43
|
+
term_width,
|
|
44
|
+
terminal_size,
|
|
45
|
+
theme,
|
|
46
|
+
)
|
|
47
|
+
from sparcli.core import markup as markup
|
|
48
|
+
from sparcli.core import terminal as terminal
|
|
49
|
+
from sparcli.core import width as width
|
|
50
|
+
from sparcli.errors import (
|
|
51
|
+
ConfigError,
|
|
52
|
+
NoTerminalError,
|
|
53
|
+
SparcliError,
|
|
54
|
+
TerminalError,
|
|
55
|
+
)
|
|
56
|
+
from sparcli.input import (
|
|
57
|
+
Confirm,
|
|
58
|
+
DatePicker,
|
|
59
|
+
FuzzySelect,
|
|
60
|
+
History,
|
|
61
|
+
NumberInput,
|
|
62
|
+
Outcome,
|
|
63
|
+
OutcomeKind,
|
|
64
|
+
PasswordInput,
|
|
65
|
+
Select,
|
|
66
|
+
Shortcut,
|
|
67
|
+
Textarea,
|
|
68
|
+
TextInput,
|
|
69
|
+
edit_file,
|
|
70
|
+
)
|
|
71
|
+
from sparcli.input import event as event
|
|
72
|
+
from sparcli.input import shortcut as shortcut
|
|
73
|
+
from sparcli.input import validate as validate
|
|
74
|
+
from sparcli.output import (
|
|
75
|
+
Alert,
|
|
76
|
+
AlertKind,
|
|
77
|
+
Badge,
|
|
78
|
+
Cell,
|
|
79
|
+
Column,
|
|
80
|
+
Columns,
|
|
81
|
+
Diff,
|
|
82
|
+
KeyValue,
|
|
83
|
+
List,
|
|
84
|
+
Live,
|
|
85
|
+
Marker,
|
|
86
|
+
MultiProgress,
|
|
87
|
+
Pager,
|
|
88
|
+
Panel,
|
|
89
|
+
ProgressBar,
|
|
90
|
+
ProgressStyle,
|
|
91
|
+
Rule,
|
|
92
|
+
Spinner,
|
|
93
|
+
SpinnerStyle,
|
|
94
|
+
Table,
|
|
95
|
+
Thresholds,
|
|
96
|
+
Tree,
|
|
97
|
+
TreeNode,
|
|
98
|
+
align,
|
|
99
|
+
pad,
|
|
100
|
+
vstack,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
__all__ = [
|
|
104
|
+
"DEFAULT_ACCENT",
|
|
105
|
+
"Alert",
|
|
106
|
+
"AlertKind",
|
|
107
|
+
"Align",
|
|
108
|
+
"Attribute",
|
|
109
|
+
"Badge",
|
|
110
|
+
"BorderChars",
|
|
111
|
+
"BorderType",
|
|
112
|
+
"Cell",
|
|
113
|
+
"Color",
|
|
114
|
+
"ColorName",
|
|
115
|
+
"ColorSupport",
|
|
116
|
+
"Column",
|
|
117
|
+
"Columns",
|
|
118
|
+
"Confirm",
|
|
119
|
+
"ConfigError",
|
|
120
|
+
"DatePicker",
|
|
121
|
+
"Diff",
|
|
122
|
+
"Edges",
|
|
123
|
+
"FuzzySelect",
|
|
124
|
+
"History",
|
|
125
|
+
"KeyValue",
|
|
126
|
+
"Line",
|
|
127
|
+
"List",
|
|
128
|
+
"Live",
|
|
129
|
+
"Marker",
|
|
130
|
+
"Modifier",
|
|
131
|
+
"MultiProgress",
|
|
132
|
+
"NoTerminalError",
|
|
133
|
+
"NumberInput",
|
|
134
|
+
"Outcome",
|
|
135
|
+
"OutcomeKind",
|
|
136
|
+
"Pager",
|
|
137
|
+
"Panel",
|
|
138
|
+
"PasswordInput",
|
|
139
|
+
"Position",
|
|
140
|
+
"ProgressBar",
|
|
141
|
+
"ProgressStyle",
|
|
142
|
+
"Rendered",
|
|
143
|
+
"Renderable",
|
|
144
|
+
"Rule",
|
|
145
|
+
"Select",
|
|
146
|
+
"Shortcut",
|
|
147
|
+
"Span",
|
|
148
|
+
"SparcliError",
|
|
149
|
+
"Spinner",
|
|
150
|
+
"SpinnerStyle",
|
|
151
|
+
"Style",
|
|
152
|
+
"Table",
|
|
153
|
+
"TerminalError",
|
|
154
|
+
"Text",
|
|
155
|
+
"TextInput",
|
|
156
|
+
"Textarea",
|
|
157
|
+
"Theme",
|
|
158
|
+
"Thresholds",
|
|
159
|
+
"Title",
|
|
160
|
+
"Tree",
|
|
161
|
+
"TreeNode",
|
|
162
|
+
"VAlign",
|
|
163
|
+
"align",
|
|
164
|
+
"color_support",
|
|
165
|
+
"edit_file",
|
|
166
|
+
"event",
|
|
167
|
+
"into_line",
|
|
168
|
+
"into_span",
|
|
169
|
+
"into_text",
|
|
170
|
+
"is_input_tty",
|
|
171
|
+
"is_output_tty",
|
|
172
|
+
"markup",
|
|
173
|
+
"pad",
|
|
174
|
+
"set_theme",
|
|
175
|
+
"shortcut",
|
|
176
|
+
"term_height",
|
|
177
|
+
"term_width",
|
|
178
|
+
"terminal",
|
|
179
|
+
"terminal_size",
|
|
180
|
+
"theme",
|
|
181
|
+
"validate",
|
|
182
|
+
"vstack",
|
|
183
|
+
"width",
|
|
184
|
+
]
|
sparcli/core/__init__.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sparcli.core
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
The foundation layer: styling, text, rendering, geometry, borders, theming,
|
|
6
|
+
width math, terminal capabilities and inline markup.
|
|
7
|
+
|
|
8
|
+
Nothing in this package depends on the widget layers; ``output`` and ``input``
|
|
9
|
+
build on top of it.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from sparcli.core.border import BorderChars, BorderType
|
|
13
|
+
from sparcli.core.color import Color, ColorName
|
|
14
|
+
from sparcli.core.geometry import Align, Edges, Position, Title, VAlign
|
|
15
|
+
from sparcli.core.markup import markup_print, markup_println, parse
|
|
16
|
+
from sparcli.core.render import (
|
|
17
|
+
Renderable,
|
|
18
|
+
Rendered,
|
|
19
|
+
SupportsWrite,
|
|
20
|
+
write_line,
|
|
21
|
+
write_rendered,
|
|
22
|
+
)
|
|
23
|
+
from sparcli.core.style import Attribute, Modifier, Style
|
|
24
|
+
from sparcli.core.terminal import (
|
|
25
|
+
ColorSupport,
|
|
26
|
+
color_support,
|
|
27
|
+
is_input_tty,
|
|
28
|
+
is_output_tty,
|
|
29
|
+
term_height,
|
|
30
|
+
term_width,
|
|
31
|
+
terminal_size,
|
|
32
|
+
)
|
|
33
|
+
from sparcli.core.text import (
|
|
34
|
+
IntoLine,
|
|
35
|
+
IntoSpan,
|
|
36
|
+
IntoText,
|
|
37
|
+
Line,
|
|
38
|
+
Span,
|
|
39
|
+
Text,
|
|
40
|
+
into_line,
|
|
41
|
+
into_span,
|
|
42
|
+
into_text,
|
|
43
|
+
)
|
|
44
|
+
from sparcli.core.theme import DEFAULT_ACCENT, Theme, set_theme, theme
|
|
45
|
+
from sparcli.core.width import strip_ansi, truncate, visible_width, wrap
|
|
46
|
+
|
|
47
|
+
__all__ = [
|
|
48
|
+
"DEFAULT_ACCENT",
|
|
49
|
+
"Align",
|
|
50
|
+
"Attribute",
|
|
51
|
+
"BorderChars",
|
|
52
|
+
"BorderType",
|
|
53
|
+
"Color",
|
|
54
|
+
"ColorName",
|
|
55
|
+
"ColorSupport",
|
|
56
|
+
"Edges",
|
|
57
|
+
"IntoLine",
|
|
58
|
+
"IntoSpan",
|
|
59
|
+
"IntoText",
|
|
60
|
+
"Line",
|
|
61
|
+
"Modifier",
|
|
62
|
+
"Position",
|
|
63
|
+
"Rendered",
|
|
64
|
+
"Renderable",
|
|
65
|
+
"Span",
|
|
66
|
+
"Style",
|
|
67
|
+
"SupportsWrite",
|
|
68
|
+
"Text",
|
|
69
|
+
"Theme",
|
|
70
|
+
"Title",
|
|
71
|
+
"VAlign",
|
|
72
|
+
"color_support",
|
|
73
|
+
"into_line",
|
|
74
|
+
"into_span",
|
|
75
|
+
"into_text",
|
|
76
|
+
"is_input_tty",
|
|
77
|
+
"is_output_tty",
|
|
78
|
+
"markup_print",
|
|
79
|
+
"markup_println",
|
|
80
|
+
"parse",
|
|
81
|
+
"set_theme",
|
|
82
|
+
"strip_ansi",
|
|
83
|
+
"term_height",
|
|
84
|
+
"term_width",
|
|
85
|
+
"terminal_size",
|
|
86
|
+
"theme",
|
|
87
|
+
"truncate",
|
|
88
|
+
"visible_width",
|
|
89
|
+
"wrap",
|
|
90
|
+
"write_line",
|
|
91
|
+
"write_rendered",
|
|
92
|
+
]
|