Skip to main content

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, no typer, no argparse boilerplate.
  • Types drive everything. int/float/str/bool/list annotations become parsing and validation; bool becomes 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 and command.invoke(...) calls the function — no sys.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

Metadata

Release files for larzcli 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for larzcli 0.1.0
File Size Uploaded
larzcli-0.1.0.tar.gz 8.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for larzcli 0.1.0
File Interpreter ABI Platform
larzcli-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 16.3 kB

Release files / larzcli-0.1.0.tar.gz

Download URL larzcli-0.1.0.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
657ca14c8feb212c7e96b5b5bc5d6a1b02059a9c78bb00bcebe06ff010472d1c
BLAKE2b-256 checksum
How to use checksums
1d717198c17b000165eb3af42f45f300a31c6fd1f3fda77a665f28b0da1fe932
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / larzcli-0.1.0-py3-none-any.whl

Download URL larzcli-0.1.0-py3-none-any.whl
Size 8.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e2e6fb717b9d40809ed9308fce973081ad6bf44800185b7a8569ff550953c372
BLAKE2b-256 checksum
How to use checksums
1ecd1432088692f0e23c031d53f4aa19dbcd1213a2f29b25fc00de681411cdb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page