Turn any CLI into a Python API, automatically.
Project description
cli-to-py
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
- Installation
- Quick start
- Agent code mode
- Validation
- Runtime control
- Code generation
- Parser limits
- Public API
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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d97734f4c896df552bc57bac0c76a64356749f1fa9adebb7607ec3d7616572a
|
|
| MD5 |
fc88f338e59d71b9c56e60c58a6c4431
|
|
| BLAKE2b-256 |
312f9cf832df2c80f900e0465b7ca7dd05169ce8ebe44c62509102feda663ff7
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc055dd7bbc216c9621aecc1b715e50a53eea07579387e20a692ab05911749f9
|
|
| MD5 |
8735bf6c3f199e46d925569b9f8a9a06
|
|
| BLAKE2b-256 |
02ed9d0f65f4d9ab42bc988f96209d572338151f62bdaf7de85d250e522a3ec9
|