# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['subby']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'subby',
    'version': '0.2.0',
    'description': 'Subprocesses simplified',
    'long_description': '[![Travis CI](https://travis-ci.org/jdidion/subby.svg?branch=master)](https://travis-ci.org/jdidion/subby)\n[![Code Coverage](https://codecov.io/gh/jdidion/subby/branch/master/graph/badge.svg)](https://codecov.io/gh/jdidion/subby)\n\nSubby is a small Python library with the goal of simplifying the use of subprocesses. Subby is similar to [delegator.py](https://github.com/amitt001/delegator.py), but it adds a few additional features and excludes others (e.g. no `pexpect` support).\n\n## Requirements\n\nThe only requirement is python 3.6+. There are no other 3rd-party runtime dependencies. The `pytest` and `coverage` packages are required for testing.\n\n## Installation\n\n`pip install subby`\n\n## Usage\n\nSubby\'s primary interface is the `run` function. It takes a list of commands and executes them. If there is are multiple commands, they are chained (i.e., piped) together.\n\n```python\nimport subby\n\n# We can pass input to the stdin of the command as bytes\ninput_str = "foo\\nbar"\n\n# The following three commands are equivalent; each returns a\n# `Processes` object that can be used to inspect and control\n# the process(es).\np1 = subby.run([["grep foo", "wc -l"]], stdin=input_str)\np2 = subby.run(("grep foo", "wc -l"), stdin=input_str)\np3 = subby.run("grep foo | wc -l", stdin=input_str)\n\n# The `done` property tells us whether the processes have finished\nassert p1.done and p2.done and p3.done\n\n# The `output` property provides the output of the command\nassert p1.output == p2.output == p3.output == "1"\n```\n\n### Raw mode\n\nBy default, text I/O is used for stdin/stdout/stderr. You can instead use raw I/O (bytes) by passing `mode=bytes`.\n\n```python\nimport subby\n\nassert b"1" == subby.run(\n    "grep foo | wc -l", stdin="foo\\nbar", mode=bytes\n).output\n```\n\n### Non-blocking processes\n\nBy default, the `run` function blocks until the processes are finshed running. This behavior can be changed by passing `block=False`, in which case, the caller is responsible for checking the status and/or calling the `Processes.block()` method manually.\n\n```python\nimport subby\nimport time\n\np = subby.run("sleep 10", block=False)\nfor i in range(5):\n    if p.done:\n        break\n    else:\n        time.sleep(1)\nelse:\n    # A timeout can be used to kill the process if it doesn\'t\n    # complete in a certain amount of time. By default, block()\n    # raises an error if the return code is non-zero.\n    p.block(timeout=10, raise_on_error=False)\n    \n    # The process can also be killed manually.\n    p.kill()\n\n# The `Processes.ok` property is True if the processes have\n# finished and the return code is 0.\nif not p.ok:\n    # The `Processes.output` and `Processes.error` properties\n    # provide access to the process stdout and stderr.\n    print(f"The command failed: stderr={p.error}")\n```\n\n### Convenience methods\n\nThere are also some convenience methods to improve the ergonomics for common scenarios.\n\n* `subby.cmd`: Run a single command. Equivalent to calling `subby.run([cmd], ...)`, where `cmd` is a string (with no \'|\') or list of strings.\n* `subby.sub`: Equivalent to calling `subby.run` with `mode=str` and `block=True` and returning the `output` attribute (stdout) of the resulting `Processes` object.\n\n```python\nimport subby\n\nassert subby.cmd("grep foo", stdin="foo\\nbar").output == "foo"\nassert subby.cmd(["grep", "foo"], stdin="foo\\nbar").output == "foo"\n\nassert subby.sub("grep foo | wc -l", stdin="foo\\nbar") == "1"\n```\n\n### stdin/stdout/stderr\n\nSubby supports several different types of arguments for stdin, stdout, and stderr:\n\n* A file: specified as a `pathlib.Path`; for stdin, the content is read from the file, whereas for stdout/stderr the content is written to the file (and is thus not available via the `output`/`error` properties).\n* A bytes string: for stdin, the bytes are written to a temporary file, which is passed to the process stdin.\n* One of the values provided by the `StdType` enumeration:\n    * PIPE: for stdout/stderr, `subprocess.PIPE` is used, giving the caller direct access to the process stdout/stderr streams.\n    * BUFFER: for stdout/stderr, a temporary file is used, and the contents are made available via the `output`/`error` properties after the process completes.\n    * SYS: stdin/stdout/stderr is passed through from the main process (i.e. the `sys.stdin/sys.stdout/sys.stderr` streams).\n\nBy default, the stderr streams of all processes in a chain are captured (you can disable this by passing `capture_stderr=False` to `run()`).\n\n```python\nimport subby\np = subby.run("echo -n hi | tee /dev/stderr | tee /dev/stderr")\nassert p.output == b"hi"\nassert p.get_all_stderr() == [b"", b"hi", b"hi"]\n```\n\n### Logging\n\nBy default, all executed commands are logged (with loglevel INFO). You can disable this behavior by passing `echo=False` to `run()`.\n\n```python\nimport subby\nsubby.run("touch foo")  # Echoes "touch foo" to the log with level INFO\nsubby.run("login -p mypassword", echo=False)  # Does not echo mypassword\n```\n\n### Return codes\n\nBy default, Subby treats a return code of `0` as success and all other return codes as failure. In some cases, this is not the desired behavior. A well-known example is `grep`, which has a returncode of `1` when no lines are matched. To ignore additional return codes, set the `allowed_return_codes` keyword argument to `run()`.\n\n```python\nimport subby\nsubby.run("echo foo | grep bar")  # Raises CalledProcessError\nsubby.run("echo foo | grep bar", allowed_return_codes=(0, 1))\n```\n## Contributing\n\nSubby is considered to be largely feature-complete, but if you find a bug or have a suggestion for improvement, please submit an issue (or even better, a pull request).\n\n## Acknowledgements\n\nSubby was inspired by [delegator.py](https://github.com/amitt001/delegator.py).\n\nSubby was originally written as part of the [dxpy.sugar](https://github.com/dnanexus/dx-toolkit/tree/SCI-1321_dx_sugar/src/python/dxpy/sugar) package, but because it is (hopefully) useful more generally, it is being made available as a separate package. [@Damien-Black](https://github.com/@Damien-Black) and [@msimbirsky](https://github.com/msimbirsky) contributed code and reviews.\n',
    'author': 'John Didion',
    'author_email': 'github@didion.net',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/jdidion/subby',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
