A simple CLI app framework for Python.
Project description
NeatCLI
A simple yet powerful framework for quickly and reliably writing command-line applications in Python.
Architecture
NeatCLI is organized into three distinct, decoupled toolkits to manage every aspect of a command-line application without external dependencies:
App: Handles command routing, option/flag parsing, and grouping.Prompt: Handles user input collection, data validation, and sensitive masking.Interface: Handles visual layouts, ANSI styling, status indicators, and grids.
Core Applications (App)
The App class serves as the entry point and router for your CLI tool. Commands are registered using decorators, and parameters are automatically populated from sys.argv.
Basic Usage
import sys
from ncli import App
app = App()
@app.command
def version(opts):
"""Print version"""
print("1.0.0")
db = app.group("db", help="Database management commands")
@db.command
@app.argument("name", help="Migration name")
@app.help("Create a new migration")
def create(opts, name):
print(f"Creating migration: {name}")
@db.command
@app.option("force", short="f", default=False, help="Force the reset")
@app.help("Reset the database")
def reset(opts):
print(f"Resetting db (force={opts.force})")
app.run(sys.argv[1:])
Routing & Options API
@app.command: Registers the decorated function as a runnable command. The function's name becomes the subcommand keyword.@app.option(name, short=None, default=None): Attaches a flag option to the command. Options are bundled and passed as the first argument (options) to the target function.@app.help(text): Attaches a descriptive help string to the command for documentation generation.
Interactive Inputs (Prompt)
Prompt provides utilities for gathering input dynamically mid-execution, enforcing validations, and safely processing secure variables.
API Reference
Prompt.ask(prompt: str, default: str = None, type: Callable = None) -> AnyPrompts the user for inline string input. If atypeis specified (e.g.,int), it automatically verifies compliance and prompts again if invalid.Prompt.confirm(prompt: str, default: bool = False) -> boolAppends a standard binary choice marker ([y/N]or[Y/n]). Enforces explicit confirmation and returns a boolean value.Prompt.secret(prompt: str) -> strMasks terminal keystrokes, completely hiding sensitive values (like passwords or tokens) while they are typed.
Example
from neatcli import Prompt
username = Prompt.ask("Admin username", default="root")
threads = Prompt.ask("Worker threads", default=4, type=int)
if Prompt.confirm("Proceed with initialization?"):
password = Prompt.secret("Enter encryption key")
Terminal Presentation (Interface)
The Interface module provides components for formatting layouts, generating text styles, and animating operations safely using standard streaming outputs.
ANSI Styling
Apply inline constants to control text attributes. Always append Interface.RESET to avoid leakage across lines.
from neatcli import Interface
print(f"{Interface.GREEN}Success:{Interface.RESET} Process completed.")
print(f"{Interface.RED}{Interface.BOLD}Error:{Interface.RESET} Build halted.")
- Colors:
RED,GREEN,YELLOW,BLUE,CYAN,GRAY - Attributes:
BOLD,RESET
Status Indicators
Both spinner and progress_bar use context managers (with blocks) to manage lifecycle states, safely hide the terminal cursor, and handle line clears upon exit.
import time
from neatcli import Interface
# background animation thread
with Interface.spinner("Compiling plane binaries..."):
time.sleep(2.0)
# block tracking bar
steps = 4
with Interface.progress_bar("Flashing ROM memory", total=steps) as pbar:
for _ in range(steps):
time.sleep(0.5)
pbar.update(1)
Dynamic Grids
Interface.table takes header sequences and nested row arrays, calculating matching margin widths automatically.
from neatcli import Interface
headers = ["Register", "Value", "Status"]
rows = [
["R0", "0x0000", "Hardwired Zero"],
["R1", "0x0A2F", "Active"],
["PC", "0x0084", "Program Counter"]
]
Interface.table(headers, rows)
Complete Example Integration
import time
from neatcli import App, Prompt, Interface
app = App()
@app.command
@app.help("Deploy code to target ecosystem.")
def deploy(options):
print(f"{Interface.BOLD}NEATCLI Deployment Suite{Interface.RESET}\n")
target = Prompt.ask("Target device address", default="127.0.0.1")
if not Prompt.confirm("Do you want to clear volatile storage before write?"):
print("Aborted.")
return
with Interface.spinner(f"Establishing link to {target}..."):
time.sleep(1.5)
with Interface.progress_bar("Uploading sectors", total=100) as pbar:
for _ in range(10):
time.sleep(0.1)
pbar.update(10)
print(f"\n{Interface.GREEN}Deployment complete.{Interface.RESET}")
if __name__ == "__main__":
app.run()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neatcli-0.1.0.tar.gz.
File metadata
- Download URL: neatcli-0.1.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0d4eb13d2f1e2cb4e3be837fe31daef865f9227df732a34f8307c022b30efdc
|
|
| MD5 |
fa28017e67b8d00dccfac3ff0096eeec
|
|
| BLAKE2b-256 |
b6a2c74421d3b1cfb94ac471bc1b87fd8ba56055be303b38c62c9a34ce3dc95d
|
Provenance
The following attestation bundles were made for neatcli-0.1.0.tar.gz:
Publisher:
publish.yml on las-r/neatcli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neatcli-0.1.0.tar.gz -
Subject digest:
e0d4eb13d2f1e2cb4e3be837fe31daef865f9227df732a34f8307c022b30efdc - Sigstore transparency entry: 2072891324
- Sigstore integration time:
-
Permalink:
las-r/neatcli@a56c0078404cf420faeb9a5495f359f26586963f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/las-r
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a56c0078404cf420faeb9a5495f359f26586963f -
Trigger Event:
release
-
Statement type:
File details
Details for the file neatcli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: neatcli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c75223e2a3148692b70341c50a7689b9e0d1e4077a2a167ee785eefe88538f9b
|
|
| MD5 |
9f1bf7dd02bbd834177d05f84955169c
|
|
| BLAKE2b-256 |
6676d836e5c9a0fa7df3789c899baee1eb7d3da9c4f22beeeaae7d48f295950d
|
Provenance
The following attestation bundles were made for neatcli-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on las-r/neatcli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neatcli-0.1.0-py3-none-any.whl -
Subject digest:
c75223e2a3148692b70341c50a7689b9e0d1e4077a2a167ee785eefe88538f9b - Sigstore transparency entry: 2072891363
- Sigstore integration time:
-
Permalink:
las-r/neatcli@a56c0078404cf420faeb9a5495f359f26586963f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/las-r
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a56c0078404cf420faeb9a5495f359f26586963f -
Trigger Event:
release
-
Statement type: