camayoc.command module¶
Execute local or remote commands.
-
class
camayoc.command.
Command
(system, response_handler=None)[source]¶ Bases:
object
A convenience class for working with local or remote commands.
This class provides the ability to execute shell commands on either the local system or a remote system. Here is a pedagogic usage example:
>>> from camayoc import command >>> system = command.System(hostname='localhost', transport='local') >>> cmd = command.Command(system) >>> response = cmd.run(('echo', '-n', 'foo')) >>> response.returncode == 0 True >>> response.stdout == 'foo' True >>> response.stderr == '' True
The above example shows how various classes fit together. It’s also verbose: smartly chosen defaults mean that most real code is much more concise.
You can customize how
Command
objects execute commands and handle responses by fiddling with the two public instance attributes:machine
- A Plumbum machine.
run()
delegates all command execution responsibilities to this object. response_handler
- A callback function. Each time
machine
executes a command, the result is handed to this callback, and the callback’s return value is handed to the user.
If
system.transport
islocal
orssh
,machine
will be set so that commands run locally or over SSH, respectively. Ifsystem.transport
isNone
, the constructor will guess how to setmachine
by comparing the hostname embedded insystem.hostname
against the current system’s hostname. If they match,machine
is set to execute commands locally; and vice versa.Parameters: - system (camayoc.command.System) – Information about the system on which commands will be executed.
- response_handler – A callback function. Defaults to
camayoc.command.code_handler()
.
-
run
(args, **kwargs)[source]¶ Run a command and
return self.response_handler(result)
.This method is a thin wrapper around Plumbum’s BaseCommand.run method, which is itself a thin wrapper around the standard library’s subprocess.Popen class. See their documentation for detailed usage instructions. See
camayoc.command.Command
for a usage example.
-
class
camayoc.command.
CompletedProcess
(args, returncode, stdout, stderr)[source]¶ Bases:
object
A process that has finished running.
This class is similar to the
subprocess.CompletedProcess
class available in Python 3.5 and above. Significant differences include the following:- All constructor arguments are required.
check_returncode()
returns a custom exception, notsubprocess.CalledProcessError
.
All constructor arguments are stored as instance attributes.
Parameters: - args – A string or a sequence. The arguments passed to
camayoc.command.Command.run()
. - returncode – The integer exit code of the executed process. Negative for signals.
- stdout – The standard output of the executed process.
- stderr – The standard error of the executed process.
-
check_returncode
()[source]¶ Raise an exception if
returncode
is non-zero.Raise
camayoc.exceptions.CalledProcessError
ifreturncode
is non-zero.Why not raise
subprocess.CalledProcessError
? Because stdout and stderr are not included when str() is called on a CalledProcessError object. A typical message is:"Command '('ls', 'foo')' returned non-zero exit status 2"
This information is valuable. One could still make
subprocess.CalledProcessError
work by overloadingargs
:>>> if isinstance(args, (str, bytes)): ... custom_args = (args, stdout, stderr) ... else: ... custom_args = tuple(args) + (stdout, stderr) >>> subprocess.CalledProcessError(args, returncode)
But this seems like a hack.
In addition, it’s generally good for an application to raise expected exceptions from its own namespace, so as to better abstract away dependencies.
-
class
camayoc.command.
System
(hostname, transport)¶ Bases:
tuple
A system representation to run commands on.
-
hostname
¶ Alias for field number 0
-
transport
¶ Alias for field number 1
-
-
camayoc.command.
code_handler
(completed_proc)[source]¶ Check the process for a non-zero return code. Return the process.
Check the return code by calling
completed_proc.check_returncode()
. See:camayoc.command.CompletedProcess.check_returncode()
.