Skip to main content

Tool to represent CLI tools as native python objects

Project description

CLI Wrapper

CLI Wrapper uses subprocess to wrap external CLI tools and present an interface that looks more like a python class. CLI commands become methods on the class, positional arguments and flags become args and kwargs respectively. It supports input validation and output parsing.

Why would you use this?

CLI tools wrap a lot of functionaility, and they tend to do it in a way that's simpler and more stable than the underlying API. So if you're writing some DevOps tooling that interacts with the Kubernetes API, for example:

  • you could pull in the kubernetes client library, introduce a fast-moving dependency, deal with all of your kube resources one at a time, and still not have a builder for CRDs your operators expose
  • you could use this wrapping kubectl, use dicts, templated manifest files, or serializable objects. You get the same functionality, but now you only need to update your manifests when the api changes. Kubernetes version changes are punted to kubectl. If you manage your manifests in a smart way, you will have decoupled your code from the underlying kubernetes version.

An enormous number of things in the kubernetes ecosystem provide cli tools that are stable and first-class, but libraries favour Go and Python bindings are often non-existent or badly maintained. With this, you can leave all of that behind. Want to tie in the latest Cilium feature? Want to do some fancy Argo automation? No problem!

If you accept this argument, then the next question is: why not just use subprocess? I think the example code speaks for itself. You get an interface for cli arguments that behaves just like a python class. How things are parsed and what gets returned are hidden in the wrapper config, so your business logic is all business.

Example

from cli_wrapper import CLIWrapper

# this assumes kubectl is in your path; otherwise provide the full path 
kubectl = CLIWrapper("kubectl")
# by default, this will translate to `kubectl get pods --namespace default`, and it will return the text output
kubectl.get("pods", namespace="default")
# you can refine this by defining the command explicitly:
kubectl._update_command("get", default_flags={"output": "json"}, parse=["json", "dotted_dict"])
a = kubectl.get("pods", namespace="kube-system")
print(a.items[0].metadata.name)  # prints a pod name

# If you want async:
kubectl.async_ = True  # or use CLIWrapper("kubectl", async_=True)
a = await kubectl.get("pods", namespace="kube-system")

# you can also set env vars where that's helpful:
kubectl.env = {
    "KUBECONFIG": "/home/user/.kube/config",
    "KUBECTL_CONTEXT": "my-other-cluster",
}
a = await kubectl.get("pods", namespace="kube-system")  # use the context from the env vars

Todo

  • build and publish to PyPI
  • Core wrapper functionality, trusting mode by default
    • args and kwargs mapping to positional and flag arguments
    • support for default flags
    • support for argument transformation (e.g., kubectl.create(a_dict) would write that dict to a file and become kubectl.create(filename=a_dict_filename))
    • support for input validation
      • possibly wrap this into argument transformation
  • Support for parsing output
    • better default support for extracting output (e.g., if result["kind"] == "List", return result["items"] instead of the whole dict)
      • We can already do this by putting a function in the parse list, but it would be nice to make this serializable
  • Custom error handling
  • Nested wrappers (e.g., helm.repos.list() instead of helm.repos('list'))]
  • Tool to create configuration dictionaries by parsing help output recursively
    • golang flag style help/usage
    • argparse style
  • Configuration dictionaries for common tools
    • kubectl
    • helm
    • docker
    • cilium

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

cli_wrapper-0.0.1-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

Details for the file cli_wrapper-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: cli_wrapper-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 11.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for cli_wrapper-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 13c389c4d2669b685677ac6875df46f7d4656f8df6f5b18a6df350a4b5343187
MD5 7ab938d879da56682979b217d7865778
BLAKE2b-256 e2338350aeabe9eaf154b8771a638629cd906b5489ed08961c98faf2d0fd6014

See more details on using hashes here.

Provenance

The following attestation bundles were made for cli_wrapper-0.0.1-py3-none-any.whl:

Publisher: pypi.yaml on orstensemantics/cli_wrapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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