commandlib 0.3.5
Pythonic command runner
License: MIT
Keywords: subprocess commands

CommandLib
==========

CommandLib is a pythonic wrapper around subprocess that lets you pass around command objects
and daisy-chain:

* Arguments
* Paths
* Other environment variables
* Runtime directory
* Other runtime properties (run in shell, conceal stdout/stderr, ignore error codes, etc.)

It is somewhat inspired by amoffat's sh, Kenneth Reitz's requests, jaraco's path.py
and SQLAlchemy.

To install:

.. code-block:: sh

    $ pip install commandlib


Example:

.. code-block:: python

    >>> from commandlib import Command
    >>> ls = Command("ls")
    >>> ls("-t").in_dir("/").with_shell().run()
    sys  tmp  run  dev  proc  etc  boot  sbin  root  vmlinuz  initrd.img  bin  lib  opt  vmlinuz.old  initrd.img.old  media  home  cdrom  lost+found  var  srv  usr  mnt


CommandPath example:

.. code-block:: python


    >>> from commandlib import CommandPath
    >>> bin = CommandPath("/bin")
    >>> bin.ls("-t").in_dir("/").run()
    sys  tmp  run  dev  proc  etc  boot  sbin  root  vmlinuz  initrd.img  bin  lib  opt  vmlinuz.old  initrd.img.old  media  home  cdrom  lost+found  var  srv  usr  mnt




API
---

.. code-block:: python

    >>> from commandlib import Command, run

    # Create command object
    >>> py = Command("/usr/bin/python")

    # Run with *additional* environment variable PYTHONPATH (*added* to global environment when command is run)
    >>> py = py.with_env(PYTHONPATH="/home/user/pythondirectory")    

    # Run with additional path (appended to existing PATH environment variable when command is run)
    >>> py = py.with_path("/home/user/bin")

    # Run in specified directory (default is current directory)
    >>> py = py.in_dir("/home/user/mydir")

    # Run in shell
    >>> py = py.with_shell()

    # Suppress stderr
    >>> py = py.silently() # Suppress stdout and stderr

    # Finally run command explicitly with all of the above
    >>> run(py)
    >>> py.run() # alternative syntax


Why?
----

Commandlib is a library to make it easier to pass around immutable (sort of) command objects between different
modules and classes and incrementally modify the command's behavior in a readable way - adding environment
variables, paths, etc.

* call, check_call and Popen do not have the friendliest of APIs and code that uses them a lot can get ugly fast.
* sh does a similar thing but has a lot of magic (e.g. overriding import).
* envoy and sarge are more focused on chaining commands rather than arguments, environment variables, etc.

Advanced API
------------

Add trailing arguments:

.. code-block:: python

    >>> from commandlib import Command, run
    >>> manage = Command("/usr/bin/python", "manage.py").with_trailing_arguments("--settings", "local_settings.py").in_dir("projectdir")
    >>> run(manage("runserver"))
    [ Runs "/usr/bin/python manage.py runserver --settings local_settings.py" inside projectdir ]

Dynamically generate command bundles from directories with executables in them:

.. code-block:: python

    >>> from commandlib import CommandPath, Command, run
    >>> postgres94 = CommandPath("/usr/lib/postgresql/9.4/bin/")
    >>> run(postgres94.postgres)
    [ Runs postgres ]

    >>> run(postgres94.createdb)
    [ Runs createdb ]

Use with path.py (or any other library where str(object) resolves to a string:

.. code-block:: python

    >>> from path import Path
    >>> postgres94 = CommandPath(Path("/usr/lib/postgresql/9.4/bin/"))
    >>> run(postgres94.postgres)