Skip to main content

Turn any CLI into a Python API, automatically.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cli_to_py-0.2.0.tar.gz (66.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cli_to_py-0.2.0-py3-none-any.whl (41.8 kB view details)

Uploaded Python 3

File details

Details for the file cli_to_py-0.2.0.tar.gz.

File metadata

  • Download URL: cli_to_py-0.2.0.tar.gz
  • Upload date:
  • Size: 66.7 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for cli_to_py-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0d97734f4c896df552bc57bac0c76a64356749f1fa9adebb7607ec3d7616572a
MD5 fc88f338e59d71b9c56e60c58a6c4431
BLAKE2b-256 312f9cf832df2c80f900e0465b7ca7dd05169ce8ebe44c62509102feda663ff7

See more details on using hashes here.

File details

Details for the file cli_to_py-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cli_to_py-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 41.8 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for cli_to_py-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cc055dd7bbc216c9621aecc1b715e50a53eea07579387e20a692ab05911749f9
MD5 8735bf6c3f199e46d925569b9f8a9a06
BLAKE2b-256 02ed9d0f65f4d9ab42bc988f96209d572338151f62bdaf7de85d250e522a3ec9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page