Skip to main content

cli-to-py

PyPI version Python versions CI Docs License: MIT

Turn CLI binaries into Python APIs for applications and LLM agents.

cli-to-py reads a command's help output, builds a callable Python wrapper, and lets you run subcommands with keyword arguments instead of hand-built shell strings.

Full documentation: https://oneryalcin.github.io/cli-to-py/

Install

pip install cli-to-py

or:

uv add cli-to-py

Requires Python 3.11 or newer.

Quick Start

import asyncio
from cli_to_py import convert

async def main():
    git = await convert("git")

    result = await git.status(short=True)
    print(result.stdout)

    branch = await git.branch(show_current=True).text()
    changed = await git("diff", name_only=True, _=["HEAD~1"]).lines()

    print(branch)
    print(changed)

asyncio.run(main())

Flags use Python names and are converted to CLI flags:

await git.commit(message="fix", all=True)
# runs: git commit --message fix --all

Use _ for positional arguments:

await git("diff", name_only=True, _=["HEAD~1"])
# runs: git diff --name-only HEAD~1

Use _global for options that must come before the subcommand (git -C, docker --context, kubectl --namespace):

await git("log", _global={"C": "/path/to/repo"}, max_count=15)
# runs: git -C /path/to/repo log --max-count 15

Nested command trees dispatch fluently, or as a space-separated string:

uv = await convert("uv")
await uv.pip.install(upgrade=True, _=["httpx"])
# runs: uv pip install --upgrade httpx
await uv("pip install", upgrade=True, _=["httpx"])   # equivalent

Why It Exists

Traditional tool calling makes agents call tools one step at a time. That is awkward when a task needs loops, branching, arithmetic, retries, filtering, or many repeated CLI calls.

cli-to-py gives those CLIs a function-shaped Python interface. An agent can write code that coordinates commands directly:

git = await convert("git")

changed = await git("diff", name_only=True, _=["HEAD~1"]).lines()
for path in changed:
    if path.endswith(".py"):
        print(await git("log", oneline=True, n=1, _=["--", path]).text())

That pairs naturally with code-mode interpreters such as Monty, where host applications expose a controlled set of functions and the agent writes Python to orchestrate them.

Why Use It

  • Convert CLIs into async Python APIs with no runtime dependencies.
  • Expose command-line tools as functions for agent code-mode workflows.
  • Validate flags and arguments before spawning a subprocess.
  • Keep subprocess output ergonomic with .text(), .lines(), and .json().
  • Stream output, inherit stdio, set timeouts, pass env/cwd, and cancel work.
  • Generate standalone wrapper modules for tools you want to check into a project.

Documentation

CLI Wrapper Generation

Generate a dependency-free Python wrapper from a CLI:

cli-to-py git -o git_wrapper.py

The generated .py module and .pyi stub can be committed to another project without depending on cli-to-py at runtime.

Development

make test      # unit and integration tests
make ci        # full CI path, including package build
make docs      # strict MkDocs build
make build     # source distribution and wheel

See the release checklist for publishing steps.

Status

This project parses common --help formats pragmatically. It is useful for many CLIs, but it is not a formal parser for every help style. See parser limits before relying on generated wrappers for unusual CLIs.

Release files for cli-to-py 0.2.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 cli-to-py 0.2.0
File Size Uploaded
cli_to_py-0.2.0.tar.gz 66.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cli-to-py 0.2.0
File Interpreter ABI Platform
cli_to_py-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 108.5 kB

Release files / cli_to_py-0.2.0.tar.gz

Download URL cli_to_py-0.2.0.tar.gz
Size 66.7 kB
Tags Source
SHA-256 checksum
How to use checksums
0d97734f4c896df552bc57bac0c76a64356749f1fa9adebb7607ec3d7616572a
BLAKE2b-256 checksum
How to use checksums
312f9cf832df2c80f900e0465b7ca7dd05169ce8ebe44c62509102feda663ff7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / cli_to_py-0.2.0-py3-none-any.whl

Download URL cli_to_py-0.2.0-py3-none-any.whl
Size 41.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc055dd7bbc216c9621aecc1b715e50a53eea07579387e20a692ab05911749f9
BLAKE2b-256 checksum
How to use checksums
02ed9d0f65f4d9ab42bc988f96209d572338151f62bdaf7de85d250e522a3ec9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

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