larzcli
Define a function, get a CLI. Pure Python, zero dependencies.
Write a normal type-annotated function and larzcli builds the command-line
interface from its signature — arguments, types, defaults, boolean flags, and
--help. The CLI and the code can't drift apart, and there's no parser to
configure.
from larzcli import command, run
@command
def greet(name: str, count: int = 1, shout: bool = False):
"""Greet someone."""
for _ in range(count):
print(("HI " if shout else "Hi ") + name)
if __name__ == "__main__":
run(greet)
$ greet Ada --count 3 --shout
HI Ada
HI Ada
HI Ada
What makes it different
Function-first CLIs aren't new — larzcli's edge is layered configuration built in. Options resolve as command line → environment variable → default, so the same command is 12-factor-configurable with zero extra code:
from larzcli import App
app = App("tool", env_prefix="TOOL_")
@app.command
def serve(host: str = "127.0.0.1", port: int = 8080):
"""Run the server."""
...
app.run()
$ tool serve --port 9000 # explicit
$ TOOL_PORT=9000 tool serve # from the environment
$ tool serve # default 8080
The --help even documents which env var backs each option. It pairs naturally
with larzconf for the same layering
philosophy across your whole app.
Why else
- Zero dependencies. No
click, notyper, noargparseboilerplate. - Types drive everything.
int/float/str/bool/listannotations become parsing and validation;boolbecomes a--flag/--no-flag; params without a default become required positionals. - Subcommands with one decorator (
@app.command), auto-generated help. - Testable.
command.parse(argv, env=...)returns the resolved kwargs andcommand.invoke(...)calls the function — nosys.exit, no globals, so unit testing a CLI is trivial.
Install
pip install larzcli
Usage
from larzcli import command, App, run
# single command
@command
def build(target: str, jobs: int = 4, verbose: bool = False):
"""Build a target."""
...
run(build) # build app --jobs 8 --verbose
# multi-command app
app = App("git-ish", help="A tiny VCS.")
@app.command
def add(path: str):
"""Stage a file."""
...
@app.command(name="commit")
def do_commit(message: str, amend: bool = False):
"""Record changes."""
...
app.run() # git-ish add file.py ; git-ish commit --message "wip"
Testing a CLI
build.parse(["main", "--jobs", "8"]) # {"target": "main", "jobs": 8, ...}
build.invoke(["main", "--verbose"]) # actually calls build(...)
app.invoke(["add", "file.py"], env={...})
Tests
python -m unittest discover -s tests -v # 21 tests, zero deps
The Larz stack
Pure-Python, zero-dependency building blocks: larz · larzchain · larzmoney · larzcrypt · larzdb · larzagent · larzchart · larzmark · larztask · larzvault · larzvm · larzcache · larzvalidate · larzid · larzrpc · larzstate · larzhttp · larzconf · larzcron · larzlimit · larzlog · larzcli
License
MIT © larz-scripter
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 larzcli-0.1.0.tar.gz.
File metadata
- Download URL: larzcli-0.1.0.tar.gz
- Upload date:
- Size: 8.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
657ca14c8feb212c7e96b5b5bc5d6a1b02059a9c78bb00bcebe06ff010472d1c
|
|
| MD5 |
22b3f82f3ee92e234df1eb06a85e18d2
|
|
| BLAKE2b-256 |
1d717198c17b000165eb3af42f45f300a31c6fd1f3fda77a665f28b0da1fe932
|
File details
Details for the file larzcli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: larzcli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2e6fb717b9d40809ed9308fce973081ad6bf44800185b7a8569ff550953c372
|
|
| MD5 |
b7757d54fbc85081b9859737d55cf03f
|
|
| BLAKE2b-256 |
1ecd1432088692f0e23c031d53f4aa19dbcd1213a2f29b25fc00de681411cdb5
|